1. OpenCode CLI 提示词工程调试为什么要用 mitmproxy 抓包看 LLM 请求OpenCode 是一个跑在终端里的交互式 CLI 编程助手它会把系统提示词、工具定义、环境信息、历史对话拼成一份完整的 messages 数组再发给 LLM。很多人用 OpenCode 时只看到最终回答却不知道模型到底收到了什么——系统提示词里塞了多少约束、工具 schema 有多长、上下文是怎么一轮轮叠加的。提示词工程的核心不是改一句「你是一个专家」而是看清真实请求结构后做精准调整。mitmproxy 在这里扮演的角色是一个本地 HTTP/HTTPS 中间人观察器。它不修改 OpenCode 的代码只在网络层把请求和响应完整记录下来。你可以把它理解成给 CLI 装了一个「行车记录仪」OpenCode 照常发请求mitmproxy 在旁边把每一帧都存下来包括 system prompt、tools 数组、stream 分片、token 用量。适合谁看这篇已经在用 OpenCode 或类似 CLI Agent、想搞清楚提示词是怎么组装的开发者正在做 Agent 提示词调优、需要定位「为什么模型不听话」的人以及想学习 LLM 请求结构、做提示词工程实证分析的同学。整篇会交付可复制的 mitmproxy 启动命令、OpenCode 环境变量配置、一次完整的抓包验证动作以及常见报错排查。我试过直接读 OpenCode 源码找提示词但版本迭代快、拼接逻辑分散在多处不如抓一次真实请求来得直接。抓包能看到的是「运行时真相」比读代码更贴近实际。2. TaoToken 前置准备给 OpenCode 配一个可观测的 LLM 入口要让 mitmproxy 抓到 OpenCode 的 LLM 请求前提是 OpenCode 的请求走一个你能控制的 Base URL。这里用 TaoToken 作为模型接入入口它提供 OpenAI 兼容的 APIOpenCode 通过环境变量指向它即可。这样做的好处是Base URL 明确、Key 明确、Model ID 明确抓包时一眼能对上。先拿到三件套。打开官网 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 注册后进入控制台在 API Keys 页面创建一个 Key。控制台地址是 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite API Keys 页面是 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 。创建时建议给 Key 起个能识别的名字比如 opencode-debug方便后面在抓包记录里核对。三件套具体是配置项值说明Base URLhttps://taotoken.net/apiOpenAI 兼容入口不加 UTMAPI Key控制台创建的 sk- 开头字符串只显示一次及时保存Model ID控制台模型列表里的完整 ID例如 ali-codingplan/qwen3.5-plus 这类带前缀的写法Model ID 一定要用控制台里显示的完整字符串不要自己简写。OpenCode 抓包时你会看到请求体里的 model 字段如果写错返回的报错通常是 model not found 或 404而不是 401这个区别后面排障会用到。如果你还想先验证模型本身能不能通可以用模型对话页面 https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel_chatutm_campaignrewrite 发一条消息确认 Key 和 Model ID 组合有效再去配 OpenCode。这一步能省掉后面「到底是 OpenCode 配错还是 Key 无效」的扯皮。对于长期做编码 Agent 调试的场景Coding Plan 页面 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite 里有套餐说明调试阶段用按量即可稳定跑起来再考虑套餐。接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 里面有各客户端的配置示例遇到字段不确定时对照看。3. 可复制配置mitmproxy 启动参数与 OpenCode 环境变量这一节是全文最需要照抄的部分。分两步先起 mitmproxy再让 OpenCode 把请求指向 mitmproxy 的监听端口。3.1 安装 mitmproxy用 pip 安装即可官方文档在 https://docs.mitmproxy.org/stable/ 。命令pip install mitmproxy安装完成后会有三个命令mitmproxy交互式 TUI、mitmweb网页界面、mitmdump无界面。调试提示词推荐 mitmweb因为请求体是 JSON网页里展开看比终端舒服。3.2 启动 mitmweb 并监听 OpenCode 流量原始命令里用了--mode local:opencode这是 mitmproxy 的 local 模式专门用来抓某个本地进程的流量不需要改系统全局代理。完整启动命令mitmweb --mode local:opencode --web-port 8081 --showhost --ssl-insecure --set upstream_certfalse --set connection_strategylazy --set tls_version_client_minUNBOUNDED --set tls_version_server_minUNBOUNDED --verbose逐个参数说明方便你按需裁剪参数作用--mode local:opencode只拦截名为 opencode 的进程流量不影响其他程序--web-port 8081mitmweb 网页界面端口浏览器开 http://127.0.0.1:8081--showhost请求列表里显示完整 host便于区分不同域名--ssl-insecure上游证书校验放宽避免自签证书导致握手失败--set upstream_certfalse不向上游出示客户端证书--set connection_strategylazy延迟建连减少握手开销--set tls_version_client_minUNBOUNDED客户端 TLS 版本不设下限--set tls_version_server_minUNBOUNDED服务端 TLS 版本不设下限--verbose输出详细日志排障时有用注意--mode local:opencode依赖进程名匹配。Windows 下进程名可能是 opencode.exe如果抓不到把参数改成--mode local:opencode.exe试一次。macOS/Linux 下一般是 opencode。3.3 OpenCode 环境变量配置OpenCode 读取环境变量来决定请求发往哪里。核心是三个Base URL、API Key、Model。以 OpenAI 兼容方式配置export OPENAI_BASE_URLhttps://taotoken.net/api export OPENAI_API_KEYsk-你的Key export OPENCODE_MODELali-codingplan/qwen3.5-plusWindows PowerShell 下写法不同$env:OPENAI_BASE_URLhttps://taotoken.net/api $env:OPENAI_API_KEYsk-你的Key $env:OPENCODE_MODELali-codingplan/qwen3.5-plus如果你用的是 OpenCode 的配置文件方式可以在项目根目录或用户配置目录放一份 settings 风格的 JSON。下面这份是可直接复制的片段路径按你实际安装位置调整{ provider: { openai: { options: { baseURL: https://taotoken.net/api, apiKey: sk-你的Key } } }, model: ali-codingplan/qwen3.5-plus }注意Base URL 写 https://taotoken.net/api不要带末尾斜杠也不要加 UTM 参数。UTM 只用于网页跳转统计写进 API 地址会导致路径拼接错误。配置完成后OpenCode 发出的请求会先到 mitmproxy 的 local 监听再转发到 TaoToken。mitmweb 里就能看到完整的请求体。4. 验证请求一次完整的抓包动作与提示词结构观察配置就绪后做一次最小验证。启动 mitmweb另开一个终端启动 OpenCode依次输入三条指令你好 介绍一下你自己 当前工作目录是什么在 mitmweb 的请求列表里你会看到多次 LLM 交互。第一次交互的请求体结构最值得看它包含几个关键字段{ model: qwen3.5-plus, max_tokens: 32000, top_p: 1, messages: [ { role: system, content: You are opencode, an interactive CLI tool... }, { role: user, content: 你好 } ], tools: [ { type: function, function: { name: question, description: ... } }, { type: function, function: { name: bash, description: ... } } ], stream: true, stream_options: { include_usage: true } }从这份结构里能读出几件事。system 字段是一大段行为约束包含身份定义、语气要求、工具使用策略、环境信息工作目录、平台、日期、可用 skills 列表。tools 数组里每个工具都有完整的 JSON Schema光 question 和 bash 两个工具的 description 就占了不少 token。第一次请求的 prompt_tokens 达到 31978而用户消息只有「你好」两个字——也就是说绝大部分 token 花在系统提示词和工具定义上。第二次交互是给对话起标题system 提示词换成了 title generator要求输出单行、≤50 字符、不加解释。这次请求没有 tools 数组messages 里带上了前一轮的对话。这说明 OpenCode 会根据任务类型切换不同的系统提示词而不是一套提示词走天下。后续每一轮对话messages 数组都在前一轮基础上叠加形成完整的上下文。抓包时你可以对比第 1 轮和第 3 轮的 messages 长度直观看到上下文是怎么增长的。响应侧是 SSE 流式分片每个 data 行是一个 chunkdelta 里可能同时有 reasoning_content 和 content。最后一条带 usage 的 chunk 给出 prompt_tokens、completion_tokens、total_tokens以及 reasoning_tokens 和 text_tokens 的拆分。这些数字是提示词工程调优的量化依据如果 prompt_tokens 异常高说明系统提示词或工具定义太臃肿。提示mitmweb 里可以直接对请求体做搜索搜 system 定位系统提示词搜 tools 定位工具定义比手动滚动快得多。5. 本篇常见错排查401、local proxy failed、reading choices、OAuth抓包调试最容易卡在几个固定报错上逐个对照。401 Unauthorized请求到了 TaoToken 但 Key 无效。检查 OPENAI_API_KEY 是否完整、有没有多余空格、是不是复制时漏了字符。如果 mitmweb 里能看到请求头 Authorization 字段直接核对。注意 401 是 Key 问题不是 Base URL 问题。404 model not foundBase URL 对了、Key 对了但 Model ID 写错。回到控制台复制完整 Model ID注意带前缀的写法。这个报错和 401 要区分开别混着查。local proxy failed / connection refusedmitmproxy 没起来或者--mode local:opencode的进程名不匹配。先确认 mitmweb 进程在跑、8081 端口没被占再确认 OpenCode 进程名。Windows 下试 opencode.exe。如果还是抓不到临时用--mode regular配合系统代理验证一次确认是进程名问题还是配置问题。reading choices 相关报错通常是响应流解析失败。常见原因是上游返回了非 SSE 格式的错误体比如 HTML 错误页而客户端按 SSE 解析。在 mitmweb 里看响应体原始内容如果是 HTML说明请求根本没到模型层多半是 Base URL 路径不对或网关拦截。确认 Base URL 是 https://taotoken.net/api路径拼接正确。OAuth 相关报错如果你之前用 OAuth 方式登录过某个客户端环境变量和 OAuth 凭据可能冲突。清理旧的凭据缓存确保 OpenCode 走的是环境变量里的 Key。OAuth 流程和 API Key 流程不要混用。抓到了请求但响应为空检查--ssl-insecure和 upstream_cert 设置。有些环境对证书校验严格握手阶段就断了。按第 3 节的完整参数启动不要随意删参数。token 数对不上usage 里的 prompt_tokens 包含系统提示词、工具定义、历史消息。如果你只数了用户消息肯定对不上。以 usage 为准。排查顺序建议先确认 mitmproxy 能抓到任何请求哪怕是一个 401再确认请求体结构正确最后看响应。抓不到请求是网络层问题抓到了但报错是配置层问题分清楚能省很多时间。6. 继续深入把抓包变成提示词工程的日常动作抓到第一次请求后你可以做几件更有价值的事。对比不同指令下的系统提示词差异看 OpenCode 在什么条件下切换提示词模板统计各轮 prompt_tokens 增长曲线找出上下文膨胀的拐点把 tools 数组单独拎出来评估工具定义占了多少 token判断有没有精简空间。如果你要长期做编码 Agent 的提示词调优建议把 mitmproxy 抓包固化成流程每次改配置后跑一遍固定指令集对比请求体差异。Coding Plan 页面 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite 适合这种高频调试场景。接入文档 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 里有字段说明配置拿不准时对照。API Keys 管理在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 调试用的 Key 和生产的 Key 建议分开建方便随时吊销。最后留一个实操建议把 mitmweb 的请求导出成 JSON 文件用脚本解析 messages 和 tools 的 token 占比。这一步做完你对「提示词工程」的理解会从感觉层面落到数字层面。
阅读完成 · 觉得有帮助?