引言:大模型项目,不能只有“能跑的代码”

很多AI应用开发者都有这样的经历:在Jupyter Notebook里跑通了一个RAG Demo,兴奋地准备部署上线,结果发现——

  • 同事拉下代码后,依赖版本冲突,跑不起来;
  • 模型权重文件几十GB,Git直接报错拒绝推送;
  • 线上环境缺一个关键库,手动安装后版本对不上;
  • 改了一行Prompt,没经过任何测试就上线,结果引发生产故障。

这些场景揭示了一个残酷的现实:AI项目从“Demo能跑”到“生产可用”,差的不是模型能力,而是一套完整的工程化底座。

2026年,行业对AI应用开发的共识已经清晰:Agent = Model + Harness,模型负责“思考”,而Harness负责让这份思考变得可理解、可协作、可复现、可长期运行。对于一个大模型产品,模型也许只完成20%的工作,剩下80%——让产品持续可靠工作的基础——是Harness

Harness的第一块基石,就是Git、虚拟环境、依赖打包与CI/CD构成的那一层“工程化底座”。它不直接产生AI能力,但没有了它,任何AI能力都无法被团队规模化地交付和运维。


一、Git版本控制:不止管代码,还要管模型

1.1 代码版本控制:团队协作的基线

Git是工程化的起点。在大模型项目中,代码版本控制面临比传统项目更高的要求:

  • Prompt即代码:Prompt的质量直接影响模型输出,Prompt的变更必须可追溯、可回滚
  • 配置即代码:模型参数、温度、Top-P等超参数需要版本化
  • 分支策略:开发/测试/生产环境的Prompt和配置需要隔离管理

一个典型的团队实践是采用分支策略区分开发和生产环境:开发分支上进行Prompt迭代和Agent逻辑调试,通过MR/PR流程合并到主分支,再由CI/CD流水线部署到不同环境。

1.2 模型权重的版本控制:Git LFS与DVC

大模型项目最大的特殊性在于:模型权重文件往往以GB甚至百GB为单位。常规Git无法处理这类大文件,必须借助专门工具。

Git LFS(Large File Storage) 是目前最成熟的方案。它通过指针文件代替实际大文件,将大文件存储在独立服务器上,Git仓库只保存轻量级的指针。

以下是初始化Git LFS并管理模型文件的完整流程:

# 安装Git LFS
git lfs install

# 创建项目仓库
mkdir my-llm-project
cd my-llm-project
git init

# 配置LFS跟踪模型文件类型(.bin、.safetensors、.pt等)
git lfs track "*.bin"
git lfs track "*.safetensors" 
git lfs track "*.pt"
git lfs track "*.h5"
git lfs track "*.onnx"

# 将.gitattributes提交到仓库
git add .gitattributes
git commit -m "chore: configure Git LFS for model files"

# 添加模型文件
cp /path/to/your/model.safetensors .
git add model.safetensors
git commit -m "feat: add model v1.0 weights"

# 推送到远程
git push origin main

对于已有Git历史中存在大文件的情况,可以使用迁移命令将历史中的大文件转为LFS管理:

# 查看需要迁移的大文件
git lfs migrate info

# 迁移超过100MB的文件到LFS
git lfs migrate import --above 100MB
git push --force-with-lease

DVC(Data Version Control) 是另一个更专门的方案,适合需要同时管理数据集、模型权重和训练实验的场景。DVC采用“双仓库架构”:代码放在Git中,数据和模型文件放在云存储或本地存储,DVC只记录元数据和版本引用。

# DVC数据版本控制示例
dvc add dataset/train.csv
git add dvc.yaml dataset.dvc
git commit -m "v1.2 数据集更新"
dvc push  # 将数据文件推送到远程存储

腾讯云在实践中的建议是:使用对象存储(如COS)存储模型文件,结合版本控制功能自动保留历史版本,通过API或控制台进行回滚。

关键原则:模型文件需独立于代码管理,所有变更需可追溯,生产环境部署前验证历史版本兼容性。


二、虚拟环境与依赖管理:告别“在我机器上能跑”

