opencode System Prompt 构建机制 & AGENTS.md注入机制

opencode System Prompt 构建机制 & AGENTS.md注入机制

概述

opencode 的 System Prompt 由多个部分动态拼接而成,在每次 LLM 调用前组装。整体结构如下:

css 复制代码
[Provider/Agent 基础提示词]
  + [环境信息 env]
  + [指令文件内容 instructions]
  + [技能列表 skills]

核心组装逻辑分布在两个文件:

  • packages/opencode/src/session/llm.ts --- 最终拼接
  • packages/opencode/src/session/prompt.ts --- 准备 env / instructions / skills

各部分详解

1. Provider/Agent 基础提示词

来源: packages/opencode/src/session/system.tsprovider() 函数
组装位置: packages/opencode/src/session/llm.ts:103

css 复制代码
...(input.agent.prompt ? [input.agent.prompt] : SystemPrompt.provider(input.model))

逻辑:

  • 如果当前 Agent 在配置中定义了自定义 prompt,直接使用该 prompt
  • 否则根据模型 ID 自动选择内置 provider 提示词文件:
模型匹配规则 提示词文件
包含 claude prompt/anthropic.txt
包含 gpt-4o1o3 prompt/beast.txt
包含 codex prompt/codex.txt
包含其他 gpt prompt/gpt.txt
包含 gemini- prompt/gemini.txt
包含 trinity prompt/trinity.txt
包含 kimi prompt/kimi.txt
其他 prompt/default.txt

所有提示词文件位于 packages/opencode/src/session/prompt/ 目录。

内置示例:prompt/anthropic.txt(Claude 模型使用)

vbnet 复制代码
You are OpenCode, the best coding agent on the planet.

You are an interactive CLI tool that helps users with software engineering tasks.
Use the instructions below and the tools available to you to assist the user.

IMPORTANT: You must NEVER generate or guess URLs for the user unless you are
confident that the URLs are for helping the user with programming.

If the user asks for help or wants to give feedback inform them of the following:
- ctrl+p to list available actions
- To give feedback, users should report the issue at
  https://github.com/anomalyco/opencode

# Tone and style
- Only use emojis if the user explicitly requests it.
- Your output will be displayed on a command line interface.
...

# Professional objectivity
Prioritize technical accuracy and truthfulness over validating the user's beliefs.
...

# Task Management
You have access to the TodoWrite tools to help you manage and plan tasks.
Use these tools VERY frequently to ensure that you are tracking your tasks.
...

# Doing tasks
The user will primarily request you perform software engineering tasks.
...

# Tool usage policy
- When doing file search, prefer to use the Task tool in order to reduce context usage.
...

# Code References
When referencing specific functions or pieces of code include the pattern
`file_path:line_number` to allow the user to easily navigate to the source code location.

完整内容见 packages/opencode/src/session/prompt/anthropic.txt
default.txt 用于其他模型,风格更简洁,强调"回答少于 4 行、不加无用前缀"。

Agent 自定义 prompt 示例opencode.json):

json 复制代码
{
  "agent": {
    "my-agent": {
      "prompt": "你是一个专注于代码审查的助手,只读取文件,不修改。"
    }
  }
}

2. 环境信息(env)

来源: packages/opencode/src/session/system.tsenvironment() 方法
组装位置: packages/opencode/src/session/prompt.ts:1444

bash 复制代码
Effect.sync(() => sys.environment(model))

每次调用时动态生成,内容如下:

vbnet 复制代码
You are powered by the model named <model.api.id>. The exact model ID is <providerID>/<modelID>
Here is some useful information about the environment you are running in:
<env>
  Working directory: /path/to/project
  Workspace root folder: /path/to/worktree
  Is directory a git repo: yes
  Platform: darwin
  Today's date: Mon May 04 2026
</env>

3. 指令文件(instructions)

来源: packages/opencode/src/session/instruction.tssystem() 方法
组装位置: packages/opencode/src/session/prompt.ts:1445

scss 复制代码
instruction.system().pipe(Effect.orDie)

