OpenCode 构建提示词
OpenCode 构建提示词
1. 构建系统提示词
1.1 调用处理器前获取的系统提示词
在src/session/prompt.ts的loop函数中会创建系统提示词:
const system = [
...(await SystemPrompt.environment(model)), // 环境信息
...(await InstructionPrompt.system()) // 指令文件
]
返回的系统提示词当做processor.process函数的参数传入:
const result = await processor.process({
......
system,
......
})
1.1.1 SystemPrompt.environment
位置: src/session/system.ts:29-53
export async function environment(model: Provider.Model) {
return [
`You are powered by the model named ${model.api.id}...`,
`Working directory: ${Instance.directory}`,
`Is directory a git repo: ${project.vcs === "git" ? "yes" : "no"}`,
`Platform: ${process.platform}`,
`Today's date: ${new Date().toDateString()}`,
// ...
]
}
1.2 InstructionPrompt.system 的作用
位置: src/session/instruction.ts
InstructionPrompt 负责加载和管理额外的指令文件:
const FILES = [
"AGENTS.md",
"CLAUDE.md",
"CONTEXT.md", // deprecated
]
export async function system() {
const paths = await systemPaths()
const files = Array.from(paths).map(async (p) => {
const content = await Bun.file(p).text().catch(() => "")
return content ? "Instructions from: " + p + "\n" + content : ""
})
// 也支持从 URL 加载
const fetches = urls.map((url) => fetch(url)...)
return Promise.all([...files, ...fetches]).then((result) => result.filter(Boolean))
}
1.3 指令文件查找顺序
1.3.1 文件查找优先级
FILES 数组定义了查找顺序:["AGENTS.md", "CLAUDE.md", "CONTEXT.md"]
位置:src/session/instruction.ts:13-17
const FILES = [
"AGENTS.md",
"CLAUDE.md",
"CONTEXT.md", // deprecated
]
1.3.2 项目目录查找(替换关系)
位置:src/session/instruction.ts:75-84
for (const file of FILES) {
const matches = await Filesystem.findUp(file, Instance.directory, Instance.worktree)
if (matches.length > 0) {
matches.forEach((p) => { paths.add(path.resolve(p)) })
break // ← 关键:找到第一个存在的文件类型就停止
}
}
查找逻辑:
- 在当前目录向上查找
AGENTS.md - 如果没找到,在当前目录向上查找
CLAUDE.md - 如果没找到,在当前目录向上查找
CONTEXT.md - 找到任意一个就停止查找其他文件名
是替换关系:当前目录有 AGENTS.md 就不会查找 CLAUDE.md 和 CONTEXT.md。
1.3.3 全局目录查找
位置:src/session/instruction.ts:19-29, 87-92
function globalFiles() {
const files = []
if (Flag.OPENCODE_CONFIG_DIR) {
files.push(path.join(Flag.OPENCODE_CONFIG_DIR, "AGENTS.md"))
}
files.push(path.join(Global.Path.config, "AGENTS.md"))
if (!Flag.OPENCODE_DISABLE_CLAUDE_CODE_PROMPT) {
files.push(path.join(os.homedir(), ".claude", "CLAUDE.md"))
}
return files
}
for (const file of globalFiles()) {
if (await Bun.file(file).exists()) {
paths.add(path.resolve(file))
break // ← 找到第一个存在的就停止
}
}
1.3.4 项目目录和全局目录的关系(叠加关系)
| 来源 | 结果 |
|---|---|
| 项目目录 | 找到一个文件(AGENTS.md 或 CLAUDE.md 或 CONTEXT.md) |
| 全局目录 | 找到一个文件 |
| 最终 | 两个文件叠加(如果都存在) |
不是替换:当前目录有 CLAUDE.md 不会阻止查找全局目录的文件。
1.3.5 文件都不存在时
如果所有指令文件都不存在:
paths为空 SetInstructionPrompt.system()返回空内容- 只使用 agent 默认提示词 + 环境信息 + 用户输入
1.4 完整的 system 提示词组成
1.4.1 system 提示词的堆栈
位置:src/session/llm.ts:67-79
const system = []
system.push(
[
// 1. agent 提示词 或 提供商默认提示词
...(input.agent.prompt ? [input.agent.prompt] : SystemPrompt.provider(input.model)),
// 2. 环境信息 + 指令文件内容(来自 prompt.ts)
...input.system,
// 3. 用户消息中的自定义系统提示词
...(input.user.system ? [input.user.system] : []),
]
.filter((x) => x)
.join("\n"),
)
system 提示词堆栈:
┌─────────────────────────────────────────────────────────────┐
│ system 提示词 │
├─────────────────────────────────────────────────────────────┤
│ 1. agent.prompt 或 SystemPrompt.provider(model) │
│ - agent 自定义提示词,或根据模型提供商返回默认提示词 │
├─────────────────────────────────────────────────────────────┤
│ 2. SystemPrompt.environment(model) │
│ - 模型信息、工作目录、平台、日期等 │
├─────────────────────────────────────────────────────────────┤
│ 3. InstructionPrompt.system() │
│ - AGENTS.md / CLAUDE.md / CONTEXT.md 内容 │
├─────────────────────────────────────────────────────────────┤
│ 4. user.system │
│ - 用户消息中附带的自定义系统提示词 │
└─────────────────────────────────────────────────────────────┘
1.4.2 agent.prompt 的来源
从 agent 配置中获取,不同 agent 有不同的提示词:
// agent.ts 中的定义
export const AgentSchema = z.object({
name: z.string(),
prompt: z.string().optional(), // ← 自定义提示词
// ...
})
// 内置 Agent 示例
const agents = {
build: { prompt: "You are a helpful coding assistant..." },
plan: { prompt: "You are a planning assistant..." },
compaction: { prompt: "Summarize the conversation..." },
// ...
}
1.4.3 调用 API 时的消息结构
位置:src/session/llm.ts:229-237
messages: [
...system.map((x): ModelMessage => ({
role: "system", // ← 明确是 system 角色
content: x,
})),
...input.messages, // ← 用户消息历史(user/assistant 交替)
]
系统提示词和用户输入不在同一个字段:
system→{ role: "system", content: "..." }input.messages→{ role: "user/assistant", content: "..." }
1.1.2 SystemPrompt.provider
位置: src/session/system.ts:19-27
根据模型类型选择不同的提示词模板:
- GPT/O1/O3:
PROMPT_BEAST - Gemini:
PROMPT_GEMINI - Claude:
PROMPT_ANTHROPIC - 其他:
PROMPT_ANTHROPIC_WITHOUT_TODO
1.4.4 总结
| 问题 | 答案 |
|---|---|
| agent.prompt 是系统还是用户提示词? | 系统提示词,role: "system" |
| 系统提示词和用户输入是否同字段? | 不是,分开传递给 AI SDK |
| 存在 AGENTS.md 是否替换 agent.prompt? | 不是替换,是叠加,都会被使用 |
| agent.prompt 从哪获取? | agent 配置中定义,不同 agent 有不同提示词 |
2. 构建用户提示词
2.1 createUserMessage 函数
位置: src/session/prompt.ts:957-1325
主要处理:
- 解析 agent 引用
- 解析文件引用(@file 语法)
- 处理 MCP 资源
- 调用 ReadTool 预读取文件
2.2 insertReminders 函数
位置: src/session/prompt.ts:1327-1465
根据当前 agent 和历史添加提醒:
planagent: 添加规划模式提示- 从
plan切换到build: 添加切换提示

浙公网安备 33010602011771号