multi - TeamTrace 协作记忆与轨迹治理
在多智能体(Multi-Agent)协作中,如何让 Agent 知道“别人刚才说了什么”?如何统计整个团队的消耗?如何防止 Agent 之间陷入死循环?
TeamTrace 是 Solon AI 提供的协作轨迹模型。它像一个随身的“黑匣子”,全程记录团队内部每个智能体的发言、耗时及决策路径。
1、自动收集原理:数据是怎么进来的?
开发者不需要手动为每个 Agent 写抓取代码。其核心秘密在于 Agent 接口的默认执行逻辑:
环境感知:TeamAgent 启动时,会在工作流上下文(FlowContext)中埋入一个 _current_trace_key。
生命周期注入:每个 Agent 执行时,其 run 方法会自动完成以下操作:
- 读记忆:从 TeamTrace 提取历史记录,拼接到当前 Prompt 中,让 Agent 拥有“全局视野”。
- 记轨迹:执行完成后,自动调用 trace.addStep(...),记录谁(Name)、说了什么(Content)、耗时多久(Duration)。
2、示例参考:在自定义 Agent 中利用 TeamTrace
当你实现自定义 Agent 时,可以通过 TeamTrace 实现更复杂的逻辑判断,例如“根据前一个人的反馈来调整自己的策略”。
场景:一个负责“复核”的 Agent
public class ReviewAgent implements Agent {
@Override
public String name() { return "reviewer"; }
@Override
public String call(FlowContext context, Prompt prompt) throws Throwable {
// 1. 获取轨迹 Key,进而拿到 TeamTrace 实例
String traceKey = context.getAs(Agent.KEY_CURRENT_TRACE_KEY);
TeamTrace trace = context.getAs(traceKey);
if (trace != null) {
// 2. 检查最近一次协作
List<TeamStep> steps = trace.getSteps();
TeamStep lastStep = steps.get(steps.size() - 1);
// 如果前一个 Agent 耗时过短,可能产生了幻觉,要求重审
if (lastStep.getDuration() < 500) {
return "检测到前置任务处理过快,请重新生成详细逻辑。";
}
// 3. 获取完整的格式化历史,用于自定义 Prompt 构造
String history = trace.getFormattedHistory();
System.out.println("当前协作进展:\n" + history);
}
return "审核通过。";
}
}
3、高级功能:协作治理与死循环检测
TeamTrace 不仅记录数据,还负责“监督”协作质量。
-
死循环检测 (isLooping): 底层算法会自动检查 steps。如果发现 Agent 输出了与之前完全相同的内容,或者出现了 A->B->A->B 的复读机模式,isLooping() 将返回 true。
-
最终结果设置 (setFinalAnswer): 在自由模式下,你需要手动调用此方法设置团队的“最终答复”,这样最外层的 team.call().getAnswer() 才能正确获取结果。
4、常用 API 快速查阅
| 分类 | 方法 | 返回类型 | 功能描述 |
|---|---|---|---|
| 基础信息 | getPrompt() | Prompt | 获取原始任务的提示词(用户最初输入的指令)。 |
| getConfig() | TeamConfig | 获取当前团队的配置信息(如超时、重试策略等)。 | |
| 轨迹记录 | getSteps() | List<TeamStep> | 获取所有协作步骤列表,可遍历获取每一步的 Agent 名字、内容和耗时。 |
| getStepCount() | int | 获取已执行的步骤总数。 | |
| addStep(name, content, duration) | void | 手动添加一条协作记录(通常由引擎自动调用)。 | |
| 逻辑治理 | getFormattedHistory() | String | 获取格式化的对话历史 |
| isLooping() | bool | 智能检测是否陷入死循环(如 A-B-A-B 模式或重复输出),用于及时熔断。 | |
| nextIterations() | Map<String, Object> | 获取策略上下文。用于在 Agent 之间传递非文本的结构化数据(如对象、状态位)。 | |
| getRoute() | String | 获取当前的路由指令(例如 Supervisor 决策的下一个目标)。 | |
| setRoute(route) | void | 设置当前的路由指令(例如 Supervisor 决策的下一个目标) | |
| getFinalAnswer() | String | 获取团队的最终答案。 | |
| setFinalAnswer(content) | void | 设置团队的最终答案。在“自由模式”或自定义 Join 节点中必须调用。 |
5、最佳实践提示
- 内存管理:对于超长对话,TeamTrace 会记录所有步骤。如果步骤过多,建议在自定义 Agent 中对 getFormattedHistory() 的结果进行摘要处理。
- 多线程安全:TeamTrace 内部使用了线程安全容器(如 AtomicInteger),但在并行模式下手动修改 protocolContext 时,仍需注意并发安全。
6、使用建议
- 如何获取 TeamTrace 实例?
在 Agent 的 call 方法或 solon-flow 的 task 中,通过 FlowContext 获取:
// 这里的 key 需要对应 TeamAgent 定义时的 ID 或使用规范约定的 Key
TeamTrace trace = context.getAs(Agent.KEY_CURRENT_TRACE_KEY);
- 什么时候该用 getProtocolContext()?
如果你的团队在执行过程中需要传递一些“中间变量”(例如:提取出的订单号、临时校验状态),不要试图解析 FormattedHistory 的文本,直接放进 protocolContext 这个 Map 中更可靠