2.1 Python虚拟环境的必要性

Python生态的依赖管理长期以来是开发者的痛点。包A需要某个库的1.x版本,包B需要2.x版本,而pip会安装它最后“算出来”的那个版本——悄无声息地把另一个包弄坏。

在AI项目中,这个问题会被进一步放大:

  • PyTorch、TensorFlow等深度学习框架的版本兼容性极其敏感
  • 不同版本的CUDA、cuDNN需要精确匹配
  • 多个项目可能依赖不同版本的Python解释器

虚拟环境的核心价值:为每个项目提供隔离的Python运行环境

2.2 Python标准库方案:venv

Python3.3+内置的venv模块是最基础的虚拟环境工具:

# 创建虚拟环境
python3 -m venv venv

# 激活虚拟环境(Linux/macOS)
source venv/bin/activate

# 激活虚拟环境(Windows)
venv\Scripts\activate

# 安装依赖
pip install -r requirements.txt

# 退出虚拟环境
deactivate

2.3 现代依赖管理:Poetry

虽然venv能解决环境隔离问题,但依赖版本锁定一直是pip的短板。Poetry提供了更完善的解决方案:统一的依赖解析、确定性的lock文件、自动的虚拟环境管理。

初始化Poetry项目

# 创建新项目
poetry new my-ai-project
cd my-ai-project

# 或在已有项目中初始化
cd existing-project
poetry init

pyproject.toml配置示例

[tool.poetry]
name = "ai-agent-service"
version = "1.0.0"
description = "Production-grade AI Agent with RAG"
authors = ["Your Team <team@example.com>"]

[tool.poetry.dependencies]
python = "^3.10"
openai = "^1.0"
langchain = "^0.3"
pydantic = "^2.0"
fastapi = "^0.115"
chromadb = "^0.5"
sentence-transformers = "^2.0"
torch = "^2.0"

[tool.poetry.group.dev.dependencies]
pytest = "^8.0"
black = "^24.0"
mypy = "^1.0"
ruff = "^0.3"
pre-commit = "^3.0"

