Agent
Agent 定义了 AI 助手的配置和行为模式。
概述
Agent 是 OpenCode 中 AI 助手的配置单元,每个 Agent 有特定的权限、模型、提示词和行为模式。OpenCode 内置多个 Agent,用户也可以自定义 Agent。
定义位置
`packages/opencode/src/agent/agent.ts:22-46
属性说明
| 属性名 | 类型 | 必填 | 说明 | | ------------------ | ------------------- | --------- | ------------------------ | --- | ---------- | | name | string | 是 | Agent 唯一名称 | | description | string | 否 | Agent 描述 | | mode | "subagent" | "primary" | "all" | 是 | Agent 模式 | | native | boolean | 否 | 是否为内置 Agent | | hidden | boolean | 否 | 是否在 UI 中隐藏 | | topP | number | 否 | Top-P 采样参数 | | temperature | number | 否 | 温度参数 | | color | string | 否 | UI 显示颜色(HEX) | | permission | PermissionRuleset | 是 | 权限规则集 | | model | object | 否 | 默认模型配置 | | model.modelID | string | - | 模型 ID | | model.providerID | string | - | 提供商 ID | | prompt | string | 否 | 自定义提示词 | | options | Record<string, any> | 是 | 附加选项 | | steps | number | 否 | 最大步骤数(子任务限制) |
TypeScript 类型定义
export type Agent = {
name: string
description?: string
mode: "subagent" | "primary" | "all"
native?: boolean
hidden?: boolean
topP?: number
temperature?: number
color?: string
permission: PermissionRuleset
model?: {
modelID: string
providerID: string
}
prompt?: string
options: Record<string, any>
steps?: number
}
Agent 模式
| 模式 | 说明 |
|---|---|
primary | 主要 Agent,在对话中直接使用 |
subagent | 子 Agent,被其他 Agent 调用 |
all | 可作为主要或子 Agent 使用 |
内置 Agent
OpenCode 内置以下 Agent:
1. build
- 模式: primary
- 用途: 构建和编译项目
- 特殊权限:
question: allow,plan_enter: allow
2. plan
- 模式: primary
- 用途: 规划任务和创建计划文档
- 特殊权限:
question: allow,plan_exit: allow - 限制编辑: 仅允许编辑
.opencode/plans/*.md
3. general
- 模式: subagent
- 用途: 通用目的 Agent,执行复杂多步骤任务
- 描述: 研究复杂问题并并行执行多个工作单元
- 限制: 禁用
todoread,todowrite
4. explore
- 模式: subagent
- 用途: 快速探索代码库
- 支持工具:
grep,glob,list,bash,webfetch,websearch,codesearch,read - 限制: 其他工具被禁用
5. fixer
- 模式: primary
- 用途: 修复 bug 和问题
- 默认使用
6. reviewer
- 模式: primary
- 用途: 代码审查
7. test
- 模式: primary
- 用途: 编写和运行测试
自定义 Agent
用户可以通过配置文件自定义 Agent:
{
"agent": {
"my-agent": {
"description": "Custom agent for specific tasks",
"mode": "primary",
"permission": {
"*": "allow",
"write": "ask",
},
"model": {
"providerID": "anthropic",
"modelID": "claude-3-5-sonnet",
},
"temperature": 0.7,
"topP": 0.9,
},
},
}
典型使用场景
1. 获取 Agent 配置
const agent = await Agent.get("general")
console.log(agent.name) // "general"
console.log(agent.description) // "General-purpose agent..."
console.log(agent.permission) // PermissionRuleset
2. 列出所有可用 Agent
const agents = await Agent.list()
for (const agent of agents) {
console.log(`${agent.name}: ${agent.mode}`)
}
3. 检查 Agent 权限
const agent = await Agent.get("plan")
// plan Agent 有特殊的编辑权限
// 只能编辑 .opencode/plans 目录下的文件
const rule = agent.permission.find((r) => r.permission === "edit" && r.pattern.includes("plans"))
4. 在 Message 中使用 Agent
const userMessage: MessageV2.User = {
id: Identifier.ascending("message"),
sessionID: session.id,
role: "user",
agent: "general", // 指定使用 general Agent
model: {
providerID: "anthropic",
modelID: "claude-3-5-sonnet",
},
time: { created: Date.now() },
}
Agent 通信机制
Agent 之间通过 Task 工具 进行通信,支持父 Agent 委动子 Agent 处理复杂任务。
核心机制
1. 父子 Session 层级关系
- 父 Agent 调用 Task 工具时,会创建子 Session
- 子 Session 通过
parentID关联到父 Session - 建立会话树状结构
2. 事件驱动通信
- 父 Agent 监听子会话的
PartUpdated事件 - 实时获取子 Agent 的执行进度
- 通过
ctx.metadata()更新元数据
3. 独立消息历史
- 子 Session 有独立的消息历史
- 不直接继承父 Session 的消息
- 父 Agent 通过事件和返回结果获取子 Agent 输出
4. 权限控制
- 子 Agent 可以禁用特定工具(如 task、todo)
- 防止无限递归调用
- 支持细粒度权限管理
工作流程
代码示例
1. 启动子 Agent
// 父 Agent 调用
const result = await TaskTool.execute(
{
description: "分析代码库结构",
prompt: "分析当前项目的代码组织方式,返回主要模块和它们的职责",
subagent_type: "explore",
},
ctx,
)
console.log(result.output) // 子 Agent 的返回结果
console.log(result.metadata.sessionId) // 子 Session ID
console.log(result.metadata.summary) // 工具执行摘要
2. 监听子任务进度
Task 工具内部自动实现监听逻辑:
// packages/opencode/src/tool/task.ts:117-38
const parts: Record<string, {...}> = {}
const unsub = Bus.subscribe(MessageV2.Event.PartUpdated, async (evt) => {
if (evt.properties.part.sessionID !== session.id) return
if (evt.properties.part.messageID === messageID) return
if (evt.properties.part.type !== "tool") return
const part = evt.properties.part
parts[part.id] = {
id: part.id,
tool: part.tool,
state: { status, title }
}
// 实时更新父 Agent 知道的进度
ctx.metadata({
title: params.description,
metadata: {
summary: Object.values(parts), // 工具执行摘要
sessionId: session.id,
model,
},
})
})
3. 并行启动多个 Agent
// 父 Agent 可以并行启动多个子 Agent
const results = await Promise.all([
TaskTool.execute(
{
description: "分析前端",
prompt: "分析前端架构",
subagent_type: "explore",
},
ctx,
),
TaskTool.execute(
{
description: "分析后端",
prompt: "分析后端架构",
subagent_type: "explore",
},
ctx,
),
])
权限管理
子 Session 的默认权限限制(packages/opencode/src/tool/task.ts:71-96):
permission: [
{
permission: "todowrite",
pattern: "*",
action: "deny",
},
{
permission: "todoread",
pattern: "*",
action: "deny",
},
...(hasTaskPermission
? []
: [
{
permission: "task",
pattern: "*",
action: "deny",
},
]),
...(config.experimental?.primary_tools?.map((t) => ({
pattern: "*",
action: "allow",
permission: t,
})) ?? []),
]
权限说明:
todowrite: deny - 防止子 Agent 管理父 Agent 的 todotodoread: deny - 防止子 Agent 读取父 Agent 的 todotask: deny(可选)- 防止子 Agent 再次调用 task,避免递归primary_tools: 根据配置允许特定工具
上下文传递
传递给子 Session 的内容:
| 内容 | 类型 | 是否传递 | 说明 |
|---|---|---|---|
parentID | string | ✅ 是 | 父会话 ID |
title | string | ✅ 是 | 子会话标题 |
permission | Ruleset | ✅ 是 | 权限规则(可能受限) |
projectID | string | ✅ 是 | 通过 Instance 继承 |
directory | string | ✅ 是 | 通过 Instance 继承 |
worktree | string | ✅ 是 | 通过 Instance 继承 |
子 Session 独立内容:
- 消息历史(Messages)
- summary
- share
- 时间戳(time)
Agent 权限合并
Agent 的权限是分层合并的:
- 默认权限: 系统定义的基础权限
- Agent 权限: Agent 自身的权限配置
- 用户权限: 用户配置文件中的权限覆盖
- 最终权限: 上述三者合并的结果
Agent 颜色
内置 Agent 使用固定颜色:
| Agent | 颜色 (HEX) |
|---|---|
| build | #10B981 |
| plan | #3B82F6 |
| general | #F59E0B |
| explore | #8B5CF6 |
| fixer | #EF4444 |
| reviewer | #06B6D4 |
| test | #EC4899 |
自定义 Agent 可以在配置中指定 color 字段。
对象关系
变更历史
| 版本 | 变更内容 | 日期 |
|---|---|---|
| v1 | 初始 Agent 架构 | - |
| v1.1 | 添加 explore Agent | - |
| v1.2 | 添加 steps 字段支持步骤限制 | - |
相关文档
- Permission - 权限系统
- Message - 消息对象
- Config - 配置系统
- Session - 会话对象
- Task - Task 工具详解