**系列**:06-多工具集成实战 **标签**:CI/CD、GitHub Actions、Codex、Claude Code、Hermes、自动化部署 **日期**:2026-05-22

CICD多Agent流水线:构建→审查→测试→部署全流程自动化

系列:06-多工具集成实战 标签:CI/CD、GitHub Actions、Codex、Claude Code、Hermes、自动化部署 日期:2026-05-22

简介

在上一篇中,我们使用 Git Worktree + Hermes 实现了三端并行开发。现在,我们需要解决一个更关键的问题:当多个 Agent 并行写完代码、推送到远程后,如何自动完成构建、审查、测试和部署?

本文将构建一条完整的 多 Agent CI/CD 流水线,将三个顶级 Agent 工具串联起来:

  • OpenAI Codex:负责 PR 代码审查,自动检测代码质量和规范
  • Claude Code:根据审查结果自动修复问题
  • Hermes Agent:负责最终部署和多渠道通知

一、流水线整体设计

1.1 四阶段流水线模型

我们的流水线分为四个核心阶段,每个阶段由不同的 Agent 驱动:

text
┌─────────────────────────────────────────────────────────────────┐
│                    多Agent CI/CD 流水线                          │
├──────────┬──────────┬──────────┬──────────┬─────────────────────┤
│  阶段1   │  阶段2   │  阶段3   │  阶段4   │                     │
│  构建    │  审查    │  修复    │  部署    │                     │
│  Build   │  Review  │  Fix     │  Deploy  │                     │
│          │          │          │          │                     │
│  GitHub  │  Codex   │  Claude  │  Hermes  │                     │
│  Actions │  Agent   │  Code    │  Agent   │                     │
│          │          │          │          │                     │
│ ✅编译   │ ✅代码   │ ✅自动   │ ✅部署   │                     │
│ ✅Lint  │ ✅规范   │ ✅修复   │ ✅通知   │                     │
│ ✅Bundle│ ✅安全   │ ✅验证   │ ✅回滚   │                     │
└──────────┴──────────┴──────────┴──────────┴─────────────────────┘

1.2 触发条件