[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

Poetry的核心命令

# 安装所有依赖(根据pyproject.toml和poetry.lock)
poetry install

# 添加新依赖(自动更新poetry.lock)
poetry add pandas

# 添加开发依赖
poetry add --group dev pytest

# 更新所有依赖到最新兼容版本
poetry update

# 更新特定依赖
poetry update langchain

# 查看依赖树
poetry show --tree

# 在虚拟环境中运行脚本
poetry run python main.py

Lock文件的价值:当使用poetry addpoetry install时,Poetry会解析所有依赖,并把精确版本(包含所有传递依赖)写入poetry.lock。这保证了团队所有成员和CI/CD环境使用完全一致的包版本。

2.4 依赖打包与分发

对于需要将AI应用打包分发的场景,有两种主要方案:

方案一:venv-pack(环境打包)

venv-pack2可以将整个虚拟环境打包为zip文件,便于在目标机器上解压即用:

# 源机器上打包环境
venv-pack -o env.zip

# 目标机器上解压
mkdir my_env
python -m zipfile -e env.zip my_env/

方案二:Docker镜像(容器化)

Docker是更彻底的解决方案——不仅封装Python依赖,还封装操作系统、CUDA版本等全部运行时环境。

FROM python:3.10-slim

WORKDIR /app

# 安装系统依赖(如CUDA相关库)
RUN apt-get update && apt-get install -y \
    build-essential \
    && rm -rf /var/lib/apt/lists/*

# 使用Poetry管理Python依赖
COPY pyproject.toml poetry.lock ./
RUN pip install poetry && \
    poetry config virtualenvs.create false && \
    poetry install --no-interaction --no-ansi

# 复制应用代码
COPY . .

# 启动服务
CMD ["python", "main.py"]

三、CI/CD:让AI应用的交付自动化

3.1 为什么AI应用需要CI/CD

在传统软件开发中,CI/CD已经是最佳实践。对AI应用而言,CI/CD的必要性甚至更高:

  • 模型更新频繁:从基线模型到微调版本,可能需要频繁部署
  • 评测门槛高:AI应用的正确性不能仅靠单元测试验证,需要效果评估
  • 回归风险大:看似无害的Prompt改动可能引发连锁反应
  • 环境一致性要求严格:模型推理对运行时环境敏感

3.2 AI应用的CI/CD流水线架构

一个完整的AI应用CI/CD流水线应包含以下阶段:

通过

失败

代码提交

CI触发

环境准备

代码检查/Lint

单元测试

模型评估/效果测试

质量门禁

构建Docker镜像

告警通知

推送镜像仓库

CD部署

3.3 使用GitHub Actions构建CI流水线

以下是一个面向AI应用的GitHub Actions完整流水线示例:

name: AI Agent CI/CD

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

env:
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ github.repository }}

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.10'
          
      - name: Install Poetry
        run: pipx install poetry
        
      - name: Install dependencies
        run: poetry install --with dev
        
      - name: Run Ruff lint
        run: poetry run ruff check .
        
      - name: Run mypy type check
        run: poetry run mypy src/

  test:
    runs-on: ubuntu-latest
    needs: lint
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.10'
          
      - name: Install Poetry
        run: pipx install poetry
        
      - name: Install dependencies
        run: poetry install
        
      - name: Run unit tests
        run: poetry run pytest tests/unit -v --cov=src --cov-report=xml
        
      - name: Upload coverage
        uses: codecov/codecov-action@v4
        with:
          file: ./coverage.xml

  evaluate:
    runs-on: ubuntu-latest
    needs: test
    # 仅在main分支或PR时运行效果评估
    if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.10'
          
      - name: Install Poetry
        run: pipx install poetry
        
      - name: Install dependencies
        run: poetry install
        
      - name: Run model evaluation
        env:
          OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
        run: |
          poetry run python scripts/evaluate.py \
            --testset tests/data/eval_qa.jsonl \
            --output reports/eval_results.json
            
      - name: Check quality gate
        run: |
          # 检查评估结果是否通过质量门禁
          poetry run python scripts/check_quality.py \
            --report reports/eval_results.json \
            --threshold 0.85

  build:
    runs-on: ubuntu-latest
    needs: evaluate
    if: github.ref == 'refs/heads/main'
    permissions:
      contents: read
      packages: write
    steps:
      - uses: actions/checkout@v4
      
      - name: Login to Container Registry
        uses: docker/login-action@v3
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}
          
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3
        
      - name: Build and push Docker image
        uses: docker/build-push-action@v6
        with:
          context: .
          push: true
          tags: |
            ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}
            ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
          cache-from: type=gha
          cache-to: type=gha,mode=max

  deploy:
    runs-on: ubuntu-latest
    needs: build
    if: github.ref == 'refs/heads/main'
    environment: production
    steps:
      - uses: actions/checkout@v4
      
      - name: Deploy to Kubernetes
        run: |
          # 使用kubectl更新部署镜像版本
          kubectl set image deployment/ai-agent \
            ai-agent=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }} \
            -n production
          
          # 等待滚动更新完成
          kubectl rollout status deployment/ai-agent -n production

质量门禁(Quality Gate)的核心意义:在AI应用中,代码通过单元测试只是最低要求,还需要通过模型效果评估才能进入部署阶段。这可以用LLM-as-Judge的方式自动化评估——让一个更强的模型对输出结果打分,或者用预先标注的测试集计算准确率。

3.4 Docker容器化:环境一致性的终极方案

Docker是CI/CD流水线的核心环节。每次构建生成一个包含完整运行时环境的镜像,确保开发、测试、生产环境的一致性

一个面向AI推理服务的Dockerfile示例:

# 使用CUDA基础镜像(如需GPU推理)
FROM pytorch/pytorch:2.0.1-cuda11.7-cudnn8-runtime

WORKDIR /app

# 安装系统依赖
RUN apt-get update && apt-get install -y \
    build-essential \
    curl \
    && rm -rf /var/lib/apt/lists/*

# 安装Poetry
RUN pip install poetry==1.7.0

# 复制依赖文件并安装(利用Docker缓存层)
COPY pyproject.toml poetry.lock ./
RUN poetry config virtualenvs.create false && \
    poetry install --no-interaction --no-ansi --only main

# 复制应用代码
COPY . .

# 创建非root用户运行服务
RUN useradd -m -u 1000 appuser && chown -R appuser:appuser /app
USER appuser

# 暴露服务端口
EXPOSE 8000

# 启动命令
CMD ["python", "-m", "uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

多阶段构建优化镜像大小:对于AI应用,镜像大小动辄数GB,多阶段构建可以有效减小最终镜像体积:

# 第一阶段:构建依赖
FROM python:3.10-slim AS builder

WORKDIR /app
COPY pyproject.toml poetry.lock ./
RUN pip install poetry && \
    poetry export -f requirements.txt --output requirements.txt && \
    pip install --user -r requirements.txt

# 第二阶段:运行时镜像
FROM python:3.10-slim

WORKDIR /app
COPY --from=builder /root/.local /root/.local
COPY . .

ENV PATH=/root/.local/bin:$PATH
CMD ["python", "main.py"]

3.5 部署策略:蓝绿部署与灰度发布

对于AI应用的生产部署,推荐采用蓝绿部署或灰度发布策略,以降低新模型版本上线带来的风险:

# Kubernetes Deployment示例
apiVersion: apps/v1
kind: Deployment
metadata:
  name: ai-agent
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  selector:
    matchLabels:
      app: ai-agent
  template:
    metadata:
      labels:
        app: ai-agent
        version: v2
    spec:
      containers:
      - name: ai-agent
        image: ghcr.io/my-org/ai-agent:latest
        ports:
        - containerPort: 8000
        resources:
          limits:
            memory: "4Gi"
            cpu: "2"
            nvidia.com/gpu: 1
        env:
        - name: MODEL_PATH
          value: "/models/v2"
        readinessProbe:
          httpGet:
            path: /health
            port: 8000
          initialDelaySeconds: 30
          periodSeconds: 10
        livenessProbe:
          httpGet:
            path: /health
            port: 8000
          initialDelaySeconds: 60
          periodSeconds: 20

四、最佳实践总结

4.1 工程化底座的核心原则

实践领域 核心原则 推荐工具
代码版本控制 代码和模型分开管理,所有变更可追溯 Git + Git LFS / DVC
依赖管理 确定性锁文件,环境一致性 Poetry / venv + requirements
持续集成 自动化测试+效果评估+质量门禁 GitHub Actions / GitLab CI
容器化 环境封装,一次构建处处运行 Docker / OCI
持续部署 灰度发布,快速回滚 Kubernetes / Helm

4.2 常见陷阱与避坑指南

  1. 不要把模型权重直接提交到普通Git仓库:使用Git LFS或DVC,否则仓库会膨胀到无法克隆。

  2. 不要使用宽松版本约束(如pandas>=1.0)而不锁定版本:这会导致不同时间、不同环境安装的版本不同,产生“在我机器上能跑”的问题。

  3. 不要跳过模型效果评估这一步:单元测试只能保证代码逻辑正确,无法保证AI输出质量。质量门禁应包含效果指标。

  4. 不要手动管理多环境配置:使用poetrypip-tools等工具自动管理依赖,并确保poetry.lock提交到版本控制。

  5. 不要在CI/CD中硬编码密钥:使用环境变量或Secrets管理工具(如GitHub Secrets、Vault)。


结语

大模型应用开发正在经历一场深刻的“去魔法化”。开发者不再满足于写几段调用API的代码,而是需要构建一套完整的工程体系。

Git、虚拟环境、依赖打包与CI/CD构成的那一层“工程化底座”,看似是“基础设施”,但它决定了AI项目能否被团队规模化地开发、交付和运维。

2026年,AI应用开发的竞争已经不仅仅是模型能力的竞争,更是工程化能力的竞争。 模型能力决定下限,工程能力决定上限。搭建好这套工程化底座,AI能力才能真正从“能对话”走向“能干活”。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