---
title: "react - ReActTrace 思考记忆与轨迹"
---



在 ReAct（Reasoning and Acting）模式下，智能体不再是简单的"问答机"，而是一个具备"思考-行动-观察"循环的逻辑引擎。ReActTrace 正是记录这一循环过程的核心载体。它充当了智能体的运行时记忆和状态机，确保在复杂的推理过程中逻辑不丢失、状态可回溯。

### 1、核心职责：不仅是记录，更是驱动
ReActTrace 在一个典型的推理周期中承担了四种关键角色：

- 逻辑状态机：维护 REASON（推理）、ACTION（行动）、END（结束）的流转状态。
- 工作记忆 (Working Memory)：实时存储当前任务的所有上下文、模型思考内容、工具调用参数及其返回结果（Observation）。
- 度量审计：自动统计推理轮次（Turn Count）、工具调用次数以及 Token 消耗。
- 计划中枢：如果启用了 Planning 能力，它还负责动态维护执行计划及其进度。

### 2、获取方式
从会话中提取"当前" ReActTrace

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

```
从同步调用结果中获取

```java
ReActResponse resp = agent.prompt("...").call();
ReActTrace trace = resp.getTrace();

```
从流式响应事件中获取

```java
agent.prompt("...").stream()
    .doOnNext(event -> {
        if (event instanceof ReasonDeltaEvent) {
            ReasonDeltaEvent reasonEvent = (ReasonDeltaEvent) event;
            reasonEvent.getTrace();
        }
    })
    .subscribe();

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

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

| 分类       | 方法 | 返回类型 | 功能描述 |
|------------|------|----------|----------|
| 基础上下文 | `getOriginalPrompt()` | `Prompt` | 获取用户最初输入的任务指令。 |
|            | `getSession()` | `AgentSession` | 获取当前会话上下文（持有对话历史）。 |
|            | `getContext()` | `FlowContext` | 获取流程快照，用于跨节点数据共享。 |
| 状态控制   | `getRoute() / setRoute()` | `String` | 获取或更新当前的路由逻辑标识。 |
|            | `getTurnCount()` | `int` | 获取当前已进行的推理**轮次**。 |
|            | `nextTurn()` | `int` | 轮次递增（通常由引擎在每一轮 Reason 前自动调用）。 |
| 执行计划   | `setPlans(Collection)` | `void` | 注入或更新智能体生成的执行计划列表。 |
|            | `getFormattedPlans()` | `String` | 获取 Markdown 格式的计划列表，用于增强模型感知的有序性。 |
|            | `getPlanProgress()` | `String` | 获取当前进度描述（如：总步数与当前进度的对比）。 |
| 结果与度量 | `getFinalAnswer()` | `String` | 获取最终生成的结论。 |
|            | `getMetrics()` | `Metrics` | 获取性能度量指标（耗时、Token 消耗等）。 |
|            | `getFormattedHistory()` | `String` | 获取人性化的对话与行动历史记录（Markdown 格式）。 |

> **注意**：旧方法 `getStepCount()` / `nextStep()` 已在 4.0 版本标记为 `@Deprecated`，请统一使用 `getTurnCount()` / `nextTurn()`。

### 4、自定义拦截器中的应用示例
这个示例展示了如何通过拦截器实现两个最常用的功能：实时监控推理过程以及防止模型死循环的"轮次熔断"。

