Ollama 集成(中文译文)
原始 DeepWiki 页面:https://deepwiki.com/open-webui/open-webui/13.2-ollama-integration
翻译时间:2026-06-09T16:11:07.908Z
翻译模型:deepseek-chat
原文字符数:11743
项目:Open WebUI (open-webui)
---
Ollama 集成
相关源文件
以下文件为本 wiki 页面的生成提供了上下文:
backend/open_webui/routers/ollama.pybackend/open_webui/routers/openai.pybackend/open_webui/utils/embeddings.pybackend/open_webui/utils/misc.pybackend/open_webui/utils/payload.pybackend/open_webui/utils/response.pysrc/lib/apis/ollama/index.tssrc/lib/apis/openai/index.tssrc/lib/components/chat/Settings/Connections.svelte
目的与范围
本文档描述 Open WebUI 如何与本地 LLM 运行时 Ollama 集成。该集成使 Open WebUI 能够发现、管理并与一个或多个 Ollama 服务器上托管的模型进行交互,包括模型发现、聊天补全、嵌入生成,以及 OpenAI API 格式与 Ollama 原生格式之间的双向格式转换。
关于 OpenAI API 集成,请参见 OpenAI 集成。关于通用模型管理概念,请参见 模型配置与访问。
---
架构概述
Open WebUI 充当兼容层,向前端提供统一的 OpenAI 兼容 API,同时将请求转换为 Ollama 的原生格式。可配置多个 Ollama 实例,模型会跨所有实例聚合。
系统组件与数据流
下图展示了用户界面的自然语言请求如何转换为代码实体并路由到 Ollama 后端。
标题:Ollama 请求路由与转换
graph TB
subgraph "前端空间"
UI["聊天界面<br/>(自然语言)"]
OllamaAPI["ollama/index.ts<br/>[src/lib/apis/ollama/index.ts:1]()"]
end
subgraph "代码实体空间:后端 API 层"
ChatRouter["generate_chat_completion()<br/>[backend/open_webui/routers/ollama.py:1174]()"]
OllamaRouter["ollama.py 路由器<br/>[backend/open_webui/routers/ollama.py:217]()"]
PayloadConv["convert_payload_openai_to_ollama()<br/>[backend/open_webui/utils/payload.py:280]()"]
ResponseConv["convert_response_ollama_to_openai()<br/>[backend/open_webui/utils/response.py:116]()"]
end
subgraph "配置与状态"
Config["request.app.state.config<br/>ENABLE_OLLAMA_API<br/>OLLAMA_BASE_URLS"]
ModelCache["request.app.state.MODELS<br/>Dict[model_id, model_info]"]
end
subgraph "外部:Ollama 服务器"
Ollama1["Ollama 实例 1<br/>/api/chat"]
Ollama2["Ollama 实例 2<br/>/api/chat"]
end
UI --> OllamaAPI
OllamaAPI -->|"OpenAI 格式负载"| ChatRouter
ChatRouter -->|"如果 owned_by == 'ollama'"| PayloadConv
PayloadConv -->|"Ollama 格式负载"| OllamaRouter
OllamaRouter -->|"send_request()"| Ollama1
OllamaRouter -->|"send_request()"| Ollama2
Ollama1 -->|"流式 JSON"| ResponseConv
ResponseConv -->|"OpenAI 格式数据块"| ChatRouter
ChatRouter -->|"服务器推送事件"| UI
Config -.->|"运行时配置"| OllamaRouter
ModelCache -.->|"模型元数据"| OllamaRouter
来源: backend/open_webui/routers/ollama.py:217, backend/open_webui/routers/ollama.py:1174, backend/open_webui/utils/payload.py:280-371, backend/open_webui/utils/response.py:116-135, src/lib/apis/ollama/index.ts:1-10
---
配置系统
环境变量与持久化配置
Ollama 集成通过 PersistentConfig 系统进行配置。关键配置值可通过后端的 request.app.state.config 和前端的 OllamaConfig 访问 src/lib/apis/ollama/index.ts:65-69。
| 配置键 | 类型 | 描述 |
|---|---|---|
ENABLE_OLLAMA_API | bool | 启用/禁用 Ollama 集成的总开关 backend/open_webui/routers/ollama.py:264 |
OLLAMA_BASE_URLS | list[str] | Ollama 服务器 URL 列表 backend/open_webui/routers/ollama.py:265 |
OLLAMA_API_CONFIGS | dict | 按位置或 URL 索引的每个实例配置 backend/open_webui/routers/ollama.py:267 |
API 配置结构: OLLAMA_API_CONFIGS 中的每个条目可包含元数据,例如用于 Bearer 令牌的 key、用于模型命名空间的 prefix_id 以及用于分类的 tags backend/open_webui/routers/ollama.py:188-194。
来源: backend/open_webui/routers/ollama.py:188-194, backend/open_webui/routers/ollama.py:261-297, src/lib/apis/ollama/index.ts:65-69
---
模型发现与聚合
发现过程
Ollama 模型通过查询每个已配置实例的 /api/tags 端点来发现。系统将这些模型聚合到一个统一的列表中。
标题:Ollama 模型发现与聚合
sequenceDiagram
participant Client as "Settings/Connections.svelte [src/lib/components/chat/Settings/Connections.svelte:1]()"
participant G as "get_all_models()<br/>[backend/open_webui/routers/ollama.py:321]()"
participant O1 as "Ollama 实例 1"
participant O2 as "Ollama 实例 2"
participant M as "merge_ollama_models_lists()<br/>[backend/open_webui/routers/ollama.py:448]()"
Client->>G: 通过 /api/tags 请求模型
par 并发发现
G->>O1: GET /api/tags
G->>O2: GET /api/tags
end
O1-->>G: {models: [...]}
O2-->>G: {models: [...]}
G->>M: 合并结果
M-->>G: 合并后的 Dict[model_id, metadata]
G-->>Client: JSON 模型列表
模型合并逻辑: merge_ollama_models_lists() 函数合并来自多个实例的模型 backend/open_webui/routers/ollama.py:448-501。如果同一模型存在于多个服务器上,它会在 urls 列表中跟踪所有实例索引 backend/open_webui/routers/ollama.py:476。
来源: backend/open_webui/routers/ollama.py:321-415, backend/open_webui/routers/ollama.py:448-501, src/lib/components/chat/Settings/Connections.svelte:1-20
---
负载格式转换
OpenAI 到 Ollama 的转换
主要的转换函数是 convert_payload_openai_to_ollama(),它将 OpenAI 兼容的聊天补全请求转换为 Ollama 的原生 /api/chat 格式 backend/open_webui/utils/payload.py:280-371。
关键转换:
| OpenAI 字段 | Ollama 字段 | 转换逻辑 |
|---|---|---|
max_tokens | num_predict | 重命名并移至 options backend/open_webui/utils/payload.py:140-148 |
messages | messages | 通过 convert_messages_openai_to_ollama() 格式化 backend/open_webui/utils/payload.py:200-278 |
temperature | options.temperature | 转换为 float backend/open_webui/utils/payload.py:151 |
stop | options.stop | 解码 unicode 转义字符串 backend/open_webui/utils/payload.py:167 |
消息格式转换
convert_messages_openai_to_ollama() 函数处理多模态内容,将 OpenAI 的 image_url 格式中的 base64 图像数据提取到 Ollama 的 images 数组中 backend/open_webui/utils/payload.py:230-245。它还处理工具调用从 OpenAI 嵌套结构到 Ollama 预期格式的转换 backend/open_webui/utils/payload.py:255-276。
来源: backend/open_webui/utils/payload.py:120-197, backend/open_webui/utils/payload.py:200-278, backend/open_webui/utils/payload.py:280-371
---
聊天补全流程
请求路由
当聊天补全请求到达 generate_ollama_chat_completion() backend/open_webui/routers/ollama.py:1174 时,系统会:
- 通过
request.app.state.MODELS将模型解析为物理 URLbackend/open_webui/routers/ollama.py:1238。 - 从模型名称中去除已配置的
prefix_idbackend/open_webui/routers/ollama.py:1253-1260。 - 通过
apply_model_params_to_body_ollama()应用模型特定参数backend/open_webui/utils/payload.py:120-197。 - 使用
send_request()转发请求backend/open_webui/routers/ollama.py:125-203。
来源: backend/open_webui/routers/ollama.py:125-203, backend/open_webui/routers/ollama.py:1174-1381, backend/open_webui/utils/payload.py:120-197
---
响应格式转换
使用量指标
Ollama 的性能指标(例如 prompt_eval_count、eval_duration)通过 convert_ollama_usage_to_openai() 转换为 OpenAI 兼容的 usage 统计信息 backend/open_webui/utils/response.py:69-113。
计算指标:
- input_tokens:从
prompt_eval_count映射backend/open_webui/utils/response.py:70。 - output_tokens:从
eval_count映射backend/open_webui/utils/response.py:71。 - response_token/s:计算为
eval_count / (eval_duration / 10,000,000)backend/open_webui/utils/response.py:83-90。
来源: backend/open_webui/utils/response.py:69-113, backend/open_webui/utils/response.py:116-178
---
嵌入生成
Open WebUI 支持 Ollama 的批量嵌入端点 /api/embed backend/open_webui/routers/ollama.py:1383。
- 分发:
embeddings.py中的generate_embeddings工具检测模型所有者并路由到 Ollama 后端backend/open_webui/utils/embeddings.py:74-81。 - 负载转换:
convert_embed_payload_openai_to_ollama()将 OpenAI 的input映射到 Ollama 的结构backend/open_webui/utils/payload.py:402-426。 - 响应转换:
convert_embedding_response_ollama_to_openai()将 Ollama 的响应转换为 OpenAI 的列表格式backend/open_webui/utils/response.py:177-246。
来源: backend/open_webui/routers/ollama.py:1383-1434, backend/open_webui/utils/payload.py:402-426, backend/open_webui/utils/response.py:177-246, backend/open_webui/utils/embeddings.py:24-89
---
模型管理操作
Open WebUI 通过专用路由暴露 Ollama 的管理 API:
| 操作 | 路由 | 实现 |
|---|---|---|
| 拉取模型 | POST /api/pull | backend/open_webui/routers/ollama.py:646 |
| 推送模型 | POST /api/push | backend/open_webui/routers/ollama.py:708 |
| 创建模型 | POST /api/create | backend/open_webui/routers/ollama.py:776 |
| 删除模型 | DELETE /api/delete | backend/open_webui/routers/ollama.py:874 |
| 卸载模型 | POST /api/unload | 通过 /api/generate 设置 keep_alive: 0 backend/open_webui/routers/ollama.py:1003 |
来源: backend/open_webui/routers/ollama.py:646-1035
---
性能与安全
负载均衡
当前实现使用简单的轮询方式(random.choice),当多个 URL 托管同一模型时 backend/open_webui/routers/ollama.py:9-11。存在一个 TODO,计划实现更智能的加权轮询或最少连接逻辑 backend/open_webui/routers/ollama.py:1-3。
标头转发
如果 ENABLE_FORWARD_USER_INFO_HEADERS 为 true,Open WebUI 会通过 include_user_info_headers() 将用户身份转发到 Ollama 后端 backend/open_webui/routers/ollama.py:146-149。如果元数据中提供了 chat_id,也会一并转发 backend/open_webui/routers/ollama.py:148-149。
来源: backend/open_webui/routers/ollama.py:1-11, backend/open_webui/routers/ollama.py:141-150