
传统软件的CI/CD大家都已经非常熟悉,写业务代码、提交代码后流水线自动做编译、单元测试、集成测试,通过之后直接部署上线,整个流程高度标准化。但当业务从普通后端业务转向大模型应用之后,我们会发现老一套CI/CD直接水土不服。
普通软件交付的核心产物是代码二进制包,逻辑是确定的,输入固定就会输出固定结果;而大模型应用的交付物不再只有代码,还包含权重文件、Prompt模板、向量知识库、微调数据集、工具配置等大量资产。大模型本身具备生成不确定性,同样输入,模型每次返回结果可能存在差异,传统单元测试很难直接套用。
我们早期做大模型项目,大都是本地调试Prompt,手动导出向量库,手动调用微调脚本,人工简单看几条样例效果之后就直接上线。上线之后经常遇到问题:Prompt改完没有版本记录;微调之后模型效果退化;知识库更新没有校验;线上大模型输出幻觉、回答跑偏;出问题之后无法复现是代码、Prompt、数据集还是模型权重导致的故障。这些问题本质就是缺少适配大模型特性的CI/CD流水线。
大模型应用CI/CD,并不是把传统CI/CD直接复制粘贴过来,而是在原有代码持续集成基础之上,新增模型资产版本管理、模型自动化评估、Prompt测试、数据集校验、向量库版本管控、安全对齐检测、模型灰度发布这一系列全新环节。今天我们详细探讨如何搞懂如何搭建一套可用的LLM CI/CD,解决大模型项目迭代混乱、上线风险高、问题难以复现的工程难题。

在深入大模型专属CI/CD体系之前,我们必须夯实传统软件CI/CD的核心基础。大模型CI/CD并非凭空诞生,而是在传统CI/CD工程理念上的迭代与扩容,只有吃透传统流水线的设计逻辑、核心流程和适用场景,才能精准理解大模型场景下的改造差异和优化思路。
CI/CD是现代软件工程的核心基石,全称持续集成(Continuous Integration)、持续交付(Continuous Delivery)/持续部署(Continuous Deployment),是一套标准化、自动化的软件研发交付体系,彻底解决了传统手工开发、测试、部署模式的各类痛点。
在早期软件研发模式中,开发人员各自在本地编写代码,项目迭代末期统一合并代码、集中测试、手动打包部署。这种模式极易出现代码冲突、隐藏Bug堆积、部署环境不一致、上线耗时久、故障难溯源等问题。而CI/CD通过自动化流水线,规范了代码从提交、校验、构建、测试到上线的全流程,实现研发交付的高效、稳定、可追溯。
其中CI持续集成和CD持续交付/部署各司其职,形成完整闭环,三者定义边界清晰、分工明确:

持续集成(CI):核心是“代码频繁合并、自动校验”。
持续交付(CD):核心是“制品可控、按需发布”。
持续部署(CD):核心是“全自动化、无人值守上线”。
传统软件CI/CD流水线是一套标准化、固定化的流程体系,所有业务代码迭代都遵循统一流程执行,无特殊定制逻辑,整体分为六大核心步骤,全程可自动化执行,适配所有后端、前端、客户端常规软件项目。

传统CI/CD能够成为软件工程通用标准,核心在于其高度标准化、自动化、可控化的特性,完美适配确定性软件的交付需求,核心优势体现在四个方面。
传统CI/CD工具生态成熟、选型稳定,各行各业通用,无技术壁垒,核心工具分为流水线编排、代码管理、制品管理三大类,搭配即可搭建完整交付体系。
传统CI/CD是为确定性代码软件设计的标准化体系,适配常规业务系统、互联网服务、后端接口等项目,但存在天然局限性,这也是其无法直接适配大模型应用的核心原因。
传统软件CI/CD面向确定性程序逻辑,交付主体为源代码、配置文件、编译产物。整个流水线围绕代码变更驱动。
传统流水线风险点主要来自代码Bug、配置错误、依赖冲突。所有资产都可以放在Git仓库中进行版本追踪,回滚简单,直接切换镜像版本即可完成回滚操作。
大模型应用是代码+模型资产的混合系统,很多资产无法直接存入Git仓库,这也是最大的区别,主要包含下面几类资产:
这里要注意的是大权重模型文件体积巨大,不能直接提交Git,需要借助模型版本仓库做版本管控。
维度 | 传统应用CI/CD | 大模型应用CI/CD |
|---|---|---|
变更触发源 | 代码变更 | 代码、Prompt、数据集、权重、知识库均会触发流水线 |
测试逻辑 | 确定性单元、接口测试 | 确定性代码测试 + 大模型主观/客观效果评估 |
制品 | 镜像、程序包 | 镜像+模型权重+LoRA+向量快照+Prompt版本包 |
失败判断 | 断言相等即可判断失败 | 需要语义相似度、准确率、幻觉检测等指标判断效果退化 |
回滚 | 回滚镜像 | 同时回滚镜像、Prompt版本、权重版本、向量知识库快照 |
实际项目中常见痛点:
基于以上差异,设计LLM CI/CD流水线需要遵守几条核心原则:
完整的大模型CI/CD流水线分为5大阶段:
触发阶段 → 持续集成CI阶段 → 模型专项校验阶段 → 持续交付CD阶段 → 线上运维观测闭环。
触发源不再仅仅是Git代码提交,还包含:Prompt仓库变更、数据集版本更新、微调任务完成、知识库文档更新。简单理解整个流程:

