面试官:OpenCode Prompt 系统了解吗?

本系列文章皆基于开源 Vibecoding 工具 Opencode 源码进行详细拆解。

源码链接:github.com/anomalyco/o...


写在前面

上次咱们聊完了 Tool 工具系统,兄弟们是不是觉得 AI 终于能"动手"干活了?

!但是!光能动手也不行啊,兄弟们有没有想过这个问题:AI 是怎么"理解"自己是谁的?它怎么知道自己是 OpenCode 而不是 Claude?它怎么知道要在当前项目根目录工作而不是别的地方?

今天咱们就来看看,AI 背后的"灵魂"到底是咋构建的!这个 Prompt 系统,简直就是 OpenCode 的大脑中枢


一、什么是 Prompt 模块?

兄弟们,这个问题太关键了!Prompt 模块就是给 AI 灌输"世界观"的存在!

你跟 AI 说一句话,它不是直接就把那句话发出去了,它得先给自己"叠甲":

  • 我是谁?
  • 我在什么地方?
  • 我有什么能力?
  • 我要注意什么?

这些信息从哪来?就是 Prompt 模块给的!

Prompt 解决了什么问题?

问题 Prompt 方案
AI 不知道自己是谁 角色定义(你是 OpenCode)
不同模型需要不同调教 模型特定 Prompt
项目需要自定义规则 AGENTS.md 加载
指令散落各地不好找 层级向上查找
团队需要共享指令 远程 URL 支持

你说这些重要吗?简直不要太重要!没有 Prompt,AI 就是一个没有记忆、没有身份的"无头苍蝇"!


二、核心架构

看图!这四个东西就是 Prompt 模块的核心组件:

graph TB subgraph Prompt 模块 S[system.ts<br/>模型特定提示] I[instruction.ts<br/>指令文件加载] P[prompt.ts<br/>主Prompt逻辑] SK[skill.ts<br/>技能系统] end S --> P I --> P SK --> P P -->|组装完成| AI[AI Model]

2.1 各组件职责

