五张脸的瞬间
为什么 opencode 不写'一份 prompt 走天下'
一、原理:同一 prompt 在不同模型上为什么效果天差地别
如果你用过 ChatGPT 和 Claude,可能感受过同一个问题问下去,两个模型给的答案"气质"很不一样。Claude 更愿意承认自己不确定、更愿意按步骤讲清楚;GPT 更倾向直接给方案、更愿意"自信地"猜测;Gemini 经常严格遵守你的格式要求,但对边界情况处理得没那么细。
这种气质差异在普通对话里只是"风格",但在 Agent 场景里是产品质量问题。AI Agent 接到任务后要做一连串决策:先查代码还是先问用户、改一个文件还是改几个、要不要先跑测试、什么时候停下来汇报。这一连串决策怎么做,很大程度取决于背后 LLM 的"性格"。
如果你给所有 LLM 写同一份 system prompt,会发生什么?答案是:每个模型都会被压抑到中下水平。
给 Claude 写的 prompt 在 GPT 上往往太"客气"——GPT 本来可以更主动,被压得磨磨唧唧。给 GPT 写的 prompt 在 Claude 上往往太"硬"——Claude 本来可以更细致解释,被压得只给结论。给 Gemini 写的 prompt 在 Claude / GPT 上又显得过于规则化。
这是工业级 prompt engineering 一个已经普遍接受、但产品层面尚未公开承认的现实。多数 AI 产品对外说"我们支持多模型",但内部 prompt 是单份的、靠"中间值"去 cover 所有模型。后果是:每个模型都没有被充分释放。
这个问题没有银弹解法。如果你想让 AI Agent 在多个 LLM 上都表现到位,理论上只有两条路:
第一,让 LLM 自己适应你的统一 prompt。这是 OpenAI 之类的姿态——他们希望你写一份 prompt,他们的模型自己消化你的意图。代价是你被绑定在一家厂商。
第二,为每个模型写一份针对它"病症"的 prompt。这条路工程量大、维护成本高,但能让每个模型在自己的舒适区里发挥。
opencode 选了第二条。它有 5 张完全独立的"脸"——按 LLM 模型族动态切换。这不是 5 份风格变体,是 5 份对模型不同病症的诊断和处方。
二、案例:五张脸的实况
opencode 仓库里有一个叫 packages/opencode/src/session/prompt/ 的目录。里面 14 个 .txt 文件,5 个是 system prompt 的核心:
default.txt—— 没识别出模型族时的兜底anthropic.txt—— Claude 系列gpt.txt—— OpenAI 非推理模型gemini.txt—— Google Gemini 系列beast.txt—— GPT-4 / o1 / o3 等推理模型,野兽模式
opencode 在每次跟模型对话前,会读模型 ID 字符串,按子串匹配选其中一个 prompt 文件。这种 dispatch 写在 session/system.ts 第 25-39 行——是真实运行时的行为,不是某个用户能改的配置。
打开这五个文件读全文,你会发现 opencode 是五个不同的产品伪装成一个。
anthropic.txt 第一行:
"You are OpenCode, the best coding agent on the planet."
地球最强。开门见山自吹自擂。继续往下读,会看到一个叫「Professional objectivity」的章节,明确告诉 Claude——「不要谄媚用户的信念,给直接客观的技术建议」。
gpt.txt 第一行:
"You are OpenCode, You and the user share the same workspace and collaborate to achieve the user's goals."
完全相反的语气。「我们共用工作区,一起干活」。继续读,关键词是 「deeply pragmatic, effective software engineer」——「深度务实、有效的工程师」。这个 prompt 从头到尾没有任何自吹。
gemini.txt 第一行:
"You are opencode, an interactive CLI agent specializing in software engineering tasks."
平淡。它的核心在后面——5 步软件工程工作流:Understand → Plan → Implement → Verify (Tests) → Verify (Standards)。每一步都明确该做什么、不该做什么。整份 prompt 像一份新员工培训手册。
beast.txt 第一行:
"You are opencode, an agent - please keep going until the user's query is completely resolved, before ending your turn and yielding back to the user."
野兽模式。继续往下读:"You MUST iterate and keep going until the problem is solved." 后面更激进:"THE PROBLEM CAN NOT BE SOLVED WITHOUT EXTENSIVE INTERNET RESEARCH." 这个 prompt 比其他三个加起来都激进。
default.txt 是兜底版——平淡通用,没有强人设。
把这四张脸(不含兜底)的核心姿态摆在一起:
| Anthropic | GPT | Gemini | Beast | |
|---|---|---|---|---|
| 自我描述 | "the best coding agent on the planet" | "deeply pragmatic, effective" | "interactive CLI agent specializing" | "an agent" |
| 主推行为 | TodoWrite 用得勤 | commentary 频道勤更新 | 5 步工作流 | extensive internet research |
| 态度 | 自信 + 直接 | 克制 + 协作 | 流程化 + 验证 | 顽强 + 迭代 |
| 反 anti-pattern | "不要谄媚" | "不要 conversational interjections" | "不要 chitchat" | "持续到所有 TODO 完成" |
这不是 prompt 风格略有不同。这是四种完全不同的产品判断,每种针对一类模型的真实弱点。
Anthropic 模型被告诫「不要谄媚」——因为 Claude 系列有 agreeable 倾向(容易顺着用户说)。「Best on the planet」这种开场是反向校准——给 Claude 一个自信的人设锚,避免它被用户带偏。
GPT 模型被告诫「不要 conversational interjections」——因为 GPT 在闲聊和铺垫上消耗大量 token("Great question!"、"Let me think...")。整个 prompt 围绕「少说多做」展开。
Gemini 模型被强制 5 步流程——因为 Gemini 在自由发挥时容易偏离项目约定。流程是约束。
GPT-4 / o1 / o3 被强制「MUST iterate」——因为推理模型如果不被告诫「继续」,会在一两轮后就停下来等用户。野兽模式是为了让 reasoning 模型不要中途休息。
四个 prompt 对应四种已知的模型病。每张脸都是针对一类模型设计的 anti-pattern 校正器。
Beast Mode 这张脸还有一个戏剧性的来源问题。beast.txt 第 114 行写着:
"You have a memory that stores information about the user and their preferences. The memory is stored in a file called
.github/instructions/memory.instruction.md."
.github/instructions/memory.instruction.md 不是 opencode 的路径约定——opencode 用的是 .opencode/ 目录、AGENTS.md 文件。从来不用 .github/instructions/。
这个路径来自 GitHub Copilot。Copilot 的 custom instruction 存在 .github/copilot-instructions.md 里。.github/instructions/ 是 Copilot 社区约定的扩展。
继续读 beast.txt,会发现 "You MUST iterate and keep going until the problem is solved" 这种句式在 Cursor / Copilot 用户社区里流传过一阵,叫「Beast Mode」。是用户互相分享的 prompt 模板,专门用来让推理模型不要中途偷懒。
beast.txt 不是 opencode 团队原创——是从对手社区移植过来的 prompt 模板,几乎没怎么改。.github/instructions/memory.instruction.md 这句话甚至没换回 opencode 的路径——是抄过来时漏改。
这本身不是丑闻。Prompt 在 AI 工具圈是流通的——Cursor 的 prompt、Copilot 的 prompt、ChatGPT 用户分享的 prompt 都在 GitHub Gist 和 Twitter 上传播。opencode 借用业界已经被验证的 prompt 模板,是务实选择。
但有戏剧性的是——marketing 上 opencode 不正面跟 Cursor 比,但 prompt 文件层面,opencode 用了 Cursor 用户的劳动成果。竞争的真实战场,不在首页对比表,在 .txt 文件里。
三、设计启示:什么时候你该为每个模型写独立 prompt
不是所有 AI 产品都需要 opencode 这种"按模型换脸"的做法。它有适用条件。
你产品的成败重度依赖 LLM 的输出质量时——值得做。AI Agent 这种"AI 决策一连串行动"的场景,模型差异会被放大。一个细微的"早停"倾向,在 Agent 里会变成"任务做一半就停下"的产品 bug。
你产品只是给用户提供"AI 辅助"时——往往不需要。Chatbot 类产品(聊天、问答、翻译)模型差异主要表现为"风格",统一一份 prompt 就够用,多份反而维护负担大。
你的用户跨多个 LLM 提供商时——值得做。如果你的用户里有人用 Claude、有人用 GPT、有人用 Gemini,那么"中间值 prompt"会让每个用户都不满意。
你只对接一家 LLM 时——不必做。Claude Code 只对接 Claude,它就只有一张脸。这不是设计上的偷懒,是 scope 上的合理。
如果你决定走"每模型一张脸"的路,有三件事要做好。
第一,把诊断显式写出来。opencode 的五张脸里隐含着「Claude 是谄媚的高手、GPT 是聪慧的啰嗦鬼、Gemini 是粗心的学生、Beast 是不放过自己的偏执狂」这些诊断。如果你不写下来,团队里每个人对模型的认知会随时间漂移,prompt 会失去针对性。
第二,定期重新校准。LLM 在升级。Claude 3.5 → Claude 4 的版本变化里,"谄媚"问题可能减弱了,但"过度搜索"问题可能新出现了。你的 prompt 文件不应该是"写一次就放着"的资产,它应该是活的文档,每次模型升级都重读一遍。
第三,给 prompt 文件做版本控制。opencode 的 5 张脸都在 git 里。每次修改有 commit message。看 commit history 就能看到这个团队"对模型的诊断"是怎么演化的。如果你的 prompt 散落在配置文件里、写死在代码里、或者每个工程师一份本地版本,你就失去了观察自己设计演化的能力。
这一章的核心论点是:prompt engineering 不是文案优化,是模型诊断学。每张脸都是对一类模型病症的处方。你的 AI 产品如果想真的把每个模型用到位,就必须把这件事显式做出来,做成可演化、可对比、可审计的产品资产。
接下来 7 章我们会逐张脸看进去——anthropic.txt 怎么治 Claude 的谄媚、gpt.txt 怎么堵 GPT 的嘴、gemini.txt 怎么管 Gemini 的粗心、beast.txt 怎么让推理模型不停下。每张脸都是一次完整的诊断 + 处方。看完这 7 章你就有了一套自己的 prompt 工程框架——遇到任何新模型,能用同一套思路去诊断它的病、写它的处方。