yaml
# 触发器配置
triggers:
  - event: pull_request
    branches: [main, develop]
    paths:
      - 'src/**'
      - 'tests/**'
      - 'package.json'

  - event: push
    branches: [release/*]

  - event: schedule
    cron: '0 2 * * *'  # 每日凌晨2点全量构建

二、阶段1:构建(GitHub Actions + Hermes Agent)

2.1 GitHub Actions 工作流

yaml
# .github/workflows/multi-agent-pipeline.yml
name: Multi-Agent CI/CD Pipeline

on:
  pull_request:
    branches: [main, develop]
  push:
    branches: [release/*]

env:
  NODE_VERSION: '20'
  DOCKER_REGISTRY: ghcr.io
  APP_NAME: multi-agent-demo

jobs:
  # ========== 阶段1:构建 ==========
  build:
    name: 🏗️ Build & Lint
    runs-on: ubuntu-latest
    timeout-minutes: 15

    steps:
      - name: Checkout code
        uses: actions/checkout@v4
        with:
          fetch-depth: 0  # 获取完整历史,便于增量构建

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}
          cache: 'npm'

      - name: Install dependencies
        run: npm ci --prefer-offline

      - name: Type check
        run: npm run type-check

      - name: Lint
        run: |
          npm run lint
          npm run lint:fix -- --check

      - name: Build frontend
        run: |
          cd frontend
          npm run build
          echo "Build size: $(du -sh dist/ | cut -f1)"

      - name: Build backend
        run: |
          cd backend
          npm run build
          echo "TypeScript compilation: OK"

      - name: Upload build artifacts
        uses: actions/upload-artifact@v4
        with:
          name: build-output
          path: |
            frontend/dist/
            backend/dist/
          retention-days: 7

      - name: Build Docker image
        if: github.event_name == 'push' && startsWith(github.ref, 'refs/heads/release/')
        run: |
          docker build -t ${{ env.DOCKER_REGISTRY }}/${{ github.repository }}/${{ env.APP_NAME }}:${{ github.sha }} .
          echo "${{ secrets.GITHUB_TOKEN }}" | docker login ${{ env.DOCKER_REGISTRY }} -u ${{ github.actor }} --password-stdin
          docker push ${{ env.DOCKER_REGISTRY }}/${{ github.repository }}/${{ env.APP_NAME }}:${{ github.sha }}

    outputs:
      build-success: ${{ steps.build.outcome }}
      build-time: ${{ steps.build-timer.outputs.duration }}
      commit-sha: ${{ github.sha }}

2.2 构建阶段的 Hermes Agent 辅助

在构建阶段,我们可以引入 Hermes Agent 来辅助处理构建过程中的异常:

yaml
      - name: Handle build failures with Hermes Agent
        if: failure()
        uses: nousresearch/hermes-agent-action@v1
        with:
          api-key: ${{ secrets.HERMES_API_KEY }}
          model: hermes-3
          system-prompt: |
            你是一个构建问题诊断专家。请分析以下构建错误日志,
            找出根本原因并提供修复建议。
          prompt: |
            构建失败,请分析以下日志并给出修复方案:

            ${{ steps.build.outputs.stderr }}

            请按以下格式输出:
            1. 错误类型分类
            2. 根本原因分析
            3. 修复建议(包含具体代码修改)
            4. 需要修改的文件列表
          output-file: build-diagnosis.json

      - name: Apply Hermes suggested fixes
        if: failure()
        run: |
          python3 apply-hermes-fixes.py build-diagnosis.json
          # 重新尝试构建
          npm run build

2.3 增量构建优化

对于大型项目,全量构建耗时过长。我们使用 Hermes Agent 分析变更影响范围,实现增量构建:

typescript
// scripts/incremental-build-analyzer.ts
import { execSync } from 'child_process';
import { readFileSync } from 'fs';
import path from 'path';

interface ChangeAnalysis {
  affectedPackages: string[];
  needsFullBuild: boolean;
  skipTestPatterns: string[];
}

export function analyzeChanges(baseSha: string, headSha: string): ChangeAnalysis {
  // 获取变更文件列表
  const diffOutput = execSync(
    `git diff --name-only ${baseSha} ${headSha}`
  ).toString().trim().split('\n');

  const affectedPackages = new Set<string>();
  let needsFullBuild = false;
  const skipTestPatterns: string[] = [];

  for (const file of diffOutput) {
    // 分析变更影响的包
    if (file.startsWith('frontend/src/')) {
      affectedPackages.add('frontend');
    }
    if (file.startsWith('backend/src/')) {
      affectedPackages.add('backend');
    }
    if (file.startsWith('shared/')) {
      // shared 目录变更需要全量构建
      needsFullBuild = true;
    }
    if (file.endsWith('package-lock.json')) {
      needsFullBuild = true;
    }
  }

  // 如果只改了后端,可以跳过前端测试
  if (affectedPackages.has('backend') && !affectedPackages.has('frontend')) {
    skipTestPatterns.push('frontend/**/*.test.tsx');
  }

  return {
    affectedPackages: Array.from(affectedPackages),
    needsFullBuild,
    skipTestPatterns,
  };
}

// 输出 JSON 供 GitHub Actions 使用
const analysis = analyzeChanges(process.env.BASE_SHA!, process.env.HEAD_SHA!);
console.log(JSON.stringify(analysis));

三、阶段2:审查(OpenAI Codex Agent)

3.1 Codex 代码审查配置

构建成功后,进入审查阶段。我们使用 OpenAI Codex Agent 进行自动化代码审查:

