文章目录
- [1. 概述](#1. 概述)
- [2. 接口分层](#2. 接口分层)
-
- [2.1 CallableAgent(同步调用)](#2.1 CallableAgent(同步调用))
- [2.2 StreamableAgent(流式调用)](#2.2 StreamableAgent(流式调用))
- [2.3 ObservableAgent(被动观察)](#2.3 ObservableAgent(被动观察))
- [2.4 Agent(统一接口)](#2.4 Agent(统一接口))
- [3. AgentBase](#3. AgentBase)
-
- [3.1 核心能力](#3.1 核心能力)
- [3.2 并发控制](#3.2 并发控制)
- [3.3 生命周期](#3.3 生命周期)
- [4. Event(流式事件)](#4. Event(流式事件))
-
- [4.1 EventType(事件类型)](#4.1 EventType(事件类型))
- [4.2 EventSource(事件溯源)](#4.2 EventSource(事件溯源))
- [4.3 StreamOptions(流控)](#4.3 StreamOptions(流控))
- [5. RuntimeContext(每次调用的元数据容器)](#5. RuntimeContext(每次调用的元数据容器))
- [6. ReactConfig (ReAct 配置)](#6. ReactConfig (ReAct 配置))
- [7. 完整调用链](#7. 完整调用链)
- [8. 2.0 废弃 API 与新 API 对照](#8. 2.0 废弃 API 与新 API 对照)
-
- [8.1 流式 API](#8.1 流式 API)
- [8.2 新事件类型](#8.2 新事件类型)
- [8.3 中断 API 的变化](#8.3 中断 API 的变化)
- [8.4 其他废弃](#8.4 其他废弃)
1. 概述
io.agentscope.core.agent 是 AgentScope 的智能体核心抽象层 ,定义了 Agent 的完整行为契约。采用接口分层 设计,将 Agent 的能力拆分为三个正交维度,最终汇聚到 Agent 统一接口。
CallableAgent StreamableAgent ObservableAgent
"调用并等待结果" "流式观察执行过程" "被动接收消息"
│ │ │
└─────────────────────┼──────────────────────┘
▼
Agent
(统一接口 + 中断 + 身份)
│
▼
AgentBase
(抽象基类,实现全部通用逻辑)
│
┌────────┴────────┐
▼ ▼
ReActAgent HarnessAgent
(ReAct 推理) (工程化封装)
2. 接口分层
2.1 CallableAgent(同步调用)
java
public interface CallableAgent {
// 核心:传入消息列表,返回 Mono<Msg>
Mono<Msg> call(List<Msg> messages);
// 结构化输出变体
Mono<Msg> call(List<Msg> messages, Class<?> outputType);
Mono<Msg> call(List<Msg> messages, JsonNode outputSchema);
// 便捷方法
default Mono<Msg> call(Msg... messages);
default Mono<Msg> call(Msg msg);
default Mono<Msg> call();
}
2.2 StreamableAgent(流式调用)
java
public interface StreamableAgent {
// 核心:传入消息列表 + 流选项,返回 Flux<Event>
Flux<Event> stream(List<Msg> messages, StreamOptions options);
// 结构化输出变体
Flux<Event> stream(List<Msg> messages, StreamOptions options, Class<?> outputType);
Flux<Event> stream(List<Msg> messages, StreamOptions options, JsonNode outputSchema);
// 便捷方法
default Flux<Event> stream(Msg msg, StreamOptions options);
default Flux<Event> stream(List<Msg> messages);
default Flux<Event> stream(StreamOptions options);
}
2.3 ObservableAgent(被动观察)
java
public interface ObservableAgent {
Mono<Void> observe(Msg msg);
Mono<Void> observe(List<Msg> messages);
}
用于多 Agent 协作:主 Agent 通过 observe() 向子 Agent 推送消息,子 Agent 被动接收而不需要返回结果。
2.4 Agent(统一接口)
java
public interface Agent extends CallableAgent, StreamableAgent, ObservableAgent {
String getAgentId(); // 唯一标识
String getName(); // Agent 名称
default String getDescription(); // 描述
void interrupt(); // 中断当前执行
void interrupt(Msg feedbackMsg); // 中断并注入反馈消息
default AgentState getAgentState(); // 获取当前会话状态
}
3. AgentBase
AgentBase 实现了 Agent 的全部通用逻辑,是 ReActAgent 的父类。
3.1 核心能力
- 生命周期管理:
runLifecycle()→ 编排PreCall Hook→doCall()→PostCall Hook - 并发控制:
per-session串行门(相同sessionId的call自动FIFO排队) - 中断机制:
interrupt()→ 设置中断标志 → 推理循环检查 →handleInterrupt() Hook系统:注册/排序/调用PreCallHook/PostCallHook/ErrorHook- 事件流:
stream()→ 创建EventStream→ 逐Event发射 - 子
Agent通信:hubSubscribers+broadcastToSubscribers()
3.2 并发控制
java
// AgentBase 内部维护 per-session 的串行门
private final ConcurrentHashMap<Object, Mono<Void>> callGates;
// 相同 key(如 sessionId)的调用自动 FIFO 排队
protected Object callSerializationKey(RuntimeContext ctx) {
return ctx.getSessionId(); // 默认按 sessionId 串行
}
同一 sessionId 的 call() 自动排队,不同 sessionId 的调用完全并行。
3.3 生命周期
call(messages)
│
├─ notifyPreCall(messages)
│ └── 触发所有 PreCallHook
│
├─ serializeOnKey(sessionId, doCall(messages))
│ └── per-session 串行化
│
├─ doCall(messages) ← 子类实现(ReActAgent 的推理循环)
│
├─ notifyPostCall(result)
│ └── 触发所有 PostCallHook
│
└─ observe(result)
└── 广播给所有 subscriber(子 Agent)
4. Event(流式事件)
stream() 方法返回 Flux<Event>,每个 Event 包含:
java
public class Event {
EventType getType(); // 事件类型
Msg getMessage(); // 携带的消息
boolean isLast(); // 是否为最后一个事件
EventSource getSource(); // 事件来源(哪个 Agent 发出的)
}
4.1 EventType(事件类型)
| 枚举值 | 触发时机 | 携带内容 |
|---|---|---|
REASONING |
模型推理输出 | 文本增量 / 最终推理结果 |
TOOL_RESULT |
工具执行完成 | 工具调用 + 工具结果 |
HINT |
Agent 需要提示用户 | 提示文本 |
AGENT_RESULT |
Agent 任务完成 | 最终回复 |
SUMMARY |
对话摘要生成 | 摘要文本 |
ALL |
包含所有类型 | --- |
4.2 EventSource(事件溯源)
java
EventSource.builder()
.agentKey("main") // Agent Key
.agentId("agent-001") // Agent ID
.agentName("weather-agent") // Agent 名
.sessionId("s1") // 会话 ID
.parentSessionId("p1") // 父会话(子 Agent 场景)
.taskId("task-001") // 任务 ID(子 Agent 场景)
.depth(1) // 嵌套深度
.path("main/sub1") // 路径
.build();
4.3 StreamOptions(流控)
java
StreamOptions.builder()
.eventTypes(Set.of(EventType.REASONING, EventType.TOOL_RESULT))
.incremental(true) // 增量模式(逐 token 发射)
.includeReasoningChunk(true) // 推理的增量块
.includeReasoningResult(true) // 推理的最终结果
.includeActingChunk(true) // 工具执行的增量
.includeSummaryChunk(true) // 摘要的增量
.includeSummaryResult(true) // 摘要的最终结果
.build();
5. RuntimeContext(每次调用的元数据容器)
java
RuntimeContext ctx = RuntimeContext.builder()
.sessionId("s-001") // 会话 ID(决定状态槽位)
.userId("alice") // 用户 ID(决定租户隔离)
.put("request_id", "abc") // 字符串属性
.put(MyClass.class, obj) // 类型化属性
.build();
| 方法 | 说明 |
|---|---|
getSessionId() / getUserId() |
路由状态槽位与租户 |
getAgentState() / setAgentState() |
call-scoped 状态,框架在 call 入口自动注入 |
resolveAgentState(ctx, agent) |
静态辅助:优先 ctx.getAgentState() |
get(String) / put(String, Object) |
字符串键存取 |
get(Class<T>) / put(Class<T>, T) |
按类型存取 |
getExtra() |
字符串属性 Map(可变) |
asToolExecutionContext() |
转为工具执行上下文 |
empty() |
空上下文 |
6. ReactConfig (ReAct 配置)
java
public record ReactConfig(
int maxIters, // 最大推理迭代次数(默认 10)
boolean stopOnReject // 权限拒绝时是否停止(默认 true)
) {
static ReactConfig defaults(); // maxIters=10, stopOnReject=true
}
7. 完整调用链
用户: Msg("北京天气怎么样?")
│
▼
agent.call(List.of(msg))
│
▼
AgentBase.runLifecycle()
│
├─ 1. PreCallHook → 预处理消息(注入上下文、权限检查)
├─ 2. serializeOnKey() → per-session 排队
├─ 3. doCall(messages) → ReActAgent 推理循环:
│ ├─ prepareMessages()
│ ├─ reasoning() → Model.stream() → REASONING Event
│ ├─ acting() → Toolkit.callTools() → TOOL_RESULT Event
│ └─ isFinished()? → 循环或结束
├─ 4. PostCallHook → 后处理(日志、观测)
└─ 5. observe(result) → 广播给 SubAgent
│
▼
返回 Mono<Msg> / Flux<Event>
8. 2.0 废弃 API 与新 API 对照
AgentScope 2.0 对 Agent 层的 API 进行了大幅清理 。以下列出所有 @Deprecated 标记及其替代方案。
8.1 流式 API
这是 2.0 最核心的 API 变化。v1 的 stream() 返回粗粒度 Event,v2 的 streamEvents() 返回细粒度 AgentEvent。
| 废弃(v1) | 替代(v2) | 废弃级别 |
|---|---|---|
StreamableAgent 整个接口 |
直接调用 ReActAgent |
@Deprecated(forRemoval=true) |
StreamableAgent.stream(...) 全部 11 个方法 |
ReActAgent.streamEvents(...) |
@Deprecated(forRemoval=true) |
AgentBase.stream(...) 3 个方法 |
ReActAgent.streamEvents(...) |
@Deprecated(forRemoval=true) |
Event 类 |
AgentEvent |
@Deprecated(since="2.0.0") |
EventType 枚举 |
AgentEventType |
@Deprecated(since="2.0.0") |
EventSource 类 |
AgentEvent 内嵌 source 字段 | @Deprecated(since="2.0.0") |
StreamingHook |
MiddlewareBase |
@Deprecated(forRemoval=true) |
streamEvents() :
java
// v1(废弃)
Flux<Event> stream = agent.stream(messages, StreamOptions.defaults());
// v2(新 API)
Flux<AgentEvent> stream = agent.streamEvents(messages);
// 或带 RuntimeContext
Flux<AgentEvent> stream = agent.streamEvents(messages, runtimeContext);
8.2 新事件类型
v2 将 v1 的 6 种粗粒度事件拆分为 27 种细粒度事件:
| 分类 | v1 EventType | v2 AgentEventType |
|---|---|---|
| Agent 生命周期 | --- | AGENT_START, AGENT_END |
| 模型调用 | REASONING |
MODEL_CALL_START, MODEL_CALL_END |
| 文本输出 | --- | TEXT_BLOCK_START, TEXT_BLOCK_DELTA, TEXT_BLOCK_END |
| 思考输出 | --- | THINKING_BLOCK_START, THINKING_BLOCK_DELTA, THINKING_BLOCK_END |
| 数据输出 | --- | DATA_BLOCK_START, DATA_BLOCK_DELTA, DATA_BLOCK_END |
| 工具调用 | TOOL_RESULT |
TOOL_CALL_START, TOOL_CALL_DELTA, TOOL_CALL_END |
| 工具结果 | --- | TOOL_RESULT_START, TOOL_RESULT_TEXT_DELTA, TOOL_RESULT_DATA_DELTA, TOOL_RESULT_END |
| 异常 | --- | EXCEED_MAX_ITERS |
| HITL | --- | REQUIRE_USER_CONFIRM, USER_CONFIRM_RESULT, REQUIRE_EXTERNAL_EXECUTION, EXTERNAL_EXECUTION_RESULT |
| 中断 | --- | REQUEST_STOP |
| 子 Agent | --- | SUBAGENT_EXPOSED |
| 旧类型 | HINT, AGENT_RESULT, SUMMARY, ALL |
--- |
8.3 中断 API 的变化
| 废弃 | 说明 | 替代 |
|---|---|---|
AgentBase.interrupt() |
v1 全局中断 | 子类实现 per-session 中断(AgentState.interruptControl()) |
AgentBase.interrupt(Msg) |
v1 带消息中断 | 子类实现 per-session 中断 |
AgentBase.interrupt(InterruptSource) |
v1 中断源 | 子类实现 |
AgentBase.getInterruptFlag() |
v1 中断标志 | per-session InterruptControl |
AgentBase.getInterruptSource() |
返回永远是 USER | AgentState.interruptControl().getSource() |
AgentBase.resetInterruptFlag() |
v1 重置 | No-op,由 AgentState.interruptControl() 管理 |
AgentBase.checkInterruptedAsync() |
v1 异步检查 | No-op stub |
8.4 其他废弃
| 废弃 | 说明 | 替代 |
|---|---|---|
AgentBase 构造器(旧版) |
AgentBase(String, String, boolean, List) |
AgentBase(String, String, List) |
AgentBase.isCheckRunning() |
不再强制,per-session 串行化已替代 | --- |
StreamUserInput |
v1 用户输入流 | 移除 |
UserAgent |
v1 用户 Agent 抽象 | 移除 |
UserInputBase / UserInputData |
v1 用户输入数据类 | 移除 |