主题
18 · 智能体进程(The AgentProcess)
每次运行 Agent 都会创建一个 AgentProcess,它拥有唯一的 id。
执行模式(Execution Modes)
Embabel 支持两种 Agent 进程执行模式,由 embabel.agent.platform.process-type 属性控制。
SimpleAgentProcess(默认)
SimpleAgentProcess 是默认的执行模式。 在每一个规划 tick,它从当前计划中选出唯一的最优动作,把它跑完,然后重新规划。
这种顺序方式可预测、易于推理:动作永不并行,下一个动作开始时黑板总是处于一致状态。
ConcurrentAgentProcess
ConcurrentAgentProcess 扩展了 SimpleAgentProcess,在每个规划 tick 并行运行所有当前可达的动作。
它不再每个 tick 只挑一个动作,而是找出当前世界状态下计划中每一个可达动作, 并用平台的 Asyncer 抽象(底层是 Spring 托管任务执行器 + 虚拟线程)并发启动它们。 所有已启动的动作完成后进程重新规划,如此循环往复。
当 Agent 拥有可以同时推进的独立子任务时,这很有用 —— 例如并行补全多个数据项, 或运行若干彼此输出互不依赖的分析步骤。
启用 ConcurrentAgentProcess
在应用配置中设置:
yaml
embabel:
agent:
platform:
process-type: CONCURRENT或在 application.properties 中:
properties
embabel.agent.platform.process-type=CONCURRENT默认值是 SIMPLE。
并发模式下的重规划
SimpleAgentProcess 与 ConcurrentAgentProcess 都支持 ReplanRequestedException —— 动作可以抛出它,表示 Agent 应当先更新黑板并重规划,再继续推进。
在 ConcurrentAgentProcess 中,多个并发运行的动作可能同时抛出 ReplanRequestedException。 此时只有第一个请求被采纳 —— 它的黑板更新会被应用,并且触发它的那个动作会在下一个规划周期被拉黑, 以避免立即出现死循环。其余请求被静默丢弃,因为它们所运行的上下文本来就要被重规划。
拉黑名单会在一次成功的规划周期后自动清除。 如果拉黑生效期间找不到任何计划,则清除拉黑并重试规划,确保 Agent 不会永久卡死。
如何选择执行模式
| 模式 | 何时使用 | 代价与收益 |
|---|---|---|
SIMPLE | 大多数 Agent;顺序流水线;动作顺序重要的场景 | 可预测、更易调试、无并发开销 |
CONCURRENT | 彼此独立的并行子任务;fan-out/fan-in 模式;对吞吐敏感的工作负载 | 吞吐更高;但要求动作在共享黑板上并发运行是安全的 |
ProcessOptions
Agent 进程可以用 ProcessOptions 配置。它控制以下内容:
contextId:Agent 所运行的既有上下文的标识符。blackboard:该 Agent 使用的黑板。允许从某个特定状态开始。test:Agent 是否运行在测试模式。verbosity:Agent 的详细程度。可对"打印提示词、LLM 返回以及详细规划信息"做细粒度控制。control:控制选项,决定是否应作为最后手段终止 Agent。提前终止策略(EarlyTerminationPolicy)可以基于动作的绝对数量或最大预算。- Delays(延迟):操作(动作)与工具都可以设置延迟 —— 用来避免触发限流。
ephemaral:阻止 Agent 进程持久化到 Agent 进程仓库,也阻止它派生创建子进程(轻量级 Agent 进程)。toolCallContext:带外元数据(例如 auth token、tenant ID、correlation ID),会传给该进程期间的所有工具调用。 该上下文贯穿整条工具链路 —— 包括装饰器链与 MCP 工具 —— 且不会暴露给 LLM。 通过withToolCallContext()设置:
java
var processOptions = new ProcessOptions()
.withToolCallContext(Map.of(
"authToken", bearerToken,
"tenantId", tenantId
));工具如何接收该上下文,见
/reference/tools#tool-call-context。
上下文类型(原页面末尾的概念图)
类型一览
| 类型 | 说明 |
|---|---|
ProcessContext | 进程级服务(Process-scoped services) |
OperationContext | 操作执行上下文(Operation execution context) |
LlmOperations | LLM 后端服务 |
ActionContext | 动作专属上下文 |
PromptRunner | LLM 交互 API |
Blackboard | 共享状态存储 |
IoBinding | 输入/输出绑定 |
ToolGroupRequirement | 工具依赖 |
ToolObject | 带 @Tool 注解的对象 |
LlmOptions | 模型配置 |
ThinkingPromptRunnerOperations | 感知 thinking 的操作 |
ToolGroup | 一组连贯的工具 |
PromptContributor | 提示词元素 |
Message | 对话元素 |
ThinkingResponse | 结果 + thinking 块 |
关系
| 起点 | 关系 | 终点 |
|---|---|---|
ProcessContext | 提供(provides) | OperationContext |
ProcessContext | 提供(provides) | LlmOperations |
OperationContext | 特化为(specializes to) | ActionContext |
OperationContext | 创建(creates) | PromptRunner |
OperationContext | 访问(accesses) | Blackboard |
OperationContext | 管理(manages) | IoBinding |
ActionContext | 增强(enhances) | PromptRunner |
ActionContext | 声明(declares) | ToolGroupRequirement |
ActionContext | 从领域对象创建(creates from domain objects) | ToolObject |
ActionContext | 读写(reads/writes) | Blackboard |
PromptRunner | 委派给(delegates to) | LlmOperations |
PromptRunner | 由…配置(configured by) | LlmOptions |
PromptRunner | withThinking() | ThinkingPromptRunnerOperations |
PromptRunner | withToolGroup() | ToolGroup |
PromptRunner | withToolObject() | ToolObject |
PromptRunner | withPromptContributor() | PromptContributor |
PromptRunner | withMessage() | Message |
ThinkingPromptRunnerOperations | 返回(returns) | ThinkingResponse |
ToolGroupRequirement | 需要(requires) | ToolGroup |
Blackboard | 通过…存储(stores via) | IoBinding |