本系列文章皆基于开源 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 选择逻辑
// 源码位置: 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 支持的指令文件
// 源码位置: packages/opencode/src/session/instruction.ts:14
const FILES = [
"AGENTS.md", // OpenCode 标准
"CLAUDE.md", // Claude Code 兼容
"CONTEXT.md", // 已废弃,别用了!
]
4.2 多层级查找(核心亮点!!!)
兄弟们,这个设计简直是太香了!!!香到爆!!!
想象一下这个场景:
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 向上查找算法
// 源码位置: 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) // 继续向上查找!!!
}
面试官可能会问:这个设计有什么好处?
- 子目录自动继承父目录指令:不用每个子项目都配一遍
- 就近优先:子目录的指令会覆盖父目录的
- 去重机制:不会重复加载同一个文件
就问你香不香???香爆了!!!
4.4 远程指令支持
// 源码位置: 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(() => "")
)
在配置文件里可以这样用:
{
"instructions": [
"https://example.com/team-rules.md",
"~/my-instructions/custom.md"
]
}
这样团队成员就能共享一份在线指令文档了!分布式团队开发,简直不要太爽!!!
五、技能(Skill)系统
这个是 OpenCode 的一个特色功能!让你的 AI 会"技能召唤"!!!
5.1 Skill 是什么?
兄弟们,Skill 就像是一个可插拔的能力包。
// 源码位置: 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 的好处
- 按需加载:AI 根据任务自己决定要不要加载
- 权限控制:可以禁用某些 Skill
- 可扩展:任何人都可以添加新的 Skill
这不就是程序员梦寐以求的"插件系统"吗???太香了!!!
六、环境信息注入
每次对话都会自动注入当前环境信息,AI 简直就是一个"环境感知大师"!
// 源码位置: 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.md、CLAUDE.md 等指令文件,直到找到为止。所有找到的指令文件都会被加载,靠近当前目录的优先级更高。,简直就是"继承"机制的完美实现!
Q4: 如何添加对新模型的支持?
答:在 system.ts 的 provider 函数中添加模型判断逻辑,然后创建一个对应的提示词模板文件(.txt)。简单到爆!!!
Q5: 远程指令是怎么实现的?
答:通过 fetch API 加载配置中指定的 URL,5秒超时,返回内容作为指令追加到 Prompt 中。团队协作神器!!!
总结
兄弟们,今天咱们聊的 Prompt 模块,简直就是 OpenCode 的"大脑中枢"!它负责:
- 因材施教:为不同模型准备特定提示词
- 指令管理:自动加载和合并项目指令
- 技能扩展:支持动态加载 specialized 能力
- 环境感知:注入工作环境上下文
这个设计让 OpenCode 能够灵活适应不同模型和项目需求,是整个系统的核心基础设施。
兄弟们,这个设计你们觉得怎么样???是不是香到爆???
往期好文推荐
写在最后
兄弟们,如果文章对您有帮助麻烦亲点赞、收藏 + 关注和博主一起成长哟!!! 也欢迎在评论区留言讨论,说说你们觉得 Prompt 模块哪个设计最牛逼!!!
咱们下期再见!!!❤️❤️❤️