Day 30:Prompt 管理系统
学习目标
昨天我们学习了 AI 应用的整体工程架构,其中提到了 Prompt 管理层——它负责把 Prompt 当成可管理、可版本化、可测试的资产来对待。今天我们要深入这个模块,把它从概念变成可以落地的系统设计。
一个行业分析系统可能有几十个 Prompt:行业概览 Prompt、岗位拆解 Prompt、流程拆解 Prompt、AI 机会评分 Prompt、风险审查 Prompt、报告生成 Prompt。每个 Prompt 会经历无数次修改和迭代。如果没有管理系统,你会陷入”不知道用的是哪个版本""不知道为什么改了之后效果变差了""不知道该不该回滚”的混乱状态。
今天的目标是设计并实现一个 Prompt 管理系统。具体来说:理解 Prompt 版本管理的必要性、设计 Prompt 的元数据结构、建立 Prompt 测试集和评分机制、实现 Prompt 的变更记录和回滚功能。学完这一天,你应该能管理 20 个以上的 Prompt,每个都有清晰的版本、测试结果和迭代历史。
核心概念
Prompt 版本
什么是 Prompt 版本?简单说,每次修改 Prompt 的内容,就产生一个新版本。
为什么需要版本管理?三个场景你一定遇到过。
第一个场景:改了 Prompt 之后效果变差了,想回退到之前的版本,但之前的版本没保存,你只能凭记忆重新写一遍,写出来的跟原来的还不一样。
第二个场景:团队协作时,你改了 Prompt A,同事改了 Prompt B,两人改完之后发现系统的整体效果变了,但不知道是哪个改动导致的。如果每个 Prompt 都有版本记录,你可以分别测试两个版本,快速定位问题。
第三个场景:客户反馈”上周的结果比这周好”,你上周改了 Prompt,但不确定是不是 Prompt 的问题。如果有版本历史,你可以查看上周用的是什么版本、本周用的是什么版本,然后做对比测试。
版本号的设计推荐用”主版本.次版本”的格式。主版本表示 Prompt 的重大改版(比如换了完全不同的指令结构),次版本表示小调整(比如改了一句话的措辞)。比如 v1.0 是初始版本,v1.1 是微调措辞,v2.0 是全新改版。
每个版本需要记录的信息包括:版本号、Prompt 内容、修改时间、修改人、修改原因(为什么改)、关联的测试结果(改完之后跑了什么测试、结果怎么样)。
修改原因这一条很多人会忽略,但它非常重要。三个月后你翻看版本历史,看到 v1.5 跟 v1.4 的差异是一句话的措辞变化,但不记得为什么要改这一句话。如果你当时记录了”客户反馈行业概览缺少竞争分析部分,所以加了’请包含竞争格局分析’这句话”,三个月后你就知道这个改动的来龙去脉了。
Prompt ID
每个 Prompt 需要一个唯一标识符,方便在代码里引用。
Prompt ID 的命名建议用”模块.功能”的格式。比如:
- industry.overview:行业概览 Prompt
- industry.competitors:竞争分析 Prompt
- role.breakdown:岗位拆解 Prompt
- process.analysis:流程分析 Prompt
- ai_opportunity.scoring:AI 机会评分 Prompt
- risk.review:风险审查 Prompt
- report.generation:报告生成 Prompt
- report.summary:报告摘要 Prompt
这种命名方式的好处是:看到 ID 就知道这个 Prompt 用在什么地方;同模块的 Prompt 排列在一起方便管理;新加 Prompt 时命名有规律可循。
一个系统里的 Prompt ID 一旦确定就不要再改。因为代码里到处都在引用这个 ID。改 ID 意味着全项目搜索替换,既麻烦又容易遗漏。
Prompt ID 跟版本号组合起来就是 Prompt 的完整标识。比如”industry.overview v2.1”就唯一确定了一个 Prompt 的特定版本。
Prompt 输入 Schema
每个 Prompt 模板都需要定义它的输入参数。这就像函数需要定义参数列表一样。
输入 Schema 要回答的问题是:这个 Prompt 需要哪些参数?每个参数的类型是什么?哪些是必填的?哪些是可选的?默认值是什么?
拿”行业概览”Prompt 举例。它的输入参数可能包括:行业名称(必填,字符串)、关注维度(可选,字符串数组,默认为空表示全部维度)、分析深度(可选,枚举值:简要/标准/详细,默认为标准)、目标受众(可选,字符串,比如”给老板看的”或”给工程师看的”)。
定义输入 Schema 的意义在于三方面。
第一,防止调用错误。如果输入 Schema 明确要求”行业名称”是必填参数,那么调用时忘了传行业名称,系统应该立即报错,而不是用一个空字符串去调模型,得到一个毫无意义的结果。
第二,支持自动校验。根据 Schema 可以自动校验输入数据的类型和范围。比如”分析深度”只能是”简要/标准/详细”三个值之一,传了”随便”就应该被拒绝。
第三,便于生成文档。有了输入 Schema,可以自动生成 Prompt 的使用文档:需要什么参数、每个参数的类型和含义、哪些必填哪些可选。新团队成员看文档就知道怎么用这个 Prompt。
输入 Schema 推荐用 JSON Schema 格式定义。JSON Schema 是一个标准化的格式描述规范,大多数编程语言都有对应的校验库。
Prompt 输出 Schema
跟输入 Schema 对应,每个 Prompt 也需要定义它的输出格式。
输出 Schema 要回答的问题是:这个 Prompt 期望模型返回什么结构?包含哪些字段?每个字段的类型和含义是什么?哪些字段可能缺失?缺失时怎么处理?
拿”行业概览”Prompt 举例。它的输出 Schema 可能包括:行业名称(字符串)、产业链结构(对象数组,每个对象包含环节名称和描述)、主要企业(对象数组,每个对象包含企业名称和简介)、市场规模(对象,包含当前规模和增长率)、技术趋势(字符串数组)、发展挑战(字符串数组)。
输出 Schema 的作用比输入 Schema 更大,因为输出的结构直接决定了下游系统能不能正确处理。
如果一个 Prompt 的输出格式不稳定(有时候有”技术趋势”字段,有时候没有),下游的消费方就必须写大量的防御性代码来处理各种可能的情况。这会让整个系统变得脆弱。
设计输出 Schema 时有几个原则。
第一,宁可多定义字段也不要少定义。即使某些字段有时候为空,也要在 Schema 里定义,并且标注”可选”。这样下游系统知道这个字段可能不存在,会提前做处理。
第二,避免用自由文本字段。尽量把输出结构化成对象和数组,而不是一大段文字。比如”产业链结构”不要定义成一个长字符串”上游包括…中游包括…下游包括…”,而是定义成数组,每个环节一个对象。
第三,给每个字段加描述。字段名有时候不够直观,加一句描述能让使用这个 Schema 的人(包括三个月后的你)快速理解这个字段的含义。
Prompt 测试集
Prompt 测试集是一组标准化的测试用例,用来验证 Prompt 的效果。
为什么需要测试集?因为 Prompt 的修改非常频繁,每次修改都可能影响效果。如果你没有测试集,改完 Prompt 之后只能人工抽查几个例子,很容易遗漏问题。如果有测试集,改完之后自动跑一遍,几秒钟就能看到整体效果变化。
测试集的设计方法。
第一步,收集典型输入。从实际使用中收集有代表性的输入数据。比如”行业概览”Prompt 的测试集应该包含不同类型的行业:成熟的行业(制造业、金融)、新兴行业(AI、新能源)、小众行业(半导体材料、特种化工)、模糊的输入(“互联网""科技”这种大类)。
第二步,为每个输入定义期望输出。期望输出不需要精确到每个字都一样,但应该定义关键要素。比如行业概览的期望输出应该包含:产业链至少分三个环节、至少列出三家代表性企业、市场规模有具体数字或范围、发展趋势至少列三条。
第三步,定义评分标准。每个测试用例的输出应该从多个维度评分:完整性(期望的字段都有吗)、准确性(内容是否跟实际情况吻合)、格式合规性(输出格式是否符合 Schema)、可读性(生成的文本是否通顺易读)。
测试集的规模。初期 10-20 个测试用例就够用。随着系统上线,从实际使用中收集更多边界案例(Corner Case),逐步扩充到 50 个以上。
测试集要跟 Prompt 版本绑定。每次改 Prompt 之后跑同一套测试集,才能做版本间的公平对比。如果每次跑的测试集不一样,就没法判断效果变化是 Prompt 改的还是测试集变的。
Prompt 评分
Prompt 评分是对测试结果进行量化评估的机制。
评分维度应该根据 Prompt 的用途来定。一般来说,以下维度适用于大多数 Prompt。
格式合规分(0-100):输出是否严格符合定义的 Schema。如果输出完全符合,100 分;如果有字段缺失或类型错误,扣分;如果根本不是 JSON 格式,0 分。
完整性分(0-100):输出是否覆盖了期望的所有信息点。比如行业概览应该包含产业链、主要企业、市场规模、趋势、挑战,如果缺少了市场规模,完整性就扣分。
准确性分(0-100):输出内容是否跟事实吻合。这个维度最难自动评分,通常需要人工判断或者用另一个模型来做交叉验证。
相关性分(0-100):输出是否紧扣输入的主题。如果输入是”半导体”,输出却花了大量篇幅讲互联网,相关性就低。
可执行性分(0-100):输出的内容是否具有可操作性。比如”AI 机会评分”的输出如果只是泛泛而谈”可以用 AI”,没有具体的场景、优先级、ROI 估算,可执行性就低。
评分方式有两种:自动评分和人工评分。
自动评分用另一个模型(评分模型)来评判目标 Prompt 的输出质量。评分模型接收原始输入、目标 Prompt 的输出、评分标准,然后给出各维度的分数和评语。自动评分的优点是速度快、成本低,缺点是评分模型本身可能不准确。
人工评分由人来逐条检查输出质量。人工评分更准确,但速度慢、成本高。建议的做法是:日常迭代用自动评分快速反馈,关键版本发布前用人工评分做最终验证。
综合分数的计算。各个维分的权重应该根据业务场景来定。比如”行业概览”Prompt 可能更看重完整性和可读性,“AI 机会评分”Prompt 更看重准确性和可执行性。综合分数等于各维度分数的加权平均。
Prompt 变更记录
Prompt 变更记录是 Prompt 管理系统的”审计日志”。
每次修改 Prompt 都要记录:谁改的、什么时候改的、改了什么(具体的内容差异)、为什么改(修改原因)、改完之后测试结果如何。
变更记录的价值体现在三个时刻。
第一个时刻:排查问题。系统输出质量突然下降,你需要找出原因。翻看变更记录,发现昨天改了某个 Prompt,改完之后的自动评分确实比之前低了。问题定位完毕。
第二个时刻:团队协作。同事问你”为什么行业概览的 Prompt 里要加这句话?“你翻看变更记录,发现是三个月前因为某个客户反馈加的,记录里还有客户的原始反馈内容。信息完整,沟通高效。
第三个时刻:知识沉淀。长期积累的变更记录本身就是一份宝贵的知识库。你会发现在哪些方向上的修改通常是有效的、哪些方向的修改通常是无效的。这些经验能指导你未来更高效地迭代 Prompt。
变更记录的格式建议包含以下字段:变更 ID(自增编号)、Prompt ID、变更前版本号、变更后版本号、变更类型(新建/修改/删除/回滚)、变更内容(具体的文本差异)、变更原因、测试结果摘要、操作人、操作时间。
Prompt 回滚
回滚是把 Prompt 恢复到之前的某个版本。
什么时候需要回滚?最常见的情况是:改了 Prompt 之后发现效果变差了,而且短时间内找不到更好的改进方案,先回到之前能用的版本。
回滚不是”撤销”。撤销是撤销上一次操作,回滚是跳到任意历史版本。你可以从 v2.3 直接回滚到 v1.8,不需要中间的版本都撤销一遍。
回滚操作需要记录。回滚本身也是一种变更,要在变更记录里体现:从哪个版本回滚到哪个版本、为什么回滚。这样未来看版本历史时能清楚地知道每个版本的来龙去脉。
回滚的技术实现比较简单。因为每个版本的完整内容都保存在数据库里,回滚只需要把”当前使用的版本”指向目标版本即可。不需要删除或覆盖任何数据。
一个成熟的 Prompt 管理系统还支持”灰度回滚”:先让一小部分流量使用旧版本,观察效果,确认没问题后再全量切回。这在生产环境中非常有用,因为某些 Prompt 版本在测试环境下表现良好,但在真实场景中可能暴露问题。
概念关系图
+----------------------------------------------------------+
| Prompt 管理系统 |
+----------------------------------------------------------+
| |
| Prompt ID (唯一标识) |
| | |
| +---> 版本 v1.0 ---+ |
| | | |
| +---> 版本 v1.1 ---+---> 变更记录链 |
| | | (谁/何时/改了什么/为什么) |
| +---> 版本 v2.0 ---+ | |
| | | v |
| +---> 版本 v2.1 | 版本对比 |
| (当前版本) | |
| | |
| +-----------+ +------+-------+ +-------------+ |
| | 输入 | | | | 输出 | |
| | Schema |--->| Prompt 模板 |--->| Schema | |
| | (参数定义) | | (模板内容) | | (格式定义) | |
| +-----------+ +--------------+ +-------------+ |
| | | | |
| v v v |
| +-----------------------------------------------+ |
| | 测试集 & 评分 | |
| | | |
| | 测试用例1 --> 运行 --> 输出 --> 评分 --> 记录 | |
| | 测试用例2 --> 运行 --> 输出 --> 评分 --> 记录 | |
| | 测试用例3 --> 运行 --> 输出 --> 评分 --> 记录 | |
| | ... | |
| | 综合评分报告 | |
| +-----------------------------------------------+ |
| | |
| v |
| 版本效果对比表 |
| (哪个版本在哪个维度更好) |
| | |
| v |
| 回滚 / 灰度切换 |
+----------------------------------------------------------+
实战分析
建 Prompt 管理表
实战的第一步是建立 Prompt 管理的数据表结构。这是整个系统的基础。
Prompt 主表存储 Prompt 的基本信息:Prompt ID(唯一标识)、名称(人类可读的名称)、描述(这个 Prompt 用在什么地方)、当前版本号(指向最新有效版本)、所属模块(行业分析/岗位分析/流程分析/报告生成等)、创建时间、更新时间。
Prompt 版本表存储每个版本的具体内容:版本 ID、Prompt ID、版本号、模板内容(实际的 Prompt 文本,包含变量占位符)、输入 Schema(JSON 格式定义)、输出 Schema(JSON 格式定义)、修改原因、操作人、创建时间。
Prompt 测试表存储测试用例和结果:测试 ID、Prompt ID、版本号、测试输入(具体参数值)、期望输出描述(关键字段和检查点)、实际输出(模型生成的结果)、各维度评分(格式分、完整性分、准确性分等)、测试时间。
三张表通过 Prompt ID 关联。查询某个 Prompt 的完整信息时,先从主表拿到当前版本号,再从版本表拿到具体内容,从测试表拿到各版本的测试结果。
存储 20 个 Prompt
系统的价值在于有足够多的 Prompt 被管理起来。实战要求你把之前写的 Prompt 全部录入管理系统。
建议按模块组织 Prompt。行业分析模块的 Prompt 包括:行业概览、竞争分析、市场规模估算、技术趋势分析、发展挑战识别。岗位分析模块包括:岗位拆解、岗位 AI 机会识别、岗位任务分类、岗位数据需求分析。流程分析模块包括:流程拆解、流程 AI 优化点识别、流程自动化评估、流程风险评估。报告生成模块包括:报告大纲生成、各章节内容生成、报告摘要生成、报告格式优化。综合评估模块包括:AI 机会评分、ROI 估算、风险审查、方案优先级排序。
每个 Prompt 录入时需要填写:名称、描述、所属模块、模板内容(包含变量占位符的完整 Prompt 文本)、输入参数定义、输出格式定义。
给每个 Prompt 加版本
录入时初始版本号为 v1.0。之后每次修改模板内容,版本号自增。
建议的版本管理流程。第一步,修改 Prompt 模板内容。第二步,记录修改原因。第三步,运行测试集验证效果。第四步,如果测试通过,版本号自增并保存。如果测试不通过,分析原因,决定是继续修改还是回滚。
这个过程看起来麻烦,但它建立了一个”修改-测试-验证”的闭环。没有这个闭环,Prompt 的迭代就是盲目的——改了也不知道效果好不好。
记录测试结果
每个 Prompt 版本的测试结果都要记录下来,形成版本间的效果对比数据。
测试结果至少记录以下信息:测试的 Prompt ID 和版本号、测试用例数量、各维度的平均分、失败用例的数量和具体原因、总 Token 用量、总成本。
随着数据积累,你会看到一个 Prompt 的”质量曲线”:每次修改后质量是上升了还是下降了。这条曲线比任何主观感受都更有说服力。
当日产物说明
《Prompt 管理系统设计》
一份完整的系统设计文档,包括:数据表结构(主表、版本表、测试表的字段定义和关系)、核心接口(增删改查 Prompt、版本管理、测试运行)、流程图(Prompt 修改-测试-发布的完整流程)。
质量标准:表结构字段完整、接口定义清晰、流程可执行。
《Prompt 版本表》
一张包含 20 个 Prompt 的版本管理表,每个 Prompt 包含:ID、名称、当前版本号、最新版本的模板内容摘要、最近一次修改时间和原因。
质量标准:所有 Prompt 都已录入、版本号格式统一、修改原因不为空。
《Prompt 测试结果表》
至少 5 个核心 Prompt 的测试结果汇总,每个 Prompt 包含:当前版本号、测试用例数量、各维度平均分、失败案例说明。
质量标准:测试维度覆盖完整、失败原因分析到位、有明确的改进方向。
常见误区与避坑
误区一:Prompt 不需要管理,记在脑子里就行
这是最常见的错误想法。当你只有 3-5 个 Prompt 时,确实可以靠记忆管理。但一旦数量超过 10 个,并且开始频繁迭代,记忆就完全不够用了。你会忘记某个 Prompt 为什么这么写、上次改了什么、效果是变好了还是变差了。Prompt 管理系统不是”高级特性”,是必须品。
误区二:只存最新版本,旧版本删掉
每个版本都有存在的价值。旧版本是你迭代过程的历史记录,也是回滚的依据。删掉旧版本就像删掉 Git 的历史提交——你可能永远不会用到,但一旦需要就追悔莫及。存储成本几乎可以忽略不计(几十个 Prompt 的文本能占多少空间?),所以不要为了”干净”而删掉历史版本。
误区三:测试集太小或太单一
测试集如果只有 3-5 个”正常”用例,发现不了边界问题。好的测试集应该包含:正常用例(典型输入,验证基本功能)、边界用例(极端输入,验证鲁棒性)、错误用例(格式错误的输入,验证容错能力)、对抗用例(可能诱导模型产生有害输出的输入,验证安全性)。每个类别至少 3-5 个用例。
误区四:只看综合分数,不看各维度分数
综合分数可能掩盖某个维度的严重问题。比如一个 Prompt 的格式合规分是 100、准确性分也是 100,但可执行性分只有 30,综合分数可能是 77,看起来还行。但实际上”可执行性差”意味着输出的内容没有实际操作价值,这对用户来说可能是致命的。评分报告应该展示各维度的详细分数,不能只看一个综合数。
误区五:修改后不跑测试就直接上线
这是最危险的做法。Prompt 的一个小改动可能对输出质量产生巨大影响。改了一句话的措辞,可能让模型从”结构化输出”变成”自由文本输出”;加了一个约束条件,可能让模型在处理某些输入时完全无法工作。每次修改 Prompt 后都必须跑测试集,确认效果没有退化,才能把新版本上线。
延伸思考
今天的 Prompt 管理系统是明天 Eval 评估体系的前置条件。Eval 的核心工作就是用测试集评估系统输出质量,而测试集和评分机制正是今天我们设计的。
Prompt 管理系统也是成本优化(Day 32)的数据来源。每次测试集运行都会记录 Token 用量和成本,这些数据是成本分析和优化的基础。
安全与权限系统(Day 33)会影响 Prompt 管理系统的访问控制:谁有权限修改 Prompt?谁有权限发布新版本?谁只能查看?这些权限规则需要在 Prompt 管理系统中实现。
部署与上线(Day 34)时,Prompt 管理系统需要考虑一个问题:生产环境的 Prompt 配置怎么管理?是用数据库存储还是用配置文件?怎么保证开发环境和生产环境的 Prompt 版本一致?这些问题在部署环节会具体解决。
自测问题
- 为什么 Prompt 需要版本管理?举三个必须回滚 Prompt 的场景。
- Prompt ID 的命名应该遵循什么原则?为什么 Prompt ID 一旦确定就不要改?
- 输入 Schema 的作用是什么?如果没有输入 Schema 会发生什么问题?
- 输出 Schema 为什么比输入 Schema 更重要?输出格式不稳定会导致什么后果?
- 测试集应该包含哪几类用例?每类用例的目的是什么?
- 自动评分和人工评分各自的优缺点是什么?应该怎么配合使用?
- 变更记录应该包含哪些字段?“修改原因”这一条为什么重要?
- 回滚和撤销的区别是什么?回滚操作本身需不需要记录?
- 如果你发现某个 Prompt 在 v1.5 之后效果持续下降,你会怎么分析和处理?
- 一个好的 Prompt 管理系统应该有哪些核心功能?按优先级排序。
关键词
- Prompt 版本管理:每次修改 Prompt 都产生新版本,保留完整历史以支持对比和回滚
- Prompt ID:Prompt 的唯一标识符,建议用”模块.功能”格式命名
- 输入 Schema:定义 Prompt 模板需要的参数、类型、必填性和默认值
- 输出 Schema:定义 Prompt 期望输出的字段结构、类型和可选性
- Prompt 测试集:标准化的测试用例集合,用于验证 Prompt 修改后的效果
- Prompt 评分:从格式合规、完整性、准确性、可执行性等维度量化评估 Prompt 质量
- 变更记录:记录每次 Prompt 修改的详细信息,包括修改人、时间、原因和测试结果
- Prompt 回滚:将 Prompt 恢复到任意历史版本的操作
- 灰度回滚:先让部分流量使用旧版本,验证效果后再全量切换的策略
- 版本效果对比:通过测试集数据对比不同 Prompt 版本在各维度的表现差异