高端定制网站速度北京软件外包公司排名
- 作者: 五速梦信息网
- 时间: 2026年03月21日 11:14
当前位置: 首页 > news >正文
高端定制网站速度,北京软件外包公司排名,wordpress 收费模板,外包公司软件开发可以去吗感谢您点开这篇文章:D#xff0c;鼠鼠我是一个代码小白#xff0c;下文是学习开源项目Open WebUI过程中的一点笔记记录#xff0c;希望能帮助到你#xff5e; 本人菜鸟#xff0c;持续成长#xff0c;能力不足有疏漏的地方欢迎一起探讨指正#xff0c;比心心#xff5e… 感谢您点开这篇文章:D鼠鼠我是一个代码小白下文是学习开源项目Open WebUI过程中的一点笔记记录希望能帮助到你 本人菜鸟持续成长能力不足有疏漏的地方欢迎一起探讨指正比心心
通过本文您可以了解 Open WebUI项目的基本信息和架构 通过ollama部署大模型、通过docker镜像和源码运行Open WebUI项目的方法 项目后端代码在多情景普通提问、联网搜索提问、上传PDF文件且联网提问、上传PDF文件非联网提问下的相关代码实现逻辑 RAG模块实现逻辑流程 目录
一、项目基本信息
二、运行项目源码
1、通过ollama部署大模型
1.1、安装ollma
1.2、配置ollama
1.3、下载模型
1.4、运行服务
命令行直接对话
REST API
2、搭建Open WebUI
2.1、通过docker部署
2.2、通过源码构建
编辑
三、项目结构
1、backend目录后端代码
1.1、start.sh
1.2、data目录
1.3、open_webui目录
1.3.1、main.py
中间件应用于FastAPI应用中
Task Endpoints
Pipelines Endpoints
Config Endpoints
OAuth Login Callback
1.3.2、apps目录
1.3.2.1、webui/main.py
1.3.2.2、webui/models重点数据库实体
1.3.2.3、openai/main.py
1.3.2.4、openai/chat_interceptor
1.3.3、retrieval目录
main.py
utils.py
2、src目录前端代码
四、特定情景下代码链路逻辑
情景1用户在界面发送消息时代码调用逻辑
情景2用户进行联网搜索提问“武汉今天天气如何”时代码调用逻辑
情景3.1用户上传PDF文件让其帮忙总结联网搜索功能关闭代码逻辑
情景3.2用户上传PDF文件让其帮忙总结联网搜索功能开启代码逻辑
五、总结 一、项目基本信息 Githubhttps://github.com/open-webui/open-webui 官方文档https://docs.openwebui.com/getting-started/ 代码版本v0.3.322024.10.6——本文学习版本目前最新版本已更新至v0.3.35截至2024.10.28 二、运行项目源码 作者本地环境Ubuntu24.04纯CPU 通过ollama部署大模型qwen2:7b作为模型端通过Open WebUI提供用户chat服务。 1、通过ollama部署大模型 ollama是大模型部署方案对应docker本质也是基于docker的容器化技术 1.1、安装ollma
官方地址https://ollama.com/
开源地址https://github.com/ollama/ollama
打开官网点击Downloard根据操作系统选择对应下载方式。 以Ubuntu24.04为例通过下述命令下载
curl -fsSL https://ollama.com/install.sh | sh#下载完成后查询版本信息
ollama -v#查看状态如上ollama已经成功安装。
1.2、配置ollama
通过编辑ollama.service进行配置
sudo vim /etc/systemd/system/ollama.service 更改HOST
由于Ollama的默认参数配置启动时设置了仅本地访问因此需要对HOST进行配置开启监听任何来源IP。
[Service]
配置远程访问
EnvironmentOLLAMA_HOST0.0.0.0 更改模型存储路径
默认情况下不同操作系统大模型存储的路径如下
macOS: ~/.ollama/modelsLinux: /usr/share/ollama/.ollama/modelsWindows: C:\Users.ollama\models
如果要修改模型文件的存储路径设置如下
[Service]
配置OLLAMA的模型存放路径
EnvironmentOLLAMA_MODELS/data/ollama/models
如果因为指定的目录ollama用户及用户组没有相应权限导致服务不能启动。可以通过授权给相应的目录权限解决问题
chown ollama:ollama ollama/models 应用配置
重载systemd并重启Ollama
systemctl daemon-reload
systemctl restart ollama
配置完成后访问测试。浏览器访问http://IP:11434/出现Ollama is running代表成功。 1.3、下载模型
ollama的命令和docker操作命令非常相似。可通过shell窗口输入ollama查看相关命令
******:~/work# ollama
Usage:ollama [flags]ollama [command]Available Commands:serve Start ollamacreate Create a model from a Modelfileshow Show information for a modelrun Run a modelpull Pull a model from a registrypush Push a model to a registrylist List modelsps List running modelscp Copy a modelrm Remove a modelhelp Help about any commandFlags:-h, –help help for ollama-v, –version Show version informationUse ollama [command] –help for more information about a command.由上可知ollama相关命令
ollama serve # 启动ollama
ollama create # 从模型文件创建模型
ollama show # 显示模型信息
ollama run # 运行模型
ollama pull # 从注册仓库中拉取模型
ollama push # 将模型推送到注册仓库
ollama list # 列出已下载模型
ollama cp # 复制模型
ollama rm # 删除模型
ollama help # 获取有关任何命令的帮助信息 拉取qwen2-7b模型
ollama pull qwen2:7b#下载成功查看模型
ollama list
可见已成功拉取 也可以自定义模型所谓自定义模型就是不适用Ollama官方模型库中的模型理论可以使用其他各类经过转换处理的模型有从GGUF导入和从PyTorch或Safetensors导入两种方式。
所谓从从PyTorch或Safetensors导入Ollama其实就是使用llama.cpp项目对PyTorch或Safetensors类型的模型进行转换、量化处理成GGUF格式的模型然后再用Ollama加载使用 。
参考Ollama一个在本地部署、运行大型语言模型的工具-CSDN博客 运行模型
运行模型并进行对话
ollama run qwen2:7b 1.4、运行服务
命令行直接对话
如上运行模型可以直接与模型进行对话。
REST API
运行模型后执行ollama serve命令启动Ollama服务然后就可以通过API形式进行模型调用。ollama serve会自动启动一个http服务可以通过http请求模型服务。
参考官方API文档https://github.com/ollama/ollama/blob/main/docs/api.md 生成回复
curl http://localhost:11434/api/generate -d {model: qwen2:7b,prompt:你是谁为什么天空是蓝色的?
}
上述localhost也可以换成ip。 若要禁用流式如下操作
curl http://ip:11434/api/generate -d {model: qwen2:7b,prompt:你是谁为什么天空是蓝色的?,stream:false
} 与模型聊天
curl http://localhost:11434/api/chat -d {model: qwen2:7b,messages: [{ role: user, content: 天空为什么是蓝色的? }]
} 也可以带历史记录
curl http://localhost:11434/api/chat -d {model: qwen2:7b,messages: [{role: user,content: why is the sky blue?},{role: assistant,content: due to rayleigh scattering.},{role: user,content: how is that different than mie scattering?}]
}
2、搭建Open WebUI Open WebUI 是一个可扩展、功能丰富且用户友好的自托管 WebUI旨在完全离线操作。它支持各种 LLM 运行程序包括 Ollama 和 OpenAI 兼容的 API。 Githubhttps://github.com/open-webui/open-webui Open WebUIhttps://docs.openwebui.com/ 社区https://openwebui.com/
2.1、通过docker部署
使用Docker部署安装Open WebUI。计算机已有ollama使用以下命令
docker run -d -p 3000:8080 –add-hosthost.docker.internal:host-gateway -v open-webui:/app/backend/data –name open-webui –restart always ghcr.io/open-webui/open-webui:main 访问http://IP:3000创建一个账号(管理员) 登陆账号 进入Open WebUI后界面如下。在Settings中进行相关设置 管理员设置设置外部连接 设置连接后在选择模型部分可见上面下载下来的千问模型 选择模型即可进行对话 2.2、通过源码构建
也可以通过本地运行项目源码进行搭建。以Linux为例
Copying required .env file
cp -RPp .env.example .env# Building Frontend Using Node npm install npm run buildcd ./backend# Optional: To install using Conda as your development environment, follow these instructions:
Create and activate a Conda environment
conda create –name open-webui-env python3.11
conda activate open-webui-env# Install dependencies
pip install -r requirements.txt -U# Start the application
bash start.sh
在鼠鼠我多次构建的过程中有次有遇到一个错误报错如下
(venv) ***:~/PycharmProjects/openwebui(v0.3.32)/open-webui$ npm run build open-webui0.3.32 buildnpm run pyodide:fetch vite build open-webui0.3.32 pyodide:fetchnode scripts/prepare-pyodide.jsSetting up pyodide micropip
Failed to load Pyodide: Error [ERR_MODULE_NOT_FOUND]: Cannot find module /home//PycharmProjects/openwebuiv0.3.32/open-webui/node_modules/pyodide/pyodide.asm.js imported from /home//PycharmProjects/openwebui(v0.3.32)/open-webui/node_modules/pyodide/pyodide.mjsat new NodeError (node:internal/errors:405:5)at finalizeResolution (node:internal/modules/esm/resolve:327:11)at moduleResolve (node:internal/modules/esm/resolve:980:10)at defaultResolve (node:internal/modules/esm/resolve:1193:11)at ModuleLoader.defaultResolve (node:internal/modules/esm/loader:403:12)at ModuleLoader.resolve (node:internal/modules/esm/loader:372:25)at ModuleLoader.getModuleJob (node:internal/modules/esm/loader:249:38)at ModuleLoader.import (node:internal/modules/esm/loader:335:34)at importModuleDynamically (node:internal/modules/esm/translators:143:35)at importModuleDynamicallyCallback (node:internal/modules/esm/utils:112:14) {url: file:///home//PycharmProjects/openwebuiv0.3.32/open-webui/node_modules/pyodide/pyodide.asm.js,code: ERR_MODULE_NOT_FOUND
}
Copying Pyodide files into static directory
node:internal/process/promises:288triggerUncaughtException(err, true /* fromPromise /);^[Error: ENOENT: no such file or directory, open /home/**/PycharmProjects/openwebuiv0.3.32/open-webui/node_modules/pyodide/python_stdlib.zip] {errno: -2,code: ENOENT,syscall: open,path: /home/*/PycharmProjects/openwebuiv0.3.32/open-webui/node_modules/pyodide/python_stdlib.zip
}Node.js v18.19.1原因涉及两方面一是node.js 版本问题如下图官方最新文档要求目前版本低于要求版本。 另一个方面——文件夹命名问题。原来的项目处于的一个文件夹为“openwebui(v0.3.32)”其中包含括号和.在后续代码执行中由于路径中包含特殊字符在这个案例中是括号 ( 和 )导致命令解释错误或者文件系统路径解析出现问题。在文件或目录名称中使用特殊字符如括号、星号、问号、波浪线等经常会导致这类问题因为这些字符在 Unix 和 Linux 命令行中可能有特殊含义。
解决方法将项目所处的目录进行重命名为“openwebui_v0_3_32”即可解决。 Q点击“”功能只有“上传文件”没有“联网搜索”如何解决
A需要管理员在面板中进行设置搜索引擎本质上是通过api调用 三、项目结构
整个代码语言构成分布如下其中Svelte 是一种现代的前端框架用于构建高性能的Web应用程序。 项目文件如下所示主要分为前端、后端、测试和部署脚本 backend目录后端代码目录包含API服务、数据库操作等 cypress 目录包含Cypress测试框架的配置和测试脚本用于端到端测试 docs 目录文档目录包含项目说明、安全指南等。 kubernetes 包含Kubernetes部署配置文件。 scripts 包含各种脚本文件用于自动化部署、测试或其他任务的脚本。 src 前端代码目录存放Svelte组件和相关资源的地方。 static 静态文件目录如图片、CSS、客户端JavaScript等。 test/test_files/image_gen 测试目录下的子目录包含用于测试的图像生成器。 1、backend目录后端代码 data文件夹用于存储后端服务需要的数据文件如数据库、文档等 open-webui文件夹包含后端服务的主要代码和配置文件 dev.sh用于本地开发环境的启动脚本 start.sh 和 start_windows.bat - 用于启动后端服务的脚本分别适用于类Unix系统和Windows系统。
1.1、start.sh
启动脚本最后会启动一个 Uvicorn 服务器并通过这个命令来运行 open-webui/backend/open_webui/main.py 文件中的FastAPI的 app 应用对象监听在指定的主机和端口上并允许所有的转发 IP 地址。 1.2、data目录 cache - 用于存储应用程序的缓存数据。 functions - 包含一些后端服务使用的函数或脚本。 tools - 包含一些用于后端服务的工具或脚本。 uploads - 用于存储用户上传的文件。 vector_db - 用于存储向量数据库或类似的数据结构。 readme.txt - 包含文件夹的说明或使用指南。 webui.db - 后端服务使用的数据库文件。 1.3、open_webui目录 apps - 包含后端服务的应用程序逻辑。 data - 与主data文件夹类似用于存储后端服务需要的数据文件。 migrations - 包含数据库迁移脚本用于数据库结构的版本控制。 static - 包含静态文件如图片、CSS、JavaScript等。 test - 包含测试代码和测试用例。 utils - 包含一些后端服务使用的实用工具或函数。 init.py - Python模块初始化文件。 alembic.ini - Alembic数据库迁移工具的配置文件。 config.py - 后端服务的配置文件。 constants.py - 包含后端服务使用的常量。 env.py - 包含环境变量的配置。 main.py - 是后端服务的入口点或主程序。
1.3.1、main.py
中间件应用于FastAPI应用中
ChatCompletionMiddleware类 用于处理与聊天补全相关的请求包括模型选择、过滤函数、工具函数调用和文件处理。 PipelineMiddleware类对请求进行预处理和后处理。处理管道中的过滤器调用。 也添加中间件CORSMiddleware、SecurityHeadersMiddleware 以及 PipelineMiddleware 本身分别负责处理跨域资源共享CORS、安全头部设置以及自定义的业务逻辑处理。
设置相关路由 app.get(/api/models) 用于获取模型的列表 app.post(/api/chat/completed)完整的聊天补全请求处理流程包括模型验证、外部API调用、事件处理、全局和本地过滤器调用。 app.post(/api/chat/actions/{action_id})用于处理特定动作的请求。它通过执行与动作ID关联的功能来响应聊天中的动作请求 Task Endpoints 路由 作用 GET请求端点/api/task/config 它返回当前应用的状态配置信息 POST请求端点/api/task/config/update 用于更新任务配置。只有管理员用户可以访问此端点并且需要提供一个符合TaskConfigForm模型的JSON数据体来进行更新操作。 POST请求端点/api/task/title/completions 用于根据给定的提示生成标题 POST请求端点/api/task/query/completions 用于根据用户的对话历史生成搜索查询 POST请求端点/api/task/emoji/completions 用于根据文本内容生成相应的表情符号 POST请求端点/api/task/moa/completions 用于综合多个模型的响应生成最终答案 Pipelines Endpoints
app.get(/api/pipelines/list)通过调用get_openai_models函数获取模型列表然后筛选出包含“pipelines”字段的响应并返回相应的API URL和索引
Config Endpoints
app.post(/api/pipelines/upload)允许用户上传Python脚本文件作为管道。 接下来的几个段落分别定义了添加、删除管道以及获取管道详情等的端点
并且定义了一系列API端点用于管理和获取应用程序的配置信息。 OAuth Login Callback
实现完整的OAuth登录和注册流程包括客户端注册、会话管理、用户认证和JWT令牌生成等功能。 1.3.2、apps目录 1.3.2.1、webui/main.py
注册了多个路由处理器处理不同类型api请求如用户认证、文件上传、模型管理等。
定义相关核心函数 get_status根路由处理函数返回应用的状态信息。 get_function_module根据管道ID加载函数模块。 get_pipe_models获取管道模型的详细信息。 execute_pipe执行管道函数。 get_message_content从不同的响应类型中获取消息内容。 process_line处理聊天消息的每一行。 get_pipe_id从表单数据中获取管道ID。 get_function_params获取函数参数。 最后定义函数generate_function_chat_completion实现聊天补全处理相关逻辑。 1.3.2.2、webui/models重点数据库实体
未完待续。。。。。。待整理 1.3.2.3、openai/main.py 设置FastAPI应用、Middleware和依赖注入中间件会在每次请求前执行确保在访问模型端点之前已经加载了模型数据。 设置api路由 /config提供了一个GET方法来返回当前的应用程序配置包括是否启用OpenAI API的功能。 /config/update接受一个POST请求更新应用程序的配置特别是启用或禁用OpenAI API的功能。 /urls和/keys分别提供了GET方法来显示当前的OpenAI API URLs和Keys列表以及POST方法来更新这些列表。 /audio/speech这是一个音频处理的端点接受用户的语音输入并生成对应的音频文件响应。 设置异步函数例如fetch_url, cleanup_response, merge_models_lists, get_all_models_raw, get_all_models等。这些函数主要负责与外部API通信、处理JSON数据、合并模型列表等工作。 1.3.2.4、openai/chat_interceptor
实现一个简单的聊天系统拦截器可以用于检查和处理特定的情况例如不支持的URL或过长的上下文文本。 模块 实现 解析用户输入 get_message_text函数从用户输入中提取文本内容 生成聊天响应 generate_chat_response函数生成聊天响应包括生成一个唯一的ID、创建时间、模型名称、选择内容和使用情况 拦截器列表 包含了一系列的拦截器实例 chat_interceptor_before_lark_doc_content和 chat_interceptor_after_lark_doc_content 分别在处理飞书文档内容之前和之后使用的拦截器列表。 拦截器入口 遍历拦截器列表并调用每个拦截器的 intercept 方法 intercept_chat_completion_before_lark_doc_content和intercept_chat_completion_after_lark_doc_content 分别是在处理飞书文档内容之前和之后调用的拦截器入口函数。 拦截器类型 UnsupportedUrlChatCompletionInterceptor 检查用户输入中是否包含不支持的URL如果是则返回默认回答。 LongContextTextChatCompletionInterceptor 检查用户输入的文本是否过长如果是则返回默认回答。 拦截器调用 在发送聊天请求之前或之后调用拦截器列表中的拦截器每个拦截器都会检查请求并决定是否拦截请求。 1.3.3、retrieval目录 loaders从各种来源加载和处理文档内容适用于需要跨多种文件格式工作的应用场景。 models定义了用于检索任务的模型 vector 包含与向量相关的文件如dbs和connector.py用于处理向量数据库的连接和交互以及向量化文本数据以用于相似性搜索。 main.py文件可能包含与向量检索相关的主要逻辑。 web 包含多个与Web相关的Python文件如brave.py、duckduckgo.py等这些文件用于实现与不同搜索引擎如Brave Search、DuckDuckGo的交互以便从这些搜索引擎获取数据。 main.py和utils.py文件可能包含Web应用的主要逻辑和辅助功能。 testdata目录可能包含用于测试的示例数据。 utils.py一个通用的工具文件包含在整个应用中使用的辅助函数和类。 main.py后端服务入口点主要用于处理文档检索和向量数据库操作。 下面的内容是旧版本v0.3.21中rag目录即对应v0.3.32中retrieval目录两版本肯定有差异下面是之前学习旧版本的笔记仅供参考 main.py
配置和模型更新 定义 update_embedding_model 和 update_reranking_model 函数来更新嵌入和重排模型。 使用 get_embedding_function 获取嵌入函数用于将文本转换为向量表示
API 路由和处理函数 定义了多个 API 路由和处理函数例如 /根路由返回应用状态。 /embedding返回嵌入模型的配置。 /reranking返回重排模型的配置。 /embedding/update 和 /reranking/update更新嵌入和重排模型的配置。 /config返回 RAG 应用的配置。 /config/update更新 RAG 应用的配置。 /template 和 /query/settings获取和更新查询模板和设置。 /query/doc 和 /query/collection处理文档和集合的查询请求。 /youtube 和 /web处理 YouTube 视频和网页内容的存储请求。 /web/search处理网页搜索请求。
文档和网页处理 定义了 get_loader 函数根据文件类型选择适当的加载器如 TikaLoader、TextLoader 等。 定义了 store_data_in_vector_db 和 store_text_in_vector_db 函数用于将数据存储到向量数据库中。
错误处理 使用 HTTPException 处理错误情况并返回错误信息。
辅助函数 定义 get_web_loader、validate_url、resolve_hostname 等辅助函数用于加载和验证网页内容。
搜索功能 定义 search_web 函数用于通过不同的搜索引擎进行搜索。
安全加载器 定义 SafeWebBaseLoader 类用于增强错误处理确保即使某些 URL 无法访问系统仍然可以正常工作。 rag模块的作用流程 utils.py
处理检索增强生成RAG任务的函数主要涉及从不同数据源中提取和查询信息 query_doc 函数用于从一个指定的集合中查询与给定查询最相关的文档。 query_doc_with_hybrid_search 函数扩展了基本的查询功能引入了混合搜索的概念。它不仅使用BM25Retriever进行初步筛选还结合了ChromaRetriever进行更精确的搜索并通过EnsembleRetriever组合两者的结果。此外它还包括一个重排序步骤通过RerankCompressor对结果进行进一步优化。 merge_and_sort_query_results 函数用于合并多个查询结果并对它们按相关性进行排序。它会将所有结果的距离、文档和元数据合并在一起然后根据距离进行降序或升序排列最后只保留前K个结果。 query_collection 和 query_collection_with_hybrid_search 函数这两个函数分别实现了基于普通搜索和混合搜索的多集合查询。它们遍历一组集合名称对每个集合执行相应的查询操作并将结果合并和排序后返回。 rag_template 函数用于替换模板字符串中的占位符以便在生成的上下文中插入具体的查询和上下文内容。 get_embedding_function 函数根据不同的嵌入引擎和模型生成对应的嵌入函数。 get_rag_context 函数从文件列表和消息记录中提取与当前查询最相关的上下文。 get_model_path 函数用于确定Hugging Face模型的本地路径。 generate_openai_embeddings 和 generate_openai_batch_embeddings 函数用于调用OpenAI API生成文本的嵌入向量。前者处理单个文本输入后者则可以处理一批文本输入适用于批量处理的场景。 ChromaRetriever 类和 RerankCompressor 类分别是LangChain库中原有的Retriever和DocumentCompressor的具体实现。ChromaRetriever负责从Chroma数据库中检索文档而RerankCompressor则在检索到的文档基础上进行进一步的重排序。 。。。。。。未完待续鼠鼠后面有空会继续更新的惹 2、src目录前端代码 lib包含可重用的JavaScript或Svelte组件、工具函数、实用程序等 routes:包含Svelte路由文件用于定义应用程序的页面路由。 app.css:包含全局样式表定义了样式重置、通用样式或主题。 app.d.ts:TypeScript的声明文件用于为项目提供类型定义。 app.html:项目的HTML模板文件通常是应用程序的入口点。 tailwind.css:使用Tailwind CSS时的全局样式文件。 由于前端不是鼠鼠我学习的重点所以没在看前端部分了 四、特定情景下代码链路逻辑
情景1用户在界面发送消息时代码调用逻辑 核心部分
1、构建prompt和调用大模型 [open_webui.apps.ollama.main]
app.post(/api/chat/{url_idx})
async def generate_chat_completion(form_data: GenerateChatCompletionForm,url_idx: Optional[int] None,userDepends(get_verified_user),
):log.info(f/api/chat或/api/chat/{url_idx})payload {form_data.model_dump(exclude_noneTrue)}log.debug(f{payload })if metadata in payload:del payload[metadata]model_id form_data.modelif app.state.config.ENABLE_MODEL_FILTER:if user.role user and model_id not in app.state.config.MODEL_FILTER_LIST:raise HTTPException(status_code403,detailModel not found,)model_info Models.get_model_by_id(model_id)if model_info:if model_info.base_model_id:payload[model] model_info.base_model_idparams model_info.params.model_dump()if params:if payload.get(options) is None:payload[options] {}payload[options] apply_model_params_to_body_ollama(params, payload[options])#构建promptpayload apply_model_system_prompt_to_body(params, payload, user)if : not in payload[model]:payload[model] f{payload[model]}:latesturl get_ollama_url(url_idx, payload[model])log.info(furl: {url})log.debug(payload)#调用大模型return await post_streaming_url(f{url}/api/chat,json.dumps(payload),streamform_data.stream,content_typeapplication/x-ndjson,)
构建prompt的apply_model_system_prompt_to_body函数细节 backend/open_webui/utils/payload.py
inplace function: form_data is modified
def apply_model_system_prompt_to_body(params: dict, form_data: dict, user) - dict:system params.get(system, None)if not system:return form_dataif user:template_params {user_name: user.name,user_location: user.info.get(location) if user.info else None,}else:template_params {}system prompt_template(system, template_params)form_data[messages] add_or_update_system_message(system, form_data.get(messages, []))return form_data调用大模型的post_streaming_url函数细节 backend/open_webui/apps/ollama/main.py async def post_streaming_url(url: str, payload: Union[str, bytes], stream: bool True, content_typeNone ):log.info(post_streaming_url)r Nonetry:session aiohttp.ClientSession(trust_envTrue, timeoutaiohttp.ClientTimeout(totalAIOHTTP_CLIENT_TIMEOUT))r await session.post(url,datapayload,headers{Content-Type: application/json},)r.raise_for_status()if stream:headers dict(r.headers)if content_type:headers[Content-Type] content_typereturn StreamingResponse(r.content,status_coder.status,headersheaders,backgroundBackgroundTask(cleanup_response, responser, sessionsession),)else:res await r.json()await cleanup_response(r, session)return resexcept Exception as e:error_detail Open WebUI: Server Connection Errorif r is not None:try:res await r.json()if error in res:error_detail fOllama: {res[error]}except Exception:error_detail fOllama: {e}raise HTTPException(status_coder.status if r else 500,detailerror_detail,)情景2用户进行联网搜索提问“武汉今天天气如何”时代码调用逻辑 核心代码 1、生成搜索查询 backend/open_webui/main.py app.post(/api/task/query/completions) async def generate_search_query(form_data: dict, userDepends(get_verified_user)):log.info(/api/task/query/completions)print(generate_search_query)if not app.state.config.ENABLE_SEARCH_QUERY:raise HTTPException(status_codestatus.HTTP_400_BAD_REQUEST,detailfSearch query generation is disabled,)model_id form_data[model]if model_id not in app.state.MODELS:raise HTTPException(status_codestatus.HTTP_404_NOT_FOUND,detailModel not found,)# Check if the user has a custom task model# If the user has a custom task model, use that modeltask_model_id get_task_model_id(model_id)print(task_model_id)model app.state.MODELS[task_model_id]if app.state.config.SEARCH_QUERY_GENERATION_PROMPT_TEMPLATE ! :template app.state.config.SEARCH_QUERY_GENERATION_PROMPT_TEMPLATEelse:template Given the users message and interaction history, decide if a web search is necessary. You must be concise and exclusively provide a search query if one is necessary. Refrain from verbose responses or any additional commentary. Prefer suggesting a search if uncertain to provide comprehensive or updated information. If a search isnt needed at all, respond with an empty string. Default to a search query when in doubt. Todays date is {{CURRENT_DATE}}.User Message: {{prompt:end:4000}}Interaction History: {{MESSAGES:END:6}}Search Query:content search_query_generation_template(template, form_data[messages], {name: user.name})print(content, content)payload {model: task_model_id,messages: [{role: user, content: content}],stream: False,({max_tokens: 30}if app.state.MODELS[task_model_id][owned_by] ollamaelse {max_completion_tokens: 30,}),metadata: {task: str(TASKS.QUERY_GENERATION), task_body: form_data},}log.debug(payload)# Handle pipeline filterstry:payload filter_pipeline(payload, user)except Exception as e:if len(e.args) 1:return JSONResponse(status_codee.args[0],content{detail: e.args[1]},)else:return JSONResponse(status_codestatus.HTTP_400_BAD_REQUEST,content{detail: str(e)},)if chat_id in payload:del payload[chat_id]return await generate_chat_completions(form_datapayload, useruser) 2、执行搜索查询 backend/open_webui/apps/retrieval/main.py app.post(/process/web/search) def process_web_search(form_data: SearchForm, userDepends(get_verified_user)):log.info(调用函数process_web_search)try:logging.info(ftrying to web search with {app.state.config.RAG_WEB_SEARCH_ENGINE, form_data.query})web_results search_web(app.state.config.RAG_WEB_SEARCH_ENGINE, form_data.query)except Exception as e:log.exception(e)print(e)raise HTTPException(status_codestatus.HTTP_400_BAD_REQUEST,detailERROR_MESSAGES.WEB_SEARCH_ERROR(e),)try:collection_name form_data.collection_nameif collection_name :collection_name calculate_sha256_string(form_data.query)[:63]urls [result.link for result in web_results]loader get_web_loader(urls)docs loader.load()save_docs_to_vector_db(docs, collection_name, overwriteTrue)return {status: True,collection_name: collection_name,filenames: urls,}except Exception as e:log.exception(e)raise HTTPException(status_codestatus.HTTP_400_BAD_REQUEST,detailERROR_MESSAGES.DEFAULT(e),) 情景3.1用户上传PDF文件让其帮忙总结联网搜索功能关闭代码逻辑 核心代码 1、接收处理保存用户上传的PDF文件 backend/open_webui/apps/webui/routers/files.py router.post(/) def upload_file(file: UploadFile File(…), userDepends(get_verified_user)):log.info(调用函数upload_file)log.info(ffile.content_type: {file.content_type})try:unsanitized_filename file.filenamefilename os.path.basename(unsanitizedfilename)# replace filename with uuidid str(uuid.uuid4())name filenamefilename f{id}{filename}file_path f{UPLOAD_DIR}/{filename}contents file.file.read()with open(file_path, wb) as f:f.write(contents)f.close()file Files.insert_new_file(user.id,FileForm({id: id,filename: filename,meta: {name: name,content_type: file.content_type,size: len(contents),path: file_path,},}),)try:process_file(ProcessFileForm(file_idid))file Files.get_file_by_id(idid)except Exception as e:log.exception(e)log.error(fError processing file: {file.id})if file:return fileelse:raise HTTPException(status_codestatus.HTTP_400_BAD_REQUEST,detailERROR_MESSAGES.DEFAULT(Error uploading file),)except Exception as e:log.exception(e)raise HTTPException(status_codestatus.HTTP_400_BAD_REQUEST,detailERROR_MESSAGES.DEFAULT(e),) 2、上述调用的处理文件的函数 backend/open_webui/apps/retrieval/main.py app.post(/process/file) def process_file(form_data: ProcessFileForm,userDepends(get_verified_user), ):log.info(调用函数process_file)try:file Files.get_file_by_id(form_data.file_id)collection_name form_data.collection_nameif collection_name is None:collection_name ffile-{file.id}if form_data.content:# Update the content in the file# Usage: /files/{file_id}/data/content/updateVECTOR_DB_CLIENT.delete(collection_nameffile-{file.id},filter{file_id: file.id},)docs [Document(page_contentform_data.content,metadata{name: file.meta.get(name, file.filename),created_by: file.user_id,file_id: file.id,file.meta,},)]text_content form_data.contentelif form_data.collection_name:# Check if the file has already been processed and save the content# Usage: /knowledge/{id}/file/add, /knowledge/{id}/file/updateresult VECTOR_DB_CLIENT.query(collection_nameffile-{file.id}, filter{file_id: file.id})if len(result.ids[0]) 0:docs [Document(page_contentresult.documents[0][idx],metadataresult.metadatas[0][idx],)for idx, id in enumerate(result.ids[0])]else:docs [Document(page_contentfile.data.get(content, ),metadata{name: file.meta.get(name, file.filename),created_by: file.user_id,file_id: file.id,file.meta,},)]text_content file.data.get(content, )else:# Process the file and save the content# Usage: /files/file_path file.meta.get(path, None)if file_path:loader Loader(engineapp.state.config.CONTENT_EXTRACTION_ENGINE,TIKA_SERVER_URLapp.state.config.TIKA_SERVER_URL,PDF_EXTRACT_IMAGESapp.state.config.PDF_EXTRACT_IMAGES,)docs loader.load(file.filename, file.meta.get(content_type), file_path)else:docs [Document(page_contentfile.data.get(content, ),metadata{name: file.filename,created_by: file.user_id,file_id: file.id,file.meta,},)]text_content .join([doc.page_content for doc in docs])log.debug(ftext_content: {text_content})Files.update_file_data_by_id(file.id,{content: text_content},)hash calculate_sha256_string(text_content)Files.update_file_hash_by_id(file.id, hash)try:result save_docs_to_vector_db(docsdocs,collection_namecollection_name,metadata{file_id: file.id,name: file.meta.get(name, file.filename),hash: hash,},add(True if form_data.collection_name else False),)if result:Files.update_file_metadata_by_id(file.id,{collection_name: collection_name,},)return {status: True,collection_name: collection_name,filename: file.meta.get(name, file.filename),content: text_content,}except Exception as e:raise eexcept Exception as e:log.exception(e)if No pandoc was found in str(e):raise HTTPException(status_codestatus.HTTP_400_BAD_REQUEST,detailERROR_MESSAGES.PANDOC_NOT_INSTALLED,)else:raise HTTPException(status_codestatus.HTTP_400_BAD_REQUEST,detailstr(e),)情景3.2用户上传PDF文件让其帮忙总结联网搜索功能开启代码逻辑 五、总结 开源项目目前还在不断更新迭代相信后面会有更好的功能体验。本人水平有限有错轻喷谢谢
- 上一篇: 高端定制网站设计2023免费网站推广
- 下一篇: 高端建站的公司谷歌云 阿里云 做网站
相关文章
-
高端定制网站设计2023免费网站推广
高端定制网站设计2023免费网站推广
- 技术栈
- 2026年03月21日
-
高端定制网站公司哪家好wordpress 体育
高端定制网站公司哪家好wordpress 体育
- 技术栈
- 2026年03月21日
-
高端的网站优化公司网页游戏网站排名
高端的网站优化公司网页游戏网站排名
- 技术栈
- 2026年03月21日
-
高端建站的公司谷歌云 阿里云 做网站
高端建站的公司谷歌云 阿里云 做网站
- 技术栈
- 2026年03月21日
-
高端建站什么意思什么是多页面网站
高端建站什么意思什么是多页面网站
- 技术栈
- 2026年03月21日
-
高端美食网站建设网站建设布局
高端美食网站建设网站建设布局
- 技术栈
- 2026年03月21日






