在多智能体（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、获取方式

从会话中提取“当前” TeamTrace

```java
TeamTrace.getCurrent(session.getSnapshot());
```

从同步调用结果中获取

```java
TeamResponse resp = agent.prompt("...").call();
TeamTrace treace = resp.getTrace();
```

从流式响应块中获取

```java
agent.prompt("...").stream()
    .doOnNext(chunk -> {
        if(chunk instanceof SupervisorChunk){
            SupervisorChunk supervisorChunk = (SupervisorChunk)chunk;
            supervisorChunk.getTrace();
        }

    })
    .subscribe();
```

从拦截器中取获。具体参考拦截器资料。



### 3、示例参考：在自定义 Agent 中利用 TeamTrace


当你实现自定义 Agent 时，可以通过 TeamTrace 实现更复杂的逻辑判断，例如“根据前一个人的反馈来调整自己的策略”。


场景：一个负责“复核”的 Agent

```java
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 < 500) {
                 return "检测到前置任务处理过快，请重新生成详细逻辑。";
            }
            
            // 3. 获取完整的格式化历史，用于自定义 Prompt 构造
            String history = trace.getFormattedHistory();
            System.out.println("当前协作进展：\n" + history);
        }

        return ChatMessage.ofAssistant("审核通过。");
    }
}
```



### 4、高级功能：协作治理与死循环检测

TeamTrace 不仅记录数据，还负责“监督”协作质量。


* 迭代安全计数 (getTurnCount)：底层会自动维护 turnCounter。每经过一轮决策或执行，计数器加一。这可用于在拦截器中判断是否达到了“最大轮次”从而强制熔断。

* 协议私有上下文 (protocolContext)：这是智能体之间的“小纸条”。如果你需要传递非文本数据（如：数据库连接对象、权限状态位），应存放在这里。

* 最终结果设置 (setFinalAnswer)：在复杂流程或自由编排模式下，必须手动调用此方法设置团队的“最终答复”，否则 team.call().getContent() 将无法获取结果。


### 5、常用 API 快速查阅




| 分类 | 方法 | 返回类型 | 功能描述 |
| -------- | -------- | -------- | -------- |
| 基础信息  | `getOriginalPrompt()` | `Prompt` | 获取用户最初输入的任务指令。  |
|  | `getConfig()` | `TeamAgentConfig` |  获取当前团队的静态配置信息。 |
|  | `getSession()` | `AgentSession` | 获取当前协作关联的会话（持有 LLM 记忆）。  |
| 轨迹记录  | `getRecords()` | `List<TeamRecord>` |  获取所有协作足迹（按时间排序的流水账）。 |
|  | `getRecordCount()` | `int` | 获取已执行的步骤（记录）总数。 |
|  | `getLastAgentContent()` | `String` |  快速提取最近一位专家 Agent 的输出内容。 |
|  | `getLastAgentDuration()` | `long` | 获取最近一位专家 Agent 的执行耗时（毫秒）。  |
|  逻辑治理 | `getFormattedHistory()` | `String` |  获取 Markdown 格式的全量对话历史（含系统指令）。 |
|  | `getProtocolContext()` | `Map` | 获取协议私有上下文，用于传递结构化中间变量。  |
|  | `getTurnCount()` | `int` | 获取当前的协作轮数（迭代次数）。  |
|  | `getRoute() / setRoute()` | `String` |  获取或设置当前的路由指令（决策指向）。 |
|  | `getFinalAnswer()` | `String` |  获取团队的最终输出答案。 |
|  | `setFinalAnswer(content)` | `void` |  关键：设置最终答案，标志协作任务圆满完成。 |




### 6、最佳实践提示


* 内存与长度管理：对于超长对话，`getFormattedHistory()` 会产生巨大的字符串。如果 LLM 窗口受限，建议使用 `getFormattedHistory(windowSize)` 仅获取最近 N 步。
* 结构化通信：如果你的团队在执行过程中需要传递中间变量（如：提取出的订单号），不要试图让下一个 Agent 去解析上一人的文本，直接使用 `getProtocolContext().put(key, value)` 更加可靠。
* 如何获取实例？：


```java
// 在任何能拿到 FlowContext 的地方执行
TeamTrace trace = TeamTrace.getCurrent(context);
```











