回归测试(Regression Testing)
每次变更后用已验证的测试集重新跑一遍,确保没有破坏已有功能。
Agent 应用开发中代码、Prompt、版本号与文档的标准化规范体系
内容摘要
开发规范是一套约束团队成员"怎么写代码、怎么管 Prompt、怎么打版本号、怎么写文档"的标准化规则。它的作用类似于建筑施工图里的"制图标准":不同工程师画出来的图纸,线型、符号、比例尺都一样,任何人拿到都能看懂。
开发规范是一套约束团队成员"怎么写代码、怎么管 Prompt、怎么打版本号、怎么写文档"的标准化规则。它的作用类似于建筑施工图里的"制图标准":不同工程师画出来的图纸,线型、符号、比例尺都一样,任何人拿到都能看懂。
传统软件开发已经有成熟的代码规范(如 PEP 8、ESLint),但 Agent 应用有一个独特问题:Prompt 也是"代码"。一个系统 Prompt 的措辞微调,可能导致 LLM 输出质量大幅波动。如果 Prompt 没有版本控制,出问题后既无法定位原因,也无法回滚。因此,Agent 开发规范比传统开发规范多了一个核心维度——Prompt 管理规范。
开发规范不是"锦上添花"的事情。在 1-2 人的原型阶段,没有规范也能活;但当团队超过 3 人、或者项目进入生产环境后,没有规范的项目会陷入"改一处、崩三处"的维护泥潭。规范的本质是把隐性的个人习惯变成显性的团队契约,让代码审查、自动化工具、新人上手都有据可依。
Agent 开发规范由四个维度组成,每个维度解决一类一致性问题:
| 维度 | 解决的问题 | 核心产出物 |
|---|---|---|
| 代码规范 | 不同人写的代码风格不一致 | .flake8、ruff.toml 等配置文件 |
| Prompt 管理规范 | Prompt 修改没有记录,无法回滚 | Prompt 版本库 + 变更日志 |
| 版本号规范 | 版本号随意命名,无法判断变更程度 | 语义化版本号(SemVer)策略 |
| 文档规范 | 文档格式混乱,过时严重 | 统一的文档模板 + CHANGELOG |
代码规范定义了源代码的书写格式,包括缩进方式、命名约定、行长限制、导入排序等。以 Python 为例,PEP 8 是官方推荐的风格指南,规定了 4 空格缩进、snake_case 函数命名、79 字符行长等。
代码规范的执行不靠人工盯,而是靠 Lint 工具(代码检查器)自动化。常见的 Python Lint 工具对比:
Lint 工具通常在三个阶段执行:开发者本地运行、Git pre-commit hook 自动拦截、CI/CD 流水线最终把关。
Agent 应用的核心逻辑内化在 Prompt 中。传统软件改一行代码,只影响那行代码的逻辑;而改 Prompt 里的一个词,可能让 LLM 的整个输出行为发生变化。Prompt 管理规范的核心原则:
agent.classify.system_v2)采用语义化版本(Semantic Versioning,SemVer),格式为 MAJOR.MINOR.PATCH:
SemVer 的价值在于版本号本身携带信息。用户看到 1.2.3 -> 2.0.0,立刻知道"有不兼容变更,需要检查代码";看到 1.2.3 -> 1.2.4,知道"这是个安全的小修复"。
文档规范的核心是"文档即代码"(Docs as Code):文档存放在代码仓库中,与代码一起版本控制,确保同步更新。包括:
开发规范的运作逻辑是"规则定义 -> 工具自动执行 -> 流水线强制拦截"的三层保障机制:
.flake8、ruff.toml)和规范文档这三层的关系是逐步收紧的:本地工具提供即时反馈(秒级),pre-commit 提供提交前拦截(秒级),CI/CD 提供最终门禁(分钟级)。这样设计的好处是:开发者能在最早的阶段发现问题,而不是等到代码审查时才被打回。
对于 Prompt 规范,工作机制类似但有差异:Prompt 的"Lint"不是检查语法格式,而是检查结构完整性(是否有系统提示、是否有输出格式约束)和效果指标(通过评测集自动跑分)。
规则定义层的四个维度分别输出配置文件和模板,工具执行层用这些配置在本地进行自动检查,流水线强制层作为最终门禁确保不合规代码无法进入主分支。未通过检查的代码会被打回到工具执行层重新修复,形成闭环。
以下伪代码展示 Prompt 版本管理的核心机制:每个 Prompt 有唯一 ID,每次修改自动递增版本号,并记录变更原因和评测结果。
# Prompt 版本管理的核心机制示例(伪代码)
class PromptVersion:
"""一个 Prompt 版本的最小结构"""
def __init__(self, prompt_id: str, version: str, content: str,
change_log: str, eval_score: float = None):
self.prompt_id = prompt_id # 唯一标识,如 "agent.classify.system"
self.version = version # 语义化版本号,如 "v1.2.0"
self.content = content # Prompt 文本内容
self.change_log = change_log # 变更说明(What + Why)
self.eval_score = eval_score # 评测得分(可选)
class PromptRegistry:
"""Prompt 注册中心:管理所有 Prompt 的版本历史"""
def __init__(self):
self.history = {} # {prompt_id: [PromptVersion, ...]}
def register(self, prompt_id, content, change_log, eval_score=None):
"""注册新版本,自动递增版本号"""
versions = self.history.setdefault(prompt_id, [])
patch = len(versions)
new_version = PromptVersion(
prompt_id=prompt_id,
version=f"v1.0.{patch}",
content=content,
change_log=change_log,
eval_score=eval_score,
)
versions.append(new_version)
return new_version
def rollback(self, prompt_id, target_version):
"""回滚到指定历史版本(创建新版本,内容复制自目标版本)"""
for v in self.history.get(prompt_id, []):
if v.version == target_version:
return self.register(
prompt_id, v.content,
change_log=f"回滚至 {target_version}"
)
return None
def get_latest(self, prompt_id):
"""获取最新版本"""
versions = self.history.get(prompt_id, [])
return versions[-1] if versions else None
这段代码对应前面"Prompt 管理规范"的三个核心能力:唯一标识(prompt_id)、版本追踪(register 方法自动递增)、回滚能力(rollback 方法创建新版本但复制旧内容)。实际工程中通常用 Git 管理 Prompt 文件,或使用 LangSmith、Humanloop 等专用平台。
| 概念 | 与开发规范的区别 | 更适合关注的重点 |
|---|---|---|
| 代码审查(Code Review) | 开发规范是"规则本身",代码审查是"执行规则的活动"。规范定义了检查标准,审查是按标准逐条检查的过程 | 审查的重点是业务逻辑和设计决策,风格问题应由 Lint 工具自动处理 |
| CI/CD | CI/CD 是自动化流水线,开发规范是流水线中检查的"规则集"。CI/CD 是执行者,规范是被执行的对象 | CI/CD 关注的是流水线编排和部署策略,规范关注的是质量标准的定义 |
| 编码规约(Coding Convention) | 编码规约只是开发规范的一个子集,专指代码书写风格。开发规范还包括 Prompt 管理、版本号策略、文档标准 | 编码规约只管"代码长什么样",开发规范管"整个开发产出物长什么样" |
核心区别:
| 常见误区 | 正确理解 |
|---|---|
| "规范只管代码风格,是可有可无的形式主义" | 代码风格只是规范的一个子集。Agent 项目的规范还必须覆盖 Prompt 版本管理、语义化版本号、文档标准。这些直接影响线上稳定性和团队协作效率 |
| "有了 Lint 工具就等于有了规范" | Lint 工具只是规范的自动化执行手段。没有团队讨论确定的规则集、没有 Prompt 管理策略、没有版本号约定,单有 Lint 工具解决不了全局问题 |
| "Prompt 不需要版本控制,改完直接上线就行" | Prompt 是 Agent 的核心逻辑载体,改一个词可能导致输出行为巨变。没有版本控制,出问题时既无法定位是哪个版本引入的 Bug,也无法快速回滚 |
| "版本号就是个标签,叫什么都行" | 语义化版本号(SemVer)让版本号本身携带信息。1.0.0 -> 2.0.0 表示有不兼容变更,1.0.0 -> 1.0.1 表示安全修复。随意命名的版本号无法传递这些信息 |
| "先跑起来再说,规范以后补" | 项目越大、技术债越多,补规范的成本越高。建议在团队超过 2 人、或项目进入生产环境前就建立基础规范 |
参考答案:
四个维度:代码规范、Prompt 管理规范、版本号规范(SemVer)、文档规范。
核心区别:代码规范检查的是语法格式和命名风格,改动影响范围可预测;Prompt 管理规范关注的是语义内容的版本控制,因为 Prompt 的微小文字调整可能导致 LLM 输出行为的非线性变化,所以需要绑定评测结果、支持灰度发布和快速回滚。
参考答案:
MINOR 版本号变更(1.0.0 -> 1.1.0),表示向下兼容的功能新增,不影响已有调用方。
效果变差的处理流程:(1) 查看 Prompt 变更日志,确认 v1.1.0 修改了什么内容和原因;(2) 对比 v1.0.0 和 v1.1.0 的评测结果,确认效果下降的具体指标;(3) 通过回滚机制切回 v1.0.0(创建 v1.1.1 但内容复制自 v1.0.0);(4) 分析 v1.1.0 导致效果下降的原因,修复后再发布 v1.2.0。
参考答案:
最小可行方案包含三个要素:
(1) Prompt 文件结构:在代码仓库中建立 prompts/ 目录,每个 Agent 一个子目录(prompts/customer_service/、prompts/data_analyst/、prompts/code_reviewer/),每个版本一个文件(如 system_v1.0.0.md)。
(2) 变更日志:每个子目录下维护 CHANGELOG.md,每次修改必须记录"改了什么"(What)、"为什么改"(Why)、"评测结果"(Score)。
(3) 回滚机制:CI/CD 中配置 Prompt 部署脚本,支持通过环境变量指定使用哪个版本(如 PROMPT_VERSION=v1.0.0),回滚时只需修改环境变量并重新部署。
可选增强:接入 LangSmith 等平台进行 Prompt 的 A/B 测试和灰度发布。
优先展示同分类且标签更接近的内容,方便继续串联学习。
每次变更后用已验证的测试集重新跑一遍,确保没有破坏已有功能。
Agent 开发团队如何通过 Prompt 版本管理、行为评估和知识库共享实现高效协同
从代码提交到生产部署的全流程自动化体系,覆盖传统 CI/CD 与 Agent 特有的 Prompt/模型评估流水线