文件 行数 职责
system.ts 72 模型特定提示词选择
instruction.ts 192 指令文件加载
prompt.ts 1968 主 Prompt 构建逻辑
prompt/*.txt - 各模型提示词模板

兄弟们,1968 行的 prompt.ts 是整个模块的大本营,里面逻辑那是相当的复杂!咱们后面会细讲!!


三、模型特定 Prompt 系统(面试重点!!!)

这个设计面试官特别喜欢问!!!问到你头皮发麻都有可能!!!

3.1 为什么需要区分模型?

兄弟们,这个设计太真实了。不同模型的"性格"完全不同!

  • Claude: 擅长思考,需要详细角色定义
  • GPT: 擅长执行,需要强调行动
  • Gemini: 有自己的特定优化方向
  • Qwen: 中文模型,不需要 TODO 功能

你说,你能让一个"思考型"模型去干"执行型"的活吗?能,但是效果不好。

所以 OpenCode 选择因材施教,给每个模型准备特定的提示词!这就是大厂的设计水平吗???简直离谱!!!

3.2 选择逻辑

typescript 复制代码
// 源码位置: packages/opencode/src/session/system.ts:22
export function provider(model: Provider.Model) {
  // GPT 系列(包括 o1/o3)
  if (model.api.id.includes("gpt-") || model.api.id.includes("o1") || model.api.id.includes("o3"))
    return [PROMPT_BEAST]
  
  // Gemini
  if (model.api.id.includes("gemini-")) return [PROMPT_GEMINI]
  
  // Claude
  if (model.api.id.includes("claude")) return [PROMPT_ANTHROPIC]
  
  // Trinity
  if (model.api.id.toLowerCase().includes("trinity")) return [PROMPT_TRINITY]
  
  // 默认(Qwen 等)
  return [PROMPT_ANTHROPIC_WITHOUT_TODO]
}

面试官可能会问:如果我要添加一个新模型,比如 DeepSeek,怎么做?

答案简直不要太简单!在这个函数里加一个判断,然后提供一个对应的提示词模板文件就行!就这???对,就这!!!

3.3 各模型提示词模板

模型 模板文件 特点
Claude anthropic.txt 标准 OpenCode 角色定义,105 行
GPT beast.txt 强调高效执行
Gemini gemini.txt Gemini 特定优化
Qwen qwen.txt 无 TODO 功能
Codex codex_header.txt 极简 header
Trinity trinity.txt 三合一模式

四、指令文件加载系统(必考!!!)

这个是面试重灾区,一定要搞懂!!!面试官问到你怀疑人生!!!

4.1 支持的指令文件

typescript 复制代码
// 源码位置: packages/opencode/src/session/instruction.ts:14
const FILES = [
  "AGENTS.md",   // OpenCode 标准
  "CLAUDE.md",   // Claude Code 兼容
  "CONTEXT.md",  // 已废弃,别用了!
]

4.2 多层级查找(核心亮点!!!)

兄弟们,这个设计简直是太香了!!!香到爆!!!

想象一下这个场景:

bash 复制代码
project/
├── AGENTS.md           # 项目根目录的指令
├── packages/
│   └── common/
│       └── AGENTS.md   # 子包的指令

当你在 packages/common/ 目录下工作时,OpenCode 会自动向上查找所有 AGENTS.md

这就是传说中的"继承"机制!太牛逼了!!!

graph TB subgraph 查找顺序 A[当前目录<br/>packages/common] B[上级目录<br/>packages] C[项目根目录<br/>project] D[全局配置目录] end A -->|未找到| B B -->|未找到| C C -->|未找到| D

4.3 向上查找算法

typescript 复制代码
// 源码位置: packages/opencode/src/session/instruction.ts:177
while (current.startsWith(root) && current !== root) {
  const found = await find(current)
  
  // 找到且不是目标文件、不是系统文件、未被加载过
  if (found && found !== target && !system.has(found) && !already.has(found)) {
    // 加载这个指令文件
    const content = await Filesystem.readText(found)
    results.push({ filepath: found, content })
  }
  current = path.dirname(current)  // 继续向上查找!!!
}

面试官可能会问:这个设计有什么好处?

  1. 子目录自动继承父目录指令:不用每个子项目都配一遍
  2. 就近优先:子目录的指令会覆盖父目录的
  3. 去重机制:不会重复加载同一个文件

就问你香不香???香爆了!!!

4.4 远程指令支持

typescript 复制代码
// 源码位置: packages/opencode/src/session/instruction.ts:134
const fetches = urls.map((url) =>
  fetch(url, { signal: AbortSignal.timeout(5000) })
    .then((res) => (res.ok ? res.text() : ""))
    .catch(() => "")
)

在配置文件里可以这样用:

json 复制代码
{
  "instructions": [
    "https://example.com/team-rules.md",
    "~/my-instructions/custom.md"
  ]
}

这样团队成员就能共享一份在线指令文档了!分布式团队开发,简直不要太爽!!!


五、技能(Skill)系统

这个是 OpenCode 的一个特色功能!让你的 AI 会"技能召唤"!!!

5.1 Skill 是什么?

兄弟们,Skill 就像是一个可插拔的能力包

typescript 复制代码
// 源码位置: packages/opencode/src/session/system.ts:59
export async function skills(agent: Agent.Info) {
  // 检查权限
  if (PermissionNext.disabled(["skill"], agent.permission).has("skill")) return
  
  // 获取可用技能列表
  const list = await Skill.available(agent)
  
  return Skill.fmt(list, { verbose: true })
}

5.2 Skill 的好处

  1. 按需加载:AI 根据任务自己决定要不要加载
  2. 权限控制:可以禁用某些 Skill
  3. 可扩展:任何人都可以添加新的 Skill

这不就是程序员梦寐以求的"插件系统"吗???太香了!!!


六、环境信息注入

每次对话都会自动注入当前环境信息,AI 简直就是一个"环境感知大师"!

typescript 复制代码
// 源码位置: packages/opencode/src/session/system.ts:32
export async function environment(model: Provider.Model) {
  return [
    `You are powered by the model named ${model.api.id}.`,
    `The exact model ID is ${model.providerID}/${model.api.id}`,
    `Here is some useful information about the environment you are running in:`,
    `<env>`,
    `  Working directory: ${Instance.directory}`,
    `  Workspace root folder: ${Instance.worktree}`,
    `  Is directory a git repo: ${project.vcs === "git" ? "yes" : "no"}`,
    `  Platform: ${process.platform}`,
    `  Today's date: ${new Date().toDateString()}`,
    `</env>`,
  ].join("\n")
}

这些信息帮助 AI 做出更准确的决策,比如:

  • 知道在哪个目录工作
  • 知道是什么平台(Windows/Linux/Mac)
  • 知道是不是 git 仓库

这不比某些 AI 连自己在哪都不知道强???甩它们十条街!!!


七、完整 Prompt 构建流程

sequenceDiagram participant U as 用户消息 participant P as Prompt 模块 participant S as SystemPrompt participant I as InstructionPrompt participant SK as Skill participant AI as AI Model U->>P: 用户发送消息 P->>S: 获取模型特定提示 S-->>P: 返回提示词模板 P->>I: 加载指令文件 I-->>P: 返回 AGENTS.md 内容 P->>SK: 获取可用技能 SK-->>P: 返回技能列表 P->>P: 组装完整上下文 P->>AI: 发送完整 Prompt AI-->>P: 返回响应

八、面试常见问题

Q1: Prompt 模块的核心职责是什么?

:负责构建 AI 每次对话的完整提示词,包括角色定义、模型特定指令、指令文件、Skill、环境信息等。这就是 AI 的"灵魂"!

Q2: 为什么需要模型特定的 Prompt?

:不同模型的"性格"和擅长领域不同。Claude 擅长思考,GPT 擅长执行,Gemini 有自己的优化方向。通过模型特定的 Prompt 可以最大化每个模型的效果。这就跟"因材施教"一个道理!!!

Q3: AGENTS.md 的向上查找机制是怎么工作的?

:从当前目录开始,逐层向上查找 AGENTS.mdCLAUDE.md 等指令文件,直到找到为止。所有找到的指令文件都会被加载,靠近当前目录的优先级更高。,简直就是"继承"机制的完美实现!

Q4: 如何添加对新模型的支持?

:在 system.tsprovider 函数中添加模型判断逻辑,然后创建一个对应的提示词模板文件(.txt)。简单到爆!!!

Q5: 远程指令是怎么实现的?

:通过 fetch API 加载配置中指定的 URL,5秒超时,返回内容作为指令追加到 Prompt 中。团队协作神器!!!


总结

兄弟们,今天咱们聊的 Prompt 模块,简直就是 OpenCode 的"大脑中枢"!它负责:

  1. 因材施教:为不同模型准备特定提示词
  2. 指令管理:自动加载和合并项目指令
  3. 技能扩展:支持动态加载 specialized 能力
  4. 环境感知:注入工作环境上下文

这个设计让 OpenCode 能够灵活适应不同模型和项目需求,是整个系统的核心基础设施。

兄弟们,这个设计你们觉得怎么样???是不是香到爆???


往期好文推荐


写在最后

兄弟们,如果文章对您有帮助麻烦亲点赞、收藏 + 关注和博主一起成长哟!!! 也欢迎在评论区留言讨论,说说你们觉得 Prompt 模块哪个设计最牛逼!!!

咱们下期再见!!!❤️❤️❤️

相关推荐
leoZ23114 分钟前
第 10 篇 数据飞轮与冷启动:AI 产品的数据从哪来
人工智能·大模型·agent
笃行35017 分钟前
使用Rokid AIUI做了一个童年推箱子游戏
前端
excel1 小时前
前端加密的作用与使用场景
前端
坐吃山猪2 小时前
Harness Engineering知识总结
llm·agent·harness
杨杨杨大侠2 小时前
RAG 到底是怎么工作的?从用户提问到模型回答的完整链路
spring·openai·ai编程
李燚2 小时前
Agent 要用 API key,但明文一次都不能进模型——Secret Runtime 落地实录(第110篇)
ai·agent·credential·secret·eino·deepflux·secret runtime
invicinble2 小时前
agent操作Windows的原理,以及操作其他的操作系统里面的数据
agent
计算机魔术师2 小时前
纽约时报版权诉讼披露:微软高管内部称训练 AI 是人类历史上最大规模劳动窃取
前端
去伪存真3 小时前
大模型的参数量为什么那么大?
前端·人工智能
IT_陈寒3 小时前
Java空指针这次真把我坑惨了
前端·人工智能·后端