大模型CI/CD需要在传统CI工具之上补充LLM专用工具,这里给出工程落地常用选型,不绑定某一套,可按需替换。
流水线输入(触发变更源)
流水线输出制品,每一次运行全部打版本标签
这里需要注意的是每一个制品之间通过同一个run_id关联,后续排查问题输入run_id,即可找到本次上线所有资产版本。
前置检查包含:
GitHub Actions极简示例:做前置校验片段 .github/workflows/llm_ci.yml
name: LLM应用CI流水线
on:
push:
branches: [ main, dev ]
pull_request:
branches: [ main, dev ]
# 支持手动触发
workflow_dispatch:
jobs:
pre_check:
runs-on: ubuntu‑latest
steps:
- name: 拉取代码
uses: actions/checkout@v4
- name: Python环境准备
uses: actions/setup‑python@v5
with:
python‑version: "3.11"
- name: 安装依赖
run: |
python -m pip install --upgrade pip
pip install flake8 pydantic
- name: 代码静态检查
run: flake8 ./src --max‑line‑length=120
- name: 执行Prompt模板校验脚本
run: python ./scripts/prompt_validate.py
- name: 数据集格式校验
run: python ./scripts/dataset_validate.py配套简单校验脚本:scripts/prompt_validate.py
"""Prompt模板校验脚本:检查模板占位符是否合法"""
from pydantic import BaseModel
import jinja2
import os
PROMPT_DIR = "./prompts"
def validate_prompt_template(file_path: str):
with open(file_path, "r", encoding="utf‑8") as f:
content = f.read()
try:
env = jinja2.Environment()
env.parse(content)
print(f"✅ {file_path} 模板语法正常")
except jinja2.exceptions.TemplateSyntaxError as e:
print(f"❌ {file_path} 模板语法错误 {e}")
raise SystemExit(1)
if __name__ == "__main__":
all_files = [os.path.join(PROMPT_DIR, f) for f in os.listdir(PROMPT_DIR) if f.endswith(".jinja2")]
for fp in all_files:
validate_prompt_template(fp)
print("全部Prompt模板校验通过")这一部分和传统CI类似,针对确定性逻辑做测试,不要尝试在这里测试大模型生成效果。可以测试的内容:
调用真实大模型判断回答好不好,不需要在这里测试,这类放到后续模型评估阶段。
前置检查、单元测试全部通过之后,开始构建全部制品:

这里需要注意,向量库不直接写入线上向量库,只生成快照制品,交付阶段再部署,防止CI阶段直接污染生产知识库。
数据集是大模型效果根源,很多上线故障来自脏数据集。校验分为格式校验与样本质量校验。
格式校验:字段完整性、json格式、文本非空,前面脚本已经覆盖。
样本质量校验:
简易数据集检测示例:
import json
from collections import Counter
def dataset_check(dataset_path: str, repeat_threshold: float = 0.2):
with open(dataset_path, "r", encoding="utf‑8") as f:
data = json.load(f)
texts = []
for item in data:
q = item.get("instruction","") + item.get("input","") + item.get("output","")
texts.append(q.strip())
# 重复样本检测
counter = Counter(texts)
repeat_count = sum([cnt for cnt in counter.values() if cnt>1])
repeat_rate = repeat_count / len(texts)
print(f"数据集总样本:{len(texts)},重复率:{repeat_rate:.2%}")
if repeat_rate > repeat_threshold:
print("❌ 数据集重复样本过高,流水线阻断")
raise SystemExit(1)
print("✅数据集质量校验通过")
if __name__ == "__main__":
dataset_check("./data/eval_dataset.json")修改Prompt模板之后,不能靠人肉眼看,流水线自动传入一批固定冒烟Query,渲染Prompt,调用测试环境大模型,快速看是否发生严重异常。
冒烟测试目标不是评估效果好坏,而是拦截严重故障:模板渲染报错、输出全部为空、全部乱码、完全不遵循指令。执行逻辑:

这是整套LLM CI最核心的环节,也是和传统CI最大区别。当微调权重更新、Prompt更新、知识库更新之后,必须运行评估集,对比历史基线指标,判断是否发生效果退化。评估分为两类:

