02 · Agent 由什么构成? - Core Components
所属知识库:Agent 全栈技术地图
所属领域:02 · Agent
所属章节:01 · Agent 是什么?它如何工作? - Fundamentals
文档类型:技术原理与工程实践研究
版本:v1.1
更新日期:2026 年 10 月 28 日
核心问题:如何从可观察的 Agent 行为推导其最小组成、核心组件及其接口?模型、指令、上下文、状态、行动接口、执行控制与可选扩展机制如何在一次真实执行中协作?如何区分功能能力、软件组件、运行时职责与部署实体,并验证组件组合确实构成可运行 Agent?
专题导读
《Definition & Boundaries》研究什么样的系统可以称为 Agent。本篇进一步追问:如果准备亲手构建一个 Agent,必须准备哪些组成部分,它们以什么接口连接,怎样在运行过程中交换数据并产生行动?这不是简单地列举“模型、记忆、工具、规划”等名词,而是要回答系统的组成关系和装配原理。
本篇将首先建立四个容易混淆的层次:行为能力、功能职责、软件组件、部署实体;再从一次任务执行的最小闭环推导现代模型驱动型 Agent 的必要条件和可选扩展。随后分析任务契约、模型适配、指令与上下文装配、决策协议、工具执行、权威状态和控制器之间的接口,解释组件组合如何形成一个能持续观察、选择行动、执行并检查结果的系统。文章进一步比较单进程轻量架构、框架式图执行和服务化架构,给出组件划分判据、故障隔离方法与一个不依赖外部模型 API 的可运行最小 Agent。
本篇的核心论点:Agent 的组成不是固定的“十件套”,而是一组必须被满足的行为职责及其可执行连接关系。 某项职责可以由模型、规则或程序承担;某个组件也可以承担多项职责。只有将职责、接口、状态所有权与执行控制说明清楚,才能判断系统是否真正构成 Agent。
一、研究定位:从组成清单转向可运行系统
1.1 四个不同的描述层次
| 层次 | 研究问题 | 示例 | 常见误区 |
|---|---|---|---|
| 行为能力(Capability) | 系统在特定条件下能做什么? | 检索、规划、修改文件、恢复任务 | 把“接入工具”当作已具备可靠工具能力 |
| 功能职责(Responsibility) | 哪种机制必须承担什么责任? | 选择行动、验证参数、维护状态 | 把职责直接等同于一个模块 |
| 软件组件(Component) | 哪段程序或服务实现职责? | ModelAdapter、ContextBuilder、ToolExecutor | 认为每项职责必须一个独立类或服务 |
| 部署实体(Deployment Unit) | 程序实际在哪里运行? | 本地进程、容器、远端 API、数据库 | 把部署拓扑误当逻辑架构 |
例如,“工具使用”是一种行为能力;“将模型产生的工具调用请求转换成合法执行”是一组职责;ToolRegistry 和 ToolExecutor 是可能的组件;它们可以位于同一进程,也可以部署为隔离的服务。四个层次的对应关系通常是多对多,而非一一映射。
同样,“Memory”可以指跨任务信息利用的能力、记忆读写策略的职责、某个检索组件,或者独立的数据库服务。若不先明确层次,架构图会把本应讨论的运行机制画成一排并列方框。
1.2 组成的判定标准
一个组成部分是否应当被纳入最小架构,不能依据流行框架是否提供该功能,而应检查:去掉它以后,目标系统是否仍能满足 Agent 的行为契约?
对现代 LLM 驱动的工具型 Agent,通常需要:(1)可执行目标与结束判据;(2)获取当前决策所需信息的方式;(3)产生下一步行动的决策机制;(4)将行动作用于环境的接口;(5)把执行结果反馈到后续决策的控制机制;(6)由可信程序维护执行状态与边界。模型是该类 Agent 的核心决策依赖,但不是经典 Agent 的普遍必要条件;长期记忆、RAG、独立规划器和多 Agent 通信则不是所有 Agent 的必要条件。
这是一套面向现代工具型 Agent 的工程判据,而非跨所有智能体研究传统的统一定义。一个仅在模拟环境中改变内部状态的 Agent,也可以具有真实的行动与反馈;反之,一个仅把用户问题发送给模型并返回回答的应用,即使拥有复杂提示词,也未必具有可独立持续执行的行动闭环。
1.3 研究边界
本篇聚焦组成关系、组件契约和最小装配。A1-A10 将分别深入角色、模型、指令、上下文、记忆、知识、工具、技能、规划与权限的内部机制;《Execution Mechanism》 深入控制循环的状态转换;《Agent Lifecycle》 研究长期运行与恢复;Agent System 与 Agent Platform 进一步研究执行引擎、分布式调度和平台治理。这里会给出足以理解组成关系的实现细节,但不把所有专题的内容重复一遍。
二、从行为闭环推导最小组成
2.1 最小行为模型
用一个简化模型描述一次 Agent 决策:
其中,g 是目标,o 是可观察结果,s 是系统维护的任务状态,c 是提供给决策器的信息,A_t 是当下允许的行动集合,π 是决策策略。该式是本文用于分析的工程抽象,不代表所有 Agent 采用相同算法,也不意味着模型必须直接读取全部历史观察。
从这个闭环可以推导出六项不可缺失的逻辑职责:任务定义、信息供给、决策生成、行动执行、反馈吸收、运行控制。授权与资源约束对任何可能产生副作用的系统都是必须明确的执行条件;对完全离线、只读或模拟环境,约束机制可以非常简单。
┌──────────任务契约──────────┐
│ 目标 / 允许动作 / 成功条件 │
└────────────┬─────────────┘
▼
┌─────────────────────┐
┌────────►│ 运行控制器 Runtime │◄───────────┐
│ │ 状态 / 预算 / 终止 │ │
│ └─────────┬───────────┘ │
│ ▼ │
│ ┌─────────────────────┐ │
│ │ 上下文装配 Context │◄── 可选记忆/知识/技能
│ └─────────┬───────────┘ │
│ ▼ │
│ ┌─────────────────────┐ │
│ │ 决策器 Model/Policy │ │
│ └─────────┬───────────┘ │
│ ▼ │
│ ┌─────────────────────┐ │
│ │ 结构化行动候选 │ │
│ └─────────┬───────────┘ │
│ ▼ │
│ ┌─────────────────────┐ │
│ │ 校验/授权/执行器 │ │
│ └─────────┬───────────┘ │
│ ▼ │
│ 环境变化 + 真实观察 ──► 状态更新 ──┘
│
└─────────────────下一轮决策─────────────────上图是职责拓扑,不是强制执行顺序:授权可在任务接纳、工具暴露和行动提交等多个阶段执行;上下文装配也可能在同一次执行中多次访问知识和记忆。
2.2 为什么“模型 + Prompt + Tools”仍可能不够
常见的最简描述是 Agent = Model + Prompt + Tools。它有助于说明基础构件,但不是完整的执行契约。假设模型生成了 send_email(to, body),工具确实存在,Prompt 也写明“必须经用户批准”。如果程序直接执行该调用,缺失的不是模型能力,而是可信的授权控制。再假设邮件已经发送但响应丢失,模型可能重复发起调用;缺失的是操作记录和副作用协调。最后,模型宣称“报告已完成”,但实际文件没有生成;缺失的是由运行时验证的完成判据。
因此,组件是否齐全,应通过端到端的执行路径和失败路径检验,而不是通过配置文件中是否出现某个字段判断。
三、任务入口:Agent 的目标如何变成可执行契约
3.1 用户意图、任务规格和运行实例
用户原始请求通常包含歧义。例如“调研三个 Agent 框架,给出选型建议”并未明确研究深度、可用资料、截止时间、是否允许运行代码、报告是否需要审批发布。系统需要将用户意图解析成任务规格;必要时向用户澄清。模型提出的补充假设不应自动扩大其操作权限。
参考任务契约:
{
"task_id": "research-001",
"objective": "比较三个框架的持久化与恢复机制",
"deliverable": "带来源和差异说明的 Markdown 报告",
"success_criteria": ["three_frameworks_covered", "sources_attached", "artifact_exists"],
"allowed_actions": ["search", "read_document", "write_draft"],
"approval_required": ["publish_external"],
"limits": {"max_steps": 12, "max_tool_calls": 20}
}这些字段是本文的参考设计,不是标准化 API。重要的不是字段名,而是区分:用户要求、系统确认的执行边界、运行时统计、最终验收事实。任务契约通常应被持久化或至少与一次执行绑定,以防多轮模型输出不断改写原始目标。
3.2 任务契约如何影响其他组件
任务契约决定上下文装配的重点、模型需要选择的行动集合、工具暴露范围、预算限制以及完成判定。若目标要求“只读研究”,工具注册表即使包含发布接口,运行时也不应将发布能力授权给该任务。若成功条件包含“产物存在”,模型生成一段文字不构成任务完成。
任务入口不是单纯的输入框,而是把自然语言需求转换为后续组件可以共同执行的机器可判断约束。
四、决策器:Model 与 Policy 的职责及接口
4.1 模型输出的是建议,不是已发生的事实
在 LLM Agent 中,模型可生成自然语言、结构化决策或工具调用请求。它可能判断需要检索、选择工具、填写参数、解释观察结果;但模型并不天然拥有执行工具、修改数据库或确认外部操作成功的权力。程序必须将模型输出解释为候选行动,并独立校验。
典型模型适配器需要接收消息、工具模式、输出约束、模型配置,并返回标准化结果:
ModelRequest {
messages, tool_schemas, model_config, response_format, trace_id
}
│
▼
ModelAdapter.invoke(request)
│
▼
ModelResult = FinalAnswer | ToolCall | InvalidOutput | ModelError真实 API 可能支持一次返回多个工具调用、并行调用、流式输出、结构化响应以及不同的 token 计量方式。上面的联合类型是便于分析的归一化接口;实现时必须定义多工具调用的顺序、失败传播和部分结果处理。
4.2 规则、模型与混合决策
并非所有决策都应交给模型。预算耗尽、权限拒绝、参数类型校验和终止条件等可以由确定性程序判断。模型适合承担语义解释、开放问题分析和候选行动选择;规则适合承担可枚举、可验证的约束;规划器或搜索算法可在多步骤问题中负责行动序列优化。
一个实用的分工是:模型负责提出“想做什么”,运行时负责判断“能否做、是否已做、做完没有”。 这是一条工程设计原则,不是关于所有模型内部推理过程的事实陈述。
4.3 决策输出协议的失败语义
若模型生成未知工具名、缺少必需参数、参数类型不匹配,系统不应将其当作普通工具失败。应区分:DECISION_INVALID(候选行动不合法)、ACTION_DENIED(不被授权)、TOOL_FAILED(工具执行失败)、OBSERVATION_UNKNOWN(结果尚不能确认)。不同错误应进入不同恢复路径,避免模型因误读错误而持续重试。
五、指令、上下文与当前状态如何进入模型
5.1 指令不等于上下文,更不等于权限
Instructions 表达工作规范和行为要求,Context 是某次模型调用实际获得的信息集合;权限是程序可强制执行的操作边界。指令文本通常作为上下文的一部分传入模型,但它不能替代程序化鉴权。
例如,研究 Agent 的“引用每条关键结论”属于指令;当前研究主题、已有证据和工具结果属于上下文;“不得向外部发布”必须由执行器的授权检查落实。三者可以在同一次执行中共同生效,但职责不同。
5.2 上下文装配是一种选择过程
一次模型请求可能需要组合:可信的系统规则、任务契约、当前计划、最近执行事件、检索证据、工具观察和可用工具描述。模型上下文窗口有限,因此 ContextBuilder 必须在 token 预算下进行筛选、排序、截断或摘要,而不是无限拼接历史消息。
ContextBuilder.build(
instructions,
task_contract,
authoritative_state,
relevant_history,
retrieved_evidence,
available_tool_schemas,
token_budget
) -> ModelRequest这里最关键的结构性问题是状态所有权。例如,“邮件已发送”不能只存在于模型生成的摘要中;外部操作是否已提交应由工具记录或权威状态保存。摘要可帮助模型理解进度,但不能作为唯一的执行事实来源。
5.3 数据可信度与指令边界
网页、文件、检索片段和工具返回值可以提供事实证据,也可能包含恶意指令。上下文构建器应保留来源与可信度信息,不应把外部内容升级为系统级命令。即使模型在文本中表示“我已获得管理员授权”,执行器仍需根据实际授权主体和操作范围进行验证。
六、工具与环境:行动如何从声明变为执行
6.1 工具调用链的五个边界
一个完整工具调用至少经过五个不同环节:发现工具、形成候选调用、参数验证、授权执行、观察结果。在复杂系统中,还需处理异步完成、超时、幂等、审计与重试。
ToolSpec(名称、描述、参数模式)
↓ 暴露给决策器
ToolCall(名称、参数、call_id)
↓ 参数/类型/范围检查
AuthorizedAction(主体、资源、动作、策略)
↓ 工具执行器
ToolResult(成功/失败/未知 + 证据)
↓ 适配成 Observation
状态更新 → 下一轮决策工具 Schema 告诉模型如何表达调用请求,但 Schema 本身不是权限系统。工具执行器必须防止模型绕过参数限制、操作越界和利用不可信输入执行危险操作。
6.2 观察不是模型的自述
如果 Agent 需要创建报告文件,正确的观察应来自文件写入结果、路径检查或内容验证,而不是模型声称“文件已保存”。如果外部工具超时,应区分“执行失败”和“执行结果未知”;对于非幂等写操作,结果未知不能直接触发盲目重试。
6.3 工具、环境与行动空间
在网页 Agent 中,行动空间可能是点击、输入、导航;在编程 Agent 中,可能是读取代码、运行测试、修改文件;在模拟机器人环境中,可能是内部动作指令。工具是行动空间的一种常见封装,而不是行动概念本身。Agent 的决策器必须知道当前可行动作集合及其参数约束,运行时负责把动作映射到环境中的真实变化。
七、状态与控制器:谁让组件形成一个 Agent
7.1 为什么控制器不是可有可无的胶水
模型、工具、知识库分别可以独立工作,但它们并不会自动构成一个能持续完成任务的系统。控制器负责组织调用顺序、记录执行事实、分配预算、处理失败、决定是否继续,并将工具观察送回决策过程。控制器可以是几十行循环,也可以是图执行器或持久化工作流。
简化控制循环:
while not terminal(state):
request = context_builder.build(task, state, observations)
decision = model_adapter.invoke(request)
if decision.is_final:
state = validate_completion(decision, state)
else:
action = validate_and_authorize(decision, state)
observation = tool_executor.execute(action)
state = reduce_state(state, action, observation)该伪代码省略了并发、持久化、流式输出和恢复机制;其价值是明确各组件之间的调用关系和权威状态的更新位置。
7.2 权威状态与模型可见状态
建议区分至少三种状态:任务权威状态(步骤数、工具结果、权限、产物引用、完成标记);模型可见状态(经过筛选的当前任务上下文);外部环境状态(文件、数据库、网页、API 的真实情况)。三者可能不同步。
例如,工具已经成功创建文件,但模型还未收到结果;此时外部环境状态先于模型可见状态。系统应由工具记录更新权威状态,再在下一轮将相关观察装配进模型上下文。不能因为模型没有看到成功信息,就假设文件未创建。
7.3 状态归约与不变量
状态更新可抽象为 new_state = reduce(old_state, validated_event)。这要求事件已由可信执行层验证,且更新满足不变量。例如:步骤计数不应减少;超预算后不能继续发起新工具调用;未经授权的操作不能产生成功执行记录;完成状态必须有可检查的产物证据。
这些不变量是将“Agent 看起来会做事”提升为“Agent 的执行过程可验证”的关键。
八、十项内部能力与最小组成的映射
知识库的 Internal Architecture 使用十项研究维度。它们是功能研究坐标,不应被误解为所有 Agent 必须安装的十个独立软件模块。
| 研究维度 | 在组成关系中的作用 | 最小 Agent 中的可能实现 | 何时需要专门组件 |
|---|---|---|---|
| A1 Identity & Role | 明确职责与任务边界 | 固定角色配置 | 多角色、动态路由、角色切换 |
| A2 Model | 提供语义决策能力 | 单个模型适配器 | 多模型路由、专门推断服务 |
| A3 Instructions | 定义工作规则 | 固定指令文本 | 分层指令、版本管理、动态编译 |
| A4 Context | 提供当前决策信息 | 当前任务与最近观察 | 长任务、预算优化、压缩与证据装配 |
| A5 Memory | 复用历史信息与经验 | 不启用跨任务记忆 | 个性化、长期任务、跨会话学习 |
| A6 Knowledge | 获取外部知识 | 无或直接读取固定资料 | 检索、RAG、多源证据管理 |
| A7 Tools | 将行动作用于环境 | 一个受控动作接口 | 多工具注册、路由、异步调用 |
| A8 Skills | 复用专业流程 | 固定指令或程序函数 | 大规模技能库、按需加载、技能组合 |
| A9 Planning & Reasoning | 组织多步行动 | 模型逐步决策 | 显式计划、搜索、重规划 |
| A10 Permissions & Constraints | 限制实际操作 | 白名单与预算校验 | 多租户、敏感写入、审批和策略引擎 |
值得注意:控制器、任务状态、事件记录和完成验证没有作为额外的 A11-A14 列出,并不意味着它们不重要。它们是把上述能力组织为可执行系统的横向运行职责;其完整实现将在 Execution Mechanism、Lifecycle 和 Agent System 中研究。
九、三种典型装配架构及取舍
9.1 单进程轻量架构
模型适配器、控制循环、工具函数和短期状态都在同一进程中。优点是接口简单、调试容易、延迟低;缺点是进程崩溃可能丢失状态,外部副作用难以协调,多用户隔离和长期恢复能力有限。适合短任务、低风险、快速原型与教学验证。
9.2 图执行或工作流架构
将决策、工具调用、审批和验证表示为节点与转换关系,并显式维护执行状态。优点是流程结构清晰、便于插入检查点与人工介入;缺点是状态模式、节点重入、版本迁移与执行语义需要额外设计。图结构不自动保证正确恢复,也不能自动处理外部非幂等副作用。
9.3 服务化与持久化运行架构
将模型网关、执行器、工具服务、状态存储、审批服务和观测系统分离。优点是资源隔离、独立扩容、可审计与可恢复;代价是网络故障、分布式一致性、身份传递、运维复杂度与成本上升。对于低并发只读 Agent,过早服务化通常不是必要条件。
| 决策维度 | 单进程 | 图/工作流 | 服务化 |
|---|---|---|---|
| 开发与调试复杂度 | 低 | 中 | 高 |
| 显式状态建模 | 可选 | 通常较强 | 必须明确 |
| 故障恢复 | 需自行补充 | 取决于持久化机制 | 取决于执行协议与存储 |
| 多用户隔离 | 需自行实现 | 需配置 | 可通过服务边界强化 |
| 外部写操作一致性 | 需设计 | 仍需设计 | 仍需设计 |
| 适用场景 | 原型、短任务 | 长任务、复杂流程 | 大规模、多租户、长期运行 |
关键判断:架构形态本身不提供正确性保证。 无论采用哪种拓扑,都需要明确谁维护权威状态、谁授权操作、谁验证结果、谁负责失败后的恢复。
十、代表性技术与研究路线:它们解决了组成中的什么问题
10.1 ReAct:将推理与行动组织成反馈闭环
ReAct(Yao 等,2023)研究如何让语言模型交替产生推理和行动,并利用环境观察更新后续决策。它的重要启发不在于“Agent 必须打印 Thought”,而在于行动结果重新进入决策输入,使系统能够在未知环境中逐步推进。工程实现应把模型产生的行动与执行器返回的真实观察分离,不能把自然语言推理文本当作可信状态或权限凭据。
10.2 Toolformer:工具使用可以成为模型学习与调用的一部分
Toolformer(Schick 等,2023)研究模型如何通过自监督方式学习何时调用工具、传入什么参数以及如何利用结果。它说明“工具选择”可以是模型能力的一部分,但工具执行仍需外部接口与程序控制。将 Toolformer 简化为“给模型一个工具列表”会忽略其训练方法与研究对象的差异。
10.3 MRKL:把语言模型与专门模块组合
MRKL Systems(Karpas 等,2022)提出结合语言模型和外部专家模块的神经-符号模块化系统视角。其工程启发是:语言理解和通用推断不必承担所有专业计算,计算器、数据库查询或领域模块可通过路由与接口组合。模块化降低了某些任务对模型内部知识的依赖,同时引入路由错误、接口契约和模块结果可信度等新问题。
10.4 工程框架提供的是组织方式,不是统一的 Agent 定义
LangGraph 等图执行框架能够显式组织节点、状态与执行流;通用持久化工作流技术(例如 Temporal)则关注执行历史、重试与长期运行。它们可以承载 Agent 的部分运行职责,但不自动决定 Agent 的任务契约、工具权限或输出质量。不同框架的 API、持久化时机和恢复语义可能随版本变化,实施时必须阅读对应版本的官方文档与源代码。
上述路线各自聚焦不同层次:ReAct 主要解释行动-观察的推理组织,Toolformer 研究工具使用能力的学习,MRKL 强调模型与专家模块的组合,图/工作流框架主要提供执行组织机制。不能把它们放在同一个“谁更先进”的单轴排名中。
十一、工程实践:最小可运行 Agent 的组件契约
本节实现一个离线研究任务模拟器,目的是验证组件如何连接成完整行动闭环,而不是模拟真实语言模型的智能水平。使用 Python 标准库,不依赖 API Key。决策器使用确定性策略,以便重复测试;替换为真实模型适配器后仍须另外验证模型输出解析、工具模式兼容和随机行为。
11.1 设计目标
任务:查询两个技术对象的已知事实,形成比较报告。系统必须:先获取两个事实,再写入报告;只有报告产物存在时才允许完成;不允许调用未授权工具;工具失败不得被模型文本掩盖;最多执行有限步数。
核心组件:Task(任务契约)、Decision(结构化行动)、Policy(决策器)、Tools(工具执行)、State(权威状态)、Runtime(控制循环)。它们都可以在一个进程中实现,但逻辑职责彼此分离。
11.2 完整 Python 实现
配套文件 02-Agent-Core-Components-v1.1-demo.py 使用 Python 3 标准库实现最小组件契约;下方为完整源码,也可直接下载运行:python3 02-Agent-Core-Components-v1.1-demo.py。
from dataclasses import dataclass, field
from typing import Any
@dataclass(frozen=True)
class Task:
required: tuple[str, ...] = ("framework_a", "framework_b")
allowed: frozenset[str] = frozenset({"lookup", "write_report"})
max_steps: int = 8
@dataclass(frozen=True)
class Decision:
action: str
args: dict[str, Any] = field(default_factory=dict)
@dataclass
class State:
facts: dict[str, str] = field(default_factory=dict)
artifacts: dict[str, str] = field(default_factory=dict)
observations: list[dict[str, Any]] = field(default_factory=list)
steps: int = 0
status: str = "RUNNING"
class Policy:
"""确定性决策器;可替换为模型适配器。"""
def decide(self, task: Task, state: State) -> Decision:
for name in task.required:
if name not in state.facts:
return Decision("lookup", {"name": name})
if "report" not in state.artifacts:
return Decision("write_report", {})
return Decision("finish", {})
class Tools:
def __init__(self):
self.catalog = {
"framework_a": "支持显式图状态与节点执行",
"framework_b": "支持持久化工作流与活动执行",
}
def execute(self, decision: Decision, state: State) -> dict[str, Any]:
if decision.action == "lookup":
name = decision.args.get("name")
if name not in self.catalog:
return {"ok": False, "error": "NOT_FOUND"}
return {"ok": True, "name": name, "fact": self.catalog[name]}
if decision.action == "write_report":
if not state.facts:
return {"ok": False, "error": "NO_EVIDENCE"}
content = "\n".join(
f"{name}: {state.facts[name]}" for name in sorted(state.facts)
)
return {"ok": True, "artifact": "report", "content": content}
return {"ok": False, "error": "UNKNOWN_TOOL"}
class Runtime:
def __init__(self, policy=None, tools=None):
self.policy = policy or Policy()
self.tools = tools or Tools()
def run(self, task: Task) -> State:
state = State()
while state.status == "RUNNING":
if state.steps >= task.max_steps:
state.status = "BUDGET_EXHAUSTED"
break
decision = self.policy.decide(task, state)
if decision.action == "finish":
complete = (
all(name in state.facts for name in task.required)
and "report" in state.artifacts
)
state.status = "COMPLETED" if complete else "FAILED_VALIDATION"
break
if decision.action not in task.allowed:
state.status = "DENIED"
break
state.steps += 1
observation = self.tools.execute(decision, state)
state.observations.append(observation)
if not observation["ok"]:
state.status = "TOOL_FAILED"
break
if decision.action == "lookup":
state.facts[observation["name"]] = observation["fact"]
elif decision.action == "write_report":
state.artifacts[observation["artifact"]] = observation["content"]
return state
if __name__ == "__main__":
task = Task()
result = Runtime().run(task)
assert result.status == "COMPLETED"
assert result.steps == 3
assert len(result.facts) == 2
assert "framework_a" in result.artifacts["report"]
class UnsafePolicy:
def decide(self, task, state):
return Decision("delete_all_files", {})
denied = Runtime(policy=UnsafePolicy()).run(task)
assert denied.status == "DENIED"
assert denied.steps == 0
class PrematurePolicy:
def decide(self, task, state):
return Decision("finish", {})
premature = Runtime(policy=PrematurePolicy()).run(task)
assert premature.status == "FAILED_VALIDATION"
class LoopPolicy:
def decide(self, task, state):
return Decision("lookup", {"name": "framework_a"})
exhausted = Runtime(policy=LoopPolicy()).run(Task(max_steps=2))
assert exhausted.status == "BUDGET_EXHAUSTED"
assert exhausted.steps == 2
print("4 component-contract tests passed")11.3 代码体现了哪些真实机制
这个示例不是把若干函数并列罗列,而是建立了可检验的组件协议:Policy 只生成候选行动,不能直接写入任务产物;Runtime 独立校验行动白名单与预算;Tools 返回结构化观察;Runtime 根据观察更新权威状态;finish 只在必要事实和产物同时存在时才生效。更换 Policy 不会改变工具执行与权限控制的职责边界。
但它没有实现真实模型调用、Schema 校验、异步工具、文件系统写入、持久化、幂等、并发、外部审批或跨任务记忆。write_report 将报告保存在内存字典中,不能当作真实文件交付。此处的测试只能证明示例中的组件协作和四条不变量,不能证明 Agent 具有真实研究能力。
11.4 从最小示例升级到真实系统
第一步,将 Policy 替换为模型适配器:使用结构化工具调用协议,校验返回类型和工具参数,保留模型错误与超时信息。第二步,将 Tools 替换为受控真实接口:区分只读和写入操作,记录操作 ID 和实际执行结果。第三步,引入持久化任务状态和检查点,使进程重启后能够恢复。第四步,按需要增加知识检索、记忆读写、技能加载和显式规划;每增加一项,都应明确它解决什么已观察到的能力缺口。第五步,用真实任务集评估成功率、错误率、资源成本和安全约束,而非仅看示例是否能跑通。
十二、组件设计的技术决策方法
12.1 按变化原因划分组件
组件划分的首要依据不是名词数量,而是变化原因是否不同。模型供应商变化通常不应迫使工具权限代码重写;工具新增不应要求改写任务完成判据;上下文压缩策略变化不应改变数据库中的权威执行事实。将变化原因不同的职责解耦,可以降低修改成本并提高可测试性。
但过度拆分同样有代价。对于几十行的只读原型,把每项职责都部署成独立服务,会显著增加通信、部署和故障处理复杂度。合理做法是先在逻辑上划清接口与所有权,再根据规模和可靠性需求决定物理拆分。
12.2 按可信边界划分执行权
模型生成的内容、外部文档和网页返回都应视为可能不准确或不可信的数据。工具授权、预算限制、任务状态转移和完成验证应由可信程序负责。尤其要避免把“模型自述已经执行成功”当作外部系统的事实。
12.3 按任务需求引入可选能力
当任务需要跨会话保留经验时,引入 Memory;需要从外部资料获取可追溯证据时,引入 Knowledge;存在多步骤依赖或高成本回退时,引入显式 Planning;需要复用稳定专业流程时,引入 Skills。它们是解决具体约束的手段,而不是提高“Agent 完整度”的装饰性组件。
12.4 按失败传播设计接口
每个组件都应明确成功、可重试失败、不可重试失败和结果未知的语义。模型超时不等于工具失败;工具响应丢失不等于工具未执行;检索没有命中不等于事实不存在。统一使用 success: bool 往往不足以表达这些差异,生产系统需要更细的错误分类与恢复协议。
十三、组件组合的验证方法
组件测试应分三层。契约测试验证单个接口的输入、输出和拒绝条件;集成测试验证模型候选行动、执行器、状态更新和观察回传是否按预期协作;任务测试验证系统是否真正完成用户目标,并满足成本与安全约束。三层测试互相补充,不能互相替代。
| 测试场景 | 应验证的组成关系 | 预期结果 |
|---|---|---|
| 模型选择未知工具 | 决策器与执行器边界 | 拒绝执行,不产生副作用 |
| 工具返回错误 | 工具与状态归约边界 | 记录真实失败,不伪造成功 |
| 模型提前声明完成 | 决策与完成判据边界 | 验收失败或继续执行 |
| 预算耗尽 | 控制器与行动边界 | 停止新的工具调用 |
| 不可信文档要求越权 | Context 与权限边界 | 文档内容不改变授权 |
| 观察结果重复到达 | 工具事件与权威状态 | 按操作语义去重或核对 |
| 进程在写入后崩溃 | 运行时与外部环境 | 恢复前核对副作用 |
| 更换模型供应商 | 模型适配器与其余组件 | 接口兼容且回归测试通过 |
测试结果应记录任务条件、组件版本、工具权限、模型配置和实际执行轨迹。一次正常演示不能证明组件架构可靠;在不同失败条件下仍能保持关键不变量,才是更强的工程证据。
十四、常见架构误区与诊断
误区一:把十项研究维度画成十个必须部署的服务。 结果是架构复杂但没有清晰数据流。应先识别职责与接口,再选择部署形态。
误区二:认为接入模型和工具后就自动拥有 Agent Loop。 若缺少状态更新和继续决策,系统可能只是一次性工具调用包装器。应沿真实任务追踪行动、观察与下一轮决策。
误区三:将 Prompt 视为权限控制。 当模型受到提示注入或误判时,外部写操作可能越权。应在执行边界实施授权与参数校验。
误区四:把模型输出当作任务状态。 可能出现“已完成”但产物不存在。应让运行时根据工具结果和验收条件维护权威状态。
误区五:把 Context、Memory、Knowledge 合并成一个无边界的“信息模块”。 可能导致来源混淆、旧信息污染和状态丢失。应区分当前输入、持久化经验、外部证据与权威执行记录。
误区六:默认复杂架构一定优于简单架构。 多服务、多模型和多阶段规划增加协调开销;若没有明确能力缺口和测试收益,简单、可验证的系统通常更易维护。
十五、核心结论与后续研究关系
现代模型驱动型 Agent 的组成可以从任务执行闭环推导:任务契约定义目标与边界,信息装配提供当前决策所需内容,模型或策略生成候选行动,执行器将合法行动作用于环境,观察结果更新权威状态,控制器根据反馈决定继续、等待、失败或完成。真正构成 Agent 的不是组件名称,而是这些职责之间存在可执行、可验证的因果连接。
十项 Internal Architecture 研究维度为分析能力来源提供统一坐标,但不对应十个强制的软件模块。最小 Agent 应优先保证任务、行动、观察、状态与终止条件之间的闭环;记忆、知识、技能和复杂规划应根据实际需求逐步引入。工程上最重要的分界,是让模型承担语义决策,让可信程序承担执行授权、状态维护和结果验证。
下一篇 《Core Capabilities》 将以此为基础,研究这些组件组合后究竟能形成哪些可观察能力,以及如何通过任务契约与评测证明能力真实存在。《Execution Mechanism》 进一步研究控制循环内部的执行过程;Internal Architecture 的 A1-A10 则分别深入各项能力机制。
参考资料与延伸阅读
- Stuart Russell & Peter Norvig, Artificial Intelligence: A Modern Approach, 4th ed., Pearson, 2021。经典智能体、环境、行动与策略的理论背景。
- Shunyu Yao et al., ReAct: Synergizing Reasoning and Acting in Language Models, ICLR 2023。论文标识:arXiv:2210.03629。用于理解推理、行动和观察的反馈组织。
- Timo Schick et al., Toolformer: Language Models Can Teach Themselves to Use Tools, NeurIPS 2023。论文标识:arXiv:2302.04761。用于理解模型学习工具调用的研究路线。
- E. Karpas et al., MRKL Systems: A Modular, Neuro-Symbolic Architecture That Combines Large Language Models, External Knowledge Sources and Discrete Reasoning, 2022。论文标识:arXiv:2205.00445。用于理解模块化组合与专家模块。
- Anthropic, Building Effective Agents, 2024。用于理解工作流、Agent 与工程控制的区别。
- OpenAI, A Practical Guide to Building Agents, 2025。用于理解 Agent 设计、工具和执行护栏的工程视角。
- LangGraph 官方文档,Graph API、State、Persistence 等章节。用于了解图执行与状态管理的框架实现;具体 API 以所用版本为准。
- Martin Kleppmann, Designing Data-Intensive Applications, O'Reilly, 2017。用于理解状态、持久化、一致性与外部副作用的系统基础。
研究声明
资料与结论性质: 本文结合原版 v1.0 的研究范围、经典 Agent 理论、代表性模型工具研究和通用软件架构原则,提出一套面向现代 LLM Agent 的组件职责与接口分析框架。文中任务契约、接口结构、状态模型和组件划分属于工程归纳,不是统一行业标准。
最新性与核验: 本次未逐项在线核验所有论文全文、2026 年官方文档更新、框架 API 兼容性和商业模型行为。涉及具体产品和框架的实施细节,应在实际开发时核对对应版本的官方资料。正文没有把未经核验的实现细节表述为已确认的源码事实。
工程验证范围: 配套 02-Agent-Core-Components-v1.1-demo.py 为标准库离线模拟,使用确定性策略代替真实 LLM;示例验证组件边界、行动授权、完成条件和预算控制。它不验证模型推理质量、真实工具副作用、持久化恢复、并发和分布式一致性。本地执行四项断言通过时输出 4 component-contract tests passed;该结果仅证明示例不变量成立。