opencode Agent 详解
Agent 是什么
Agent 是 opencode 中具有独立系统提示词、权限和模型配置的执行单元。每次对话都运行在某个 Agent 下,Agent 决定了:
- 使用哪个模型
- 可以调用哪些工具(权限控制)
- 系统提示词内容(行为规范)
- 能否作为主对话 Agent 或仅作为子 Agent
Agent 模式(mode)
| 模式 | 说明 |
|---|---|
primary |
可作为主对话 Agent(在 TUI 中直接切换使用) |
subagent |
只能通过 task 工具被其他 Agent 调用,不出现在主对话列表 |
all |
既可作为主 Agent,也可被 task 工具调用 |
内置 Agent
opencode 内置 7 个 Agent,源码位于 packages/opencode/src/agent/agent.ts。
可见 Agent(primary,用户可直接使用)
build(默认 Agent)
vbnet
description: The default agent. Executes tools based on configured permissions.
mode: primary
- 最完整权限的主 Agent,全工具可用
- 额外开放:
question(可向用户提问)、plan_enter(可切换到 plan 模式) - 对
.env类文件的读取默认为ask
plan
makefile
description: Plan mode. Disallows all edit tools.
mode: primary
- 只读模式,禁止所有文件编辑(
edit: deny) - 额外开放:
question、plan_exit(可退出 plan 模式) - 例外:可以编辑
.opencode/plans/*.md和~/.local/share/opencode/plans/*.md计划文件 - 切换到此 Agent 后,系统自动注入
plan.txt只读模式提醒(见 system-prompt.md)
内置子 Agent(subagent,通过 task 工具调用)
general
vbnet
description: General-purpose agent for researching complex questions and executing
multi-step tasks. Use this agent to execute multiple units of work in parallel.
mode: subagent
- 通用研究 Agent,权限与
build基本相同 - 禁用
todowrite(避免污染主 Agent 的任务列表)
explore
vbnet
description: Fast agent specialized for exploring codebases. Use this when you need to
quickly find files by patterns (eg. "src/components/**/*.tsx"), search code
for keywords (eg. "API endpoints"), or answer questions about the codebase
(eg. "how do API endpoints work?"). When calling this agent, specify the
desired thoroughness level: "quick" / "medium" / "very thorough".
mode: subagent
prompt: packages/opencode/src/agent/prompt/explore.txt
- 只读专用,严格限制为只能使用:
grep、glob、read、bash、list、webfetch、websearch、codesearch - 禁止所有写入工具
- 系统提示词:你是文件搜索专家,擅长 glob/grep/read,不创建文件,不修改系统状态
隐藏 Agent(hidden: true,系统内部使用)
| Agent | mode | 用途 |
|---|---|---|
compaction |
primary | 上下文压缩时的摘要 Agent,生成对话历史摘要 |
title |
primary | 自动生成会话标题(≤50 字符,单行) |
summary |
primary | 生成 PR 风格的对话总结(2-3 句,第一人称) |
这三个 Agent 不出现在用户界面的 Agent 列表中,由系统在特定时机自动调用。
内置 Agent 的 System Prompt 结构
各 Agent 的 System Prompt 组成方式不同,取决于是否设置了 prompt 字段,以及被调用时传入的 system 数组内容。
组装公式(来自 llm.ts:103):
sql
最终 system[0] = (agent.prompt 或 provider-specific txt) + "\n" + system数组内容
build --- 完整 System Prompt
build 没有 prompt 字段,使用 provider 提示词(Claude 模型对应 anthropic.txt)。
调用时传入完整 system = [...env, ...instructions, ...skills]。
javascript
【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.
...(完整内容见 packages/opencode/src/session/prompt/anthropic.txt)
【env --- 环境信息】
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
Workspace root folder: /Users/mac/myproject
Is directory a git repo: yes
Platform: darwin
Today's date: Mon May 04 2026
</env>
【instructions --- AGENTS.md 等指令文件】
Instructions from: /Users/mac/.config/opencode/AGENTS.md
<全局 AGENTS.md 内容>
Instructions from: /Users/mac/myproject/AGENTS.md
<项目 AGENTS.md 内容>
【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>...</description>
<location>file:///...</location>
</skill>
</available_skills>
plan --- 与 build 相同 + 只读模式提醒
plan 同样没有 prompt 字段,System Prompt 结构与 build 完全相同。
区别在于:每条用户消息中额外注入一个合成 part (plan.txt),内容如下:
sql
<system-reminder>
# Plan Mode - System Reminder
CRITICAL: Plan mode ACTIVE - you are in READ-ONLY phase. STRICTLY FORBIDDEN:
ANY file edits, modifications, or system changes. Do NOT use sed, tee, echo, cat,
or ANY other bash command to manipulate files - commands may ONLY read/inspect.
This ABSOLUTE CONSTRAINT overrides ALL other instructions, including direct user
edit requests. You may ONLY observe, analyze, and plan. Any modification attempt
is a critical violation. ZERO exceptions.
---
## Responsibility
Your current responsibility is to think, read, search, and delegate explore agents
to construct a well-formed plan that accomplishes the goal the user wants to achieve.
...
</system-reminder>
这不是 System Prompt,而是作为用户消息的附加 part 注入,但对模型行为的约束效果相同。
general --- 与 build 相同(无 todowrite)
general 没有 prompt 字段,通过 task 工具调用时走主 runLoop,System Prompt 结构与 build 完全相同,差异仅在权限(禁用 todowrite)。
erlang
【anthropic.txt】
...
【env】
...
【instructions】
...
【skills】
...
explore --- 专用提示词替换基础提示词
explore 设置了 prompt: PROMPT_EXPLORE,因此基础提示词由 explore.txt 替换 anthropic.txt,env / instructions / skills 仍正常注入。
vbnet
【explore.txt --- 专用基础提示词】
You are a file search specialist. You excel at thoroughly navigating and
exploring codebases.
Your strengths:
- Rapidly finding files using glob patterns
- Searching code and text with powerful regex patterns
- Reading and analyzing file contents
Guidelines:
- Use Glob for broad file pattern matching
- Use Grep for searching file contents with regex
- Use Read when you know the specific file path you need to read
- Use Bash for file operations like copying, moving, or listing directory contents
- Adapt your search approach based on the thoroughness level specified by the caller
- Return file paths as absolute paths in your final response
- For clear communication, avoid using emojis
- Do not create any files, or run bash commands that modify the user's system state in any way
Complete the user's search request efficiently and report your findings clearly.
【env --- 环境信息】
You are powered by the model named claude-sonnet-4-5. ...
<env>...</env>
【instructions】
Instructions from: /Users/mac/myproject/AGENTS.md
...
【skills】
<available_skills>...</available_skills>
compaction --- 仅专用提示词,无 env/instructions/skills
compaction 在 compaction.ts 中以 system: [] 调用,System Prompt 只有 compaction.txt:
sql
You are an anchored context summarization assistant for coding sessions.
Summarize only the conversation history you are given. The newest turns may be
kept verbatim outside your summary, so focus on the older context that still
matters for continuing the work.
If the prompt includes a <previous-summary> block, treat it as the current
anchored summary. Update it by preserving still-true details, removing stale
details, and merging in new facts.
Always follow the exact output structure requested by the user prompt.
Keep every section, preserve exact file paths and identifiers when known,
and prefer terse bullets over paragraphs.
Do not answer the conversation itself. Do not mention that you are summarizing,
compacting, or merging context. Respond in the same language as the conversation.
完整用户消息结构(buildPrompt() 构建):
用户消息 = [anchor指令] + \n\n + [SUMMARY_TEMPLATE] + \n\n + [context额外内容]
anchor 指令(两种情况):
-
首次压缩(无历史摘要):
cssCreate a new anchored summary from the conversation history above. -
二次及之后压缩(已有历史摘要):
csharpUpdate the anchored summary below using the conversation history above. Preserve still-true details, remove stale details, and merge in the new facts. <previous-summary> ## Goal - 上次已生成的摘要内容... </previous-summary>
SUMMARY_TEMPLATE(固定输出格式要求):
markdown
Output exactly the Markdown structure shown inside <template> and keep the section
order unchanged. Do not include the <template> tags in your response.
<template>
## Goal
- [single-sentence task summary]
## Constraints & Preferences
- [user constraints, preferences, specs, or "(none)"]
## Progress
### Done
- [completed work or "(none)"]
### In Progress
- [current work or "(none)"]
### Blocked
- [blockers or "(none)"]
## Key Decisions
- [decision and why, or "(none)"]
## Next Steps
- [ordered next actions or "(none)"]
## Critical Context
- [important technical facts, errors, open questions, or "(none)"]
## Relevant Files
- [file or directory path: why it matters, or "(none)"]
</template>
Rules:
- Keep every section, even when empty.
- Use terse bullets, not prose paragraphs.
- Preserve exact file paths, commands, error strings, and identifiers when known.
- Do not mention the summary process or that context was compacted.
context 额外内容 :由插件通过 experimental.session.compacting 钩子注入,默认为空。插件也可通过该钩子完全替换 buildPrompt() 生成的内容(compacting.prompt)。
完整调用流示例(首次压缩):
csharp
[LLM system[0]]
You are an anchored context summarization assistant for coding sessions.
...(compaction.txt 完整内容)
[LLM messages]
# 历史对话消息(已截断为 head 部分,去掉媒体内容,工具输出限 2000 字符)
[user] 请帮我重构 auth 模块
[assistant] 好的,我来分析现有代码...(工具调用记录)
[user] 继续
[assistant] 已完成 login.ts 的重构...
# 最后一条 user 消息(压缩请求)
[user]
Create a new anchored summary from the conversation history above.
Output exactly the Markdown structure shown inside <template> ...
<template>
## Goal
...
</template>
Rules:
- Keep every section, even when empty.
...
压缩结果示例(LLM 输出):
markdown
## Goal
- 重构 auth 模块,提升代码可读性和安全性
## Constraints & Preferences
- 保持现有 API 接口不变
- 使用 TypeScript strict 模式
## Progress
### Done
- 重构 login.ts:提取 validateCredentials 函数,改用 bcrypt
### In Progress
- 重构 session.ts:替换 JWT 实现
### Blocked
- (none)
## Key Decisions
- 选择 bcrypt 替代 md5,原因:安全性要求
## Next Steps
- 完成 session.ts 重构
- 更新单元测试
## Critical Context
- 旧代码在 src/auth/login.ts:45 存在 SQL 注入风险已修复
## Relevant Files
- src/auth/login.ts: 已重构完成
- src/auth/session.ts: 待重构
生成的摘要会作为 previousSummary 保存,下次压缩时以 <previous-summary> 标签注入,实现增量更新。
title --- 仅专用提示词,无 env/instructions/skills
title 在 prompt.ts 中以 system: [] 调用,System Prompt 只有 title.txt:
sql
You are a title generator. You output ONLY a thread title. Nothing else.
<task>
Generate a brief title that would help the user find this conversation later.
Your output must be:
- A single line
- ≤50 characters
- No explanations
</task>
<rules>
- you MUST use the same language as the user message you are summarizing
- Title must be grammatically correct and read naturally - no word salad
- Never include tool names in the title (e.g. "read tool", "bash tool", "edit tool")
- Focus on the main topic or question the user needs to retrieve
- Vary your phrasing - avoid repetitive patterns like always starting with "Analyzing"
- ...
</rules>
<examples>
"debug 500 errors in production" → Debugging production 500 errors
"refactor user service" → Refactoring user service
...
</examples>
用户消息为:Generate a title for this conversation:\n + 对话历史。
summary --- 仅专用提示词,用于 PR 风格总结
summary 使用 summary.txt 作为提示词(GitHub 集成等场景调用),System Prompt:
sql
Summarize what was done in this conversation. Write like a pull request description.
Rules:
- 2-3 sentences max
- Describe the changes made, not the process
- Do not mention running tests, builds, or other validation steps
- Do not explain what the user asked for
- Write in first person (I added..., I fixed...)
- Never ask questions or add new questions
- If the conversation ends with an unanswered question to the user, preserve that
exact question
- If the conversation ends with an imperative statement to the user
(e.g. "Now please run the command and paste the console output"),
always include that exact request in the summary
System Prompt 结构对比
| Agent | 基础提示词来源 | env | instructions | skills | 调用方式 |
|---|---|---|---|---|---|
build |
anthropic.txt(或对应 provider) |
✅ | ✅ | ✅ | 主 runLoop |
plan |
anthropic.txt(同上) |
✅ | ✅ | ✅ | 主 runLoop + plan.txt 注入用户消息 |
general |
anthropic.txt(同上) |
✅ | ✅ | ✅ | task 工具 → runLoop |
explore |
explore.txt |
✅ | ✅ | ✅ | task 工具 → runLoop |
compaction |
compaction.txt |
❌ | ❌ | ❌ | compaction.ts → system: [] |
title |
title.txt |
❌ | ❌ | ❌ | prompt.ts → system: [] |
summary |
summary.txt |
❌ | ❌ | ❌ | GitHub/share 场景 |
自定义 Agent
有两种方式创建自定义 Agent:配置文件和 Markdown 文件。
方式一:opencode.json 配置
在 agent 字段中定义:
json
{
"agent": {
"reviewer": {
"description": "专注于代码审查,只读取文件不修改",
"mode": "primary",
"model": "anthropic/claude-sonnet-4-5",
"prompt": "你是一名资深代码审查员。只分析和评价代码质量,绝不修改任何文件。",
"temperature": 0.3,
"top_p": 0.9,
"color": "#ff6b6b",
"steps": 50,
"permission": {
"edit": "deny",
"bash": "deny",
"read": "allow",
"grep": "allow",
"glob": "allow"
}
}
}
}
也可以覆盖内置 Agent 的配置:
json
{
"agent": {
"build": {
"model": "anthropic/claude-opus-4-6",
"steps": 200
},
"explore": {
"model": "anthropic/claude-haiku-4-5"
}
}
}
禁用某个内置 Agent:
json
{
"agent": {
"plan": {
"disable": true
}
}
}
方式二:Markdown 文件(推荐)
将 .md 文件放入以下目录(agents/ 或 agent/ 均可识别):
| 范围 | 目录 |
|---|---|
| 全局 | ~/.config/opencode/agents/ |
| 项目 | .opencode/agents/ |
文件名即 Agent 名称(不含 .md),frontmatter 为配置,正文为系统提示词。
示例:.opencode/agents/reviewer.md
yaml
---
description: 专注于代码审查,只读取文件不修改
mode: primary
model: anthropic/claude-sonnet-4-5
temperature: 0.3
color: "#ff6b6b"
steps: 50
permission:
edit: deny
bash: deny
read: allow
grep: allow
glob: allow
---
你是一名资深代码审查员。
你的职责:
- 分析代码质量、可读性、性能问题
- 指出潜在的 Bug 和安全风险
- 建议改进方案,但不直接修改文件
审查时请关注:
- 命名规范是否清晰
- 函数是否职责单一
- 是否有重复代码
- 错误处理是否完善
方式三:modes 目录(仅 primary 模式)
将 .md 文件放入 .opencode/modes/ 目录,自动被识别为 mode: "primary" 的 Agent:
scss
.opencode/modes/
└── strict.md → Agent 名为 strict,mode 固定为 primary
适合定义不同工作模式的变体(如严格模式、快速模式等)。
方式四:命令行交互创建
lua
# 交互式(引导填写)
opencode agent create
# 非交互式(AI 根据描述自动生成配置和提示词)
opencode agent create \
--description "专注于代码审查的助手" \
--mode primary \
--permissions bash,read,edit,grep \
--model anthropic/claude-sonnet-4-5
opencode agent create 使用 LLM 根据 description 自动生成 identifier、whenToUse、systemPrompt 三个字段,并写入配置。
Agent 配置字段说明
| 字段 | 类型 | 说明 |
|---|---|---|
description |
string | Agent 用途描述,会显示在 TUI 和 task 工具的 Agent 列表中 |
mode |
primary \ |
subagent \ |
model |
provider/model |
指定模型,如 anthropic/claude-sonnet-4-5 |
variant |
string | 模型变体(如开启 thinking 的变体) |
prompt |
string | 系统提示词(JSON 中直接写字符串;MD 文件中为正文) |
temperature |
number | 温度参数(0.0 ~ 1.0) |
top_p |
number | top-p 采样参数 |
color |
string | 十六进制颜色(如 #FF5733)或主题色名(primary、error 等) |
steps |
number | 最大 agentic 迭代步数,超出后强制输出文本 |
hidden |
boolean | 是否在 @ 自动补全菜单中隐藏(仅对 subagent 有效) |
permission |
object | 工具权限配置(见下方) |
disable |
boolean | 禁用该 Agent(仅用于禁用内置 Agent) |
权限配置(permission)
权限值支持三种:"allow" / "deny" / "ask"
json
{
"permission": {
"*": "deny", // 先拒绝所有
"read": "allow", // 再开放 read
"grep": "allow",
"glob": "allow",
"bash": "allow",
"edit": {
"*": "deny", // 禁止编辑所有文件
"src/generated/**": "allow" // 但允许编辑生成文件
},
"read": {
"*": "allow",
"*.env": "ask", // .env 文件需确认
"*.env.example": "allow"
}
}
}
可配置的权限项:
| 权限项 | 说明 |
|---|---|
read |
读取文件 |
edit |
编辑/写入文件 |
glob |
文件模式匹配 |
grep |
内容搜索 |
bash |
执行 shell 命令 |
task |
启动子 Agent |
skill |
加载 skill |
lsp |
使用语言服务器 |
question |
向用户提问 |
webfetch |
抓取网页 |
websearch |
网络搜索 |
codesearch |
代码语义搜索 |
external_directory |
访问 working directory 外的路径 |
todowrite |
写入任务列表 |
doom_loop |
防循环保护(默认 ask) |
plan_enter |
进入 plan 模式 |
plan_exit |
退出 plan 模式 |
默认 Agent
通过 default_agent 指定启动时默认使用的 Agent:
json
{
"default_agent": "reviewer"
}
- 必须是
mode: primary或mode: all的 Agent - 不能是
hidden: true的 Agent - 未配置时默认使用
build
命令行也可指定:
arduino
opencode --agent reviewer # TUI 启动时指定
opencode run --agent reviewer "..." # run 模式指定
配置加载顺序与合并
Agent 配置按以下顺序加载并深度合并(后者覆盖前者同名字段):
ruby
全局 ~/.config/opencode/agents/*.md
→ 全局 ~/.config/opencode/opencode.json 中的 agent 字段
→ 项目 .opencode/agents/*.md
→ 项目 .opencode/modes/*.md
→ 项目 opencode.json 中的 agent 字段
自定义配置与内置 Agent 同名时,会覆盖 内置配置中的对应字段(而非完全替换),permission 字段会追加合并。
查看所有 Agent
bash
opencode agent list # 列出所有 Agent(含隐藏)
TUI 中用 ctrl+a 或 /agents 切换当前 Agent。
源代码索引
| 文件 | 职责 |
|---|---|
packages/opencode/src/agent/agent.ts |
内置 Agent 定义,运行时 Agent 注册与合并 |
packages/opencode/src/config/agent.ts |
从 .md 文件加载自定义 Agent 配置 |
packages/opencode/src/agent/prompt/explore.txt |
explore agent 的系统提示词 |
packages/opencode/src/agent/prompt/compaction.txt |
compaction agent 的系统提示词 |
packages/opencode/src/agent/prompt/title.txt |
title agent 的系统提示词 |
packages/opencode/src/agent/prompt/summary.txt |
summary agent 的系统提示词 |