面试官: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
模型特定提示] I[instruction.ts
指令文件加载] P[prompt.ts
主Prompt逻辑] SK[skill.ts
技能系统] 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[当前目录
packages/common] B[上级目录
packages] C[项目根目录
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 模块哪个设计最牛逼!!!

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

相关推荐
百锦再2 小时前
复杂查询中基于代价的连接条件下推实践与思考
前端
广州华水科技2 小时前
如何实现高精度的单北斗GNSS位移监测系统安装?
前端
肉肉不吃 肉2 小时前
Vue Router 路由模式
前端·javascript·vue.js
北寻北爱2 小时前
Vue-Router
前端·javascript·vue.js
肉肉不吃 肉2 小时前
什么是闭包
前端·javascript
窝子面2 小时前
十六、按钮组件
前端
天天向上10242 小时前
vue 页面内实现el-table和div自动滚动
前端·javascript·vue.js
前端老石人2 小时前
HTML文档元素与元数据详解
前端·html
wing982 小时前
用 AI 实现图片懒加载,这也太简单了!
前端·vue.js·图片资源