AI 博客

Langfuse、PromptLayer、Agenta 与 LaunchDarkly AI Configs:回滚只能快到缓存 TTL 那么快

四款工具都给提示词做不可变版本、都靠挪动一个指针来发布,于是看起来可以互换。其中三款让你的进程在请求时穿过一层 60 秒的客户端缓存去取提示词;另一款把规则集推流下来、在本地求值。仅此一个差别,就决定了你真实的回滚时间、也决定了服务不可达时会发生什么——而每一张功能表上都没有它。

作者 智能体 AI 维基 27 分钟读完

这四款工具给的是同一个承诺——给提示词做版本、靠挪动一个指针来发布、不发版就能回滚——而其中三款实现它的方式,是让你的进程在请求时通过网络去取提示词,背后那层客户端缓存的默认存活时间是 60 秒。这个数字没人会写在对比页上,而它恰恰决定了你那套「即时回滚」是否即时:你在控制台里挪动的标签,会在一个 TTL 之后才到达某个运行中的实例,而且是逐实例地到达;如果注册中心不可达、而你又从未写过兜底,它根本到不了任何地方。

一眼概览

四款在功能表上看起来可以互换的工具,按唯一一条真正改变你运行时行为的轴排序:请求被服务的那一刻,提示词在哪里。

工具形态发布动作请求时提示词在哪里
Langfuse 开源内核,云端或自托管,以追踪为先 把一个标签挪到某个不可变版本上 按标签取回,缓存在 SDK 里
PromptLayer 闭源,托管,以编辑器为先 挪动一个发布标签,可加审批关卡 按标签取回
Agenta 开源内核,外加一个单独授权的企业版目录,可自托管 把某个环境指向某个 commit 按环境取回
LaunchDarkly AI Configs 闭源,托管,出身于功能开关一脉 改一条定向规则 由推流下来的规则集在进程内求值
Four prompt-management tools against four operational properties A matrix with Langfuse, PromptLayer, Agenta and LaunchDarkly AI Configs as rows and four properties as columns: self-hostable core, where the prompt is at request time, the rollback mechanism, and what happens when the service is unreachable. Langfuse and Agenta have self-hostable cores, PromptLayer and LaunchDarkly do not; the first three fetch a version by label or commit while LaunchDarkly evaluates a streamed ruleset locally. Where they actually differ self-hostable core prompt at request time rollback mechanism service unreachable Langfuse Yes, OSS core Fetched by label Move the label Your own constant PromptLayer No, closed Fetched by label Label + approvals Your own constant Agenta Yes, OSS core Fetched by env Deployment history Your own constant LaunchDarkly No, closed Evaluated locally Targeting change Last ruleset held Strong Workable You build it Shading is an operational judgement, not a feature count: “strong” means the product does the work, “you build it” means your code does. All four version prompts immutably and deploy by moving a pointer; the fourth column is the one nobody demos. Tiers, licences and SDK behaviour move; verify against current documentation before a procurement decision.
第四列才是会把你从床上叫起来的那一列,而每一张功能表上都没有它,包括各家自己的。

真正要紧的那条轴是「取回」对「求值」

Two places a managed prompt can be at request time Two architectures side by side. In the registry-fetch model the running process asks a prompt registry for the version carrying a label, caches it locally for a time-to-live, and serves a stale copy while revalidating, so a label change reaches the process roughly one TTL later. In the local-evaluation model a ruleset is streamed to the process and evaluated in memory on every request, so a targeting change propagates on the open connection and an unreachable service leaves the last ruleset in place. Same promise, two propagation paths Registry fetch Prompt registry immutable versions; a label points to exactly one move label ‘production’ = deploy fetch by label SDK client cache default TTL 60s; stale copy served immediately while a background refresh runs ttl = 0 disables caching Running process a label change lands ~one TTL later, per instance registry unreachable: your own code is the fallback Local evaluation Config service variations plus targeting rules; rollback is a rule change targeting = deploy stream the ruleset In-process store whole ruleset held in memory; evaluated per request against the caller’s context no per-request network hop Running process a rule change lands on the open connection service unreachable: last ruleset stays in force Both call the operation “deploy without a release”. Only the left-hand path makes your rollback time a function of a cache setting, and only the right-hand path requires the whole decision to be expressible as rules the SDK can evaluate offline. SDK modes vary by language and by product tier; confirm whether yours streams, polls, or proxies before you quote a propagation time.
控制台里是同一个动作。生产环境里是不同的物理。

提示词注册中心是一个内容寻址的存储,外加一个可变的指针。你保存一条提示词,得到一个不可变版本,而一个标签——production、staging——恰好指向其中一个版本。挪动标签就是发布;把它挪回去就是回滚。这确实是个好模型,整套借自容器标签,而这里四款中有三款实现了它的某个变体。

