89 lines
5.0 KiB
Markdown
89 lines
5.0 KiB
Markdown
# 在本地 Ollama 上运行 Agent
|
||
|
||
NanoClaw agent(智能体)可以被路由到本地 [Ollama](https://ollama.com) 实例,而非 Anthropic API。这可以将 API 成本降至零,并将所有推理保留在你的硬件上。
|
||
|
||
## 工作原理
|
||
|
||
Ollama 暴露了一个 Anthropic 兼容的 `/v1/messages` 端点。Claude Code CLI(运行在 agent 容器内)使用 Anthropic SDK,该 SDK 读取 `ANTHROPIC_BASE_URL` 来找到 API 主机。将该变量指向 Ollama 就是所需的全部——无需新的 provider(提供程序)代码,无需更改 agent 运行时。
|
||
|
||
```
|
||
┌─────────────────────────────┐
|
||
│ Agent 容器 │
|
||
│ │
|
||
│ Claude Code CLI │
|
||
│ ↓ ANTHROPIC_BASE_URL │
|
||
│ http://host.docker. │ ┌──────────────────┐
|
||
│ internal:11434 ───────┼─────▶│ Ollama :11434 │
|
||
│ │ │ gemma4:latest │
|
||
└─────────────────────────────┘ └──────────────────┘
|
||
```
|
||
|
||
`host.docker.internal` 是 Docker 的魔法主机名,从容器内部解析为宿主机——因此运行在你的 Mac 或 Linux 机器上的 Ollama 可以通过该地址访问。
|
||
|
||
## OneCLI 的复杂之处
|
||
|
||
NanoClaw 通常通过 OneCLI HTTPS 代理来运行 API 调用,该代理将真实凭据注入替换占位密钥。当重定向到 Ollama 时,你需要绕过该代理,使请求直接发出。两个环境变量处理此问题:
|
||
|
||
- `NO_PROXY=host.docker.internal`——告诉 Anthropic SDK 的 HTTP 客户端对该主机名跳过代理
|
||
- `no_proxy=host.docker.internal`——小写变体,用于检查小写形式的工具
|
||
|
||
两者都在 agent group 的 `container.json` 中与 `ANTHROPIC_BASE_URL` 一起设置。
|
||
|
||
## 网络隔离
|
||
|
||
设置 `ANTHROPIC_BASE_URL` 会重定向请求,但不能阻止配置错误的 agent 意外地直接访问 `api.anthropic.com`。`container.json` 中的 `blockedHosts` 字段添加一个 Docker `--add-host` 标志,将该域名解析为 `0.0.0.0`,使其在容器内无法物理访问:
|
||
|
||
```json
|
||
"blockedHosts": ["api.anthropic.com"]
|
||
```
|
||
|
||
有了这个设置,即使模型设置漂移回 Claude 模型名称,API 调用也会立即失败,而不是悄悄地从你的账户扣费。
|
||
|
||
## 模型选择
|
||
|
||
Claude Code CLI 从容器的 `~/.claude/settings.json` 读取其模型,NanoClaw 从 `data/v2-sessions/<agent-group-id>/.claude-shared/settings.json` bind mount 该文件。设置 `"model": "gemma4:latest"`(或你已 pull 的任何 Ollama 模型)。使用来自 `ollama list` 的精确名称。
|
||
|
||
Apple Silicon 的模型选择考量:
|
||
|
||
| 模型 | 规模 | 质量 | 速度(M4 Pro) |
|
||
|-------|------|---------|----------------|
|
||
| `gemma4:latest` | 12B | 通用良好 | 快 |
|
||
| `qwen3-coder:latest` | 32B | 编码任务出色 | 中等 |
|
||
| `llama3.2:latest` | 3B | 基础 | 非常快 |
|
||
|
||
agent 大量使用工具调用(读取/写入文件、shell 命令)。支持可靠工具调用的模型效果最好。Gemma 4 和 Qwen 3 Coder 都能很好地处理结构化工具调用。
|
||
|
||
## 代码层面的变更
|
||
|
||
三个文件需要支持此功能。确切变更见 `/add-ollama-provider`。
|
||
|
||
**`src/container-config.ts`**——`ContainerConfig` 接口需要 `env` 和 `blockedHosts` 字段,以便每个 group 的 JSON 可以携带它们。
|
||
|
||
**`src/container-runner.ts`**——在容器启动时,`env` 条目变为 `-e KEY=VAL` Docker 标志(在 OneCLI 注入的变量之后应用,因此它们获胜),`blockedHosts` 条目变为 `--add-host HOST:0.0.0.0` 标志。
|
||
|
||
**`container/Dockerfile`**——容器以宿主机用户的 uid 运行(例如 macOS 上的 501),而非 `node` 用户(uid 1000)。家目录必须是 `chmod 777`,以便任何 uid 都可以写入 `~/.claude.json` 和 `~/.claude/settings.json`。
|
||
|
||
## 权衡
|
||
|
||
| | Ollama(本地) | Anthropic API |
|
||
|---|---|---|
|
||
| 成本 | 免费 | 按 token 付费 |
|
||
| 隐私 | 完全本地 | 数据发送到 Anthropic |
|
||
| 模型质量 | 良好(开放权重) | 出色(Claude) |
|
||
| 冷启动 | 5–30 秒(模型加载) | ~1 秒 |
|
||
| 上下文窗口 | 因模型而异 | 200k tokens(Sonnet) |
|
||
| 工具调用可靠性 | 良好(大型模型) | 出色 |
|
||
| 硬件要求 | 16GB+ RAM | 无 |
|
||
|
||
对于有能力的硬件上的个人自动化,权衡倾向于本地。对于需要大上下文或高可靠性的复杂多步骤任务,Claude 仍然领先。
|
||
|
||
## 恢复使用 Claude
|
||
|
||
从 `groups/<folder>/container.json` 中移除 `env` 和 `blockedHosts` 键,从共享设置文件中移除 `"model"`,并重启服务。无需重建。
|
||
|
||
## 另见
|
||
|
||
- `/add-ollama-provider`——为任何 agent group 配置 Ollama 的分步技能
|
||
- [Ollama Anthropic 兼容文档](https://ollama.com/blog/openai-compatibility)——API 桥接的上游文档
|
||
- `docs/architecture.md`——容器启动和环境变量注入管道的工作原理
|