面试官:OpenCode Agent 代理机制了解吗?

0 阅读8分钟

本系列文章皆基于开源 Vibecoding 工具 Opencode 源码进行详细拆解。
源码链接:github.com/anomalyco/o…


写在前面

兄弟们!上次咱们聊完了 Prompt 系统,知道 AI 是怎么给自己"叠甲"的了。

但是!有没有想过这个问题:AI 拿到提示词之后,它是怎么"干活"的?它怎么知道哪些事能做,哪些事不能做?它怎么知道什么时候该"读文件",什么时候该"执行命令"?

今天咱们就来看看,AI 背后的"执行大脑"到底是咋工作的!


一、什么是 Agent?

这个问题太关键了!Agent 就是 AI 的"角色卡"!

你可以理解为:

  • Agent = 权限配置 + 系统提示词 + 模型参数

当你说"帮我写个函数"的时候,是 build Agent 在工作。 当你说"帮我搜一下这个API在哪"的时候,是 explore Agent 在工作。

它跟咱们人一样,不同场合穿不同衣服、干不同活!

Agent 解决了什么问题?

问题Agent 方案
AI 权限失控权限规则控制文件读写、命令执行
AI 行为不一致每个 Agent 有专属 system prompt
需要不同"人格"build 做事、explore 探查、plan 规划

你说这些重要吗?简直不要太重要!没有 Agent,AI 就是一个无法无天的"混世魔王"!让它删库就删库,让它跑路就跑路!!!


二、核心概念:Agent 三要素

看图!这三个东西就是 Agent 的核心:

graph TB
    subgraph Agent
        P[Permission 权限]
        S[System Prompt 提示词]
        M[Model Config 模型配置]
    end
    
    P -->|控制| T[工具调用]
    S -->|指导| T
    M -->|约束| T

2.1 Permission (权限) - 面试重点!!!

Agent 的行为边界,决定哪些工具可用!这可是面试必问的点!!!

// 源码位置: packages/opencode/src/permission/next.ts:32
export const Rule = z.object({
  permission: z.string(),    // 工具名: bash, read, write, edit...
  pattern: z.string(),       // 文件匹配模式: *.ts, src/**/*, ~/.env
  action: z.enum(["allow", "deny", "ask"]),  // 允许/禁止/询问
})

权限规则示例:

