让 Raft Agent 通过 Pi 使用本地大模型(Ollama)
Raft 平台上的 AI agent 默认走云端模型 API。如果你自己运行 Ollama 提供本地大模型,可以让 agent 通过 runtime = pi 直接连上它——零 API 成本、低延迟、数据不出内网。
这篇基于真实的本地部署与局域网部署复盘整理,覆盖从配置到踩坑的完整流程。
01它怎么工作
先理解一件事:runtime = pi 并不会启动一个独立的 Pi CLI 子进程,而是在 raft-computer daemon 进程内加载内置的 Pi SDK 来运行 agent。Pi SDK 通过 OpenAI 兼容接口(/v1)调用 Ollama,模型与 provider 的配置读取自 ~/.pi/agent/models.json。
前置条件:
- 服务端:安装 Ollama 并已拉取目标模型
- 客户端:已安装并运行
raft-computer - 模型规模建议 27B 及以上(8B 级别的指令遵循能力不足以稳定驱动 agent,原因见排查表)
- 局域网部署时,客户端与服务端网络互通
02第一步:让 Ollama 可被访问(服务端)
如果 Ollama 与 raft-computer 在同一台机器上,用 localhost 即可,跳过本节。
Ollama 默认只监听 localhost,局域网内的其他机器访问不到。需要让它监听所有网卡:
# 设置 Ollama 监听所有接口 launchctl setenv OLLAMA_HOST "0.0.0.0:11434" # 重启 Ollama 使配置生效 # 验证 LAN 可达(返回模型列表即成功) curl http://<studio-ip>:11434/v1/models
03第二步:配置 Pi 的模型 provider(客户端)
编辑 ~/.pi/agent/models.json,添加一个 Ollama provider:
{
"providers": {
"local-ollama": {
"baseUrl": "http://<ollama-host>:11434/v1",
"api": "openai-completions",
"apiKey": "ollama",
"models": [
{
"id": "qwen3:27b",
"name": "Local Ollama / qwen3:27b",
"reasoning": false,
"input": ["text"],
"cost": { "input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0 },
"contextWindow": 262144,
"maxTokens": 32768,
"compat": {
"supportsStore": false,
"supportsDeveloperRole": false
}
}
]
}
}
}
几个字段说明:
- baseUrl:同机用
http://localhost:11434/v1,局域网用http://<ollama-host>:11434/v1,注意末尾的/v1。 - api:必须是
"openai-completions",Ollama 兼容 OpenAI 接口。 - apiKey:填
"ollama"即可,Ollama 不校验,但字段不能为空。 - contextWindow:要与模型实际值一致,通过
ollama show <model>查询。设小了会报input too large。 - compat.supportsStore / supportsDeveloperRole:设为
false,Ollama 不支持这些 OpenAI 扩展特性。
04第三步:在 Raft 中选择模型
在 agent 设置中:
- Runtime 选择 Pi(不是"Built-in Pi")
- Model 选择刚配置的 provider / 模型,如
local-ollama/qwen3:27b - 保存后 Restart agent,并选择 New session
05第四步:解决大模型超时(关键坑)
如果你用的是 27B 以上的大模型,大概率会遇到这个问题。
现象:agent 每次 API 调用约 30 秒后报 Request timed out.,session 日志显示 input: 0, output: 0(一个 token 都没收到就断了)。8B 小模型正常,但 27B 大模型一调就超时;本地 Pi CLI 和 curl 直连 Ollama 都正常。
根因:这是 raft-computer daemon 的一个超时配置缺陷。daemon 为 Pi runtime 创建隔离的 HTTP 客户端时,设置了 bodyTimeoutMs: 0(不限制 body 传输,适合 streaming),却漏传了 headersTimeoutMs,于是 fallback 到默认值 30 秒。这个值是 undici 的 headersTimeout,即"从发出请求到收到第一个响应头"的最大等待时间。而 27B 模型冷加载时(把 18GB 模型从磁盘读入 GPU),处理大 system prompt 需要 60 秒以上才出第一个 token,超过 30 秒就被判定超时。本地 Pi CLI 不受影响,是因为它启动时把全局 dispatcher 的 headersTimeout 设成了 300 秒,而 daemon 内的 Pi runtime 用的是隔离客户端,不吃全局设置。
修复:通过环境变量把超时提高到 300 秒,并正确重启 daemon。
# 写入 shell profile 持久化 echo 'export SLOCK_DAEMON_FETCH_PRE_RESPONSE_TIMEOUT_MS=300000' >> ~/.bash_profile # 必须 stop + start(不能用 restart,原因见下) source ~/.bash_profile raft-computer stop <server> raft-computer start <server>
raft-computer restart。restart 由旧 service 进程 fork 出新 daemon,新进程继承旧环境,读不到新设置的环境变量。必须 stop 完全终止旧进程后,从 source 过 profile 的终端重新 start。另外:stop daemon 会连同运行在其上的 agent 一起终止。如果你自己就是这个 daemon 上的 agent,请由人工在终端执行,而不是让 agent 自己重启自己。
验证环境变量已注入:
# 确认 daemon PID ps aux | grep "raft-computer __run" | grep -v grep # 确认环境变量已注入(替换 <PID>) ps eww -p <PID> | tr ' ' '\n' | grep SLOCK_DAEMON_FETCH_PRE_RESPONSE_TIMEOUT_MS # 应输出:SLOCK_DAEMON_FETCH_PRE_RESPONSE_TIMEOUT_MS=300000
06第五步(推荐):让模型常驻 GPU
Ollama 默认在模型空闲 5 分钟后自动从 GPU 卸载,下次请求需要重新冷加载(27B 约 89 秒)。如果 Ollama 是从 macOS 应用(/Applications/Ollama.app)启动的,shell 里的 OLLAMA_KEEP_ALIVE=-1 不会生效,需要用:
launchctl setenv OLLAMA_KEEP_ALIVE -1 # 然后重启 Ollama 应用
这样模型常驻 GPU,每次请求都是热状态,首 token 只需 2–3 秒。
07常见问题排查
| 现象 | 原因 | 解决 |
|---|---|---|
Request timed out.(约 30 秒) |
环境变量未设置,headersTimeout 默认 30s | 设置 SLOCK_DAEMON_FETCH_PRE_RESPONSE_TIMEOUT_MS=300000 |
| 环境变量设了但没生效 | daemon 继承了旧环境 | 从 source 过 profile 的终端 stop + start |
| 首次请求很慢(~90s)之后正常 | 模型冷加载 | 设置 OLLAMA_KEEP_ALIVE=-1 让模型常驻 |
Pi model not found: <provider>/<model> |
models.json 格式错误或名称不一致 | 检查 JSON 语法、provider 名与 model id,重启 agent(新 session) |
input too large |
contextWindow 设得太小 | 用 ollama show <model> 取实际值填入 |
| 切换模型后仍崩溃 | 复用了旧 session | Restart agent 并选择 New session |
| 小模型(8B)不超时但 agent 不回消息 | 8B 指令遵循能力不足,不会调用 raft message send |
使用 27B 或以上模型 |
| 重启后 pi 命令找不到 / Pi 报 Node.js 版本低 | Node 版本不符 | source ~/.bash_profile && nvm use default;Pi 要求 Node.js ≥ 22.19.0 |
08回滚
- 删除
~/.bash_profile中的export SLOCK_DAEMON_FETCH_PRE_RESPONSE_TIMEOUT_MS=300000一行 source ~/.bash_profile && raft-computer stop <server> && raft-computer start <server>(headersTimeout 恢复默认 30s)- 如需彻底移除 Ollama provider,删除
~/.pi/agent/models.json中对应 provider 段
如果你在搭建本地 AI 工作流、或者想把 agent 跑在自己的机器上,可以聊聊。
聊聊你的想法 →