此功能需要 LangGraph Agent Server。使用
langgraph dev 在本地运行您的代理,或 将其部署到 LangSmith 以使用此模式。什么是分支对话?
分支对话将对话视为一棵树而非一个列表。每条消息都是一个节点,编辑消息或重新生成回复会从该点创建一个分叉。原始路径作为兄弟分支被保留,因此用户可以在不同的对话轨迹之间来回切换。 核心功能:- 编辑任何用户消息: 重写之前的提示词,并从该点重新运行智能体
- 重新生成任何AI回复: 要求智能体为相同的输入生成不同的答案
- 导航分支: 使用每条消息的分支控件在不同版本的对话之间切换
设置带有历史记录的 useStream
要启用分支功能,请传递fetchStateHistory: true,以便 useStream 获取分支操作所需的检查点元数据。
定义一个与您智能体状态模式匹配的TypeScript接口,并将其作为类型参数传递给 useStream,以便类型安全地访问状态值。在下面的示例中,将 typeof myAgent 替换为您的接口名称:
理解消息元数据
getMessagesMetadata(msg) 函数返回每条消息的分支信息:
当消息只有一个版本时,
branchOptions 包含单个条目。编辑或重新生成后,新的分支ID会被添加到 branchOptions 中,您可以在它们之间导航。
编辑消息
要编辑用户消息并创建新分支:- 从消息的元数据中获取
parent_checkpoint - 使用该检查点提交编辑后的消息
- 智能体从该点重新运行,创建新分支
- 消息的
branchOptions获得一个新条目 - 视图会自动切换到新分支
- 智能体使用更新后的消息从分叉点重新运行
- 原始版本被保留,可通过分支切换器访问
重新生成回复
要在不改变输入的情况下重新生成AI回复:- 从AI消息的元数据中获取
parent_checkpoint - 使用
undefined输入和父检查点提交 - 智能体生成新的回复,创建新分支
构建分支切换器
当消息有多个分支时,显示一个紧凑的内联控件,包含当前版本索引和导航箭头:stream.setBranch(branchId) 将对话视图切换到该分支。由于所有分支数据都已通过 fetchStateHistory: true 加载,因此这是即时完成的。
切换分支不仅影响目标消息,还会影响所有后续消息。如果您切换到消息3的不同版本,消息4、5、6等也将更新以反映跟随该版本的对话。
分支功能的工作原理
LangGraph将每个状态转换持久化为一个检查点。当您使用checkpoint 参数提交时,后端会从该点分叉,而不是追加到当前对话。结果是一个树形结构:
完整的消息组件
这是一个结合了消息显示、编辑、重新生成和分支切换的完整组件:与乐观更新结合
将分支功能与乐观更新结合,提供无缝的编辑体验。当用户保存编辑时,在服务器响应之前乐观地显示更新后的消息:添加键盘导航
为高级用户添加键盘快捷键来导航分支:最佳实践
- 始终启用
fetchStateHistory: 没有它,getMessagesMetadata无法返回分支信息。 - 仅在存在多个分支时显示分支切换器:
1/1指示器只会增加混乱而没有价值。 - 在悬停时显示分支控件: 分支导航箭头和编辑按钮应在悬停时出现,以保持界面简洁。
- 保持分支切换器紧凑: 它应内联在消息控件中,不应主导界面。
- 保持滚动位置: 切换分支时,尽量将视口锚定在发生更改的消息上。
- 指示活动分支: 使用微妙的视觉提示(例如,彩色圆点或分支标签),以便用户知道他们正在查看哪个分支。
- 在流式传输时禁用控件: 在智能体正在主动流式传输回复时,不允许编辑或重新生成。在启用这些操作之前检查
stream.isLoading。 - 取消时保留编辑文本: 如果用户开始编辑然后取消,将文本区域重置为原始消息内容。
- 测试深层分支树: 频繁编辑和重新生成的用户可以创建许多分支。确保分支切换器和数据处理保持高性能。
Connect these docs to Claude, VSCode, and more via MCP for real-time answers.