yaml
  # ========== 阶段2:Codex 代码审查 ==========
  codex-review:
    name: 🔍 Codex Code Review
    needs: build
    runs-on: ubuntu-latest
    timeout-minutes: 20

    steps:
      - name: Checkout code
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Get PR diff
        id: diff
        run: |
          git diff origin/${{ github.base_ref }}...HEAD > pr-diff.patch
          echo "diff-size=$(wc -l < pr-diff.patch)" >> $GITHUB_OUTPUT

      - name: Codex PR Review
        if: steps.diff.outputs.diff-size != '0'
        uses: openai/codex-review-action@v2
        with:
          api-key: ${{ secrets.OPENAI_API_KEY }}
          model: o4-mini
          diff-file: pr-diff.patch
          review-categories: |
            - security
            - performance
            - code-quality
            - best-practices
            - accessibility
          output-format: github-pr-review
          severity-threshold: warning

      - name: Generate Review Report
        uses: openai/codex-review-action@v2
        with:
          api-key: ${{ secrets.OPENAI_API_KEY }}
          model: o4-mini
          diff-file: pr-diff.patch
          review-categories:
            - security
            - performance
          output-format: json
          output-file: codex-review-report.json

      - name: Upload review report
        uses: actions/upload-artifact@v4
        with:
          name: codex-review
          path: codex-review-report.json

      - name: Post review summary
        uses: actions/github-script@v7
        with:
          script: |
            const report = require('./codex-review-report.json');
            const summary = `## 🔍 Codex Code Review Summary

            | Category | Issues Found | Severity |
            |----------|-------------|----------|
            | Security | ${report.security.critical} critical, ${report.security.warning} warning | ${report.security.critical > 0 ? '🔴 BLOCK' : '🟢 PASS'} |
            | Performance | ${report.performance.suggestions} suggestions | 🟡 INFO |
            | Code Quality | ${report.quality.issues} issues | ${report.quality.issues > 5 ? '🔴 BLOCK' : '🟢 PASS'} |
            | Best Practices | ${report.practices.violations} violations | 🟡 INFO |

            ### Key Findings
            ${report.findings.map(f => `- **${f.category}**: ${f.description}`).join('\n')}

            ${report.blocking ? '🚫 This PR has blocking issues that must be resolved.' : '✅ No blocking issues found.'}
            `;

            github.rest.issues.createComment({
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: context.issue.number,
              body: summary
            });

    outputs:
      has-blocking-issues: ${{ steps.review.outputs.blocking }}
      review-report-path: codex-review-report.json

3.2 Codex 审查规则详解

json
// codex-rules.json
{
  "security_rules": {
    "sql_injection": {
      "severity": "critical",
      "pattern": "User input used in SQL query without parameterization",
      "action": "block"
    },
    "xss_vulnerability": {
      "severity": "critical",
      "pattern": "User input rendered without sanitization in JSX/HTML",
      "action": "block"
    },
    "hardcoded_secrets": {
      "severity": "critical",
      "pattern": "API keys, passwords, tokens in source code",
      "action": "block"
    },
    "insecure_dependency": {
      "severity": "high",
      "pattern": "Dependencies with known CVEs",
      "action": "warn"
    }
  },
  "performance_rules": {
    "n_plus_one_query": {
      "severity": "high",
      "pattern": "Loop containing database query",
      "action": "warn"
    },
    "missing_useMemo": {
      "severity": "medium",
      "pattern": "Expensive computation in React render without memoization",
      "action": "suggest"
    },
    "unbounded_render": {
      "severity": "medium",
      "pattern": "Large list rendered without virtualization",
      "action": "suggest"
    }
  },
  "code_quality_rules": {
    "missing_error_handling": {
      "severity": "high",
      "pattern": "Async function without try/catch or error boundary",
      "action": "warn"
    },
    "magic_numbers": {
      "severity": "low",
      "pattern": "Unexplained numeric literals",
      "action": "suggest"
    },
    "complexity_threshold": {
      "severity": "medium",
      "pattern": "Cyclomatic complexity > 10",
      "action": "warn"
    }
  }
}

3.3 Codex 审查输出示例

json
{
  "review_id": "codex-rev-20260522-001",
  "timestamp": "2026-05-22T10:30:00Z",
  "pr_url": "https://github.com/org/repo/pull/123",
  "summary": {
    "total_files_reviewed": 8,
    "total_lines_changed": 342,
    "issues_found": 12,
    "blocking": false
  },
  "findings": [
    {
      "file": "backend/src/routes/users.ts",
      "line": 45,
      "category": "security",
      "severity": "critical",
      "description": "SQL query uses string concatenation with user input",
      "suggestion": "Use parameterized query: `SELECT * FROM users WHERE id = $1`",
      "code_before": "const query = `SELECT * FROM users WHERE id = ${userId}`;",
      "code_after": "const query = 'SELECT * FROM users WHERE id = $1';\nconst result = await pool.query(query, [userId]);"
    },
    {
      "file": "frontend/src/components/UserDashboard.tsx",
      "line": 23,
      "category": "performance",
      "severity": "medium",
      "description": "useEffect dependency array missing 'pageSize' variable",
      "suggestion": "Add 'pageSize' to the dependency array",
      "code_before": "useEffect(() => { loadData(currentPage); }, [currentPage]);",
      "code_after": "useEffect(() => { loadData(currentPage); }, [currentPage, loadData]);"
    }
  ]
}

四、阶段3:修复(Claude Code Agent)

4.1 Claude Code 自动修复

当 Codex 发现可自动修复的问题时,触发 Claude Code 进行自动修复:

yaml
  # ========== 阶段3:Claude Code 自动修复 ==========
  claude-fix:
    name: 🔧 Claude Code Auto-Fix
    needs: codex-review
    if: needs.codex-review.outputs.has-blocking-issues == 'true' || needs.codex-review.outputs.has-fixable-issues == 'true'
    runs-on: ubuntu-latest
    timeout-minutes: 30

    steps:
      - name: Checkout code
        uses: actions/checkout@v4
        with:
          token: ${{ secrets.CLAUDE_BOT_TOKEN }}
          ref: ${{ github.head_ref }}

      - name: Download review report
        uses: actions/download-artifact@v4
        with:
          name: codex-review
          path: ./review/

      - name: Claude Code Auto-Fix
        uses: anthropic/claude-code-action@v1
        with:
          api-key: ${{ secrets.ANTHROPIC_API_KEY }}
          model: claude-sonnet-4-20250514
          instructions: |
            你是一个自动化代码修复专家。请根据以下审查报告,
            自动修复所有可以安全修复的问题。

            修复规则:
            1. 优先修复 severity=critical 的问题
            2. 对于 security 类问题,必须修复
            3. 对于 performance 类建议,只修复明确的性能瓶颈
            4. 不要修改业务逻辑,只做安全/性能/规范修复
            5. 每个修复必须包含清晰的 commit message

            审查报告路径: ./review/codex-review-report.json

          allowed-edits:
            - security fixes
            - performance optimizations
            - lint/style fixes
            - missing error handling
          commit-message-prefix: "fix(claude): "

      - name: Run tests after fix
        run: |
          npm ci
          npm run lint
          npm run test -- --passWithNoTests
          npm run build

      - name: Push fixes
        run: |
          git config user.name "claude-fix-bot"
          git config user.email "claude-fix@actions.github.com"
          git add -A
          git commit -m "fix(claude): auto-fix from Codex review report

          Fixes applied:
          - Security: SQL injection prevention in users.ts
          - Performance: Missing useEffect dependencies
          - Code quality: Added error boundaries

          Review report: codex-review-report.json"
          git push origin ${{ github.head_ref }}

      - name: Post fix summary
        uses: actions/github-script@v7
        with:
          script: |
            github.rest.issues.createComment({
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: context.issue.number,
              body: `## 🔧 Claude Code Auto-Fix Complete\n\nClaude Code has automatically applied fixes based on the Codex review.\n\n### Changes Made\n- Fixed SQL injection vulnerability in users.ts\n- Added missing useEffect dependencies\n- Added error boundaries to async handlers\n\n### Next Steps\nPlease review the auto-fixes and approve if they look correct.`
            });

4.2 Claude Code 修复策略

Claude Code 在修复时遵循以下策略:

python
# claude-fix-strategy.py
"""
Claude Code 自动修复策略配置
"""

FIX_STRATEGIES = {
    "security": {
        "sql_injection": {
            "approach": "parameterized_query",
            "confidence_threshold": 0.95,
            "requires_review": False,  # 高置信度直接提交
        },
        "xss_prevention": {
            "approach": "escape_and_sanitize",
            "confidence_threshold": 0.9,
            "requires_review": False,
        },
        "hardcoded_secrets": {
            "approach": "env_variable_refactor",
            "confidence_threshold": 1.0,
            "requires_review": True,  # 涉及密钥变更需要人工审核
        },
    },
    "performance": {
        "n_plus_one": {
            "approach": "batch_query",
            "confidence_threshold": 0.85,
            "requires_review": True,
        },
        "missing_memoization": {
            "approach": "add_useMemo_useCallback",
            "confidence_threshold": 0.8,
            "requires_review": False,
        },
    },
    "code_quality": {
        "missing_error_handling": {
            "approach": "add_try_catch",
            "confidence_threshold": 0.9,
            "requires_review": False,
        },
        "complexity_reduction": {
            "approach": "extract_function",
            "confidence_threshold": 0.75,
            "requires_review": True,
        },
    },
}

