OpenCode API 服务 — 完整部署指南
把本地
opencode serve变成 OpenAI 兼容 API。真正的 streaming、完整的 tool calling、agent 级能力。 使用本地OpenCode读取仓库(仓库地址见评论区)即可一键封装。
架构总览
┌──────────────────────────────────────────────────────────┐
│ 你的 AI 客户端 │
│ Reeden · Cursor · NextChat · openai-python · curl 等 │
│ POST /v1/chat/completions │
│ stream: true/false · tools: [...] │
└──────────────────────────┬───────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────┐
│ opencode-session-proxy │
│ 127.0.0.1:18081 │
│ │
│ ┌──── session API 调用 ────┐ ┌──── SSE 流 ───────┐ │
│ │ POST /session │ │ /global/event │ │
│ │ POST /session/{id}/msg │ │ 逐 token 推送 │ │
│ └──────────────────────────┘ └────────────────────┘ │
└──────────────────────────┬───────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────┐
│ opencode serve │
│ 127.0.0.1:4096 │
│ │
│ 模型加载 · tool calling · 文件读写 · 命令执行 · 上下文 │
└──────────────────────────────────────────────────────────┘设计核心理念:
- 不是
opencode run(一次性问答,没有 agent 能力) - 而是 通过
/sessionREST API +/global/eventSSE 流直接操控会话引擎,智能体拥有完整能力 - 工具调用:客户端下传 OpenAI
tools→ proxy 注入系统提示让 AI 用[TOOL_CALL]格式输出 → 解析为tool_calls响应 - 流式输出:通过 opencode 的
/global/eventSSE 端点,逐 token 获取 AI 输出并实时转发 - 防泄漏:3 层过滤(pre-prompt 注入提示 + 流式前缀检测 + 响应后处理),系统指令不会暴露给客户端
- Delta 超时:每 5s 探测一次,30s 无增量 → 自动结束,不卡死
前置条件
| 组件 | 要求 | 备注 |
|---|---|---|
| mise | any | 包管理器 |
| opencode | ≥ v1.14 | mise install opencode |
| Node.js | ≥ v18 | 运行 proxy(mise install node) |
| systemd | user mode | Linux 自带 |
部署
step 1 — opencode serve (port 4096)
# install
mise install opencode
mise use -g opencode@latest
opencode --version
# first run (initializes ~/.opencode/)
opencode serve --hostname 127.0.0.1 --port 4096
# Ctrl+C 后确认无报错即可把 systemd/opencode-api.service 丢进 systemd:
mkdir -p ~/.config/systemd/user
cp systemd/opencode-api.service ~/.config/systemd/user/
systemctl --user daemon-reload
systemctl --user start opencode-api.service
systemctl --user enable opencode-api.service验证:
curl -s http://127.0.0.1:4096/health
# → {"status":"ok"}
systemd/opencode-api.service里用的opencode/latestsymlink,每次mise install opencode自动更新。 首次会从远程下载模型,可能耗时几十秒,systemctl --user status看日志。
step 2 — session proxy (port 18081)
核心文件:session-proxy.js — 304 行,零依赖。
mkdir -p ~/.opencode-cli-proxy/bin
# 从仓库复制
cp session-proxy.js ~/.opencode-cli-proxy/bin/opencode-session-proxy.js
# 或者远程机器直接拉
curl -sL https://raw.githubusercontent.com/brucevon/opencode-api-deploy/main/session-proxy.js \
-o ~/.opencode-cli-proxy/bin/opencode-session-proxy.js全部配置通过环境变量:
| 变量 | 默认值 | 说明 |
|---|---|---|
API_KEY |
sk-gw-demo |
Bearer token |
PROXY_PORT |
18081 |
监听端口 |
OPCODE_HOST |
127.0.0.1 |
opencode 地址 |
OPCODE_PORT |
4096 |
opencode 端口 |
MODELS |
auto | 逗号分隔,设了就跳过自动获取 |
OPENCODE_BIN |
auto | opencode 二进制路径 |
模型自动获取:启动时跑
opencode models动态拉取最新模型列表。MODELS环境变量可以覆盖(静态指定),适合不需要完整列表的场景。OPENCODE_BIN会自动探测 mise shims 路径,systemd 下也能正常工作。
创建 systemd 服务:
cp systemd/opencode-session-proxy.service ~/.config/systemd/user/
systemctl --user daemon-reload
systemctl --user start opencode-session-proxy.service
systemctl --user enable opencode-session-proxy.service验证:
curl -s http://127.0.0.1:18081/v1/models -H "Authorization: Bearer sk-gw-demo"
# → {"object":"list","data":[{"id":"opencode/big-pickle",...}]}step 3 — 开机自启
# 如果重启后服务没起来:
sudo loginctl enable-linger $(whoami)验证
非流式
curl -s --max-time 180 -X POST http://127.0.0.1:18081/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-gw-demo" \
-d '{
"model": "opencode/big-pickle",
"messages": [{"role": "user", "content": "创建一个 /tmp/proxy-test.txt,写入 hello world"}],
"stream": false
}'智能体应执行 write 工具创建文件,返回执行结果。首次请求需加载模型,可能 60s+。
流式
curl -N --max-time 180 -X POST http://127.0.0.1:18081/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-gw-demo" \
-d '{
"model": "opencode/big-pickle",
"messages": [{"role": "user", "content": "从 1 数到 5"}],
"stream": true
}'工具调用
# 非流式 + tools
curl -s --max-time 180 -X POST http://127.0.0.1:18081/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-gw-demo" \
-d '{
"model": "opencode/big-pickle",
"messages": [{"role": "user", "content": "Search for books about AI"}],
"tools": [{
"type": "function",
"function": {
"name": "search_books",
"description": "Search books by query",
"parameters": {
"type": "object",
"properties": {"query": {"type": "string"}},
"required": ["query"]
}
}
}],
"stream": false
}'
# → finish_reason: "tool_calls", 含 tool_calls 数组日常管理
# 状态
systemctl --user status opencode-api.service opencode-session-proxy.service
# 日志(实时)
journalctl --user -u opencode-session-proxy.service -f
# 重启
systemctl --user restart opencode-session-proxy.service
# 尾 N 条
journalctl --user -u opencode-session-proxy.service --no-pager -n 50故障排查
服务起不来
journalctl --user -u opencode-session-proxy.service --no-pager -n 50常见原因:
- node 路径不对 →
which node确认,更新ExecStart - opencode-api 没跑 →
systemctl --user start opencode-api.service - 端口占用 →
ss -tlnp | grep 18081
401
API Key 不匹配。检查 API_KEY 环境变量和请求头。
首次请求空内容
模型冷加载。重试一次。或者先预热:
curl -s --max-time 180 -X POST ... \
-d '{"model":"opencode/big-pickle","messages":[{"role":"user","content":"hi"}],"stream":false}'工具调用没返回
opencode/big-pickle 是 agent 模型,约 40% 概率会忽略 [TOOL_CALL:] 指令,直接在服务器执行内置工具。 此时响应不含 tool_calls,客户端不会得到工具调用结果。
Proxy 内置自动重试(同 session,最多 3 次),通常第二次就正确输出。如果还有问题:
- 重新发送请求(重试计数重置)
- 用非流式模式,成功率更高
跨机器访问
确认:
- proxy 绑定
0.0.0.0(systemd/opencode-session-proxy.service里Environment=PROXY_HOST=0.0.0.0) - 防火墙放行 18081
- API Key 匹配
配置参考
| 想改什么 | 怎么做 |
|---|---|
| 端口 | 设 PROXY_PORT / OPCODE_PORT 环境变量,重启 |
| API Key | 设 API_KEY 环境变量,重启 |
| 模型列表 | 设 MODELS 环境变量(逗号分隔),重启后跳过自动获取 |
| 绑定地址 | 设 PROXY_HOST=0.0.0.0 允许外部访问 |
| opencode 路径 | 设 OPENCODE_BIN 指定二进制路径 |
所有配置通过环境变量,不需要改代码。