permissionpatternaction含义
read*allow允许读所有文件
read*.envask读 .env 文件需要确认
writesrc/*allow允许写 src 目录
bashrm -rfdeny禁止删除命令

面试官可能会问:这个权限系统是怎么工作的?

这个设计太精妙了!它用的是规则匹配的方式,从上往下遍历,第一个匹配的规则就是最终结果!这不就是防火墙的"规则链"吗???

2.2 System Prompt (提示词)

Agent 的思维模式,告诉 AI 怎么思考:

AgentPrompt 特点
build执行工具,完成任务
explore只读、搜索,不修改
plan规划为主,禁止编辑
compaction压缩总结,只读
title生成标题

每个 Agent 有自己的"人设",这才是 AI 有"性格"的根本原因!

2.3 Model Config (模型配置)

配置项说明
modelID模型 ID (如 claude-sonnet-4-20250514)
providerID提供商 (如 anthropic)
temperature采样温度
topPnucleus 采样
steps最大步数限制

三、内置 Agent 详解

OpenCode 内置了 5 个核心 Agent,兄弟们一定要记住!!!

3.1 build (默认 Agent) - 用的最多的!

// 源码位置: packages/opencode/src/agent/agent.ts:77
build: {
  name: "build",
  description: "The default agent. Executes tools based on configured permissions.",
  mode: "primary",
  permission: {
    "*": "allow",           // 默认允许所有
    doom_loop: "ask",       // 死循环检测
    read: { "*.env": "ask" }, // 敏感文件询问
    question: "allow",      // 允许提问
    plan_enter: "allow",    // 允许进入计划模式
  }
}

用途: 通用任务执行,默认使用的 Agent。日常开发用它就对了!

3.2 plan (计划模式) - 面试加分项!

// 源码位置: packages/opencode/src/agent/agent.ts:92
plan: {
  name: "plan",
  description: "Plan mode. Disallows all edit tools.",
  mode: "primary",
  permission: {
    edit: { "*": "deny" },  // 禁止编辑
    write: { "*": "deny" }, // 禁止写入
  }
}

用途:

  • 让 AI 先规划再执行
  • 适合复杂任务,避免 AI 乱改
  • 这就是传说中的"三思而后行"!!!

面试官可能会问:为什么需要 plan Agent?

因为有些兄弟手痒,上来就是一顿操作,结果改错地方了!有了 plan Agent,先让你冷静冷静,想想清楚再动手!

3.3 explore (探查模式) - 安全第一!

// 源码位置: packages/opencode/src/agent/agent.ts:130
explore: {
  name: "explore",
  mode: "subagent",
  permission: {
    grep: "allow",
    glob: "allow",
    read: "allow",
    webfetch: "allow",
    websearch: "allow",
    codesearch: "allow",
  },
  prompt: PROMPT_EXPLORE,  // "You are a file search specialist..."
}

用途:

  • 代码库探查
  • 搜索文件、查找代码
  • 不修改任何文件!安全的一批!

3.4 compaction (压缩 Agent) - 幕后英雄!

// 源码位置: packages/opencode/src/agent/agent.ts:159
compaction: {
  name: "compaction",
  mode: "primary",
  hidden: true,  // 隐藏,不对外显示
  prompt: PROMPT_COMPACTION,  // "You are a helpful AI assistant tasked with summarizing conversations."
}

用途: 当对话过长时,总结历史消息(详见 Session 压缩机制)。

这个 Agent 是隐藏的,平时你感觉不到它的存在,但它一直在默默付出!这才是真正的"幕后英雄"!!!

3.5 Agent 模式对比

Agentmode可见典型用途
buildprimary通用任务
planprimary规划任务
exploresubagent代码探查
compactionprimary压缩历史
titleprimary生成标题
summaryprimary总结会话

mode 含义:

  • primary: 主 Agent,一次对话只能用一种
  • subagent: 子 Agent,可以被 primary 调用

四、实际应用中如何选择 Agent(必考!!!)

这个是面试的重灾区!兄弟们给我往死里背!!!

4.1 选择流程图

flowchart TD
    START[用户输入] --> A{用户指定 Agent?}
    A -->|是| B[使用指定的 Agent]
    A -->|否| C{调用 Task 工具?}
    C -->|是| D[AI 决定 subagent_type]
    C -->|否| E[使用 defaultAgent]
    
    D --> F{选择哪个子 Agent?}
    F -->|explore 相关| G[explore]
    F -->|通用任务| H[build]
    F -->|其他| I[general]
    
    B --> END[执行]
    G --> END
    H --> END
    I --> END
    E --> END

4.2 三种选择方式

方式说明场景
用户指定命令行 --agent 或 UI 选择明确知道要用哪个 Agent
默认 Agent系统自动选择 build普通编程任务
AI 决策通过 Task 工具调用子 Agent复杂任务分解
方式一:用户指定
# 命令行指定 Agent
opencode run "帮我分析这个项目" --agent explore
// 源码位置: packages/opencode/src/cli/cmd/run.ts:602
const entry = await Agent.get(args.agent)
if (entry?.mode === "subagent") {
  // 子 Agent 不能作为主 Agent,报错
  return undefined
}
return args.agent
方式二:默认 Agent
// 源码位置: packages/opencode/src/agent/agent.ts:266
export async function defaultAgent() {
  const cfg = await Config.get()
  const agents = await state()

  // 1. 先看配置文件是否指定了 default_agent
  if (cfg.default_agent) {
    const agent = agents[cfg.default_agent]
    if (!agent) throw new Error(`default agent "${cfg.default_agent}" not found`)
    if (agent.mode === "subagent") throw new Error("...")
    if (agent.hidden === true) throw new Error("...")
    return agent.name
  }

  // 2. 否则找第一个可见的 primary Agent
  const primaryVisible = Object.values(agents).find((a) => 
    a.mode !== "subagent" && a.hidden !== true
  )
  return primaryVisible?.name ?? "build"
}

默认选择规则:

  1. 配置文件 default_agent 指定 → 使用指定的值
  2. 否则 → 使用第一个非隐藏的 primary Agent(默认是 build

简单到爆!!!

方式三:AI 决策(Task 工具)

当 AI 判断需要并行或委托任务时,使用 Task 工具:

// 源码位置: packages/opencode/src/tool/task.ts:29
const agents = await Agent.list().then((x) => 
  x.filter((a) => a.mode !== "primary")  // 只能选 subagent
)

// AI 调用示例
{
  tool: "task",
  input: {
    description: "Search codebase",
    prompt: "Find all files related to auth",
    subagent_type: "explore"  // AI 决定用 explore
  }
}

Task 工具选择子 Agent 的依据:

AI 任务类型选择的子 Agent原因
搜索代码、找文件exploreexplore 权限只读,适合搜索
通用研究、多步骤任务generalgeneral 权限完整,适合复杂任务
需要规划planplan 禁止编辑,适合规划

4.3 使用场景对照表

场景推荐 Agent原因
写代码、修改文件build默认权限完整,可执行所有工具
只看不改explore禁止写入,安全探查
先规划再执行plan禁止编辑,只生成计划
并行处理多个子任务Task → explore/general子 Agent 可以并行
对话太长需要压缩compaction系统自动触发

五、数据结构

5.1 Agent.Info

// 源码位置: packages/opencode/src/agent/agent.ts:24
export const Info = z.object({
  name: z.string(),              // Agent 名称
  description: z.string(),      // 描述
  mode: z.enum(["subagent", "primary", "all"]),  // 模式
  hidden: z.boolean(),          // 是否隐藏
  topP: z.number(),             // 采样参数
  temperature: z.number(),      // 温度参数
  color: z.string(),            // UI 颜色
  permission: PermissionNext.Ruleset,  // 权限规则
  model: z.object({             // 模型配置
    modelID: z.string(),
    providerID: z.string(),
  }).optional(),
  variant: z.string(),          // 模型变体
  prompt: z.string(),           // 系统提示词
  options: z.record(z.any()),   // 其他选项
  steps: z.number(),            // 最大步数
})

5.2 Agent 获取流程

sequenceDiagram
    participant U as 用户
    participant C as CLI/Server
    participant A as Agent模块
    participant P as Permission模块
    participant CF as Config
    
    U->>C: run "帮我写个函数"
    C->>A: Agent.get("build")
    A->>CF: Config.get()
    CF-->>A: 返回配置
    A->>P: PermissionNext.merge()
    P-->>A: 合并后的权限
    A-->>C: 返回 Agent 配置
    C->>C: 使用权限控制工具调用

六、自定义 Agent

6.1 配置方式

opencode.config.ts 中定义:

export default defineConfig({
  agent: {
    myagent: {
      name: "myagent",
      description: "我的自定义 Agent",
      mode: "primary",
      permission: {
        read: "allow",
        write: "allow",
        bash: { "npm *": "allow" },
      },
      temperature: 0.7,
    }
  }
})

6.2 AI 生成 Agent

OpenCode 支持用 AI 自动生成 Agent 配置:

// 源码位置: packages/opencode/src/agent/agent.ts:283
export async function generate(input: { description: string }) {
  // 使用 LLM 根据描述生成 Agent 配置
}

生成示例:

输入: "创建一个代码审查 Agent"
输出: {
  identifier: "code-reviewer",
  whenToUse: "Use this agent when the user wants to review code...",
  systemPrompt: "You are a code review expert..."
}

这不比某些 AI 生成的代码强???直接生成一个完整的 Agent 配置!!!


七、Agent 与工具的交互

flowchart LR
    subgraph Session
        M[用户消息]
        S[System Prompt]
    end
    
    subgraph Agent
        P[Permission 检查]
        O[Options 参数]
    end
    
    subgraph Tool
        R[工具注册表]
        E[执行工具]
    end
    
    M --> S
    S --> P
    P --> R
    R --> E
    O --> E
    
    P -->|允许| E
    P -->|deny| X[拒绝执行]
    P -->|ask| Y[请求用户确认]

八、面试常见问题

Q1: Agent 的核心职责是什么?

:Agent 是 AI 的"角色卡",包含权限配置、系统提示词、模型参数,决定了 AI 能做什么、怎么做、怎么想。这就是 AI 的"身份证"!

Q2: 为什么需要多个 Agent?

:不同任务需要不同的权限和提示词。build 用于执行,explore 用于探查,plan 用于规划。这就是"术业有专攻"!!!

Q3: 权限检查是怎么工作的?

:使用规则链匹配,从上往下遍历,第一个匹配的规则就是最终结果。可以控制文件读写、命令执行等一切行为。

Q4: 如何添加自定义 Agent?

:在 opencode.config.ts 中配置,或者调用 Agent.generate() 让 AI 自动生成。简单到爆!!!

Q5: primary 和 subagent 有什么区别?

:primary 是主 Agent,一次对话只能用一种;subagent 是子 Agent,可以被 Task 工具调用,用于任务分解和并行处理。


总结

兄弟们,今天咱们聊的 Agent 系统,简直就是 OpenCode 的"总调度员"!它负责:

  1. 权限控制:决定 AI 能不能做某事
  2. 行为指导:告诉 AI 怎么思考
  3. 模型配置:约束 AI 的输出风格
  4. 任务分配:协调各个子 Agent 工作

这个设计让 OpenCode 能够安全、可控地让 AI 帮你干活,是整个系统的核心基础设施。


往期好文推荐


写在最后

兄弟们,如果文章对您有帮助麻烦亲点赞、收藏 + 关注和博主一起成长哟!!! 也欢迎在评论区留言讨论,说说你们觉得 Agent 系统哪个设计最牛逼!!!

咱们下期再见!!!❤️❤️❤️