1. 为什么 App 需要闭环改进
任何 LLM‑App 都生活在变化世界中。你会迎来新用户和新场景,OpenAI 会发布新模型与安全机制,你自己也会更新 MCP 服务器、Agents SDK、UI 小部件……即便所有代码都写得近乎完美(是的,我知道你几乎就是这样做的),一次模型或 prompt 的变更也可能悄悄破坏一半用例。
没有改进闭环时,日常大概是这样的:用户给支持写信:“GiftGenius 开始推荐超预算的礼物”或“要思考 15 秒才回复”。你打开日志,在 system‑prompt 里改点什么,切个模型,上线发布。一周后,同样的问题在别处重演。结果就是长期救火和一堆“魔法”改动,没人能解释清楚。
有了闭环就不同了。你会有:
- 一套清晰的信号集合,覆盖技术、资金、产品与质量;
- 一个定期的仪式:查看这些信号并选择要验证的假设;
- 可控的 code/config 变更;
- 自动化校验:黄金用例 + LLM‑evals + 实验。
于是 App 从“冻结的 prompt”变成一个活的系统,它:
- 能指明哪里在疼,以及原因;
- 能提示具体可以改进什么;
- 能在“看似无害”的 prompt 变更后防止悄然劣化。
额外的好处:这个闭环与前面模块已经构建的内容非常契合。来自 M17 的日志与 SLO 提供技术信号,来自 M19 的成本仪表化与 AARRR 提供经济与产品信号,来自 M20.1–2 的黄金用例与 LLM‑evals 提供质量信号。剩下的就是把它们串成一个清晰的运营闭环。
2. 改进信号地图
要让 App 自己提示该如何改进,你需要清楚地知道你到底拥有哪些信号以及它们从何而来。用四类来思考会更方便。
技术信号来自你的可观测性栈:日志 tool_invocation、latency 与 error‑rate 指标、MCP/ACP 的健康检查、OAuth 失败。它们回答“服务是否活着,以及有多稳定”。
经济信号来自成本仪表化与计费:cost_per_tool_call、cost_per_task、cost_per_user,以及特定工具或场景上的成本异常飙升。它们在说:“我们烧的 token 和钱超出预期”或相反,“还有余量,可以提升质量”。
产品信号由事件组成,比如 app_opened、workflow_started、workflow_completed、checkout_*。包括激活率、各漏斗步骤之间的转化、按队列的留存。它们展示真实用户行为的变化。
质量/行为信号包括基于黄金用例的 LLM‑evals 结果(correctness/helpfulness/style/safety 得分)、抽样的人工对话评审、点赞/点踩、以及商店里的投诉和评论。这最接近“App 变聪明/变笨”的直观感受。
可以把这些汇总成表格:
| 信号类型 | 示例 | 数据来源 |
|---|---|---|
| 技术 | error-rate、p95 latency、MCP/ACP timeouts | 日志/指标 (M17) |
| 经济 | cost_per_tool_call、cost_per_task、cost_per_user | 成本仪表化 (M19.1) |
| 产品 | activation、转化、留存 | 产品事件 (M19.3) |
| 质量/行为 | LLM-eval score、safety 标记、反馈 | 黄金用例 + LLM‑evals + 评论 (M20) |
关键点:所有这些信号都要按具体场景与 App 版本记录日志。也就是说,事件里至少包含 scenario、appVersion 和 experimentId。这样当你看到黄金用例上的 helpfulness 从 8.5 降到 6.2 时,不只是说“变差了”,还能说“在场景 "gift_selection" 上,于版本 "1.3.0" 的实验变体 "B" 后变差了”。
在代码里你甚至可以定义一个简单的结构体来描述信号:
// lib/improvement/signals.ts
export type SignalKind = "slo" | "cost" | "product" | "quality";
export type ImprovementSignal = {
kind: SignalKind;
scenario: string; // e.g. "gift_selection"
metric: string; // e.g. "p95_latency_ms", "cost_per_task"
value: number;
previous?: number; // 之前的值
};
这样的对象既适合做仪表盘的数据源,也方便喂给你未来的改进助手。
3. 规范的反馈闭环:4 步
现在把一个可以反复依赖的规范改进循环搭起来。它非常落地:四个步骤。
flowchart TD A[信号:发现问题
或看到增长机会] --> B[假设:
要改什么、如何改] B --> C[可控的变更
在 code/config 中] C --> D[验证:
offline + online] D --> A
第 1 步:发现问题或机会
这一阶段你回答“往哪看”。例如:
- 带预算的黄金用例上的 LLM‑eval 显示 helpfulness 下降。
- 工具 p95 latency "suggest_gifts" 从 1.2 秒涨到 3.8 秒。
- 场景 cost_per_task "gift_selection" 在切换到 reasoning 模型后上涨了 40%。
- workflow_completed → checkout_success 的转化在修改 UX 向导后下滑了 5 个百分点。
- 一周内 Store 出现了 10 条“礼物超出预算”的投诉。
一个重要细节:有时信号并非在说“变差”,而是在说“还能更好”。比如,你看到 cost_per_task 明显低于允许阈值,而 quality‑score 已经 9/10。那么可以尝试更贵的模型或更“聪明”的流程——也许转化会提升。
第 2 步:提出假设
假设不是“我们重写 prompt”,而是“我们认为在组件 Y 中做出具体变更 X 能改善指标 Z,因为……”。没有“因为”的就不是假设,只是愿望。
例如:
- “如果我们在 system‑prompt 里加入严格遵守预算的规则,并要求总是解释预算如何被使用,那么在带预算用例上的 helpfulness 至少会提高 2 分。”
- “如果我们在 rerank 步替换为更便宜的模型 "gpt-mini",cost_per_task 将下降 30% ,而转化不会下滑超过 1 个百分点。”
- “如果我们简化向导(把两步合并为一步)并重写 CTA,activation‑rate 将提升 5 个百分点。”
在代码里可以把假设显式描述出来,至少是一个对象:
// lib/improvement/hypothesis.ts
export type ImprovementHypothesis = {
id: string;
scenario: string;
description: string; // 改什么以及为什么
targetMetric: string; // 例如 "quality.helpfulness" 或 "conversion.checkout"
successCriteria: string;
};
是的,这几乎就是一张 Jira 工单,但至少它是类型化的。
第 3 步:实施可控的变更
这里有两个关键词:可控与分离。
“可控”意味着变更以 PR/commit 的形式提交,关联到某个假设,带 changelog,并尽量有 feature flag 或版本号。不是在生产上“顺手改了 prompt”,而是能清楚地说出是哪一版带来的变更。
“分离”意味着不要在一个发布里混入三个不同的假设。如果你同时:
- 更换模型,
- 重写一半的 system‑prompt,
- 并在 UX 中加入新步骤,
那么即使指标改善,也很难知道到底是哪项起作用。更稳妥的方式是小步快跑。
从技术上看,变更可能发生在任何地方:
- 代理的 system‑prompt(lib/prompt/systemPrompt.ts);
- MCP tools 的描述(description、inputSchema、annotations);
- 代理配置(reasoning 步数上限、为特定 tool 选择模型);
- 小部件代码(CTA、步骤顺序、错误文案)。
第 4 步:验证是否变好了
验证分为离线与在线。
离线验证是把黄金用例在新版本 App 上跑一遍,不涉及真实用户。你已经有:
- LLM‑evals(模块 20.1);
- 阈值/基线逻辑(模块 20.2)。
查看目标场景上的 quality‑score 如何变化:升、高、持平。同时检查 safety 用例:任何 prompt 改动都应先通过 safety 集合。
在线验证是在真实流量上的实验。最简单的做法是把新版本放给 N% 的用户,并比较:
- 目标动作的转化(checkout、重复启动场景);
- cost_per_task;
- 投诉/反馈。
之后要么闭环结束(假设被证实/证伪并已记录),要么触发新的假设。
4. 把“改进助手”作为一个独立的内部代理
现在到最有趣的部分:让 LLM 模型再多一个角色——不仅服务用户,还要帮助你改进 App。这是一个内用代理,与用户侧的 GiftGenius 分离。
它是什么
这个助手运行在你的内部环境(同一仓库、Dev Mode、独立的 ChatGPT App)中。它会:
- 读取日志与对话样本;
- 查看各类指标;
- 分析 system‑prompt 与 tools 描述;
- 帮助提出问题陈述与变更建议。
本质上,你得到一个“虚拟的产品/分析师”,它:
- 不会厌倦读对话;
- 能快速发现重复模式;
- 会写 prompt 草稿与 changelog。
它接收什么输入
把输入格式化会更有帮助。例如,定义如下类型:
// lib/improvement/assistant.ts
export type BadDialogExample = {
id: string;
userMessages: string[];
appMessages: string[];
qualityScore?: number;
};
export type ImprovementInput = {
scenario: string;
signals: ImprovementSignal[]; // 来自上一节
examples: BadDialogExample[];
systemPrompt: string;
toolsDescription: string;
};
你可以从日志里导出 10–20 个在场景 "gift_selection" 下失败的对话,再附上当前的 system‑prompt 与工具描述,组装成这样的对象。
它应该产出什么
同样把期望的输出固定下来:
export type ImprovementSuggestion = {
patterns: string[]; // 重复出现的问题
promptPatches: string[]; // system-prompt 的片段建议
toolsPatches: string[]; // 对 tools 描述的改进点
uxCopyIdeas: string[]; // UX 文案备选
changelog: string[]; // 简短的“要改什么”清单
};
这个代理的 meta‑prompt 大致是:
- “分析这些示例与信号”;
- “描述 2–3 个问题模式”;
- “分别在 prompt、tools 描述与 UX 文案上提出 1–2 条修改建议”;
- “以严格定义的 JSON 返回”。
之后你再手动拿这些片段,与团队讨论,落到代码里,并通过 eval 与实验来验证。重要原则:这个助手绝不直接改生产。它产出的是想法与文本,而不是 commit。
5. 可“调”的改进类型
当你有了这样的助手与闭环,很容易把一切都简化成“给我一版新的 system‑prompt”。实际上,可改进的空间要宽得多。
Prompt 与指令
System‑prompt 设定角色、语气、优先级与硬性规则(例如预算、安全、步骤顺序)。它可以被:
- 简化,移除互相矛盾或重复的指令;
- 增强,补足缺失的规则(如预算的例子);
- 按不同场景适配(为 "gift_selection"、"post_purchase_help" 等提供子 prompt)。
Tools 的描述帮助模型理解何时调用某个工具以及它的职能。常见的改进包括:
- 更明确的 “Use this when … / Do not use when …”;
- 措辞更清晰(减少与其他 tools 的重叠);
- 补充后果信息(destructiveHint、isConsequential)。
Safety 规则是 prompt/描述中的一部分,决定在复杂领域下的行为。只有在做好充分的 safety‑eval 之后再动它们。
行为架构(behavior)
有时问题不是改 prompt 就能解决的:需要改变动作顺序。
例如:
- 在调用昂贵 tool 前增加必答的参数澄清步骤;
- 把部分计算拆到单独、成本更低的步骤中(如在后端做预过滤);
- 限制某个场景中连续 tool 调用的次数。
这类变更通常写在代理配置或 MCP 层,而不只是 prompt。
UX 与文案
没错,按钮与错误提示的文案也是质量的一部分。GiftGenius 如果写:
“错误 500。请联系管理员”,
给人的感觉与下面这种完全不同:
“未能从商店获得响应。你已选择的创意不会丢失,请稍后再尝试下单。”
过渡页面、提示、向导结构——都会影响你所度量的激活率与转化。
经济
这里我们玩的是熟悉的“质量 ↔ 成本”博弈:
- 模型选择(带 reasoning 的高价模型 vs 快/便宜的模型);
- reasoning/代理步骤的深度(允许多少次迭代);
- 对话上限(例如单次会话不超过 N 次重算);
- 在 token/限额预算耗尽时的低成本 fallback 模式。
这里的信号会进入 cost_per_task、cost_per_user、毛利,并与 quality‑score 综合分析。
6. 护栏:哪些不能交给 LLM
当系统里出现“改进助手”和顺手的闭环时,人很容易想按下“自动优化”按钮然后去喝咖啡。我们先约法三章,哪些地方不允许这颗按钮存在。
权限变更(OAuth scopes、MCP 工具、数据访问)属于有人在环的区域。任何模型都不该自行决定让 App 现在可以读订单、触碰支付或给用户发邮件。交易流程同理:围绕 ACP/Stripe、限额、支付类型与退款的任何变更,都必须经过人工评审与测试。
App 的 safety 范围(哪些领域可以建议、哪些必须拒绝)也不适合交给 LLM。模型可以帮助起草规则文本,但你最终决定信任 App 于哪些主题。
数据与日志策略(记录什么、保存多久、如何响应数据删除请求)也在此列。LLM 可以建议 Privacy Policy 的结构,但不该在没有你参与的情况下更改代码里的留存策略。
哪些可以半自动化?Prompt 文案、tools 描述与 UX 文案的措辞,工具优先级(在合理范围内),附加的澄清问题。这些都可以把助手当作灵感来源,但最终决策与校验必须由人和 eval 脚本完成。
7. 端到端改进闭环示例(GiftGenius)
回到我们的主角。
问题
用户给出预算后,GiftGenius 仍常推荐超出该上限的礼物。日志里能看到大量对话续写为“太贵了”“再便宜点”。
信号
首先是质量:在“预算不超过 50$”的黄金用例上,LLM‑eval 的 helpfulness 约为 6/10。裁判经常在 reason 中写“礼物超出预算”或“没有解释预算如何被考虑”。
同时还会有产品与经济信号:
- 在设定上限的场景里,checkout_success 的转化低于无上限的场景;
- 部分用户在看到太贵的选项后放弃流程;
- 这类场景下的 cost_per_task 更高,因为 App 会多次按“便宜点”的要求重算礼物。
用改进助手分析
你收集 20 个用户抱怨价格的对话,构造 ImprovementInput:
- scenario = "gift_selection_with_budget";
- 包含 helpfulness 与转化下滑的 signals;
- 带有对话的 examples;
- 当前的 system‑prompt 与工具描述。
把它喂给内部改进助手。返回的结果可能是:
- 问题模式:
- 像“差不多 50$ 以内”这样的预算表达被理解得太宽松;
- system‑prompt 没有明确要求“绝不推荐超出上限的礼物”;
- 回答没有向用户解释预算是如何被考虑的。
- 建议:
- 在 system‑prompt 中加入严格遵守上限的指令;
- 要求模型总是明确说明“所有选项 ≤ X”;
- 当预算表述模糊(“差不多”“大约”)时,补一个澄清问题。
假设与变更
提出假设:
“如果我们明确要求严格遵守预算,并让模型解释预算的使用方式,那么在带预算用例上的 helpfulness 至少会升到 8/10,购买转化将提升 3 个百分点。”
在 system‑prompt 中加入如下片段:
export const budgetRule = `
如果用户指定了预算(例如 "不超过 50$" 或 "大约 30€"),
将该金额视为严格的上限。
绝不要推荐超过该上限的选项。
在每次回答中明确说明所有选项都在预算内,
以及是如何满足预算的(例如:"所有礼物都不超过 45$")。
`.trim();
并把 budgetRule 合入 GiftGenius 的总 system‑prompt。
离线校验
用新版本跑“带预算的礼物”黄金用例集合:
- LLM‑eval 的 helpfulness 从 6.0 升到 8.5;
- correctness 也上升:预算得到遵守;
- safety 至少没有变差。
如果相反——helpfulness 没提升或 safety 下降——则变更不通过,重新审视假设。
在线测试
接着启动实验:
- 10% 的用户获得新 prompt(variant B);
- 其余 90% 使用旧版(variant A)。
一周后查看:
- B 组的 workflow_completed → checkout_success 转化为 13%,而 A 组为 10%;
- cost_per_task 几乎不变;
- “太贵了”的对话占比下降。
实验被认定为成功。
固化
之后:
- 把新 prompt 覆盖到 100% 流量;
- 把新的“模糊预算至 50$”黄金用例加入回归集合;
- 在 changelog 以及可能的技术笔记里记录结果:以便半年后仍能看懂为什么 prompt 里有这段严格的预算表述。
闭环结束。下一轮可以针对例如“极小众兴趣的推荐”或“进一步优化成本”展开。
8. 自我改进型 App 的迷你路线图
为避免看起来像“又多出 100500 个任务”,不妨明确:最低门槛是什么,才能把 App 视为自我改进型;以及之后还能加什么。
版本 1.0:最小改进闭环
第一步只需三件事。
其一,结构化日志与基础 SLO。你已经会记录 tool_invocation、workflow_completed、checkout_*,并带上 requestId、userId、scenario、appVersion、costEstimateUsd。在此之上构建 SLO:latency、error‑rate、checkout 成功。
其二,10–20 个黄金用例和一个 LLM‑eval 脚本。体量不大但精挑细选,覆盖关键场景 + safety 用例。一个 CLI 脚本,把它们跑过 App 与裁判并输出 JSON 评估。
其三,每两周一次的小仪式。坐下(个人或团队),打开:
- 2–3 个关于 SLO、成本、产品指标的仪表盘;
- 黄金用例的 LLM‑eval 报告;
并选出1–2 个假设用于下一轮。写清楚、记录下来、做一个小发布、再验证。
版本 2.0:“智能”改进闭环
下一层级包括:
内部改进助手。把它定义成一个独立代理(或 ChatGPT App),接收 ImprovementInput,返回 ImprovementSuggestion。它能帮你节省成小时的手工对话排查。
自动化报告。基于日志与 eval,可以生成:
- 问题用例的聚类(例如所有用户反复改预算的场景);
- 可直接使用的 prompt/工具描述改动草稿;
- 简短的 changelog。
CI hooks。任何 prompt、代理配置、工具描述的改动会自动触发:
- 功能性黄金用例套件;
- safety 用例套件。
若 safety 用例失败或关键场景的质量过不了阈值——构建红灯,不予发布。
9. 实践
练习 1:为你的 App 搭一个迷你反馈闭环
选取你应用的一个关键场景。对于 GiftGenius,我们选的是“挑选并购买礼物”;你可以选类似或自己的场景。
用自由格式描述(或建一个小文件 improvement-plan.md):
你将跟踪哪些信号。各取一个:
- 技术:例如主力工具的 p95 latency;
- 经济:该场景的 cost_per_task;
- 产品:workflow_started → workflow_completed 或到目标动作的转化;
- 质量:该场景几个黄金用例的平均 quality_score。
然后固定下来,哪些阈值你视为退化。不是“改天再看”,而是非常明确:
- p95 > 5 秒——不好;
- cost_per_task 在收入不增的情况下上涨超过 30%——告警;
- quality_score 低于 7——需要排查。
并提出第一个假设。例如:
“我怀疑我们问了太多澄清问题。如果把向导减少一步并把问题稍微泛化一些,activation‑rate 会提升,而 helpfulness 几乎不受影响。我将通过一次小的 UX 变更和 A/B 实验来验证。”
这已经不再是“改进 UX”这样的空话,而是闭环中的一个具体动作。
练习 2:为改进助手写一个 Meta‑prompt
尝试为你的内部改进代理写一段 prompt。可以从简单开始:
- 描述它是谁:“你是 App N 的质量分析师,你……”。
- 列出它接收的输入:对话、信号、system‑prompt、descriptions。
- 明确任务:
- 找出 2–3 个问题模式;
- 在 prompt、tools、UX 文案上各提出 1–2 条建议;
- 整理一个简短的 changelog。
- 描述输出格式:带有 patterns、suggestions、changelog 字段的结构化 JSON。
即便你暂时不会在代码里调用这个代理,这样一段 prompt 也会帮助你更好地结构化对“如何改进 App”的思考。
10. 构建改进闭环的常见错误
错误 №1:只优化一个指标。
只盯着一件事很诱人。你可以只追求 cost,看到 OpenAI 账单下降而开心——却没注意到 quality‑score、转化与留存都在下滑。也可以反过来,把质量拧到 10/10(用 reasoning 模型)却忽略每个场景的成本涨到 1 美元。改进闭环要关注一组指标:质量 ↔ 金钱 ↔ 用户行为。
错误 №2:没有度量支撑的“魔法” prompt 改动。
一句“我重写了 system‑prompt,现在应该更好了”,但没有黄金用例与 eval——这就是几周后给自己挖个惊喜。任何 prompt 改动——尤其在生产上——都必须经过清晰的流程:用例集、前后对比的 LLM‑eval、必要时再做在线实验。否则你不是在改进 App,而是在随机散布质量。
错误 №3:让 LLM 助手自动部署变更。
即便改进助手写出了惊艳的 prompt 片段与令人信服的工具描述,也绝不意味着可以不经评审就推到生产。模型看不到所有业务约束、safety 风险与指标上下文。它的角色是顾问,而不是有发布权限的 DevOps。
错误 №4:变更与假设/信号脱钩。
有时团队按感觉改了东西,却没有记录是哪条信号引发的改动、要验证的假设是什么。一个月后没人记得为什么 prompt 里多了个奇怪段落、它到底有何用。一个好的质量 PR 至少要回答三个问题:“哪里在痛?”“我们改什么?”“用哪个指标判断变好了?”
错误 №5:改进时忘了 safety。
在追求有用性的过程中,很容易放松 safety 限制,删掉 prompt 里“多余的拒绝”,或忘了跑 safety 用例。任何 system‑prompt、tools 描述与代理行为的变更,都要先跑 safety 用例。如果曾经通过的用例现在失败——那就是红灯,无论其他指标多漂亮。
错误 №6:想“立刻优化一切”。
在一个发布里重写半个 prompt、换模型、再加一个 MCP tool 与新向导——听起来很高效,却让你完全无法知道哪项变更带来了效果。改进闭环只有在迭代且聚焦时才有效:一到两个假设、一小组变更、清晰的回滚计划。
错误 №7:把改进闭环变成罕见的“大扫除日”。
如果你每半年搞一次“质量日”,而其余时间没有 eval 与指标分析,App 大多数时候都会“随波逐流”。更加有益的是小而稳定的节奏:每周/双周查看信号、更新假设、做小步改动。这样你的 ChatGPT App 才能不再静态,真的开始自我改进。
GO TO FULL VERSION