# 在本地 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//.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//container.json` 中移除 `env` 和 `blockedHosts` 键,从共享设置文件中移除 `"model"`,并重启服务。无需重建。 ## 另见 - `/add-ollama-provider`——为任何 agent group 配置 Ollama 的分步技能 - [Ollama Anthropic 兼容文档](https://ollama.com/blog/openai-compatibility)——API 桥接的上游文档 - `docs/architecture.md`——容器启动和环境变量注入管道的工作原理