SolonCode 的两个"后悔药":重新运行 vs 继续运行

在 SolonCode Web 聊天界面底部,工具栏有三个按钮(从左到右):

  1. Cop --- 复制上一条回复内容
  2. Re-run(重新运行) --- 删除旧回答,重新跑一轮
  3. Continue(继续运行) --- 保留旧回答,继续追加内容

这两个按钮看起来很像,但行为完全不同。今天深入拆解它们的实现。

重新运行(Re-run)

行为: 删除旧的气泡,用同样的输入重新跑一遍。

使用场景:

  • AI 答错了,想让它重新回答
  • 想换个角度重新问

实现原理:

源码在 RerunCommand.java

java 复制代码
// 逆向遍历消息列表,找到最后一个 UserMessage
List<ChatMessage> messageList = session.getMessages();
String lastUserInput = null;

while (!messageList.isEmpty()) {
    ChatMessage msg = messageList.get(messageList.size() - 1);
    if (msg instanceof UserMessage) {
        lastUserInput = msg.getContent();
        session.removeLatestMessage(1);
        break;
    }
    session.removeLatestMessage(1);
}

// 重新运行,输入相同
if (lastUserInput != null) {
    ctx.runAgentTask(lastUserInput, null);
}

核心逻辑: 逆向遍历找到最后一个用户消息,删除它之后的所有 AI 响应,然后用同样的输入重新跑一遍。

结果: 新回答完全替换旧回答。

继续运行(Continue)

行为: 保留旧的气泡,在旧回答后面继续追加新内容。

使用场景:

  • AI 答到一半断了(比如 token 限制)
  • 想让 AI 继续写下去
  • 旧回答不完整,想让它补充

实现原理:

源码在 ContinueCommand.java

java 复制代码
ReActTrace trace = session.getContext().getAs("__main");
if (trace != null) {
    if (Agent.ID_END.equals(trace.getRoute())) {
        // 说明有结束节点,重新回到思考点
        trace.setRoute(ReActAgent.ID_REASON);
        trace.setFinalAnswer(null, false);

        ChatMessage workMessage = trace.getWorkingMemory().getLastMessage();
        if (workMessage instanceof AssistantMessage) {
            trace.getWorkingMemory().removeLastMessage();
        }

        // 回退一条 ai 历史消息(要重新生成)
        List<ChatMessage> messageList = session.getMessages();
        if (Assert.isNotEmpty(messageList) && messageList.get(messageList.size() - 1) instanceof AssistantMessage) {
            session.removeLatestMessage(1);
        }
    }
}

ctx.runAgentTask(null, null);

核心逻辑:

  1. 检查 trace 状态必须是 ID_END(已完成)
  2. 将 route 重置为 ID_REASON(回到思考阶段)
  3. 清空 finalAnswer(让 AI 重新生成)
  4. 回退最后一条 AI 消息
  5. 空的输入继续运行

结果: 旧气泡保留,新内容追加在后面。

两个按钮的对照表

维度 Re-run(重新运行) Continue(继续运行)
是否删除旧响应 ✅ 删除 ❌ 保留
是否清空历史 ✅ 剥除后续消息 ❌ 保留完整历史
是否重置 trace ✅ 重置 ❌ 仅重置 route
输入 同一个用户输入 空输入
适用场景 答错了想重答 答到一半断了
是否可链式操作 可(再 Re-run) 可(再 Continue)

三个具体场景

场景 A:AI 答错了

问题: "1 + 1 = ?" AI 回答"3"

操作: 点击 Re-run

结果:

  • 旧气泡"3"被删除
  • 新气泡"2"出现
  • 历史回到问题本身

场景 B:AI 答到一半断了

问题: 长文本生成到一半断了

操作: 点击 Continue

结果:

  • 旧气泡保留(已生成的部分)
  • 新气泡追加在后面
  • 内容无缝衔接

场景 C:先 Re-run 再 Continue

问题: 想换个思路但保留部分内容

操作:

  1. 点击 Re-run → 得到新回答 A
  2. 点击 Continue → 在 A 后面追加 B

结果: 最终有两个气泡,A 和 B 都是新内容

runId 联动机制

两个按钮都依赖一个关键字段:runId

作用: 同一轮对话的所有气泡共享同一个 runId

联动效果:

  • Re-run 时,删除该 runId 下的所有气泡
  • Continue 时,新气泡也使用同一个 runId

实现:

java 复制代码
// Web UI 中,每个气泡都有 data-run-id 属性
<div class="message" data-run-id="abc123">
  <!-- 内容 -->
</div>

// Re-run 时,JS 会删除所有 data-run-id="abc123" 的元素
$('[data-run-id="' + runId + '"]').remove();

好处:

  • 用户看到的是一整轮对话
  • 不需要手动删除单个气泡
  • 保持了对话的原子性

三端可用

这两个命令不仅存在于 Web UI,还有三个入口:

1. CLI 命令行

bash 复制代码
soloncode > /rerun    # 重新运行
soloncode > /continue # 继续运行

2. Web UI

点击工具栏的 Re-run / Continue 按钮。

3. IM 机器人

在飞书/钉钉/微信中输入 /rerun/continue

总结

  • Re-run = 删除旧回答 + 同输入重跑
  • Continue = 保留旧回答 + 空输入续跑

两个命令底层实现完全不同,但都通过 runId 联动保持对话完整性。

掌握这两个"后悔药",能让 AI 对话更流畅,出错也能快速修正。

相关推荐
小七-七牛开发者18 小时前
dsh 拆解系列 Vol.01:没有特权内核的 Agent 运行时
ai·大模型·agent·claude·token·工作流·skill·claudecode·ai coding
小七-七牛开发者2 天前
Agent 小知识|Agent 环境工程:部分可观测性、状态转移与执行隔离
ai·大模型·agent·claude·token·工作流·skill·claudecode·ai coding
格数致用4 天前
银河麒麟 V10 SP1 桌面操作系统 + VSCode + Claude Code 接入 DeepSeek-V4 全流程教程(2026年最新)
vscode·claudecode·银河麒麟 v10
仙逆GPT7 天前
ChatGPT、Codex实战:从Claude Code / Cursor迁移到Codex怎么做?/import最容易漏掉哪些配置?
cursor·codex·chatgptplus·claudecode·codex教程
神奇霸王龙9 天前
DeepSeek 接 Anthropic:迁移屠夫
ai·ai作画·agent·ai编程·claude·claudecode
小七-七牛开发者10 天前
Codex 实践系列 Vol.04:用 Goal 和 Plan 管住一个长任务
ai·大模型·agent·claude·token·工作流·claudecode·ai coding
带刺的坐椅10 天前
Solon AOT & Native:三段式编译,从 Java 到原生可执行文件
java·aot·solon·native
带刺的坐椅11 天前
Solon 的日志设计哲学:不只是用 SLF4J 做统一门面
java·logback·solon·log4j2