与 AI 代理的对话很少是线性的。你可能想重新表述问题、重新生成不满意的响应,或探索不同对话路径,同时不丢失 checkpoint 历史。分支聊天使用 LangGraph checkpoints 作为 fork 点:每次编辑或重新生成都会从所选消息的父 checkpoint 提交一次新的运行。
此功能需要 LangGraph Agent Server。使用 langgraph dev 本地运行您的智能体,或将其部署到 LangSmith,以使用此模式。

什么是分支聊天?

分支聊天将对话视为带 checkpoint 的时间线,而不是扁平列表。每条消息都有元数据,指向创建该消息之前的 checkpoint。编辑消息或重新生成响应,会从该 checkpoint 提交一次新的运行。 关键能力:
  • 编辑任意用户消息:重写先前提示词,并从该点重新运行代理
  • 重新生成任意 AI 响应:让代理基于相同输入生成不同答案
  • 检查历史:需要分支时间线时,使用 LangGraph 客户端加载 checkpoints

设置流元数据

对消息使用根流,然后在渲染每条消息的组件中读取逐消息 checkpoint 元数据。该元数据包含用于 fork 的父 checkpoint ID。
The code examples use useStream<typeof myAgent> for type-safe stream state. See Type inference for Python or JavaScript backends.

理解消息元数据

useMessageMetadata(stream, messageId) helper 会返回某条消息的 MessageMetadata。在渲染每条消息的组件中使用它,让元数据保持限定在该消息 ID 上:
parentCheckpointId 是消息之前的 checkpoint。将它用作编辑和重新生成的 fork 点。

编辑消息

若要编辑用户消息并 fork 对话:
  1. 从消息元数据中获取 parentCheckpointId
  2. 使用 forkFrom: { checkpointId } 提交编辑后的消息
  3. 代理会从该点重新运行
编辑后:
  • 代理会携带更新后的消息从 fork 点重新运行
  • 原始路径仍保留在线程历史中

重新生成响应

若要在不更改输入的情况下重新生成 AI 响应:
  1. 从 AI 消息元数据中获取 parent_checkpoint
  2. 使用空输入和 forkFrom: { checkpointId } 提交
  3. 代理会从该点生成新的响应
每次重新生成都会在该位置为 AI 消息创建一条新路径。
重新生成对非确定性代理很有用。由于 LLM 输出会随 temperature 变化,重新生成同一提示词通常会产生有意义的不同响应。

分支底层如何工作

LangGraph 会将每次状态转换持久化为 checkpoint。当你使用 forkFrom 提交时,后端会从该点启动新的执行路径,而不是追加到当前对话。结果是一个树结构:
每条路径都会持久化在 checkpoint store 中。当你想构建跨 checkpoints 的独立时间线视图时,请使用 stream.client.threads.getHistory(threadId)。

最佳实践

  • 在消息附近读取元数据:在渲染消息控件的组件中调用 useMessageMetadata。
  • 悬停时显示 fork 控件:编辑和重新生成按钮应在悬停时出现,以保持 UI 简洁。
  • 按需刷新历史:仅在渲染时间线或 fork 稳定后调用 client.threads.getHistory()。
  • 流式传输时禁用控件:当代理正在主动流式传输响应时,不要允许编辑或重新生成。启用这些操作前检查 stream.isLoading。
  • 取消时保留编辑文本:如果用户开始编辑后又取消,请将 textarea 重置为原始消息内容。
  • 使用深 checkpoint 树测试:频繁编辑和重新生成的用户可能会创建许多路径。确保时间线渲染仍保持高性能。