team - TeamTrace 协作记忆与轨迹治理
2026年7月30日 下午5:28:18
在多智能体(Multi-Agent)协作中,如何让 Agent 知道"别人刚才说了什么"?如何统计整个团队的消耗?如何防止 Agent 之间陷入死循环?
TeamTrace 是 Solon AI 提供的协作轨迹模型。它像一个随身的"黑匣子",全程记录团队内部每个智能体的发言、耗时及决策路径。
1、自动收集原理:数据是怎么进来的?
开发者不需要手动为每个 Agent 写抓取代码。其核心秘密在于 Agent 接口的默认执行逻辑:
- 环境感知:TeamAgent 启动时,会在工作流上下文(FlowContext)中埋入一个
_current_trace_key。 - 生命周期注入:每个 Agent 执行时,其 run 方法会自动完成以下操作:
- 读记忆:从 TeamTrace 提取历史记录,拼接到当前 Prompt 中,让 Agent 拥有"全局视野"。
- 记轨迹:执行完成后,自动调用
trace.addRecord(ChatRole.ASSISTANT, name(), content, duration),记录谁(Name)、说了什么(Content)、耗时多久(Duration)。
2、获取方式
从会话中提取"当前" TeamTrace
TeamTrace.getCurrent(session.getSnapshot());
从同步调用结果中获取
TeamResponse resp = agent.prompt("...").call();
TeamTrace trace = resp.getTrace();
从流式响应事件中获取
agent.prompt("...").stream()
.doOnNext(event -> {
if (event instanceof SupervisorDeltaEvent) {
SupervisorDeltaEvent supervisorEvent = (SupervisorDeltaEvent) event;
supervisorEvent.getTrace();
}
})
.subscribe();
从拦截器中获取。具体参考拦截器资料。
3、示例参考:在自定义 Agent 中利用 TeamTrace
当你实现自定义 Agent 时,可以通过 TeamTrace 实现更复杂的逻辑判断,例如"根据前一个人的反馈来调整自己的策略"。
场景:一个负责"复核"的 Agent
public class ReviewAgent implements Agent {
@Override
public String name() { return "reviewer"; }
@Override
public AssistantMessage call(FlowContext context, Prompt prompt) throws Throwable {
// 1. 获取当前 TeamTrace 实例
TeamTrace trace = TeamTrace.getCurrent(context);
if (trace != null) {
// 2. 检查最近一次协作
long duration = trace.getLastAgentDuration();
// 如果前一个 Agent 耗时过短,可能产生了幻觉,要求重审
if (duration < 1000) {
// 通过协议上下文传递重审标记,让调度器知晓
trace.getProtocolContext().put("needs_review", true);
}
// 3. 获取前一个 Agent 的输出作为上下文参考
String lastContent = trace.getLastAgentContent();
prompt = prompt.appendContext("上一个专家的输出: " + lastContent);
}
// 执行 LLM 调用
return call(prompt);
}
}
4、流式事件中的团队轨迹
在 TeamAgent 流式模式下,不仅会产生 Supervisor 调度决策事件,还会产生节点级生命周期事件:
| 事件类 | 触发时机 | 关键字段 |
|---|---|---|
TeamStartEvent | 团队协作任务开始时 | getTrace() |
TeamEndEvent | 团队协作任务结束时,携带最终 TeamResponse | getResponse(), getTrace() |
NodeStartEvent | 图节点(子 Agent)即将开始执行时 | getNode(), getTrace() |
NodeEndEvent | 图节点(子 Agent)执行完毕,携带该 Agent 的输出消息 | getNode(), getTrace(), getMessage() |
SupervisorDeltaEvent | 调度器(Supervisor)推理过程中产生流式内容 | getNode(), getTrace(), getResponse() |
注意:
NodeChunk已在 4.0.4 版本标记为@Deprecated,请使用NodeStartEvent/NodeEndEvent替代。
从流式中获取团队轨迹的完整示例:
agent.prompt("策划一次团建活动").stream()
.doOnNext(event -> {
if (event instanceof TeamStartEvent) {
TeamStartEvent e = (TeamStartEvent) event;
System.out.println("🏁 团队任务开始: " + e.getTrace().getAgentName());
} else if (event instanceof NodeStartEvent) {
NodeStartEvent e = (NodeStartEvent) event;
System.out.println("👤 专家开始工作: " + e.getNode().getId());
} else if (event instanceof SupervisorDeltaEvent) {
SupervisorDeltaEvent e = (SupervisorDeltaEvent) event;
System.out.print(e.getResponse().getMessage().getContent()); // 调度器实时输出
} else if (event instanceof NodeEndEvent) {
NodeEndEvent e = (NodeEndEvent) event;
System.out.println("✅ 专家完成: " + e.getNode().getId());
} else if (event instanceof TeamEndEvent) {
TeamEndEvent e = (TeamEndEvent) event;
System.out.println("🎯 团队任务完成,最终答案: " + e.getMessage().getContent());
}
})
.subscribe();
5、常用 API 快速查阅
| 分类 | 方法 | 返回类型 | 功能描述 |
|---|---|---|---|
| 基础信息 | getOriginalPrompt() | Prompt | 获取用户最初输入的任务指令。 |
getConfig() | TeamAgentConfig | 获取当前团队的静态配置信息。 | |
getSession() | AgentSession | 获取当前协作关联的会话(持有 LLM 记忆)。 | |
getProtocol() | TeamProtocol | 获取当前团队的协作协议(如 NONE、SWARM 等)。 | |
| 轨迹记录 | getRecords() | List<TeamRecord> | 获取所有协作足迹(按时间排序的流水账)。 |
getRecordCount() | int | 获取已执行的步骤(记录)总数。 | |
addRecord(ChatRole, source, content, duration) | void | 手动添加一条协作记录(非注入场景使用)。 | |
getLastAgentContent() | String | 快速提取最近一位专家 Agent 的输出内容。 | |
getLastAgentDuration() | long | 获取最近一位专家 Agent 的执行耗时(毫秒)。 | |
| 逻辑治理 | getFormattedHistory() | String | 获取 Markdown 格式的全量对话历史(含系统指令)。 |
getFormattedHistory(windowSize) | String | 获取最近指定步数的对话历史,适合长任务摘要。 | |
getFormattedHistory(windowSize, includeSystem) | String | 可选择是否包含调度器系统指令。 | |
getProtocolContext() | Map | 获取协议私有上下文,用于传递结构化中间变量。 | |
getProtocolDashboardSnapshot() | String | 获取协议状态快照(JSON 格式),供 Agent 感知全局进度。 | |
| 状态控制 | getTurnCount() | int | 获取当前的协作轮数(迭代次数)。 |
nextTurn() | int | 轮次递增(通常在调度器每一轮决策前自动调用)。 | |
resetTurnCount() | void | 重置轮次计数器。 | |
getRoute() / setRoute() | String | 获取或设置当前的路由指令(决策指向)。 | |
isInitial() | boolean | 判断是否初始状态(records 为空)。 | |
| 结果与度量 | getFinalAnswer() | String | 获取团队的最终输出答案。 |
setFinalAnswer(content) | void | 设置最终答案,标志协作任务圆满完成。 | |
getMetrics() | Metrics | 获取整个团队的性能度量(耗时、Token 消耗)。 |
6、最佳实践提示
- 内存与长度管理:对于超长对话,
getFormattedHistory()会产生巨大的字符串。如果 LLM 窗口受限,建议使用getFormattedHistory(windowSize)仅获取最近 N 步。 - 结构化通信:如果你的团队在执行过程中需要传递中间变量(如:提取出的订单号),不要试图让下一个 Agent 去解析上一人的文本,直接使用
getProtocolContext().put(key, value)更加可靠。 - 如何获取实例?:
// 在任何能拿到 FlowContext 的地方执行
TeamTrace trace = TeamTrace.getCurrent(context);