system() 的完整逻辑:

  1. 调用 systemPaths() 收集所有本地文件路径(Set<string>
  2. 提取 config.instructions 中的远程 URL
  3. 并发读取本地文件(最多 8 个并发)
  4. 并发拉取远程 URL(最多 4 个并发,超时 5 秒)
  5. 空文件 / 拉取失败的条目自动跳过

最终每条内容格式:

javascript 复制代码
Instructions from: /absolute/path/to/AGENTS.md
<文件内容>

AGENTS.md 加载机制

查找规则(systemPaths()

按以下三步收集文件路径,结果存入 Set<string>(自动去重,顺序:全局 → 项目 → 额外)。


第一步:全局文件(最多加载 1 个)

globalFiles() 返回候选列表,按顺序取第一个存在的文件后 break:

javascript 复制代码
1. $OPENCODE_CONFIG_DIR/AGENTS.md   (仅当 OPENCODE_CONFIG_DIR 已设置)
2. ~/.config/opencode/AGENTS.md
3. ~/.claude/CLAUDE.md              (除非设置了 OPENCODE_DISABLE_CLAUDE_CODE_PROMPT)

效果: 全局只注入一个文件,不会叠加多个。


第二步:项目文件(findUp 向上查找,同类型全部加载)

使用 findUp(file, ctx.directory, ctx.worktree) 实现:

复制代码
从 working directory 开始,依次向上收集各层目录中存在该文件名的路径,
直到 worktree 根目录为止(含根目录)。

文件类型优先级(FILES 数组):

ini 复制代码
const FILES = ["AGENTS.md", "CLAUDE.md", "CONTEXT.md"]

查找逻辑:

  • AGENTS.md 执行 findUp → 若找到任意匹配,把所有匹配都加入,然后 break(不再查 CLAUDE.mdCONTEXT.md
  • AGENTS.md 一个都没有,对 CLAUDE.md 执行同样逻辑
  • 若前两者都没有,对 CONTEXT.md(已废弃)执行

关键点:同类型文件在路径上的多个实例都会被加载。

示例目录结构:

bash 复制代码
/project/                   ← worktree 根
├── AGENTS.md               ← ✅ 被加载(findUp 命中)
├── src/
│   ├── AGENTS.md           ← ✅ 被加载(findUp 命中,与根目录同类型)
│   └── auth/               ← working directory(opencode 在此启动)
└── opencode.json

若 working directory 是 /project/src/auth/findUp("AGENTS.md", "/project/src/auth/", "/project/") 会依次检查:

  • /project/src/auth/AGENTS.md --- 不存在,跳过
  • /project/src/AGENTS.md --- 存在,收集
  • /project/AGENTS.md --- 存在,收集

结果:/project/src/AGENTS.md/project/AGENTS.md 都被注入


⚠️ 从根目录启动时,子目录的 AGENTS.md 不会被加载

findUp 只向查找,不向下扫描子目录。

ini 复制代码
/project/          ← working directory = worktree 根,在此启动 opencode
├── AGENTS.md      ← ✅ 被加载
├── src/
│   └── AGENTS.md  ← ❌ 不会被加载(子目录,findUp 不向下扫描)
└── packages/
    └── AGENTS.md  ← ❌ 不会被加载(同上)

findUp("AGENTS.md", "/project/", "/project/") 的执行过程:

  • start 与 stop 相同,只检查 /project/AGENTS.md,立即结束
  • 子目录的 AGENTS.md 完全不在查找范围内

如果需要加载子目录的 AGENTS.md,有两种方式:

  1. config.instructions glob 通配符(静态,启动时加载):

    json 复制代码
    {
      "instructions": ["**/AGENTS.md"]
    }

    利用 globUp 在每层目录执行 glob,可匹配子目录。

    注意:globUp 是从当前目录向上扫描,不是递归向下,此方式需结合相对路径 glob 才能覆盖子目录。

    更直接的方式是使用绝对路径:"/project/**/AGENTS.md"

  2. 动态加载 (按需,读取文件时触发):

    read 工具读取子目录中的文件时,resolve() 方法会自动将该文件附近的 AGENTS.md 注入为 tool result,详见下方"动态加载"章节。


第三步:配置额外指令(config.instructions

来自 opencode.json 中的 instructions 数组,支持四种格式:

perl 复制代码
{
  "instructions": [
    "docs/style-guide.md",            // 相对路径 → globUp(从 working dir 向上每层 glob)
    "~/notes/coding-rules.md",        // ~ 路径 → 展开为绝对路径后 glob
    "/shared/team-rules/*.md",        // 绝对路径 → 直接 glob(支持通配符)
    "https://example.com/rules.md"    // URL → HTTP GET(超时 5 秒)
  ]
}

相对路径 / ~/ 路径的查找行为(globUp):

scss 复制代码
从 working directory 开始,在每一层目录执行 glob(pattern),
收集所有匹配文件,然后向上到 worktree 根。

findUp 的区别:

  • findUp:精确文件名,找到即 break(按类型)
  • globUp:支持通配符,不 break,沿路径每层都 glob,结果全部收集

示例:instructions: ["docs/*.md"] 会扫描从当前目录到 worktree 根路径上,每层 docs/ 子目录中的所有 .md 文件。

URL 的获取行为:

  • 仅支持 http://https://
  • 发起 GET 请求,超时 5 秒,失败或超时则跳过(不报错)
  • 响应体以 UTF-8 解码后整体注入

完整 instructions 注入示例

假设项目结构:

arduino 复制代码
/project/
├── AGENTS.md                    # "禁止直接提交 main 分支"
├── src/
│   └── AGENTS.md                # "src 目录使用 TypeScript strict 模式"
└── opencode.json                # instructions: ["docs/style.md", "https://rules.example.com/base.md"]

~/.config/opencode/AGENTS.md 存在,内容为 "遵循公司编码规范"。

注入到 System Prompt 的 instructions 部分(4 条):

javascript 复制代码
Instructions from: /Users/mac/.config/opencode/AGENTS.md
遵循公司编码规范

Instructions from: /project/src/AGENTS.md
src 目录使用 TypeScript strict 模式

Instructions from: /project/AGENTS.md
禁止直接提交 main 分支

Instructions from: /project/docs/style.md
<style.md 文件内容>

Instructions from: https://rules.example.com/base.md
<远程规则内容>

动态加载(对话中)

除了启动时的静态加载,在对话过程中读取文件时,opencode 还会动态注入附近的指令文件。

触发时机: 使用 read 工具读取某个文件后(state.status === "completed"

机制instruction.tsresolve() 方法):

  1. 取被读取文件所在目录,向上逐级走到 worktree 根

  2. 每层检查 AGENTS.mdCLAUDE.mdCONTEXT.md(取第一个存在的)

  3. 跳过以下情况:

    • 已在启动时 System Prompt 中加载的(sys.has(found)
    • 当前 assistant 消息中已经注入过的(claims Map 追踪,每条消息重置)
    • 正在被读取的文件本身(found === target
    • 已在本对话中由其他 read 工具加载过的(extract(messages) 扫描历史)
  4. 内容以附加 tool result 的形式注入,不进入 System Prompt

效果示例:

bash 复制代码
read("src/auth/login.ts")
→ 检查 src/auth/AGENTS.md   → 存在 → 注入
→ 检查 src/AGENTS.md        → 已在系统启动时加载 → 跳过
→ 检查 /project/AGENTS.md   → 已在系统启动时加载 → 跳过

4. 技能列表(skills)

来源: packages/opencode/src/session/system.tsskills() 方法
组装位置: packages/opencode/src/session/prompt.ts:1443

scss 复制代码
sys.skills(agent)

逻辑:

  • 若 agent 的权限中禁用了 skill 工具,则返回 undefined(不注入)
  • 否则获取当前 agent 可用的 skill 列表,以详细(verbose)格式注入

注入内容格式(system.ts:65-77):

xml 复制代码
Skills provide specialized instructions and workflows for specific tasks.
Use the skill tool to load a skill when a task matches its description.
<available_skills>
  <skill>
    <name>commit</name>
    <description>Use when the user asks to commit changes</description>
    <location>file:///Users/mac/.config/opencode/skills/commit.md</location>
  </skill>
  <skill>
    <name>review</name>
    <description>Use for code review tasks</description>
    <location>file:///project/.opencode/skills/review.md</location>
  </skill>
</available_skills>

生成逻辑packages/opencode/src/skill/index.ts:264):

Skill.fmt(list, { verbose: true }) 输出 XML 格式,按 skill 名称字母升序排列,每条包含:

字段 说明
<name> skill 文件名(不含 .md
<description> skill frontmatter 中的 description 字段
<location> skill 文件的 file:// URL 绝对路径

若没有任何可用 skill,输出:No skills are currently available.

skill 工具描述中的非 verbose 格式对比:

markdown 复制代码
## Available Skills
- **commit**: Use when the user asks to commit changes
- **review**: Use for code review tasks

System Prompt 使用详细版(verbose),工具描述使用简洁版(non-verbose),两者配合:模型在 System Prompt 中获取完整信息,在工具描述中快速检索。


最终组装

packages/opencode/src/session/llm.ts 中的最终拼接:

less 复制代码
// 第一个 system block(基础提示词 + env + instructions + skills)
system.push(
  [
    ...(agent.prompt ? [agent.prompt] : SystemPrompt.provider(model)),  // 基础提示词
    ...input.system,   // = [...env, ...instructions, ...(skills ? [skills] : [])]
    ...(user.system ? [user.system] : []),  // 用户消息携带的 system(少见)
  ]
  .filter(x => x)
  .join("\n")
)

随后触发插件钩子,允许插件修改 system 数组:

perl 复制代码
plugin.trigger("experimental.chat.system.transform", { sessionID, model }, { system })

若输出格式为 json_schema,还会追加:

lua 复制代码
IMPORTANT: The user has requested structured output. You MUST use the StructuredOutput tool...

特殊注入(非 System 位置)

以下内容不在 System Prompt 中,而是以合成用户消息部分(synthetic user message part)注入:

触发条件 内容来源 说明
当前 agent 是 plan prompt/plan.txt 只读模式提醒,禁止文件修改
plan 切换到 build prompt/build-switch.txt 解除只读限制提醒
步骤数达到上限 prompt/max-steps.txt 作为最后一条 assistant 消息追加,禁用工具

完整结构图

css 复制代码
LLM 调用时的 system 数组
├── [0] 第一块(拼接为单字符串)
│   ├── 基础提示词(provider-specific 或 agent 自定义)
│   ├── env(模型名、工作目录、平台、日期)
│   ├── instructions(AGENTS.md 等文件内容)
│   └── skills(可用 skill 列表,详细版)
└── [1+] 插件通过 experimental.chat.system.transform 追加的内容

消息列表(messages)
├── 历史对话消息
├── [倒数第二] 合成 user part(plan/build-switch 提醒,若适用)
└── [最后] 若达到最大步数,追加一条 assistant 消息(max-steps 内容)

AGENTS.md 文件编写建议

AGENTS.md 是最常见的 instructions 文件,推荐结构:

markdown 复制代码
# 项目规范

## 技术栈
- 语言:TypeScript
- 包管理:pnpm
- 测试:vitest

## 开发规范
- 提交前必须运行:`pnpm typecheck && pnpm lint`
- 不要在代码中添加注释,除非逻辑不自明
- 所有新文件必须有对应的单元测试

## 目录说明
- `src/` --- 主要源代码
- `packages/` --- 子包
- `docs/` --- 文档,不要自动生成

加载优先级与覆盖关系

shell 复制代码
macOS MDM(最高)
  > 全局 AGENTS.md(~/.config/opencode/AGENTS.md)
  > 项目 AGENTS.md(项目根目录)
  > config.instructions 中的额外文件
  > 动态加载(read 工具触发)

多个文件叠加合并(不互相覆盖),均会出现在 System Prompt 中。


完整 System Prompt 示例

以下模拟一次真实调用,条件:

  • 模型:claude-sonnet-4-5(anthropic 提供商)
  • Agent:内置 build(无自定义 prompt)
  • Working directory:/Users/mac/myproject/src,worktree 根:/Users/mac/myproject
  • 项目有 /Users/mac/myproject/AGENTS.md/Users/mac/myproject/src/AGENTS.md
  • 全局有 ~/.config/opencode/AGENTS.md
  • 配置了 1 个 skill:commit

最终传给 LLM 的 system 数组(共 1 个字符串块,各部分用 \n 拼接):

sql 复制代码
==== 第 1 块(system[0])====

【基础提示词 --- anthropic.txt】
You are OpenCode, the best coding agent on the planet.

You are an interactive CLI tool that helps users with software engineering tasks. Use the instructions below and the tools available to you to assist the user.

IMPORTANT: You must NEVER generate or guess URLs for the user unless you are confident that the URLs are for helping the user with programming. You may use URLs provided by the user in their messages or local files.

If the user asks for help or wants to give feedback inform them of the following:
- ctrl+p to list available actions
- To give feedback, users should report the issue at
  https://github.com/anomalyco/opencode

# Tone and style
- Only use emojis if the user explicitly requests it. Avoid using emojis in all communication unless asked.
- Your output will be displayed on a command line interface. ...

# Professional objectivity
Prioritize technical accuracy and truthfulness over validating the user's beliefs. ...

# Task Management
You have access to the TodoWrite tools to help you manage and plan tasks. Use these tools VERY frequently ...

# Doing tasks
The user will primarily request you perform software engineering tasks. ...

# Tool usage policy
- When doing file search, prefer to use the Task tool in order to reduce context usage.
...

# Code References
When referencing specific functions or pieces of code include the pattern `file_path:line_number` ...

【环境信息 --- sys.environment()】
You are powered by the model named claude-sonnet-4-5. The exact model ID is anthropic/claude-sonnet-4-5
Here is some useful information about the environment you are running in:
<env>
  Working directory: /Users/mac/myproject/src
  Workspace root folder: /Users/mac/myproject
  Is directory a git repo: yes
  Platform: darwin
  Today's date: Mon May 04 2026
</env>

【指令文件 --- instruction.system(),共 3 条】
Instructions from: /Users/mac/.config/opencode/AGENTS.md
遵循公司统一编码规范,所有 PR 必须经过 code review。

Instructions from: /Users/mac/myproject/src/AGENTS.md
src 目录使用 TypeScript strict 模式,禁止使用 any。

Instructions from: /Users/mac/myproject/AGENTS.md
禁止直接向 main 分支提交,必须通过 PR。
提交前运行:pnpm typecheck && pnpm lint

【技能列表 --- sys.skills()】
Skills provide specialized instructions and workflows for specific tasks.
Use the skill tool to load a skill when a task matches its description.
<available_skills>
  <skill>
    <name>commit</name>
    <description>Use when the user asks to commit changes to git</description>
    <location>file:///Users/mac/.config/opencode/skills/commit.md</location>
  </skill>
</available_skills>

system[0] 是以上所有内容用 \n 连接的单个字符串 ,这是 LLM API 接收到的完整 system prompt。

若插件通过 experimental.chat.system.transform 钩子追加了额外内容,则会出现 system[1]system[2] 等。


源代码索引

文件 职责
packages/opencode/src/session/llm.ts 最终组装 system 数组,触发 plugin 钩子
packages/opencode/src/session/prompt.ts 准备 env/instructions/skills,管理对话循环
packages/opencode/src/session/system.ts environment()skills() 实现;provider() 选择提示词文件
packages/opencode/src/session/instruction.ts AGENTS.md 查找、读取、动态注入逻辑
packages/opencode/src/session/prompt/anthropic.txt Claude 模型基础提示词
packages/opencode/src/session/prompt/default.txt 其他模型默认提示词
packages/opencode/src/session/prompt/plan.txt plan agent 只读模式提醒
packages/opencode/src/session/prompt/build-switch.txt plan→build 切换提醒
packages/opencode/src/session/prompt/max-steps.txt 达到最大步数时注入
相关推荐
江南十四行1 小时前
排序算法进阶:直接插入排序(简单排序)与希尔排序
数据结构·算法·排序算法
nlpming1 小时前
opencode - 安装和配置
算法
nlpming1 小时前
opencode 内置工具
算法
nlpming1 小时前
opencode - 常用命令&自定义命令
算法
CoderCodingNo1 小时前
【CSP】CSP-J 2021真题 | 插入排序 luogu-P7910 (适合GESP四-六级及以上考生练习)
数据结构·算法·排序算法
艺术电影节2 小时前
祝贺电影《撤离》《悼念词》《水草长生》 荣获亚洲艺术电影节提名
算法·推荐算法·电视
MATLAB代码顾问2 小时前
改进鲸鱼优化算法(IWOA)求解柔性作业车间调度问题(FJSP)——附MATLAB代码
开发语言·算法·matlab
量子-Alex2 小时前
【大模型】EvoLM论文LLM训练各个阶段效果
人工智能·算法·机器学习
Hello world.Joey2 小时前
OSTrack
人工智能·算法·目标检测·目标跟踪