加载中...
返回专栏
7 / 21

【OpenCode系统性指南】第7篇:自定义代理:为不同任务分配专属AI

【OpenCode系统性指南】第7篇:自定义代理:为不同任务分配专属AI

概念图

引言

在传统 AI 编程助手中,所有任务都由同一个"全能型"模型处理——无论是编写复杂代码、搜索文件,还是生成简短的会话标题。这种"一刀切"的方式既浪费资源,又无法针对特定任务优化效果。

OpenCode 的代理系统采用了完全不同的设计理念:为不同任务分配专属的 AI 代理。每个代理都有明确的职责边界、独立的模型配置和差异化的工具权限。这种精细化分工让整个系统更高效、更安全、更灵活。本文将带你深入理解 OpenCode 的代理架构,掌握配置技巧,并了解 Agent Tool 这一强大的"元工具"机制。


一、为什么需要多种代理

1.1 单一模型的困境

想象一下,如果用 GPT-4 来处理所有任务会怎样?

任务实际需求用 GPT-4 的问题
生成会话标题10 个词以内的摘要大材小用,响应慢
搜索代码关键词简单的文件查找模型推理过剩
编写复杂功能深度推理、代码生成恰好匹配
会话摘要压缩历史记录可以用更快的小模型

单一模型配置要么"杀鸡用牛刀",要么关键任务能力不足。OpenCode 的代理系统正是为了解决这个问题。

1.2 代理分工的价值

多代理架构带来三重收益:

  1. 成本优化:轻量任务用轻量模型,复杂任务用强力模型
  2. 性能提升:每个代理专注自己的领域,响应更快
  3. 安全隔离:不同代理拥有不同的工具权限,降低风险

二、四种内置代理详解

OpenCode 内置四种代理类型,每种都有独特的职责和权限设计。

2.1 Coder Agent:主编码代理

Coder Agent 是 OpenCode 的"主力军",承担所有需要修改代码、执行命令的任务。

核心特性

  • 完整工具权限:可使用 Edit、Write、Patch、Bash、LSP 等所有工具
  • 元工具能力:拥有 Agent Tool,可生成子代理
  • MCP 扩展:自动继承所有配置的 MCP 工具

典型配置

agents:
  coder:
    model: claude-4-sonnet
    maxTokens: 5000
    reasoningEffort: medium

适用场景:代码编写、重构、Bug 修复、命令执行、文件操作等所有"写"操作。

2.2 Task Agent:只读子任务代理

Task Agent 是 Coder Agent 的"侦察兵",专门处理代码搜索和探索任务。

核心特性

  • 只读权限:只能使用 Glob、Grep、LS、View、Sourcegraph
  • 无状态执行:每次调用都是独立会话
  • 轻量高效:适合使用更快、更便宜的模型

典型配置

agents:
  task:
    model: gpt-4.1-mini
    maxTokens: 5000

适用场景:代码搜索、项目探索、文档查阅、代码审查(只读)等"读"操作。

2.3 Title Agent:会话标题生成

Title Agent 负责为会话生成简短、描述性的标题。

核心特性

  • 无工具权限:纯文本生成,不需要任何工具
  • 极短输出:maxTokens 通常设为 80
  • 自动触发:新会话开始时自动调用

典型配置

agents:
  title:
    model: claude-3.7-sonnet
    maxTokens: 80

设计考量:虽然输出很短,但标题质量直接影响用户体验,因此通常使用与主代理相同的模型。

2.4 Summarizer Agent:会话摘要

Summarizer Agent 负责压缩长会话,保留关键信息。

核心特性

  • 无工具权限:纯文本处理
  • 摘要压缩:将长对话浓缩为关键点
  • 上下文管理:防止会话超出模型上下文限制

典型配置

agents:
  summarizer:
    model: claude-3.7-sonnet
    maxTokens: 5000

截图说明


三、代理配置结构详解

3.1 配置位置

代理配置位于 opencode.jsonopencode.yamlagents 字段:

{
  "providers": { ... },
  "agents": {
    "coder": { ... },
    "task": { ... },
    "title": { ... },
    "summarizer": { ... }
  }
}

3.2 配置参数说明

每个代理支持三个核心参数:

参数类型说明示例
modelstring使用的模型 IDclaude-4-sonnet
maxTokensnumber最大输出 token 数5000
reasoningEffortstring推理强度(低/中/高)medium

reasoningEffort 参数(仅部分模型支持):

  • low:快速响应,适合简单任务
  • medium:平衡速度和质量
  • high:深度推理,适合复杂问题

3.3 完整配置示例

{
  "providers": {
    "anthropic": {
      "apiKey": "${ANTHROPIC_API_KEY}"
    },
    "openai": {
      "apiKey": "${OPENAI_API_KEY}"
    }
  },
  "agents": {
    "coder": {
      "model": "claude-4-sonnet",
      "maxTokens": 5000,
      "reasoningEffort": "high"
    },
    "task": {
      "model": "gpt-4.1-mini",
      "maxTokens": 5000
    },
    "title": {
      "model": "claude-3.7-sonnet",
      "maxTokens": 80
    },
    "summarizer": {
      "model": "claude-3.7-sonnet",
      "maxTokens": 5000
    }
  }
}

配置策略建议

  • Coder Agent 使用最强模型,reasoningEffort 设为 high
  • Task Agent 可用轻量模型(如 GPT-4.1-mini、Gemini Flash)
  • Title Agent 的 maxTokens 保持 80 即可
  • Summarizer Agent 建议使用与 Coder 相同模型保证摘要质量

四、Agent Tool:元工具机制

Agent Tool 是 OpenCode 代理系统中最精妙的设计之一——它是一个"能生成代理的工具"。

4.1 什么是 Agent Tool

Agent Tool 允许 Coder Agent 在需要时生成临时的 Task Agent 来执行子任务。这是一种层次化的任务执行模式:

Coder Agent (主代理)
    │
    ├── 发现需要搜索代码
    │
    ├── 调用 Agent Tool
    │      │
    │      └── 生成 Task Agent (子代理)
    │              │
    │              └── 执行搜索,返回结果
    │
    └── 基于结果继续工作

4.2 工作原理

从源码角度看 Agent Tool 的实现:

// internal/llm/agent/agent-tool.go
func (b *agentTool) Info() tools.ToolInfo {
    return tools.ToolInfo{
        Name: "agent",
        Description: "Launch a new agent that has access to: GlobTool, GrepTool, LS, View...",
        Parameters: map[string]any{
            "prompt": map[string]any{
                "type": "string",
                "description": "The task for the agent to perform",
            },
        },
    }
}

关键特点

  1. 单一参数:只接收 prompt 一个参数,描述子任务
  2. 固定工具集:子代理只能使用 GlobTool、GrepTool、LS、View、Sourcegraph
  3. 无状态执行:子代理完成后立即销毁,不保留上下文
  4. 并发支持:可在单条消息中调用多个 Agent Tool

4.3 触发场景

Agent Tool 通常在以下场景被自动触发:

  • 搜索关键词在代码库中的位置
  • 查找符合特定模式的文件
  • 探索项目结构和依赖关系
  • 分析代码调用链

4.4 并发执行示例

当 Coder Agent 需要同时搜索多个关键词时,可以并发调用多个 Agent Tool:

用户: 帮我找到所有使用 useState 和 useEffect 的组件

Coder Agent:
  - Agent Tool #1: 搜索 "useState"
  - Agent Tool #2: 搜索 "useEffect"
  (两个子代理并发执行)

  - 汇总结果,返回给用户

这种并发模式显著提高了搜索效率。


五、工具权限层级

OpenCode 的工具权限设计遵循"最小权限原则",不同代理拥有不同的工具集合。

5.1 权限层级图

┌─────────────────────────────────────────────────────────────┐
│  Coder Agent (完整权限)                                      │
│  ├── 文件操作: Edit, Write, Patch, View                     │
│  ├── 搜索工具: Glob, Grep, LS, Sourcegraph                  │
│  ├── 命令执行: Bash                                          │
│  ├── 网络工具: Fetch                                         │
│  ├── 代码分析: Diagnostics (LSP)                             │
│  ├── 子代理: Agent Tool                                      │
│  └── MCP 工具: 通过配置扩展                                   │
├─────────────────────────────────────────────────────────────┤
│  Task Agent (只读权限)                                       │
│  ├── 搜索工具: Glob, Grep, LS, Sourcegraph                  │
│  └── 文件查看: View                                          │
├─────────────────────────────────────────────────────────────┤
│  Title / Summarizer Agent (无工具)                          │
│  └── 仅文本生成                                              │
└─────────────────────────────────────────────────────────────┘