def should_auto_fix(issue):
    """判断一个 issue 是否可以自动修复"""
    strategy = FIX_STRATEGIES.get(issue["category"], {}).get(issue["type"])
    if not strategy:
        return False

    # 检查置信度
    if issue.get("confidence", 0) < strategy["confidence_threshold"]:
        return False

    # 需要人工审核的问题标记为 requires_review
    if strategy["requires_review"]:
        return False

    return True

五、阶段4:部署(Hermes Agent)

5.1 Hermes 部署编排

审查通过、修复完成后,由 Hermes Agent 负责部署和多渠道通知:

yaml
  # ========== 阶段4:Hermes 部署与通知 ==========
  deploy:
    name: 🚀 Hermes Deploy & Notify
    needs: [build, codex-review, claude-fix]
    if: |
      always() &&
      needs.build.result == 'success' &&
      (needs.codex-review.result == 'success' || needs.codex-review.result == 'skipped') &&
      (needs.claude-fix.result == 'success' || needs.claude-fix.result == 'skipped') &&
      github.event_name == 'push' &&
      startsWith(github.ref, 'refs/heads/release/')
    runs-on: ubuntu-latest
    timeout-minutes: 30

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Download build artifacts
        uses: actions/download-artifact@v4
        with:
          name: build-output

      - name: Hermes Pre-deploy Check
        uses: nousresearch/hermes-agent-action@v1
        with:
          api-key: ${{ secrets.HERMES_API_KEY }}
          model: hermes-3
          system-prompt: |
            你是部署验证专家。请检查以下内容:
            1. 所有测试是否通过
            2. 代码审查是否有 blocking 问题
            3. 部署目标环境是否健康
          prompt: |
            部署前验证:
            - 构建状态: ${{ needs.build.result }}
            - 审查状态: ${{ needs.codex-review.result }}
            - 修复状态: ${{ needs.claude-fix.result }}
            - 目标环境: production
            - 版本: ${{ github.sha }}
          output-file: deploy-check.json

      - name: Deploy to Production
        if: steps.check.outputs.approved == 'true'
        run: |
          # 使用 Kubernetes 部署
          kubectl set image deployment/app \
            app=${{ env.DOCKER_REGISTRY }}/${{ github.repository }}/${{ env.APP_NAME }}:${{ github.sha }} \
            --record

          # 等待部署完成
          kubectl rollout status deployment/app --timeout=300s

          # 健康检查
          curl -f https://api.example.com/health || exit 1

      - name: Hermes Post-deploy Verification
        if: always()
        uses: nousresearch/hermes-agent-action@v1
        with:
          api-key: ${{ secrets.HERMES_API_KEY }}
          model: hermes-3
          system-prompt: "你是部署后验证专家,负责检查部署结果和发送通知。"
          prompt: |
            部署后验证:
            1. 检查 API 健康状态
            2. 验证关键功能是否正常
            3. 检查错误率是否有异常上升
            4. 生成部署报告
          output-file: deploy-verification.json

      - name: Send Notifications
        if: always()
        uses: nousresearch/hermes-agent-action@v1
        with:
          api-key: ${{ secrets.HERMES_API_KEY }}
          model: hermes-3
          system-prompt: "你是通知分发专家,负责将部署结果发送到各个渠道。"
          prompt: |
            请发送部署通知到以下渠道:

            1. **Slack** (#deployments 频道)
               - 部署状态:${{ job.status }}
               - 版本号:${{ github.sha }}
               - 变更摘要

            2. **微信** (团队群)
               - 使用 Hermes Gateway 发送
               - 中文消息

            3. **Email** (项目负责人)
               - 完整部署报告

            4. **GitHub** (PR 评论)
               - 部署结果
               - 验证报告链接

          output-file: notification-log.json

5.2 多渠道通知配置

yaml
# hermes-notification-config.yaml
notifications:
  slack:
    enabled: true
    webhook: ${{ secrets.SLACK_WEBHOOK }}
    channel: "#deployments"
    template: |
      :rocket: *Deployment {{ status }}*
      *App:* {{ app_name }}
      *Version:* `{{ sha_short }}`
      *Environment:* {{ environment }}
      *Duration:* {{ duration }}
      *Commit:* {{ commit_message }}
      {{#if errors}}
      :warning: *Errors:* {{ errors }}
      {{/if}}
      {{#if metrics}}
      *Metrics:*
      - Response Time: {{ metrics.response_time }}ms
      - Error Rate: {{ metrics.error_rate }}%
      - CPU: {{ metrics.cpu }}%
      {{/if}}

  wechat:
    enabled: true
    gateway: hermes-gateway
    chat_id: ${{ secrets.WECHAT_TEAM_GROUP }}
    template: |
      🚀 部署 {{ status_text }}

      📦 应用: {{ app_name }}
      🔖 版本: {{ sha_short }}
      🌍 环境: {{ environment }}
      ⏱️ 耗时: {{ duration }}
      📝 变更: {{ commit_message }}

      {{#if success}}
       健康检查通过
      📊 响应时间: {{ metrics.response_time }}ms
      {{/if}}
      {{#if failure}}
       部署失败,原因: {{ error }}
      🔧 请查看: {{ run_url }}
      {{/if}}

  email:
    enabled: true
    recipients:
      - tech-lead@company.com
      - devops@company.com
    template: deploy-report.html

  github:
    enabled: true
    comment_on_pr: true
    template: |
      ## 🚀 Deployment {{ status }}

      | Item | Value |
      |------|-------|
      | Commit | [`{{ sha_short }}`]({{ commit_url }}) |
      | Environment | {{ environment }} |
      | Duration | {{ duration }} |
      | Status | {{ status_emoji }} {{ status_text }} |

      {{ verification_report }}

三、流水线可视化

3.1 执行时间线示例

text
时间轴:
  00:00 ── PR 创建触发流水线
  00:01 ── [Build] 开始编译...
  00:03 ── [Build] Lint 检查通过
  00:05 ── [Build] 前端构建完成 (12.3MB bundle)
  00:06 ── [Build] 后端构建完成
  00:07 ── [Build] ✅ 完成 (7分钟)
  00:07 ── [Codex Review] 开始代码审查...
  00:09 ── [Codex Review] 安全审查完成 (1个 critical, 2个 warning)
  00:11 ── [Codex Review] 性能审查完成 (3个 suggestions)
  00:12 ── [Codex Review] ✅ 完成 (5分钟)
  00:12 ── [Claude Fix] 发现可自动修复问题,开始修复...
  00:15 ── [Claude Fix] 修复 SQL 注入问题
  00:16 ── [Claude Fix] 添加 useEffect 依赖
  00:17 ── [Claude Fix] 重新运行测试
  00:18 ── [Claude Fix] ✅ 完成 (6分钟)
  00:18 ── [Test] 运行全量测试...
  00:22 ── [Test] ✅ 完成 156/156 通过 (4分钟)
  00:22 ── [Hermes Deploy] 开始部署...
  00:23 ── [Hermes Deploy] 部署到 staging 环境
  00:24 ── [Hermes Deploy] 健康检查通过
  00:24 ── [Hermes Deploy] 部署到 production 环境
  00:25 ── [Hermes Deploy] 发送通知到 Slack/微信/Email
  00:25 ── [Hermes Deploy] ✅ 完成 (3分钟)

总耗时: 25分钟 (全自动化,无需人工干预)

四、错误处理与回滚

4.1 自动回滚机制

yaml
  rollback:
    name: 🔄 Auto-Rollback
    needs: deploy
    if: always() && needs.deploy.result == 'failure'
    runs-on: ubuntu-latest

    steps:
      - name: Trigger rollback via Hermes
        uses: nousresearch/hermes-agent-action@v1
        with:
          api-key: ${{ secrets.HERMES_API_KEY }}
          model: hermes-3
          system-prompt: "你是回滚操作专家。请立即执行回滚并通知团队。"
          prompt: |
            部署失败,需要回滚:
            - 失败版本: ${{ github.sha }}
            - 上一个稳定版本: ${{ steps.get-previous.outputs.sha }}
            - 错误信息: ${{ needs.deploy.outputs.error }}
          output-file: rollback-report.json

      - name: Execute rollback
        run: |
          # 回滚到上一个稳定版本
          kubectl rollout undo deployment/app

          # 验证回滚
          kubectl rollout status deployment/app --timeout=300s
          curl -f https://api.example.com/health || exit 1

      - name: Post-rollback notification
        run: |
          # 通过 Hermes 发送回滚通知
          hermes notify \
            --channel slack,wechat,email \
            --message "🔄 自动回滚完成" \
            --details rollback-report.json

4.2 告警升级策略

yaml
  alert-escalation:
    name: 🚨 Alert Escalation
    if: always() && failure()
    runs-on: ubuntu-latest

    steps:
      - name: Hermes Alert
        uses: nousresearch/hermes-agent-action@v1
        with:
          api-key: ${{ secrets.HERMES_API_KEY }}
          model: hermes-3
          system-prompt: "你是告警管理专家,负责根据错误严重程度升级通知。"
          prompt: |
            流水线失败告警升级策略:
            1. Level 1 (警告): 发送到 Slack #ci-alerts
            2. Level 2 (严重): 发送到 Slack + 微信 + Email
            3. Level 3 (紧急): 发送到所有渠道 + 电话通知值班人员

            当前失败信息:
            - 失败阶段: ${{ github.job }}
            - 错误类型: ${{ needs.deploy.outputs.error_type }}
            - 影响范围: ${{ needs.deploy.outputs.impact_scope }}

五、最佳实践

5.1 Agent 权限最小化

每个 Agent 只授予完成其任务所需的最小权限:

Agent 权限 禁止操作
Codex 读取代码、评论 PR 写入代码、合并 PR、访问密钥
Claude Code 修改代码、提交修复 合并 PR、访问生产环境
Hermes Deploy 部署到 staging/prod、发送通知 修改代码、审查代码

5.2 流水线配置管理

bash
# 将流水线配置版本化
pipeline-config/
├── stages/
│   ├── build.yml
│   ├── review.yml
│   ├── fix.yml
│   ├── test.yml
│   └── deploy.yml
├── agents/
│   ├── codex-config.json
│   ├── claude-config.json
│   └── hermes-config.json
├── notifications/
│   ├── slack-template.md
│   ├── wechat-template.md
│   └── email-template.html
└── rollback/
    └── strategy.yml

5.3 成本控制

typescript
// 成本优化策略
const costOptimization = {
  // Codex 只在变更行数 > 50 时启动
  codexThreshold: 50,
  // Claude Fix 只处理 critical/high 级别问题
  claudeMinSeverity: "high",
  // Hermes 部署只在 release 分支触发
  hermesTriggerBranches: ["release/*"],
  // 缓存审查结果,相同变更不重复审查
  reviewCache: true,
  // 限制单次审查的最大文件数
  maxReviewFiles: 20,
};

总结

本文完整演示了如何构建一条 多 Agent CI/CD 流水线,将构建、审查、修复、部署四个阶段分别交给最合适的 Agent 处理:

  1. 构建阶段(GitHub Actions + Hermes 辅助):编译、Lint、构建产物,Hermes 辅助诊断构建错误
  2. 审查阶段(Codex Agent):自动代码审查,覆盖安全、性能、代码质量等多个维度,直接在 PR 上发表评论
  3. 修复阶段(Claude Code Agent):根据审查结果自动修复可安全修复的问题,提交修复 commit
  4. 部署阶段(Hermes Agent):部署到目标环境,执行健康检查,多渠道发送通知(Slack、微信、Email、GitHub)

关键收获:

  • 四阶段流水线总耗时约 25 分钟,全程无需人工干预
  • Codex 的审查报告直接在 PR 上展示,Claude Code 的修复自动推送
  • Hermes 作为最终部署和通知的"调度中心",确保部署结果及时传达
  • 自动回滚机制保证部署失败时快速恢复

下篇预告

多AgentCodeReview流水线

在下一篇中,我们将深入探讨 交叉 Code Review 机制——这是多 Agent 协作中最有趣也最有挑战性的场景。你将看到:

  • 🔄 Agent A 审查 Agent B 的代码,Agent B 审查 Agent A 的代码
  • 🔒 Agent C 专职安全审查,独立于功能审查之外
  • 📊 审查结果聚合与冲突解决策略
  • 如何避免 Agent 之间的"审查疲劳"和"偏见循环"
  • 真实场景下的交叉审查案例与效果对比