OllamaHub 是一个本地 HTTP 代理服务,对外模拟部分 Ollama API,并可按模型声明的协议能力直通或转换转发到上游服务,方便在 Visual Studio Copilot Chat 的 BYOM 场景中把本地 Ollama 入口桥接到其他模型提供商。
当前版本目标:
- 对外兼容 Visual Studio Copilot Chat BYOM 常用的 Ollama 接口
- 配置文件格式尽量兼容 oai-compatible-copilot
- 当前已支持按
apiMode选择 OpenAI / Anthropic / Ollama 兼容入口
GET /GET /api/versionGET /api/tagsGET /api/psPOST /api/showPOST /v1/chat/completionsPOST /openai/v1/chat/completions
其中:
/api/tags用于返回可用模型列表/api/show用于返回模型详情/v1/chat/completions提供 OpenAI Chat Completions 兼容入口/openai/v1/chat/completions提供 Azure OpenAI Chat Completions 兼容入口
配置文件名固定为:
settings.json
配置文件位置:
- 与可执行文件同级目录
例如发布后为:
OllamaHub.exesettings.json
配置结构尽量兼容 oai-compatible-copilot 的 providers / models 风格。一般格式如下:
{
"host": "127.0.0.1",
"port": 11434,
"logging":
{
"level": "None"
},
"providers": [
{
"id": "智脑",
"baseUrl": "https://api.360.cn/",
"protectedApiKey": "dpapi:..."
}
],
"models": [
{
"id": "anthropic/claude-sonnet-4-5",
"owned_by": "智脑",
"displayName": "Claude Sonnet 4.5",
"family": "claude",
"apiMode": "openai",
"context_length": 200000,
"max_tokens": 8192,
"vision": true,
"temperature": 0,
"top_p": 1,
"extra": {
"service_tier": "standard_only"
}
},
{
"id": "st/deepseek/deepseek-v4-pro",
"owned_by": "智脑",
"displayName": "deepseek/deepseek-v4-pro",
"family": "deepseek",
"apiMode": "openai",
"context_length": 1000000,
"max_tokens": 384000,
"temperature": 0,
"top_p": 1,
"extra": {
"thinking": { "type": "enabled" },
"reasoning_effort": "max"
}
},
{
"id": "z-ai/glm-5.1",
"owned_by": "智脑",
"displayName": "z-ai/glm-5.1",
"family": "glm",
"apiMode": "openai",
"context_length": 200000,
"max_tokens": 128000,
"temperature": 0,
"top_p": 1,
"extra": {
"thinking": { "type": "enabled" },
"reasoning_effort": "max"
}
}
]
}当前实际使用到的字段:
host: 可选,监听主机名或 IP,与port配合使用port: 可选,监听端口,与host配合使用url: 可选,单个监听地址,例如http://127.0.0.1:11434baseUrl: 可选,全局默认上游 base URLlogging: 可选,日志配置providers: 可选,供应商列表models: 必填,模型列表
监听地址解析优先级:
urlhost + port
如果两者都不配置,则回退到 ASP.NET Core 默认监听方式。
level: 可选,日志输出等级,支持None、Error、Warning、Info
等级规则:
None: 不输出日志Error: 只输出错误日志Warning: 输出警告和错误日志Info: 输出所有日志
默认值:None
id: 供应商 IDbaseUrl: 供应商基础地址apiKey: API Key,兼容旧格式明文配置protectedApiKey: 使用 Windows DPAPI 按当前用户保护后的 API Key,推荐使用apiMode: 可选,支持单个或多个协议模式,多个值用分号分隔,例如openai;anthropicheaders: 可选,自定义请求头
id: 模型 ID;在 Anthropic 转换路径下同时作为 Anthropic 模型名displayName: 可选,显示名称configId: 可选,用于同模型多配置;暴露给 Ollama 时会显示为id::configIdowned_by/provider/provide: 提供商 ID,三者任选其一family: 可选,默认claudebaseUrl: 可选,覆盖 provider/baseUrlapiKey: 可选,覆盖 provider/apiKey,兼容旧格式明文配置protectedApiKey: 可选,覆盖 provider/protectedApiKey,使用 Windows DPAPI 按当前用户保护apiMode: 可选,支持单个或多个协议模式,多个值用分号分隔,例如openai;anthropiccontext_length: 可选,默认128000max_tokens: 可选,默认4096vision: 可选,默认false,表示模型是否支持视觉能力;若为true,/api/show返回的capabilities中会包含visiontemperature: 可选top_p: 可选headers: 可选,模型级自定义请求头extra: 可选,在走 Anthropic 转换路径时会合并到 Anthropic 请求体
apiMode 选择规则:
- 若当前入口协议被模型声明支持,则优先同协议直通上游
- 若当前入口协议未被声明支持,但模型支持
anthropic,则回退到现有 Anthropic 转换链路 - 目前已识别的协议值为:
openai、anthropic、ollama
见仓库中的 settings.json。
核心示例:
- provider 定义
anthropic的baseUrl、apiKey、apiMode - model 使用
owned_by: "anthropic" apiMode支持单值或分号分隔多值logging.level可控制日志输出等级,默认None- 推荐使用
protectedApiKey代替明文apiKey
在仓库根目录执行:
dotnet run --project OllamaHub
设置或更新某个 provider/model 的受保护 API Key:
dotnet run --project OllamaHub --SetApiKey 智脑 你的APIKey
也可以直接运行发布后的程序:
OllamaHub SetApiKey 智脑 你的APIKey
命令会优先匹配 provider id,找不到时再匹配 model id;写入时只新增或更新 protectedApiKey,不会清空已有的明文 apiKey。该值使用 Windows DPAPI 的 CurrentUser 范围加密,只有当前 Windows 用户可解密。
监听地址现在建议直接在 settings.json 中配置。
示例 1:使用 host + port
"host": "127.0.0.1", "port": 11434
示例 2:使用单个 url
"url": "http://127.0.0.1:11434"
当前优先推荐为 VS Copilot BYOM 配置:
"url": "http://127.0.0.1:11434"
如果你仍然需要,也可以继续使用 ASP.NET Core 自带环境变量覆盖,例如:
set ASPNETCORE_URLS=http://127.0.0.1:11434
然后再启动程序。
示例:
dotnet publish OllamaHub -c Release -o publish
把 settings.json 放到 publish 目录,与生成的可执行文件同级。
思路是把 OllamaHub 当作本地 Ollama 服务。
建议步骤:
- 启动 OllamaHub,并监听一个本地 HTTP 地址,例如
http://127.0.0.1:11434 - 在 Visual Studio 的 Copilot Chat BYOM 中选择使用 Ollama / 本地 Ollama
- 把地址指向 OllamaHub 的监听地址
- Copilot 请求到达 OllamaHub 后,由它转发到配置中的 Anthropic 模型
-
若模型支持
openai,则/v1/chat/completions会直接透传到上游/v1/chat/completions -
若模型不支持
openai但支持anthropic,则会按以下规则转换为 Anthropic -
messages[].role = system会被合并为 Anthropicsystem -
messages[].content文本会映射为 Anthropictext -
messages[].content数组支持基础多模态转换:text与image_url -
assistant.tool_calls会映射为 Anthropictool_use -
tool消息会映射为 Anthropictool_result -
tools会映射为 Anthropictools -
tool_choice会转换为 Anthropictool_choice -
temperature、top_p、max_tokens会映射到对应 Anthropic 字段 -
其他未显式处理的字段会按允许列表通过
extra透传
-
若模型支持
ollama,则/api/chat会直接透传到上游/api/chat -
若模型不支持
ollama但支持anthropic,则会按以下规则转换为 Anthropic -
system消息会被合并为 Anthropic 的system -
user/assistant文本消息会映射到 Anthropicmessages -
assistant.tool_calls会映射为 Anthropictool_use -
tool角色消息会映射为 Anthropictool_result -
options.temperature->temperature -
options.top_p->top_p -
options.num_predict->max_tokens -
extra会直接合并到请求体
- 非流式:把返回文本块合并为一个 Ollama chat 响应
- 流式:把 Anthropic SSE 事件转换为 Ollama 风格 NDJSON 分块输出
- 非流式:返回 OpenAI
chat.completionJSON - 流式:返回 OpenAI 风格
text/event-stream - 工具调用会尽量映射为
tool_calls - 若 Anthropic 返回 token 统计,会尽量映射到 OpenAI
usage - 流式工具调用会拆分为起始 metadata 块和 arguments 增量块,更贴近 OpenAI delta 语义
- 流结束前会额外输出一个包含
usage的最终 chunk(若上游提供了 token 统计)
当前版本只覆盖首批可用场景,存在以下限制:
- 仅对
openai、anthropic、ollama三种协议值做内建处理 - 当前支持文本消息和基础工具调用透传
- 当前支持
/v1/chat/completions的基础 OpenAI 兼容转发 - 尚未实现图像/多模态消息透传
- 仅实现了 Copilot Chat BYOM 所需的基础 Ollama 兼容面
- 模型元数据中的大小、量化等字段为代理占位值,不代表真实模型信息
运行全部测试:
dotnet test
当前已覆盖:
- 配置加载与模型解析
- settings 中监听地址解析
- Ollama 请求到 Anthropic 请求的转换
- Ollama 工具调用到 Anthropic tool_use/tool_result 的转换
- Anthropic SSE 到 Ollama NDJSON 的映射
- OpenAI Chat Completions 到 Anthropic 的转换
- 分号分隔多
apiMode的配置解析 - Anthropic 到 OpenAI Chat Completions 的非流式/流式映射
- Anthropic usage 到 OpenAI usage 的映射
- Anthropic 流式 tool_use 到 OpenAI tool_calls delta 的细粒度映射
- OpenAI 多模态 content 数组到 Anthropic text/image 的转换
- OpenAI 流式最终 usage chunk 输出
- OpenAI 兼容接口转发
- Gemini 转发
- 工具调用透传
- 多模态内容转发
- 更完整的 Ollama API 兼容