#### 场景：推理过程监控与安全熔断
```java

import org.noear.solon.ai.agent.react.ReActInterceptor;
import org.noear.solon.ai.agent.react.ReActTrace;
import org.noear.solon.ai.agent.react.task.ToolExchanger;
import org.noear.solon.ai.chat.ChatResponse;
import org.noear.solon.ai.chat.message.AssistantMessage;
import org.noear.solon.ai.chat.message.ChatMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 一个利用 ReActInterceptor 新 API 的监控拦截器
 * 职责：1. 打印推理过程；2. 监控工具调用；3. 轮次安全熔断
 */
public class MyReActInterceptor implements ReActInterceptor {
    private static final Logger log = LoggerFactory.getLogger(MyReActInterceptor.class);
    private static final int MAX_TURNS = 20;

    @Override
    public void onAgentStart(ReActTrace trace) {
        log.info("--- 智能体任务开始 [{}] ---", trace.getOriginalPrompt().getUserContent());
    }

    @Override
    public void onReasonStart(ReActTrace trace, StringBuilder systemPromptBuf) {
        // 轮次熔断：在每次推理前检查是否超过最大轮次
        if (trace.getTurnCount() > MAX_TURNS) {
            systemPromptBuf.append("\n\n[系统提示] 已超过最大推理轮次(")
                    .append(MAX_TURNS).append(")，请尽快给出最终结论并结束。");
        }
    }

    @Override
    public void onReasonEnd(ReActTrace trace, ChatResponse resp, AssistantMessage message, long durationMs) {
        // 实时输出 AI 的推理结果（替代已废弃的 onThought）
        System.out.println("🤔 推理完成（耗时 " + durationMs + "ms）: " + message.getContent());
        if (message.isThinking()) {
            System.out.println("🧠 深度思考中...");
        }
    }

    @Override
    public void onToolCallStart(ReActTrace trace, ToolExchanger toolExchanger) {
        // 工具调用前的审计或记录（替代已废弃的 onAction）
        log.info("🛠️ 准备调用工具: {}，参数: {}", toolExchanger.getToolName(), toolExchanger.getArgs());
    }

    @Override
    public void onAgentEnd(ReActTrace trace) {
        log.info("--- 任务结束，总轮次: {}，总耗时: {}ms ---",
                trace.getTurnCount(),
                trace.getMetrics().getTotalDuration());
    }
}

```

> **向后兼容指引**：如果您在 4.0.4 之前的版本中使用了 `onThought` 和 `onAction`、`onObservation` 三个方法，它们依然可用但已被 `@Deprecated` 标记。推荐迁移到新的 API：
> - `onThought` → `onReasonEnd(ReActTrace, ChatResponse, AssistantMessage, long)`，额外获取 `ChatResponse` 和耗时参数
> - `onAction` → `onToolCallStart(ReActTrace, ToolExchanger)`，语义更明确
> - `onObservation` → `onToolCallEnd(ReActTrace, ToolExchanger, ChatMessage, Throwable, long)`，额外获取错误和耗时参数
> 新的拦截器还额外支持 `onReasonStart`（推理开始前，可修改 systemPrompt）、`onReasonRetry`（推理重试）、`onActionStart` / `onActionEnd`（整个动作阶段前后）等精细化钩子。

### 5、技术特性解析
#### 5.1 协议工具注入 (Protocol Tooling)
当智能体处于 TeamAgent 协作模式下，协作协议（TeamProtocol）可能会动态注入一些特殊工具（如 transfer_to）。这些工具被存储在 protocolToolMap 中，优先级高于智能体的默认工具。

#### 5.2 结构化历史记录
getFormattedHistory() 会将复杂的消息列表转换为易于阅读的日志格式：

- `[User]`: 原始指令
- `[Assistant]`: 模型的思考（Thought）
- `[Action]`: 调用的工具名及参数
- `[Observation]`: 工具返回的结果

#### 5.3 动态计划管理
如果开启了 `options.planningMode(true)`，智能体会先在 ReActTrace 中生成一份 plans。每一轮推理时，系统会自动将这份计划和当前进度（`getPlanProgress()`）注入提示词，显著提升 Agent 处理复杂长任务的成功率。

### 6、使用建议
调试神器：在开发阶段，打印 getFormattedHistory() 是排查智能体为什么"跑偏"的最快方式。

内存注意：对于长任务，workingMemory 会持续增长。在极高并发场景下，建议通过拦截器监控 turnCount 以防止内存异常增长。

结果提取：如果需要将 AI 的结果转换为 Java 对象，通常在 finalAnswer 产出后，配合 toBean(Class) 使用。