指标对比逻辑:流水线会读取上一个稳定版本的基线指标,当新版本指标下降超过设定阈值,流水线直接失败,禁止继续发布。
基于Ragas评估的示例:
演示流水线如何做评估,实际流水线会输出评估报告json保存为制品:
from ragas import evaluate
from ragas.metrics import faithfulness, answer_relevancy, context_recall
from datasets import Dataset
# 模拟评估数据集,流水线从eval_dataset读取
eval_data = {
"question": [
"大模型CI/CD包含哪些阶段?"
],
"answer": [""],
"contexts": [[]],
"ground_truth": ["大模型CI/CD分为触发、CI、专项校验、CD、线上观测闭环五个阶段"]
}
def run_llm_eval():
ds = Dataset.from_dict(eval_data)
result = evaluate(
ds,
metrics=[faithfulness, answer_relevancy, context_recall]
)
df = result.to_pandas()
print(df)
# 将评估结果保存为制品
df.to_json("./artifacts/eval_report.json", force_ascii=False)
avg_score = result["answer_relevancy"]
baseline = 0.70
degrade_threshold = 0.05
if avg_score < baseline - degrade_threshold:
print(f"❌效果退化!当前分数{avg_score:.2f},基线{baseline},流水线终止")
raise SystemExit(1)
print("✅模型评估通过,效果未明显退化")
if __name__ == "__main__":
run_llm_eval()根据实际需要判断是否使用生产大模型做流水线大规模评估,建议使用独立的评估模型实例,避免占用生产算力;评估集需要持续积累,样本越多评估结果越可信。
大模型资产变更,尤其是Prompt、微调数据集更新之后,必须执行安全检测,拦截越狱提示、敏感输出风险。

流水线输入一批安全测试用例:越狱Prompt、敏感问题,检测模型输出是否输出违规内容。一旦命中风险,流水线阻断发布,避免上线之后出现安全事故。
专项校验环节任意环节失败,流水线直接终止,不会进入发布环节。

所有评估报告作为流水线制品留存,即使失败也可以下载报告,定位哪里出了问题。
大模型应用环境必须严格隔离,不同环境使用独立的模型实例、独立向量库,禁止测试直接操作生产。

特别注意向量库不要多环境共用,每个环境有独立向量实例,通过流水线生成的快照制品部署,而不是直接复制线上向量。
CI和专项校验全部通过之后,进入CD交付。部署不再只是部署容器镜像,需要同步部署多份资产:

大模型绝对不建议一次性全量切流量。模型输出具有不确定性,即使自动化评估全部通过,依然可能存在评估集没有覆盖到的bad case,必须灰度。

常用灰度策略:
灰度阶段观测指标:接口QPS、错误率、超时率;业务指标:幻觉占比、用户负面反馈率、拒绝回答异常案例数量。一旦指标恶化,立刻执行回滚。
传统业务只需要回滚镜像。大模型回滚需要多资产协同回滚,这是工程应用的核心关键点。回滚操作清单:

所以流水线每一次发布都要完整保存全部制品快照,保存run_id,回滚时输入run_id一键恢复整套资产。
流水线上线完成不是工作结束,需要把线上真实业务数据回流,形成闭环。需要采集的数据:

推荐使用Langfuse、LangSmith记录链路,每一条trace绑定本次上线全部资产版本,线上出现bad case,就可以追溯是哪一次流水线引入问题。
采集线上负样本之后,做人工清洗,补充到评估数据集,部分优质样本加入微调数据集。数据集更新提交版本仓库,会自动触发新一轮CI流水线,跑完整评估,验证新版本是否修复线上发现的问题。

这样就形成闭环:线上真实问题 → 沉淀数据集 → CI流水线自动评估验证 → 发布新版本上线。避免只靠开发人员自己造测试样本。
除了变更触发流水线,还建议配置定时流水线任务,每周自动跑一遍全套评估集。
在早期接触,或没有实践经验是,不需要一步搭建超级复杂完整系统,可以分阶段落地。

不要追求一步到位,优先解决最痛的痛点:资产无版本、手动上线。
传统软件CI/CD聚焦代码,而大模型应用CI/CD本质是一套“代码+模型全资产”的持续工程体系。它不是把传统流水线抛弃,而是在传统CI基础之上扩展了模型资产版本管控、数据集校验、Prompt测试、自动化模型评估、向量制品管理、灰度回滚、线上数据闭环这一整套全新能力。
早期刚接触做大模型项目,容易把大量精力花在调Prompt、调微调参数,却忽略工程交付体系。当项目规模小,只有少量Query,手工处理尚可;业务规模扩大之后,没有LLM‑CI/CD就会面临版本混乱、上线风险高、故障无法复现,迭代效率急剧下降。核心做到所有会影响输出的资产全部版本化;能自动化校验就不要人工;上线一定要灰度,线上真实数据要回流给流水线。这样的大模型项目就可以像传统软件一样,安全、可控、可追溯的持续迭代,告别“本地效果很好,上线就翻车”的行业常见困境。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。