5.2 来限隔离的意义

安全角度:Task Agent 无法修改文件或执行命令,即使被恶意提示词攻击,也只能进行只读操作。

成本角度:只读任务不需要 Edit、Bash 等工具的上下文开销,减少 token 消耗。

稳定性角度:工具越少,出错概率越低,Task Agent 的行为更可预测。

5.3 工具集组装逻辑

// Coder Agent 工具集
func CoderAgentTools(...) []tools.BaseTool {
    return append(
        []tools.BaseTool{
            tools.NewBashTool(permissions),
            tools.NewEditTool(...),
            tools.NewGlobTool(),
            tools.NewGrepTool(),
            NewAgentTool(...),  // 元工具
            // ...更多工具
        },
        GetMcpTools(ctx, permissions)...,  // MCP 扩展
    )
}

// Task Agent 工具集
func TaskAgentTools(lspClients map[string]*lsp.Client) []tools.BaseTool {
    return []tools.BaseTool{
        tools.NewGlobTool(),
        tools.NewGrepTool(),
        tools.NewLsTool(),
        tools.NewSourcegraphTool(),
        tools.NewViewTool(lspClients),
    }
}

六、代理与命令的区别

OpenCode 同时提供"自定义代理"和"自定义命令"两种扩展机制,它们有什么区别?

6.1 核心对比

特性自定义代理自定义命令
定义位置配置文件 agents 字段.claude/commands/ 下的 .md 文件
配置参数model、maxTokens、reasoningEffort纯文本提示词 + $ARGUMENTS
工具权限继承代理类型的工具集使用 Coder Agent 的完整工具集
触发方式自动(根据任务类型)手动(Ctrl+K 或 /命令名
适用场景不同模型/配置的专用 AI预定义的提示词模板

6.2 选择指南

使用自定义代理当

  • 需要为特定任务使用不同的 AI 模型
  • 需要限制工具权限(如只读分析)
  • 需要调整 maxTokens 或 reasoningEffort

使用自定义命令当

  • 需要封装重复性工作流(如 Git 提交)
  • 需要预定义上下文和提示词
  • 需要团队共享标准化流程

6.3 组合使用

两者可以组合使用。例如,自定义命令 /review 可以在内部触发 Task Agent 进行只读代码审查:

/review src/auth/
    │
    └── Coder Agent 接收命令
            │
            └── 调用 Task Agent(通过 Agent Tool)
                    │
                    └── 只读分析,返回审查报告

七、最佳实践

7.1 模型选择策略

代理推荐模型理由
CoderClaude 4 Sonnet / GPT-4.1需要深度推理和高质量代码生成
TaskGPT-4.1-mini / Gemini Flash只读搜索,速度优先
Title与 Coder 相同标题质量影响体验
Summarizer与 Coder 相同摘要质量要求高

7.2 使用场景匹配

场景推荐代理说明
代码编写/重构Coder完整工具权限
Bug 调试Coder + TaskTask 辅助搜索定位
代码审查Task只读分析足够
项目探索Task快速搜索和浏览
文档查询Task只读查看

7.3 注意事项

  1. Task Agent 无法修改文件:需要修改时必须使用 Coder Agent
  2. Agent Tool 是无状态的:每次调用都是独立会话,不保留上下文
  3. 并发调用提高效率:多个搜索任务可并发执行
  4. MCP 工具自动继承:配置的 MCP 工具会自动添加到 Coder Agent

小结

  • 四种代理:Coder(主编码)、Task(只读子任务)、Title(标题生成)、Summarizer(会话摘要),各司其职
  • 配置灵活:每个代理可独立配置 model、maxTokens、reasoningEffort
  • Agent Tool 机制:元工具可生成子代理,实现层次化任务执行和并发搜索
  • 权限分层:完整权限 > 只读权限 > 无工具,遵循最小权限原则
  • 代理 vs 命令:代理配置模型和权限,命令封装提示词和工作流

延伸阅读

加载中...