功能开关系统把管道反转了。不是进程去要一个值,而是服务把一份规则集推流给 SDK,SDK 把它保存在内存里,并在每次请求时针对该调用方的上下文求值。提示词只是规则可以挑中的若干变体之一,而回滚是改一条规则、而不是改一个指针。请求路径上根本不取任何东西。

这两者在三个你会切身感受到的地方不同。传播:注册中心的变更要等缓存过期才到,而且各实例彼此独立,于是你的机群会短暂地同时跑着两条提示词;推流下来的规则则沿着 SDK 本来就持有的连接到达。可用性:注册中心不可达,意味着由你的代码决定会发生什么,而多数代码库决定的是崩掉;配置服务不可达,则让最后一份已知规则集继续生效,这是严格更好的默认。表达力:一个标签是一个全局指针,而一条定向规则可以在应用程序毫不知情的情况下,把不同的提示词交给不同的租户、人群或百分比。最后这一点,正是功能开关一脉在渐进式放量上胜出、而在简洁性上落败的原因。

在你把某个传播时间写进设计文档之前,有一条值得先说明的告诫:SDK 行为随语言与部署模式而异,有些是轮询或经中继,而不是推流。请去查你自己那一个,而不要从某篇博客里继承一个数字——包括这一篇。

四款工具,以及它们各自究竟是干什么用的

Langfuse——当追踪已经在那里时的默认选项

Langfuse 的提示词管理是四者中机制上最明确的一款,而它的文档对边界情况诚实得不同寻常。每次保存都会创建一个不可变版本;标签是指针,每个标签恰好指向一个版本;不带标签去取,返回的是带着 production 的那个版本。去要一个没有任何版本携带的标签,你会拿到 404——它不会悄悄回落到 production 或 latest,这是正确的选择,也是第一次有人删掉一个标签时会弄坏你 staging 环境的那个选择。

运维故事住在缓存里。各 SDK 在客户端缓存,默认 TTL 60 秒,并在后台重新校验的同时立即把过期的那份提示词发出去,所以你挪动一个标签之后,大约一个 TTL 它才会到达运行中的实例。TTL 可以按每次取回配置,设为 0 则在开发时关掉缓存。Langfuse 不可达时没有内建兜底:该项目自己的工作坊材料正是为这种情况在代码里留了一个本地常量,而那就是该照抄的模式。内核开源、可自托管,而某些能力——自托管部署上的审计日志就在其中——留给了企业版。

PromptLayer——当写提示词的人不是工程师时该选的那一款

PromptLayer 闭源、托管,它的注册中心是围绕「写提示词那个人手上没有 git 客户端」这件事建起来的。每次保存都得到一个带提交说明与 diff 的版本;像 staging 与 production 这样的发布标签决定什么上线;受保护的标签可以要求在标签挪动之前先走一道审批。更新一条生产系统提示词就是挪一个标签,而不是发一次版——这是它的卖点,也是该仔细想一想的地方,因为你刚刚给提示词的撰写权开了一条不经过代码评审的发布通路。

对一支在语气上反复打磨的支持内容团队,这笔交易是对的;对一条约束着工具调用型智能体的提示词,就是错的。各家资料在「审批流属于哪个档位」上说法不一,所以请去定价页确认,而不要从某篇对比文章里拿——包括这一篇。

Agenta——git 语义、自托管,给用分支思考的团队

Agenta 用工程师本来就在用的方式给提示词建模。变体是分支,各有自己的一串不可变 commit 历史;development、staging 与 production 是指向某个具体 commit 的部署目标,而每个目标都保留一份你可以沿着回滚的部署历史。最后这个细节是这次对比里最被低估的功能——「9 月 14 日生产环境跑在哪个 commit 上」这个问题,其他注册中心是靠推断回答的,而 Agenta 是靠查表回答的。内核以 MIT 授权,另有一个 ee/ 目录在单独授权之下,自托管免费。

如果你希望提示词历史长得像 git 历史,而且宁愿自己跑这个服务而不是租它,就选它。它的生态比 Langfuse 小,而这主要影响那些你原本没打算自己写的集成。

LaunchDarkly AI Configs——买来的、而不是自建的放量机器

AI Configs 已经作为「对提示词与模型的运行时控制」正式可用,而 LaunchDarkly 文档的一部分现在以 AgentControl 这个名字呈现它——所以搜索结果里两个名字都有。每个 config 持有一个或多个变体;默认就开启的定向规则决定某个给定上下文会收到哪个变体;你可以把一定比例的流量发给某个变体,并通过改定向、而不是重新部署,在几秒内退回基线。文档里举的例子恰恰是注册中心表达不出来的那些——把法国与比利时路由到一个法语变体、把 10% 的流量发给一条新提示词、用定向切到兜底行为。

你买到的是那套渐进交付装置:人群、百分比、即时退回,以及一条不经过你发布流水线的熔断通路。你没买到的是一个开源内核,也不是一套为提示词作者设计的撰写体验。如果你的组织已经在用 LaunchDarkly 管功能开关,这是四者中采纳成本最低的一款,因为 SDK、审计日志与值班的肌肉记忆都已经在那里了。

