CCJK Hub
使用场景2024年12月19日

使用 CCJK 进行代码审查:从代码质量到智能代理的完整工作流

深入了解如何使用 CCJK 的 ShenCha 审查引擎和 CCR 代理路由器,构建高效的代码审查工作流,提升代码质量并优化成本

CCJK 技术团队
代码审查ShenChaCCR代码质量智能代理

在现代软件开发中,代码审查是确保代码质量、安全性和可维护性的关键环节。传统的人工代码审查虽然有效,但面临着效率低下、主观性强、成本高昂等问题。今天,我们将探讨如何使用 CCJK 的 ShenCha 审查引擎和 CCR 代理路由器,构建一个智能化、自动化的代码审查系统,让团队能够在保证质量的同时提升开发效率。

使用场景:大型前端项目的代码审查挑战

项目背景

假设我们负责一个大型电商平台的前端项目,团队有 15 名开发者,日均提交 50+ 个 PR。项目包含:

  • 代码规模:50,000+ 行 TypeScript/React 代码
  • 技术栈:React 18 + TypeScript + Next.js + TailwindCSS
  • 开发团队:前端工程师(8人)+ 全栈工程师(5人)+ 实习生(2人)
  • 业务模块:用户中心、商品管理、订单系统、支付模块、营销活动

面临的挑战

  1. 审查效率低:资深工程师需要花费大量时间进行代码审查
  2. 质量不一致:不同审查者的标准不统一
  3. 安全隐患:支付相关代码的安全问题容易被忽视
  4. 成本考虑:频繁使用 Claude Opus 进行代码分析成本过高
  5. 知识传递:新人代码质量参差不齐,需要更多指导

完整工作流程

第一步:配置 CCR 代理路由器

首先,我们需要配置 CCR 来优化不同类型审查任务的成本和效率。

hljs bash
# 安装并启动 CCR ccjk ccr install ccjk ccr start # 检查服务状态 ccjk ccr status

配置多模型路由策略:

hljs yaml
# .ccr/config.yaml name: "code-review-router" version: "1.0" providers: # 免费模型 - 处理简单代码检查 deepseek: endpoint: "https://api.deepseek.com/v1" models: - "deepseek-coder" cost_per_token: 0.00014 # 快速模型 - 处理常规审查 claude_haiku: endpoint: "https://api.anthropic.com/v1" models: - "claude-3-haiku-20240307" cost_per_token: 0.00025 # 高质量模型 - 处理复杂逻辑和安全审查 claude_opus: endpoint: "https://api.anthropic.com/v1" models: - "claude-3-opus-20240229" cost_per_token: 0.015 routes: # 代码格式和基础检查 -> 免费模型 - name: "basic-check" pattern: keywords: ["format", "lint", "import", "export", "syntax"] file_types: [".ts", ".tsx", ".js", ".jsx"] max_tokens: 1000 target: "deepseek" # 常规业务逻辑审查 -> 快速模型 - name: "business-logic" pattern: keywords: ["component", "hook", "util", "helper"] file_types: [".ts", ".tsx"] max_tokens: 3000 target: "claude_haiku" # 安全敏感代码 -> 高质量模型 - name: "security-critical" pattern: keywords: ["auth", "payment", "crypto", "password", "token", "session"] file_patterns: ["**/auth/**", "**/payment/**", "**/api/secure/**"] target: "claude_opus" priority: "high" # 复杂算法和架构 -> 高质量模型 - name: "complex-logic" pattern: complexity_threshold: 10 file_size_threshold: 500 target: "claude_opus" # 成本优化配置 cost_optimization: enabled: true daily_budget: 50.0 # 每日预算 $50 fallback_strategy: "downgrade" # 超预算时降级到便宜模型 # 监控配置 monitoring: enabled: true web_ui: true port: 8080

第二步:配置 ShenCha 审查引擎

接下来配置针对电商项目特点的审查规则:

hljs yaml
# .shencha.yaml version: 1 name: "ecommerce-frontend-review" # 审查范围 include: - src/**/*.ts - src/**/*.tsx - pages/**/*.tsx - components/**/*.tsx exclude: - "**/*.test.ts" - "**/*.spec.ts" - "**/*.stories.tsx" - node_modules/** - .next/** # 针对电商项目的审查规则 rules: # 代码质量 quality: maxComplexity: 12 # 电商逻辑相对复杂,适当放宽 maxFileLines: 400 maxFunctionLines: 60 requireComments: true naming: style: "camelCase" prefixes: components: ["use", "with", "handle"] types: ["I", "T"] # 安全规则(电商项目严格要求) security: level: strict checkDependencies: true sensitivePatterns: - password - secret - apiKey - creditCard - paymentToken sensitiveFiles: - "**/payment/**" - "**/auth/**" - "**/api/secure/**" # 性能规则(用户体验关键) performance: checkNPlusOne: true checkMemoryLeaks: true maxBundleSize: 600kb # 电商页面允许稍大 requireLazyLoading: true checkImageOptimization: true # 电商特定最佳实践 bestPractices: framework: react typescript: strict accessibility: level: "AA" # 符合 WCAG 2.1 AA 标准 seo: requireMetaTags: true requireStructuredData: true testing: minCoverage: 75 # 业务逻辑要求高覆盖率 requireE2ETests: true # 自定义电商规则 customRules: # 价格处理规则 - id: "ecommerce/price-precision" pattern: "price.*[*/]" message: "价格计算必须使用精确数学库,避免浮点数精度问题" severity: error suggestion: "使用 decimal.js 或 big.js 进行价格计算" # 支付安全规则 - id: "ecommerce/payment-logging" pattern: "console\\.log.*(?:card|payment|billing)" message: "支付相关信息禁止输出到日志" severity: error files: "**/payment/**" # 用户数据保护 - id: "ecommerce/pii-exposure" pattern: "(?:email|phone|address).*localStorage" message: "个人敏感信息不应存储在 localStorage" severity: warning suggestion: "使用加密存储或会话存储" # 商品数据验证 - id: "ecommerce/product-validation" pattern: "product.*price.*[<>]\\s*0" message: "商品价格验证应考虑负数和零值情况" severity: warning # 分级审查配置 reviewLevels: intern: # 实习生代码 - 严格审查 rules: security: strict quality: strict bestPractices: strict aiModel: "claude-opus" junior: # 初级工程师 rules: security: strict quality: moderate bestPractices: moderate aiModel: "claude-haiku" senior: # 高级工程师 rules: security: strict quality: relaxed bestPractices: relaxed aiModel: "deepseek-coder" # 报告配置 report: format: markdown output: ./reviews/shencha-report.md includeCode: true includeMetrics: true maxIssues: 30 groupBy: ["severity", "category", "file"]

第三步:设置自动化工作流

配置 Git hooks 和 CI/CD 集成:

hljs yaml
# .claude/hooks/pre-commit-review.yaml name: automated-code-review event: onPreCommit stages: - name: "快速检查" condition: "changed_files < 5" handler: command: "/shencha --changed --level basic" timeout: 30s - name: "完整审查" condition: "changed_files >= 5 OR contains_payment_files" handler: command: "/shencha --changed --level full" timeout: 120s - name: "安全专项审查" condition: "touches_security_files" handler: command: "/shencha --changed --security --ai-model claude-opus" timeout: 180s onFailure: action: block message: | 🚫 代码审查发现问题,请修复后再提交: 📋 查看详细报告: cat .shencha/last-report.md 🔧 自动修复: /shencha --changed --fix 💬 获取帮助: /ask "如何修复 ShenCha 发现的问题?"
hljs yaml
# .github/workflows/shencha-review.yml name: Automated Code Review on: pull_request: types: [opened, synchronize, reopened] jobs: shencha-review: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v3 with: fetch-depth: 0 - name: Setup Node.js uses: actions/setup-node@v3 with: node-version: '18' cache: 'npm' - name: Install dependencies run: npm ci - name: Setup CCJK run: | npm install -g ccjk ccjk ccr start --config .ccr/config.yaml - name: Run ShenCha Review id: review run: | ccjk shencha --ci \ --report json \ --output review-report.json \ --fail-on error env: CCJK_API_KEY: ${{ secrets.CCJK_API_KEY }} - name: Generate Review Summary uses: actions/github-script@v6 with: script: | const fs = require('fs'); const report = JSON.parse(fs.readFileSync('review-report.json', 'utf8')); // 生成审查摘要 const summary = ` ## 🔍 代码审查报告 **总体评分**: ${report.overallScore}/10 **审查文件**: ${report.filesReviewed}个 **发现问题**: ${report.totalIssues}个 ### 📊 问题分布 - 🔴 严重: ${report.criticalIssues}个 - 🟡 警告: ${report.warningIssues}个 - 🔵 信息: ${report.infoIssues}个 ### 🏷️ 主要问题类别 ${report.issueCategories.map(cat => `- ${cat.name}: ${cat.count}个`).join('\n')} ### 💰 AI 使用成本 - 本次审查成本: $${report.cost.toFixed(4)} - 模型使用: ${report.modelUsage.map(m => `${m.model}(${m.requests}次)`).join(', ')} ${report.criticalIssues > 0 ? '⚠️ **发现严重问题,建议修复后合并**' : '✅ **代码质量良好,可以合并**'} `; github.rest.issues.createComment({ issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, body: summary }); - name: Upload Review Artifacts uses: actions/upload-artifact@v3 if: always() with: name: code-review-report path: | review-report.json .shencha/detailed-report.md

第四步:实际使用场景演示

现在让我们看几个典型的代码审查场景:

场景1:新人提交的支付组件

假设实习生小李提交了一个支付表单组件:

hljs typescript
// src/components/payment/PaymentForm.tsx import React, { useState } from 'react'; interface PaymentFormProps { onSubmit: (data: any) => void; } const PaymentForm: React.FC<PaymentFormProps> = ({ onSubmit }) => { const [cardNumber, setCardNumber] = useState(''); const [cvv, setCvv] = useState(''); const [expiry, setExpiry] = useState(''); const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); console.log('Payment data:', { cardNumber, cvv, expiry }); // 问题! // 简单验证 if (cardNumber.length === 16) { // 问题! const total = 99.99 + 5.50; // 问题!浮点数精度 onSubmit({ cardNumber: cardNumber, cvv: cvv, expiry: expiry, total: total }); } }; return ( <form onSubmit={handleSubmit}> <input type="text" placeholder="Card Number" value={cardNumber} onChange={(e) => setCardNumber(e.target.value)} /> <input type="text" placeholder="CVV" value={cvv} onChange={(e) => setCvv(e.target.value)} /> <input type="text" placeholder="MM/YY" value={expiry} onChange={(e) => setExpiry(e.target.value)} /> <button type="submit">Pay Now</button> </form> ); }; export default PaymentForm;

运行审查:

hljs bash
# 检测到支付相关文件,自动使用 Claude Opus 进行安全审查 /shencha src/components/payment/PaymentForm.tsx

ShenCha 审查结果:

🛡️ 支付组件安全审查报告

🔴 严重问题 (3):
1. [SECURITY-001] 支付敏感信息输出到控制台
   位置: line 13
   代码: console.log('Payment data:', { cardNumber, cvv, expiry });
   风险: 敏感支付信息可能泄露到日志
   修复: 移除日志输出或使用脱敏处理

2. [SECURITY-002] 信用卡号验证过于简单
   位置: line 16  
   代码: if (cardNumber.length === 16)
   风险: 无效的信用卡号可能通过验证
   修复: 使用 Luhn 算法验证信用卡号

3. [ECOMMERCE-001] 价格计算使用浮点数
   位置: line 17
   代码: const total = 99.99 + 5.50;
   风险: 浮点数精度问题可能导致金额错误
   修复: 使用 decimal.js 进行精确计算

🟡 警告 (4):
4. [ACCESSIBILITY-001] 表单缺少标签和错误提示
5. [SECURITY-003] 输入框未限制最大长度
6. [TYPES-001] onSubmit 参数类型过于宽泛 (any)
7. [VALIDATION-001] 缺少客户端验证

💡 修复建议:
需要我帮您自动修复这些问题吗?我将:
1. 移除敏感信息的日志输出
2. 添加信用卡号 Luhn 验证
3. 使用 decimal.js 进行价格计算
4. 改进类型定义和表单验证
5. 添加无障碍支持

用户确认后,ShenCha 提供修复版本:

hljs typescript
// ShenCha 修复后的版本 import React, { useState } from 'react'; import { Decimal } from 'decimal.js'; import { validateCardNumber, validateCVV, validateExpiry } from '@/utils/payment-validation'; interface PaymentData { cardNumber: string; cvv: string; expiry: string; total: string; // 使用字符串避免精度问题 } interface PaymentFormProps { onSubmit: (data: PaymentData) => void; baseAmount: number; shippingCost: number; } const PaymentForm: React.FC<PaymentFormProps> = ({ onSubmit, baseAmount, shippingCost }) => { const [cardNumber, setCardNumber] = useState(''); const [cvv, setCvv] = useState(''); const [expiry, setExpiry] = useState(''); const [errors, setErrors] = useState<Record<string, string>>({}); const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); const validationErrors: Record<string, string> = {}; // 验证信用卡号(使用 Luhn 算法) if (!validateCardNumber(cardNumber)) { validationErrors.cardNumber = '请输入有效的信用卡号'; } // 验证 CVV if (!validateCVV(cvv)) { validationErrors.cvv = '请输入有效的 CVV'; } // 验证有效期 if (!validateExpiry(expiry)) { validationErrors.expiry = '请输入有效的有效期 (MM/YY)'; } setErrors(validationErrors); if (Object.keys(validationErrors).length === 0) { // 使用 Decimal.js 进行精确计算 const total = new Decimal(baseAmount).plus(shippingCost).toString(); onSubmit({ cardNumber: cardNumber.replace(/\s/g, ''), // 移除空格 cvv, expiry, total }); } }; return ( <form onSubmit={handleSubmit} noValidate> <div> <label htmlFor="cardNumber">信用卡号 *</label> <input id="cardNumber" type="text" placeholder="1234 5678 9012 3456" value={cardNumber} maxLength={19} // 16位数字 + 3个空格 onChange={(e) => setCardNumber(e.target.value)} aria-invalid={!!errors.cardNumber} aria-describedby={errors.cardNumber ? "cardNumber-error" : undefined} /> {errors.cardNumber && ( <span id="cardNumber-error" role="alert" className="error"> {errors.cardNumber} </span> )} </div> <div> <label htmlFor="cvv">CVV *</label> <input id="cvv" type="text" placeholder="123" value={cvv} maxLength={4} onChange={(e) => setCvv(e.target.value)} aria-invalid={!!errors.cvv} aria-describedby={errors.cvv ? "cvv-error" : undefined} /> {errors.cvv && ( <span id="cvv-error" role="alert" className="error"> {errors.cvv} </span> )} </div> <div> <label htmlFor="expiry">有效期 *</label> <input id="expiry" type="text" placeholder="MM/YY" value={expiry} maxLength={5} onChange={(e) => setExpiry(e.target.value)} aria-invalid={!!errors.expiry} aria-describedby={errors.expiry ? "expiry-error" : undefined} /> {errors.expiry && ( <span id="expiry-error" role="alert" className="error"> {errors.expiry} </span> )} </div> <button type="submit"> 立即支付 ¥{new Decimal(baseAmount).plus(shippingCost).toFixed(2)} </button> </form> ); }; export default PaymentForm;

场景2:高级工程师的商品列表优化

资深工程师张三提交了商品列表性能优化:

hljs typescript
// src/components/product/ProductList.tsx import React, { useMemo } from 'react'; import { Product } from '@/types/product'; interface ProductListProps { products: Product[]; onProductClick: (id: string) => void; } const ProductList: React.FC<ProductListProps> = ({ products, onProductClick }) => { const sortedProducts = useMemo(() => { return products.sort((a, b) => b.rating - a.rating); }, [products]); return ( <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6"> {sortedProducts.map(product => ( <ProductCard key={product.id} product={product} onClick={() => onProductClick(product.id)} /> ))} </div> ); };

由于是资深工程师的代码,CCR 自动使用 DeepSeek 进行基础检查:

hljs bash
# 自动检测到高级工程师,使用轻量级审查 /shencha src/components/product/ProductList.tsx --author senior

审查结果:

✅ 代码质量良好 (8.5/10)

优点:
• 正确使用 useMemo 优化排序性能
• 类型定义完整
• 组件职责单一

🟡 可选优化建议 (1):
1. [PERF-001] 大列表可考虑虚拟化
   建议: 当 products.length > 100 时使用 react-window

💰 成本报告:
- 使用模型: DeepSeek Coder
- 审查耗时: 3.2秒  
- 成本: $0.0008

场景3:批量审查整个功能模块

产品经理要求审查整个购物车模块:

hljs bash
# 审查购物车相关所有文件 /shencha src/features/cart/ --deep --report html

ShenCha 生成详细的模块级审查报告:

🛒 购物车模块审查报告

📁 审查范围: src/features/cart/ (15 个文件)
⏱️  审查时间: 2分35秒  
🤖 使用模型: Claude Haiku (12个文件), Claude Opus (3个安全关键文件)
💰 总成本: $0.24

📊 总体评分: 7.8/10

模块结构分析:
├── components/           8.5/10  ✅ 优秀
├── hooks/               8.0/10  ✅ 良好  
├── utils/               7.2/10  ⚠️ 需改进
├── types/               9.0/10  ✅ 优秀
└── api/                 6.5/10  ⚠️ 需关注

🔍 发现的问题:

高优先级 (2):
1. utils/price-calculator.ts: 价格计算精度问题
2. api/cart-service.ts: 缺少错误重试机制

中优先级 (5):
3. hooks/useCart.ts: 状态更新可能导致不必要重渲染  
4. components/CartItem.tsx: 无障碍属性不完整
5. utils/storage.ts: localStorage 异常处理缺失
6. types/cart.ts: 部分类型定义过于宽泛
7. api/discount-service.ts: 优惠券验证逻辑复杂

低优先级 (8):
8-15. 代码风格和注释改进建议...

🎯 改进建议:

立即修复:
• price-calculator.ts 的浮点数计算问题
• cart-service.ts 添加网络异常处理

短期优化:
• 优化 useCart hook 的性能
• 完善无障碍支持
• 改进错误处理

长期规划:
• 考虑引入状态管理库(Zustand/Redux)
• 抽象通用的 API 错误处理逻辑
• 添加更多单元测试覆盖

📈 模块健康度趋势:
- 代码质量: 7.5 → 7.8 (+4%) 
- 测试覆盖: 72% → 78% (+6%)
- 性能评分: 7.0 → 8.2 (+17%)
- 安全性: 8.0 → 8.5 (+6%)

实用技巧分享

1. 成本优化策略

通过 CCR 的智能路由,我们实现了显著的成本节约:

hljs bash
# 查看成本分析报告 ccjk ccr metrics --period 30d # 输出示例 CCR 成本优化报告 (最近30天) ──────────────────────────── 总体节约: 62% ($450$171) 模型使用分布: ┌─────────────────┬────────────┬─────────────┬──────────┐ │ 模型 │ 请求次数 │ 总成本 │ 平均成本 │ ├─────────────────┼────────────┼─────────────┼──────────┤ │ DeepSeek │ 2,847 │ $23.45 │ $0.008 │ │ Claude Haiku │ 1,256 │ $87.32 │ $0.069 │ │ Claude Opus │ 187 │ $134.78 │ $0.721 │ └─────────────────┴────────────┴─────────────┴──────────┘ 任务类型分布: • 基础检查 (67%): DeepSeek 处理,节约 85% • 业务审查 (28%): Haiku 处理,节约 45% • 安全审查 (5%): Opus 处理,保证质量 优化建议: ✅ 当前配置已优化良好 💡 可考虑增加更多基础检查规则到 DeepSeek

2. 团队协作最佳实践

建立审查等级制度

hljs yaml
# .shencha/team-config.yaml authors: intern: emails: ["intern1@company.com", "intern2@company.com"] review_level: "strict" ai_model: "claude-opus" require_manual_approval: true junior: emails: ["dev1@company.com", "dev2@company.com"] review_level: "standard" ai