LangSmith回滚实战:三种机制灵活应对版本危机——ai agent开发实战
摘要:LangSmith提供了三种回滚机制:1)重新Promote旧commit到目标环境(最常用);2)移动环境标签到旧commit;3)代码中直接指定旧commit hash。对于LangGraph/Agent Server用户,还支持通过Time Travel从历史检查点重新执行。最佳实践建议使用标签而非hash引用,重大变更前创建快照标签,并推荐结合离线评测验证回滚效果。所有commit历
·
在 LangSmith 里,"回滚"不是一键按钮,而是通过三种机制组合实现:
- 把更早的 commit 重新 Promote 到目标环境(最常用)
- 把环境标签(tag)移回 旧的 commit
- 在代码里直接 指定旧 commit hash 拉取
另外,如果你是在 LangGraph Studio / Agent Server 里做"运行时回滚",还可以用 Time Travel(检查点分叉)。
下面逐一讲清楚。
一、最常用的方式:重新 Promote 一个旧 commit
场景
你在 Production 上跑了 commit
abc123,今天又 Promote 了def456,发现线上效果变差,想回到abc123。
步骤(全部在 UI 完成)
- 打开该 Prompt 的详情页(左侧 Prompts → 点击目标 Prompt)。
- 左侧会看到完整的 commit 历史,以及 Staging / Production 两个环境。
- 找到你想回滚到的那个旧 commit(比如
abc123),悬停 → 点击 Promote。 - 在弹窗中选择目标环境(例如 Production),确认。
这样 Production 的标签就指向了旧的
abc123,等效于"回滚"。def456仍然保留在 commit 历史里,不会丢失。
要点
- 回滚本身 = 把某个旧 commit 重新 Promote 到目标环境。
- 不影响 Staging;如果 Staging 也在新版本上,可以单独再 Promote 旧版到 Staging。
- 可以随时在任意两个环境之间来回 Promote,没有"只能向前"的限制。
二、用标签(Tag)回滚:把 Tag 移回旧 commit
场景
你不用 Staging/Production 预置环境,而是自己打了
v1.0、v2.0等标签;现在想把v2.0移回旧的 commit。
步骤
- 打开 Prompt 详情页,在 commit 列表中找到旧 commit。
- 悬停 → 选择 “Add tag” 或 “Move tag”(如果标签已存在于另一个 commit 上)。
- 选择要移动的标签(例如
v2.0),确认。
之后代码里
client.pull_prompt("my-prompt:v2.0")拿到的就是旧版本。
与 Promote 的区别
| Promote | 移动 Tag | |
|---|---|---|
| 操作对象 | Staging / Production 预置标签 | 任意自定义标签 |
| 谁能用 | 需要 Owner/编辑权限 | 需要 Owner/编辑权限 |
| 典型用途 | 环境级别的发布/回滚 | 自定义版本号管理 |
三、在代码里直接指定旧 commit hash(最灵活)
场景
不想改 UI 上的环境/标签配置,临时在代码里回退到已知的好版本。
做法
from langsmith import Client
client = Client()
# 正常:用 tag 拉取(跟环境/标签绑定)
prompt = client.pull_prompt("joke-generator:production")
# 回滚:直接指定某个 commit hash
prompt = client.pull_prompt("joke-generator:abc12345")
# 回滚到 staging
prompt = client.pull_prompt("joke-generator:staging")
适用情况:
- 紧急回滚,来不及改 UI。
- A/B 测试:不同请求拉不同 commit。
- 调试:对比两个 commit 的效果。
四、LangGraph Studio / Agent Server 里的"运行时回滚"(Time Travel)
如果你用的是 LangGraph + Agent Server,回滚还有一个维度:从某个历史检查点重新执行。
1) 在 Studio 中 Time Travel
- 打开一个 Thread(对话线程),右侧可以看到完整的 状态时间线。
- 点击任意一个历史检查点(状态快照),可以:
- Fork:从该点分叉出新线程继续执行。
- Re-run:从该点重新执行后续节点。
- 这等效于"回滚到某个中间状态再重新走一遍"。
2) 在 SDK 中用检查点回滚
from langgraph_sdk import get_client
client = get_client(url="http://localhost:8123")
# 获取某个 thread 的历史状态
history = await client.threads.get_history(thread_id="xxx")
# 拿到某个旧状态的 checkpoint_id
old_checkpoint = history[5].checkpoint_id
# 从该检查点重新执行(或 fork 一个新线程)
await client.runs.create(
thread_id="xxx",
assistant_id="my-agent",
input={"messages": [{"role": "user", "content": "继续"}]},
checkpoint_id=old_checkpoint, # 从这个检查点开始
)
与 Prompt 回滚的关系
| 回滚维度 | 回滚对象 | 粒度 |
|---|---|---|
| Prompt 回滚(上面三种) | Prompt 模板内容 | 整个 Prompt 的版本 |
| Time Travel | Agent 运行状态 | 某次执行的某个节点 |
| 两者可以组合:先 Prompt 回滚到旧版模板,再对受影响的 Thread 做 Time Travel 重新执行。 |
五、最佳实践:建议的回滚流程
┌──────────────────────────────────────────────────┐
│ Prompt 发布流程 │
│ │
│ Playground 编辑 ──保存──> commit_1 │
│ │ │
│ ├── Promote commit_1 ──> Staging │
│ │ │ │
│ │ 测试通过? │
│ │ │ │
│ │ 是 ├── Promote commit_1 ──> Production│
│ │ │ │
│ │ 否 └── 继续编辑 ──保存──> commit_2 │
│ │ │ │
│ │ └── Promote commit_2 ──> │
│ │ Staging(覆盖) │
│ │ │
│ ─── 线上发现异常,需要回滚 ────┐ │
│ │ │
│ 方式1: Promote commit_1 ──> Production(覆盖) │
│ 方式2: 把 production tag 移回 commit_1 │
│ 方式3: 代码里临时指定 commit_1 的 hash │
└──────────────────────────────────────────────────┘
几个关键建议:
- 每个 commit 都有唯一 hash,永远不会丢——即使你 Promote 了新版本,旧版本随时可以再 Promote 回来。
- 用 tag 而不是 hash 做代码引用——代码里写
"my-prompt:production"而不是"my-prompt:abc123",回滚时只需改 tag 指向,不需要改代码。 - 重大变更前先打一个自定义 tag 做快照(比如
v1.0-golden),方便随时回退。 - 回滚后记得跑一次 Eval——用 LangSmith 的离线评测对比新旧版本,确认回滚确实修复了问题。
更多推荐



所有评论(0)