你能多快把一条坏提示词收回来

Three rollback paths for a bad prompt Three columns comparing how a bad prompt is withdrawn: moving a registry label, which reaches running instances after the client cache expires; changing a targeting rule, which reaches instances over the streamed connection; and redeploying code, which requires a build and release cycle. How fast you can take a bad prompt back Move a label Registry points ‘production’ at the previous immutable version Reaches instances after the client cache expires Change a rule Targeting serves the baseline variation to everyone again Reaches instances over the open connection Redeploy code The prompt was a string in the repository, so the fix is a release Reaches instances on your normal deploy clock The third column is the one everyone is leaving, and the one with the clearest audit trail.
三种机制,三个时钟。其中只有一个与某项缓存设置无关。

请把这件事当作你所选工具的验收测试,因为它正是让这笔采购成立的那个场景。一条提示词变更发了出去,质量掉了,而你想把先前的行为拿回来。用注册中心,你挪动标签,然后逐实例地等缓存过期,而在那个窗口里,你的机群正在把两条不同的提示词发给分辨不出差别的用户。用定向规则,变更沿着 SDK 本来就持有的连接传播。而把提示词焙进代码仓库里,你走的是自己的发布时钟,它更慢——而且这一点值得承认——它留下的审计轨迹好得多。

这个测试的后半段才是人们会跳过的:把服务拔掉。一套由注册中心支撑、却没有本地兜底的栈,会在一个多数团队从未计入可用性预算的依赖上 fail closed,而这次故障是在每个实例各自缓存刚过期时到达的、不是一起到达的,这让它在最初二十分钟里看起来像一个间歇性的模型问题。请在第一天就把那个兜底常量写好,并在 CI 里对它做断言,正如优雅降级与兜底对待请求路径上任何依赖那样。

而无论你走哪条路,提示词现在都是一份不经提交就会变的配置——所以这次变更必须出现在你的事故复盘能找到的某个地方。请把提示词版本连接到你记录的每一条追踪上,正如质量回归检测所要求的,否则复盘会上第一个问题就没有答案。

什么情况选哪个

情形选理由要留意
你已经在跑追踪,希望提示词就在它旁边 Langfuse 版本、追踪及两者之间的连接在同一个系统里;开源内核、可自托管 那 60 秒 TTL,以及必须你自己写的兜底
提示词文本由非工程师拥有 PromptLayer diff、提交说明与带审批关卡的标签,都是为那位读者建的 一条绕过代码评审的发布通路;请确认审批在哪个档位
你想要 git 语义,并且自己托管 Agenta 分支加提交的模型,外加一份可查询的按环境部署历史 生态较小;请查清哪些功能在那份单独授权之下
你需要人群、百分比与即时退回 LaunchDarkly AI Configs 对推流规则集做本地求值;回滚是改定向,不是去取回 闭源;文档里有两个产品名;提示词撰写不是它的强项

如果上面哪一条都不是你——一条提示词、一个服务、两个工程师——那就把提示词留在代码仓库里。一个在版本控制里的字符串,有你已经理解的传播时间、你已经拥有的审计轨迹,和你已经信任的评审环节。上面这些工具挣到自己位置的时候,是提示词变更的频率超过发版的频率时,或者需要由发布者之外的人来做这些变更时。

常见问题

提示词注册中心不就是多绕几步的功能开关吗?

接近,而其间的差别正是要点。注册中心存的是不可变内容、挪的是一个指针;开关系统存的是变体,并在每次请求时针对调用方上下文对规则求值。注册中心给你更好的来源可追溯性,开关系统给你人群划分与更快的退回。

用 Langfuse 时真实的回滚时间是多少?

在你挪动标签之后,大约是每实例一个缓存 TTL,默认 60 秒且可按每次取回配置;设为零可以消掉这段延迟,代价是给每次请求加一次网络调用。那套「过期仍先发、后台再校验」的行为意味着刷新期间发出去的是旧提示词,而不是让某个请求卡在那里等。

用了这些之后,代码里还需要留一条提示词吗?

对那三款基于取回的工具,需要——一个本地常量是「注册中心不可达」与「请求路径失败」之间唯一的那道屏障,而各家自己的教学材料用的正是这个模式。换成本地求值,最后一份已知规则集会继续生效,于是这个必要性弱一些,但启动时那个情形依然存在。

哪一款把评测放进了发布通路里?

四款都可以接上去;没有哪一款把它做成默认。把「挪动标签」卡在一次评测运行之后,是你 CI 的活儿,而它是你在所选工具之上能建的、价值最高的那一件事——形状请见评测驱动开发。

把提示词搬出代码仓库会破坏可复现性吗?

除非版本标识被记在每一条追踪上,否则会破坏。一旦一条提示词能不经提交就改变,提交就不再描述这个系统,而回答「到底跑了什么」的唯一办法,就是你随输出一起记下来的那个版本。

延伸阅读

本站相关:

项目来源: