Agent基础概念与架构

Agent 基础概念与架构

系列文章第一篇。目标:一句话讲清 Agent 是什么,拆解 Agent 的骨架(Agent Loop),
并用当下最火的编码类 Agent(oh-my-opencode / Claude Code)为例,讲透它的分层架构。
下一篇:Agent 设计模式与热门框架
第三篇:动手实现简易 oh-my-opencode(附可运行 demo)


一、什么是 Agent:一句话定义

An agent is an LLM that can take actions, observe results, and decide what to do next — in a loop.
(Agent = 能采取行动、观察结果、并决定下一步的 LLM——跑在一个循环里。)

这个"反馈循环"是 Agent 与普通聊天机器人的唯一本质区别:自主性

感知(接收输入) → 推理(LLM 思考) → 行动(调用工具) → 观察(查看结果) → 回到推理
  • 聊天机器人:一次调用,一次回答。你问一句,它答一句。
  • Agent:把同一个 LLM 放在循环里,让它自己决定"下一步做什么"。它可以查文件、跑命令、写代码,然后根据结果继续行动,直到任务完成。

注意一个反直觉的点:Agent 的"智能"几乎全部来自 LLM + 工具集,框架本身只是把循环、上下文、权限这些"骨架"搭好。没有工具的执行能力,再强的 LLM 也只是个聊天机器人;没有 LLM 的决策能力,工具也只是死板的脚本。


二、Agent 的四个核心组件

组件 类比 职责
LLM(大脑) 决策中枢 理解任务、规划步骤、决定调用哪个工具、解读结果
工具 Tools(手) 执行器 读写文件、执行命令、调用 API、搜索网页…… Agent 改变世界只能通过工具
记忆 Memory(上下文) 工作台 system prompt、对话历史、工具结果;决定 Agent "记得什么"
规划 Planning(路径) 航线规划 拆解任务、决定顺序;简化为 LLM 的思维链,复杂的用 Plan-and-Execute

用编码 Agent 举个具体例子——"帮我重构 auth 模块":

  1. LLM 理解任务 → 决定先读代码(工具:read_file)
  2. 工具 返回文件内容 → 成为记忆的一部分
  3. LLM 依据新信息决定下一步(再读、搜索、改写、跑测试)
  4. 循环直到任务完成

三、核心骨架:Agent Loop(代理循环)

这是所有 Agent 框架的心脏。以 Claude Code 官方文档的定义为基准:

The agent loop refers to the repetition of the LLM responding with a tool use request,
and your application responding to the LLM with the results of evaluating that request.

┌────────────────────────────────────────────────────────────┐
│                    AGENT LOOP                              │
│                                                            │
│   ┌─────────┐LLM response  ┌────────────┐                  │
│   │LLM call │ ──────────>  │ tool_calls?│ ──否──▶ 返回最终回答 │
│   └─────────┘              └─────┬──────┘                 │
│        ▲                         │是                      │
│        │                         ▼                        │
│        │              ┌──────────────────┐                │
│        │              │  执行工具调用      │               │
│        │              │  (权限校验→执行)  │                │
│        │              └────────┬─────────┘                │
│        │                       │ 结果作为 tool 消息回填    │
│        └───────────────────────┘                          │
│                                                           │
│   终止条件:① LLM 不再请求工具 ② 达到 max_steps 上限         │
└───────────────────────────────────────────────────────────┘

关键机制:

  1. 工具调用(function calling):现代 LLM 通过 API 的 tools 参数原生输出结构化工具调用({name, arguments}),不再需要解析文本。
  2. 结果回填:每个工具结果作为一条 role=tool 消息,通过 tool_call_id 关联回对应的调用,喂回给 LLM 继续推理。
  3. 终止条件:LLM 不再请求工具(给出最终回答)→ 循环结束;或触发 max_steps 兜底,防止无限循环烧钱。
  4. 上下文管理:每轮循环消息都会增长,必须裁剪/压缩历史,否则上下文窗口会被撑爆(下面详解)。

四、以Claude Code 为例:六层架构

Claude Agent SDK 的架构公开文档把编码 Agent 拆成六层。理解这六层 = 理解现代 Agent 的全貌:

层 职责 关键问题
1. 执行循环层 prompt → 工具调用 → 结果 → 重复 让 Agent 迭代而非一次成型
2. 上下文层 system prompt + 工具定义 + 历史 + 项目记忆(CLAUDE.md/AGENTS.md) + 技能描述 让工作跨轮次保持连贯
3. 能力层 内置工具 + 自定义工具 + MCP 集成 让 Agent 能"动手"而不是只描述
4. 编排层 子代理(subagents) + 技能(skills) 并行化 + 上下文隔离
5. 治理层 权限、审批模式、hooks 让系统可控、安全
6. 产品层 CLI / SDK / IDE 插件 同一套运行时,不同界面

下面逐层展开:

4.1 执行循环层(Execution Loop)

就是上面第三节的 Agent Loop:
LLM 思考 → 输出工具调用 → 框架执行 → 结果回填 → 再思考。循环的每一步都可以被
hooks 拦截、审计、改写。

4.2 上下文层(Context)

这是 Agent 与普通 API 调用最大的工程差异点。上下文窗口(如 200k tokens)是有限资源,
而一次编码任务可能读几百个文件。主流方案:

  • 工具定义 + system prompt 前缀缓存:system prompt 和工具 schema 每次调用都相同,
    用 prompt caching 缓存,大幅降低成本。
  • 压缩(compaction):接近窗口上限时,自动把早期历史总结成摘要。
  • 按需注入:不把整个代码库塞进上下文,而是让 Agent 主动用工具去"问"(读文件、grep),
    只把需要的部分带进来。这就是为什么编码 Agent 需要 Grep/Glob 这类工具。
  • 项目记忆文件:CLAUDE.md / AGENTS.md / README 等自动注入,告诉 Agent
    项目约定(目录结构、构建命令、编码风格)。这是"持久记忆"的廉价实现。

4.3 能力层(Tools + MCP)

工具是 Agent 的"手"。典型编码 Agent 内置工具:

  • 文件操作:Read(读文件)、Write(写文件)、Edit(精确编辑)
  • 搜索:Glob(按模式找文件)、Grep(按内容搜索)
  • 执行:Bash(跑 shell 命令:git、npm、pytest……)
  • 联网:WebFetch、WebSearch
  • 代理:Task(生成子代理,见编排层)

MCP(Model Context Protocol):Anthropic 推出的开放标准,把"怎么接一个新工具"
从逐个实现变成统一协议。任何 MCP server(数据库、浏览器、issue 追踪器)都能即插即用,
"能力层"与具体集成解耦。

4.4 编排层(Subagents + Skills)

这是编码 Agent 与简单 Agent 的分水岭,也是 oh-my-opencode 这类框架的核心竞争力:

子代理(Subagents / Task 工具):主 Agent 可以通过 Task 工具启动子代理,
每个子代理有:

  • 独立的上下文窗口:子代理的工作状态不会污染主代理上下文中
  • 受限的工具集:如 explore 代理只能读不能改,天然防呆
  • 并行执行:多个子代理同时跑,主代理继续做别的
  • 结果聚合:子代理只把结论(而非全部工作过程)返回给主代理

这就是编排者-工人(Orchestrator-Workers)模式:主代理拿全局视野,
工人只知道自己那一小块任务。既解决了并行提速,又解决了单窗口上下文爆炸。

技能(Skills):把一套"提示词 + 步骤 + 脚本"打包成可复用能力。
本质是"按需加载的专家知识",避免把全部知识塞进 system prompt。

4.5 治理层(Permissions + Hooks)

LLM 会犯错、会有幻觉,所以必须有边界控制:

  • 权限系统:allowed_tools(自动放行)、disallowed_tools(禁止)、
    审批模式(读只读工具免批,写/执行需要确认)。
  • Hooks:工具调用前后触发,可以审计(记日志)、拦截(阻止危险操作)、
    改写(自动修正参数)。
  • 预算控制:max_steps、成本上限、时间上限。

4.6 产品层

同一套运行时可以有不同的壳:终端 CLI(Claude Code、opencode)、
IDE 插件(Xcode、VS Code)、SDK(Python/TS 包)。架构的深度在产品层的后面。


五、最小可运行的 Agent 骨架(伪代码)

把六层架构压缩到最核心,一个 Agent 最少只需要这段逻辑:

def agent_loop(user_input, tools):
    messages = [{"role": "system", "content": SYSTEM_PROMPT},
                {"role": "user", "content": user_input}]

    for step in range(MAX_STEPS):
        resp = llm_call(messages, tools_schema)      # 1. 大脑思考
        msg = resp["choices"][0]["message"]
        messages.append(msg)

        if not msg.get("tool_calls"):                # 2. 不再要工具 = 完成
            return msg["content"]

        for tc in msg["tool_calls"]:                 # 3. 执行所有工具
            name, args = tc["function"]["name"], json.loads(tc["function"]["arguments"])
            result = run_tool(name, args)            #    权限校验 + 执行
            messages.append({"role": "tool",         # 4. 结果回填
                             "tool_call_id": tc["id"], "content": result})

这就是我们的 demo(第三篇)的种子代码。在实际框架里,这 15 行被扩展成了
上下文裁剪、并行工具、子代理、权限、hooks、压缩……但骨架从未改变。


下一篇进入设计模式与框架:Anthropic 总结的 6 大工作流模式、ReAct 为什么是核心、
以及 2026 年主流框架(LangGraph / CrewAI / OpenAI Agents SDK / Claude Agent SDK)
怎么选。

posted @ 2026-09-10 23:32  LemHou  阅读(20)  评论(0)    收藏  举报