CodeBuddy 高级进阶教程

深度掌握 CodeBuddy,释放 AI 编程的极致潜能

目录


进阶概述

本教程面向已经掌握 CodeBuddy 基础用法的开发者,帮助你深入理解其高级特性,构建符合团队需求的高效 AI 编程工作流。

前置要求:

  • ✅ 已安装并熟悉 CodeBuddy 基础操作
  • ✅ 了解常用的命令行操作
  • ✅ 具备一定的编程经验

高级配置

系统提示词自定义

CodeBuddy 提供三种自定义系统提示词的方式,让你完全掌控 AI 的行为模式。

1. 完全替换系统提示词

使用 --system-prompt 参数,移除所有默认指令:

codebuddy --system-prompt "你是只编写带类型注解代码的 Python 专家,遵循 PEP 8 规范,注重代码可读性和性能"

适用场景: 需要完全定制 AI 行为的专用场景。

2. 从文件加载提示词

使用 --system-prompt-file 参数,确保提示词的可重现性和版本控制:

# 创建提示词文件
cat > my-prompt.txt << 'EOF'
你是资深的后端工程师,专精于高并发系统设计。
编码原则:
1. 优先考虑性能和可扩展性
2. 使用异步 I/O 处理并发请求
3. 添加详细的性能监控日志
4. 所有公共 API 必须有完整的类型注解
EOF

# 使用文件加载提示词
codebuddy -p --system-prompt-file my-prompt.txt "设计一个高性能的用户认证系统"

适用场景: 团队协作,需要统一 AI 编码标准。

3. 追加系统提示词

使用 --append-system-prompt 参数,在保留默认功能的基础上添加特定指令:

codebuddy --append-system-prompt "始终使用 TypeScript 并包含 JSDoc 注释"

适用场景: 大多数用例,推荐方式。

权限模式配置

CodeBuddy 支持三种权限模式,根据安全需求选择:

模式 说明 使用命令
auto 自动模式,对可信操作自动授权 codebuddy --permission-mode auto
plan 计划模式,先展示计划再执行 codebuddy --permission-mode plan
manual 手动模式,每步操作都需要确认 codebuddy --permission-mode manual

多模型切换

根据任务类型选择最合适的模型:

# 使用特定模型
codebuddy --model deepseek-v3.1

# 设置文生图模型
codebuddy --text-to-image-model your-image-model

# 设置图生图模型
codebuddy --image-to-image-model your-edit-model

模型选择建议:

  • 代码生成: DeepSeek-V3.1
  • 复杂推理: DeepSeek-R1
  • 中文对话: 混元 Turbo S
  • 快速响应: 混元 Lite

MCP 生态集成

MCP (Model Context Protocol) 是 CodeBuddy 的核心竞争力,让 AI 能够调用外部工具和服务。

什么是 MCP

MCP 是一个开放协议,允许 AI 助手与外部系统进行标准化交互,实现:

  • 🔄 自动化测试和部署
  • 📊 数据库查询和分析
  • 🔐 安全扫描和合规检查
  • 📧 通知和协作集成

配置 MCP 服务器

# 初始化 MCP 配置
codebuddy mcp init

# 添加 MCP 服务器
codebuddy mcp add github
codebuddy mcp add docker
codebuddy mcp add postgres

常用 MCP 服务器

GitHub MCP
# 添加 GitHub MCP
codebuddy mcp add github

# 使用示例
codebuddy "检查我的 PR 是否有冲突"
codebuddy "分析最近一周的提交记录"
Docker MCP
# 添加 Docker MCP
codebuddy mcp add docker

# 使用示例
codebuddy "重启所有停止的容器"
codebuddy "检查镜像占用空间"
PostgreSQL MCP
# 添加 PostgreSQL MCP
codebuddy mcp add postgres

# 使用示例
codebuddy "查询用户表中注册日期最近的 10 个用户"
codebuddy "优化慢查询"

自定义 MCP 服务器

创建自定义 MCP 工具:

// mcp-tools/custom-tool.js
module.exports = {
  name: 'custom-analyzer',
  description: '自定义代码分析工具',
  execute: async (params) => {
    // 实现你的逻辑
    return {
      result: '分析完成',
      metrics: params
    };
  }
};

自定义智能体与 Skills

自定义智能体让你能够创建专门的 AI 助手,处理特定类型的任务。Skills 是智能体的核心能力单元,定义了智能体可以执行的具体操作。

理解 Agent 与 Skills 的关系

Agent (智能体)
├── System Prompt (系统提示词): 定义智能体的角色和职责
├── Skills (技能集): 智能体可执行的具体能力
│   ├── Code Analysis (代码分析)
│   ├── Test Generation (测试生成)
│   ├── Documentation (文档生成)
│   └── Custom Skills (自定义技能)
├── Tools (工具集): 可调用的外部工具
└── Configuration (配置): 参数和行为设置

创建项目级智能体

基础智能体配置

在项目根目录创建智能体配置:

# .codebuddy/agents/backend-reviewer.yaml
name: Backend Reviewer
description: 专注于后端代码审查的智能体
version: 1.0.0

# 系统提示词: 定义智能体的角色
system_prompt: |
  你是后端代码审查专家,专注于:
  - Java/后端代码质量检查
  - 数据库查询优化
  - API 接口设计规范
  - 性能和安全性分析
  
  审查标准:
  1. 遵循阿里巴巴 Java 开发规范
  2. 识别 N+1 查询问题
  3. 检查事务管理是否正确
  4. 验证异常处理是否完善

# Skills 定义: 智能体的能力集合
skills:
  # Skill 1: 代码审查
  - name: code_review
    description: 审查 Java 代码质量和规范
    enabled: true
    config:
      check_style: true
      check_performance: true
      check_security: true
      frameworks:
        - spring-boot
        - mybatis
        - jpa
  
  # Skill 2: 数据库优化
  - name: database_optimization
    description: 分析和优化数据库查询
    enabled: true
    config:
      check_n_plus_one: true
      suggest_indexes: true
      analyze_slow_queries: true
  
  # Skill 3: API 文档生成
  - name: api_documentation
    description: 生成 RESTful API 文档
    enabled: true
    config:
      format: markdown
      include_examples: true
      include_auth_requirements: true
  
  # Skill 4: 单元测试生成
  - name: test_generation
    description: 为 Java 类生成单元测试
    enabled: true
    config:
      framework: junit5
      mock_framework: mockito
      coverage_target: 80

# 可用的工具
tools:
  - maven
  - gradle
  - sonarqube
  - checkstyle
  - pmd

# 环境配置
environment:
  java_version: "17"
  build_tool: "maven"
创建企业级 Java 审查智能体
# .codebuddy/agents/java-enterprise-auditor.yaml
name: Java Enterprise Auditor
description: 企业级 Java 代码审计智能体
version: 2.0.0
author: DevOps Team

# 系统提示词
system_prompt: |
  你是企业级 Java 代码审计专家,严格遵循:
  - 阿里巴巴 Java 开发手册(泰山版)
  - 企业内部安全规范
  - 金融行业安全标准
  - 数据保护法规(如 GDPR、个人信息保护法)
  
  审查重点:
  1. 安全漏洞(SQL 注入、XSS、CSRF、反序列化)
  2. 性能问题(内存泄漏、线程池配置、连接池配置)
  3. 代码质量(重复代码、复杂度、命名规范)
  4. 业务逻辑(事务一致性、并发控制、幂等性)
  
  输出要求:
  - 问题按严重程度分级(严重/高危/中危/低危/提示)
  - 提供具体的代码位置和修复建议
  - 生成可执行的修复代码
  - 评估修复风险和影响范围

# Skills 详细定义
skills:
  # Skill: 安全审计
  - name: security_audit
    description: 执行全面的安全审计
    enabled: true
    priority: high
    config:
      check_items:
        - sql_injection
        - xss
        - csrf
        - path_traversal
        - insecure_deserialization
        - weak_encryption
        - hardcoded_secrets
        - ldap_injection
      frameworks:
        - spring-security
        - shiro
        - apache-shiro
  
  # Skill: 性能分析
  - name: performance_analysis
    description: 分析代码性能瓶颈
    enabled: true
    priority: high
    config:
      check_items:
        - memory_leaks
        - thread_pool_config
        - connection_pool_config
        - cache_efficiency
        - database_query_performance
        - n_plus_one_queries
        - unnecessary_object_creation
      thresholds:
        method_complexity: 10
        class_complexity: 50
        cyclomatic_complexity: 15
  
  # Skill: 代码规范检查
  - name: style_check
    description: 检查代码规范和最佳实践
    enabled: true
    priority: medium
    config:
      checkstyle_rules: google_checks.xml
      pmd_rules: rulesets/java/quickstart.xml
      spotbugs_enabled: true
  
  # Skill: 依赖分析
  - name: dependency_analysis
    description: 分析项目依赖安全性
    enabled: true
    priority: high
    config:
      check_vulnerabilities: true
      check_licenses: true
      check_outdated: true
      allowed_licenses:
        - Apache-2.0
        - MIT
        - BSD-3-Clause
  
  # Skill: 架构评估
  - name: architecture_review
    description: 评估代码架构设计
    enabled: true
    priority: medium
    config:
      check_solid_principles: true
      check_design_patterns: true
      check_layering: true
      check_coupling: true

# 工具集成
tools:
  maven:
    enabled: true
    goals:
      - compile
      - test
      - checkstyle:check
      - pmd:check
      - spotbugs:check
      - dependency-check
  
  sonarqube:
    enabled: true
    url: ${SONARQUBE_URL}
    quality_gate: true
  
  jenkins:
    enabled: true
    pipeline_integration: true

# 输出配置
output:
  format:
    - console
    - markdown
    - json
  include_code_examples: true
  include_fix_suggestions: true
  generate_report: true

# 审查规则
review_rules:
  severity_levels:
    critical:
      auto_fail: true
      examples:
        - hardcoded_passwords
        - sql_injection_vulnerabilities
        - memory_leaks
    high:
      examples:
        - n_plus_one_queries
        - missing_error_handling
        - insecure_random
    medium:
      examples:
        - code_duplication
        - poor_naming
        - missing_documentation
    low:
      examples:
        - unused_imports
        - magic_numbers

使用 Skills 的实战示例

示例 1: 使用 Java 审查智能体
# 启动 CodeBuddy
codebuddy

# 初始化项目
> /init

# 使用智能体进行代码审查
> 使用 java-enterprise-auditor 智能体审查以下文件:
  @src/main/java/com/company/user/service/UserService.java
  @src/main/java/com/company/user/controller/UserController.java
  @src/main/java/com/company/user/repository/UserRepository.java
  
  重点检查:
  1. SQL 注入风险
  2. 事务管理是否正确
  3. N+1 查询问题
  4. 敏感信息是否加密

被审查的 Java 代码示例:

// src/main/java/com/company/user/service/UserService.java
package com.company.user.service;

import com.company.user.entity.User;
import com.company.user.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
public class UserService {
    
    @Autowired
    private UserRepository userRepository;
    
    // 问题 1: 没有输入验证
    // 问题 2: SQL 注入风险(如果使用原生 SQL)
    public User findUserById(Long userId) {
        return userRepository.findById(userId).orElse(null);
    }
    
    // 问题 3: 可能存在 N+1 查询
    @Transactional
    public List<User> findUsersWithOrders(List<Long> userIds) {
        List<User> users = userRepository.findAllById(userIds);
        
        // 这里会触发 N+1 查询
        for (User user : users) {
            user.getOrders().size(); // 触发延迟加载
        }
        
        return users;
    }
    
    // 问题 4: 敏感信息明文存储
    public void createUser(String username, String password, String email) {
        User user = new User();
        user.setUsername(username);
        user.setPassword(password); // 密码未加密
        user.setEmail(email);
        userRepository.save(user);
    }
    
    // 问题 5: 事务边界不清晰
    @Transactional
    public void updateUserProfile(Long userId, String email) {
        User user = findUserById(userId);
        user.setEmail(email);
        userRepository.save(user);
        // 这里调用外部服务可能导致事务超时
        externalService.sendEmail(user);
    }
    
    // 问题 6: 异常处理不当
    public User getUserByEmail(String email) {
        try {
            return userRepository.findByEmail(email);
        } catch (Exception e) {
            // 吞掉异常,无法追踪问题
            return null;
        }
    }
}

CodeBuddy 审查结果:

# 📋 Java Enterprise Auditor 审查报告

## 🔴 严重问题 (Critical)

### 1. 密码明文存储
**位置:** `UserService.java:32`
**风险等级:** 🔴 Critical
**问题描述:** 用户密码未加密直接存储,存在严重安全隐患

**当前代码:**
```java
user.setPassword(password); // 密码未加密

修复建议:

import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

@Autowired
private BCryptPasswordEncoder passwordEncoder;

public void createUser(String username, String password, String email) {
    User user = new User();
    user.setUsername(username);
    user.setPassword(passwordEncoder.encode(password)); // 加密存储
    user.setEmail(email);
    userRepository.save(user);
}

影响范围: 所有用户账户安全
修复优先级: 立即修复


2. SQL 注入风险

位置: UserService.java:18
风险等级: 🔴 Critical
问题描述: 如果 UserRepository 使用原生 SQL,存在 SQL 注入风险

修复建议:

// 使用 JPA 的参数化查询
public User findUserById(Long userId) {
    return userRepository.findById(userId)
        .orElseThrow(() -> new UserNotFoundException("User not found: " + userId));
}

🟠 高危问题 (High)

3. N+1 查询问题

位置: UserService.java:24-30
风险等级: 🟠 High
问题描述: 在循环中访问关联关系,导致 N+1 查询

当前代码:

for (User user : users) {
    user.getOrders().size(); // 触发延迟加载
}

修复建议:

// 使用 JOIN FETCH 一次性加载
@Transactional
public List<User> findUsersWithOrders(List<Long> userIds) {
    return userRepository.findAllWithOrders(userIds);
}

// Repository 中添加
@Query("SELECT u FROM User u LEFT JOIN FETCH u.orders WHERE u.id IN :userIds")
List<User> findAllWithOrders(@Param("userIds") List<Long> userIds);

4. 事务边界不清晰

位置: UserService.java:41-47
风险等级: 🟠 High
问题描述: 在事务方法中调用外部服务,可能导致事务超时或死锁

修复建议:

// 将事务操作和外部调用分离
@Transactional
public void updateUserProfile(Long userId, String email) {
    User user = findUserById(userId);
    user.setEmail(email);
    userRepository.save(user);
}

// 单独处理外部调用
public void sendNotification(Long userId) {
    User user = findUserById(userId);
    externalService.sendEmail(user);
}

🟡 中危问题 (Medium)

5. 缺少输入验证

位置: UserService.java:18
风险等级: 🟡 Medium
问题描述: findUserById 方法没有验证输入参数

修复建议:

public User findUserById(Long userId) {
    if (userId == null || userId <= 0) {
        throw new IllegalArgumentException("Invalid user ID");
    }
    return userRepository.findById(userId)
        .orElseThrow(() -> new UserNotFoundException("User not found: " + userId));
}

6. 异常处理不当

位置: UserService.java:49-55
风险等级: 🟡 Medium
问题描述: 吞掉异常,无法追踪问题

修复建议:

public User getUserByEmail(String email) {
    if (email == null || email.trim().isEmpty()) {
        throw new IllegalArgumentException("Email cannot be null or empty");
    }
    
    try {
        return userRepository.findByEmail(email)
            .orElseThrow(() -> new UserNotFoundException("User not found: " + email));
    } catch (DataAccessException e) {
        log.error("Failed to find user by email: {}", email, e);
        throw new ServiceException("Failed to retrieve user", e);
    }
}

📊 审查统计

  • 审查文件数: 3
  • 发现问题数: 6
  • 严重问题: 2
  • 高危问题: 2
  • 中危问题: 2
  • 代码覆盖率: 待检测

🔧 自动化修复

CodeBuddy 可以自动生成修复代码。运行以下命令:

> 为以上所有问题生成修复代码,创建新的分支

这将自动:

  1. 创建新分支 fix/security-audit-issues
  2. 生成修复代码
  3. 运行测试验证修复
  4. 创建 PR 请求

#### 示例 2: 使用 Skills 生成单元测试

```bash
# 使用 test_generation Skill
> 使用 java-enterprise-auditor 的 test_generation skill 为以下类生成单元测试:
  @src/main/java/com/company/user/service/UserService.java
  
  要求:
  1. 使用 JUnit 5
  2. 使用 Mockito 模拟依赖
  3. 覆盖率达到 80% 以上
  4. 包含正常场景和异常场景

生成的测试代码:

// src/test/java/com/company/user/service/UserServiceTest.java
package com.company.user.service;

import com.company.user.entity.User;
import com.company.user.exception.UserNotFoundException;
import com.company.user.repository.UserRepository;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

import java.util.Arrays;
import java.util.List;
import java.util.Optional;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.Mockito.*;

@ExtendWith(MockitoExtension.class)
@DisplayName("UserService 单元测试")
class UserServiceTest {
    
    @Mock
    private UserRepository userRepository;
    
    @Mock
    private PasswordEncoder passwordEncoder;
    
    @Mock
    private ExternalService externalService;
    
    @InjectMocks
    private UserService userService;
    
    private User testUser;
    
    @BeforeEach
    void setUp() {
        testUser = User.builder()
            .id(1L)
            .username("testuser")
            .password("encodedPassword")
            .email("test@example.com")
            .build();
    }
    
    @Test
    @DisplayName("根据 ID 查找用户 - 成功")
    void findUserById_Success() {
        // Given
        when(userRepository.findById(1L)).thenReturn(Optional.of(testUser));
        
        // When
        User result = userService.findUserById(1L);
        
        // Then
        assertThat(result).isNotNull();
        assertThat(result.getId()).isEqualTo(1L);
        assertThat(result.getUsername()).isEqualTo("testuser");
        verify(userRepository, times(1)).findById(1L);
    }
    
    @Test
    @DisplayName("根据 ID 查找用户 - 用户不存在")
    void findUserById_UserNotFound() {
        // Given
        when(userRepository.findById(999L)).thenReturn(Optional.empty());
        
        // When & Then
        assertThatThrownBy(() -> userService.findUserById(999L))
            .isInstanceOf(UserNotFoundException.class)
            .hasMessageContaining("User not found: 999");
        
        verify(userRepository, times(1)).findById(999L);
    }
    
    @Test
    @DisplayName("根据 ID 查找用户 - 无效 ID")
    void findUserById_InvalidId() {
        // When & Then
        assertThatThrownBy(() -> userService.findUserById(null))
            .isInstanceOf(IllegalArgumentException.class)
            .hasMessageContaining("Invalid user ID");
        
        assertThatThrownBy(() -> userService.findUserById(-1L))
            .isInstanceOf(IllegalArgumentException.class)
            .hasMessageContaining("Invalid user ID");
        
        verify(userRepository, never()).findById(anyLong());
    }
    
    @Test
    @DisplayName("创建用户 - 成功")
    void createUser_Success() {
        // Given
        when(passwordEncoder.encode("rawPassword")).thenReturn("encodedPassword");
        when(userRepository.save(any(User.class))).thenAnswer(invocation -> invocation.getArgument(0));
        
        // When
        userService.createUser("newuser", "rawPassword", "new@example.com");
        
        // Then
        verify(passwordEncoder, times(1)).encode("rawPassword");
        verify(userRepository, times(1)).save(argThat(user -> 
            user.getUsername().equals("newuser") &&
            user.getPassword().equals("encodedPassword") &&
            user.getEmail().equals("new@example.com")
        ));
    }
    
    @Test
    @DisplayName("根据邮箱查找用户 - 成功")
    void getUserByEmail_Success() {
        // Given
        when(userRepository.findByEmail("test@example.com")).thenReturn(Optional.of(testUser));
        
        // When
        User result = userService.getUserByEmail("test@example.com");
        
        // Then
        assertThat(result).isNotNull();
        assertThat(result.getEmail()).isEqualTo("test@example.com");
        verify(userRepository, times(1)).findByEmail("test@example.com");
    }
    
    @Test
    @DisplayName("根据邮箱查找用户 - 邮箱为空")
    void getUserByEmail_EmptyEmail() {
        // When & Then
        assertThatThrownBy(() -> userService.getUserByEmail(null))
            .isInstanceOf(IllegalArgumentException.class)
            .hasMessageContaining("Email cannot be null or empty");
        
        assertThatThrownBy(() -> userService.getUserByEmail(""))
            .isInstanceOf(IllegalArgumentException.class)
            .hasMessageContaining("Email cannot be null or empty");
        
        verify(userRepository, never()).findByEmail(any());
    }
    
    @Test
    @DisplayName("根据邮箱查找用户 - 数据库异常")
    void getUserByEmail_DatabaseException() {
        // Given
        when(userRepository.findByEmail("test@example.com"))
            .thenThrow(new RuntimeException("Database connection failed"));
        
        // When & Then
        assertThatThrownBy(() -> userService.getUserByEmail("test@example.com"))
            .isInstanceOf(ServiceException.class)
            .hasMessageContaining("Failed to retrieve user");
        
        verify(userRepository, times(1)).findByEmail("test@example.com");
    }
    
    @Test
    @DisplayName("批量查找用户及其订单 - 解决 N+1 问题")
    void findUsersWithOrders_WithJoinFetch() {
        // Given
        List<Long> userIds = Arrays.asList(1L, 2L, 3L);
        User user1 = User.builder().id(1L).username("user1").build();
        User user2 = User.builder().id(2L).username("user2").build();
        User user3 = User.builder().id(3L).username("user3").build();
        
        when(userRepository.findAllWithOrders(userIds))
            .thenReturn(Arrays.asList(user1, user2, user3));
        
        // When
        List<User> result = userService.findUsersWithOrders(userIds);
        
        // Then
        assertThat(result).hasSize(3);
        verify(userRepository, times(1)).findAllWithOrders(userIds);
        // 验证没有触发额外的查询
        verify(userRepository, never()).findById(anyLong());
    }
}

创建自定义 Skill

Skill 配置文件结构
# .codebuddy/skills/custom-skill.yaml
name: my_custom_skill
display_name: 自定义技能
description: 我自己的自定义技能
version: 1.0.0

# Skill 类型
type: analysis
# analysis | generation | transformation | validation

# 执行配置
execution:
  mode: synchronous
  timeout: 300
  retry_count: 3

# 输入参数定义
inputs:
  - name: source_files
    type: array
    required: true
    description: 要处理的源文件列表
  
  - name: analysis_depth
    type: enum
    required: false
    default: medium
    options:
      - shallow
      - medium
      - deep
    description: 分析深度

# 输出参数定义
outputs:
  - name: analysis_report
    type: object
    description: 分析结果报告
  
  - name: metrics
    type: object
    description: 性能指标

# 技能配置
config:
  rules:
    enabled: true
    file: .codebuddy/rules/custom-rules.json
  
  templates:
    enabled: true
    directory: .codebuddy/templates
  
  integrations:
    - sonarqube
    - jira
实现自定义 Skill 逻辑
// .codebuddy/skills/my-custom-skill.js
class MyCustomSkill {
  constructor(config) {
    this.config = config;
    this.name = 'my_custom_skill';
  }

  /**
   * 执行技能
   * @param {Object} params 输入参数
   * @param {Object} context 执行上下文
   * @returns {Promise<Object>} 执行结果
   */
  async execute(params, context) {
    const { source_files, analysis_depth } = params;
    
    try {
      // 1. 验证输入
      this.validateInputs(params);
      
      // 2. 执行分析
      const analysisResults = await this.analyzeFiles(source_files, analysis_depth, context);
      
      // 3. 生成报告
      const report = this.generateReport(analysisResults);
      
      // 4. 计算指标
      const metrics = this.calculateMetrics(analysisResults);
      
      return {
        success: true,
        data: {
          analysis_report: report,
          metrics: metrics
        }
      };
    } catch (error) {
      return {
        success: false,
        error: error.message,
        stack: error.stack
      };
    }
  }

  /**
   * 验证输入参数
   */
  validateInputs(params) {
    if (!params.source_files || !Array.isArray(params.source_files)) {
      throw new Error('source_files must be an array');
    }
    if (params.source_files.length === 0) {
      throw new Error('source_files cannot be empty');
    }
  }

  /**
   * 分析文件
   */
  async analyzeFiles(files, depth, context) {
    const results = [];
    
    for (const file of files) {
      const fileContent = await context.readFile(file);
      const analysis = await this.analyzeFile(file, fileContent, depth);
      results.push(analysis);
    }
    
    return results;
  }

  /**
   * 分析单个文件
   */
  async analyzeFile(filePath, content, depth) {
    // 这里实现具体的分析逻辑
    const lines = content.split('\n');
    const issues = [];
    
    // 示例: 检测代码复杂度
    if (depth === 'deep') {
      const complexity = this.calculateComplexity(content);
      if (complexity > 10) {
        issues.push({
          type: 'complexity',
          severity: 'warning',
          message: `High complexity detected: ${complexity}`,
          line: this.findMostComplexLine(content)
        });
      }
    }
    
    return {
      file: filePath,
      lines: lines.length,
      issues: issues,
      metrics: {
        complexity: this.calculateComplexity(content),
        maintainability: this.calculateMaintainability(content)
      }
    };
  }

  /**
   * 计算代码复杂度
   */
  calculateComplexity(content) {
    // 简化的圈复杂度计算
    const patterns = [
      /if\s*\(/g,
      /else\s+if\s*\(/g,
      /for\s*\(/g,
      /while\s*\(/g,
      /catch\s*\(/g,
      /\&\&/g,
      /\|\|/g
    ];
    
    let complexity = 1; // 基础复杂度
    for (const pattern of patterns) {
      const matches = content.match(pattern);
      if (matches) {
        complexity += matches.length;
      }
    }
    
    return complexity;
  }

  /**
   * 计算可维护性指数
   */
  calculateMaintainability(content) {
    // 简化的可维护性计算
    const lines = content.split('\n').length;
    const complexity = this.calculateComplexity(content);
    const comments = (content.match(/\/\*[\s\S]*?\*\//g) || []).length;
    
    // MI = 171 - 5.2 * ln(vol) - 0.23 * cyclomatic - 16.2 * ln(lines)
    // 这里使用简化版本
    return Math.max(0, 100 - (complexity * 2) - (lines / 10));
  }

  /**
   * 生成报告
   */
  generateReport(results) {
    const totalFiles = results.length;
    const totalIssues = results.reduce((sum, r) => sum + r.issues.length, 0);
    const avgComplexity = results.reduce((sum, r) => sum + r.metrics.complexity, 0) / totalFiles;
    
    return {
      summary: {
        total_files: totalFiles,
        total_issues: totalIssues,
        avg_complexity: avgComplexity.toFixed(2)
      },
      details: results
    };
  }

  /**
   * 计算指标
   */
  calculateMetrics(results) {
    return {
      execution_time: Date.now(),
      files_processed: results.length,
      issues_found: results.reduce((sum, r) => sum + r.issues.length, 0)
    };
  }
}

module.exports = MyCustomSkill;
注册自定义 Skill
# .codebuddy/agents/custom-agent.yaml
name: Custom Agent
description: 使用自定义技能的智能体

system_prompt: |
  你是自定义智能体,可以使用自定义技能进行代码分析。

skills:
  - name: my_custom_skill
    enabled: true
    config:
      analysis_depth: deep

  - name: code_review
    enabled: true

Skills 最佳实践

  1. 单一职责: 每个 Skill 只做一件事
  2. 可配置性: 通过配置文件灵活调整行为
  3. 可测试性: 为每个 Skill 编写单元测试
  4. 错误处理: 完善的错误处理和日志记录
  5. 性能优化: 避免阻塞操作,使用异步处理
  6. 文档完善: 提供清晰的使用文档和示例

Skills 调用方式

# 方式 1: 通过智能体调用
> 使用 java-enterprise-auditor 智能体执行 security_audit skill

# 方式 2: 直接调用 Skill
> 执行 database_optimization skill,分析 @src/main/resources/mapper/*.xml

# 方式 3: 组合多个 Skills
> 依次执行以下 skills:
  1. security_audit
  2. performance_analysis
  3. code_review
  生成综合报告

Agent 和 Skills 配置文件完整示例

# .codebuddy/agents/java-fullstack-agent.yaml
name: Java FullStack Agent
display_name: Java 全栈开发助手
description: 专业的 Java 全栈开发智能体
version: 3.0.0
author: DevOps Team

# 系统提示词
system_prompt: |
  你是 Java 全栈开发专家,精通以下技术栈:
  
  **后端技术:**
  - Java 17+, Spring Boot 3.x
  - Spring Data JPA, MyBatis
  - Spring Security, JWT
  - Redis, RabbitMQ
  - MySQL, PostgreSQL, MongoDB
  
  **前端技术:**
  - React 18+, Vue 3
  - TypeScript
  - Ant Design, Element Plus
  
  **DevOps:**
  - Docker, Kubernetes
  - Jenkins, GitLab CI
  - Prometheus, Grafana
  
  **最佳实践:**
  - 遵循阿里巴巴 Java 开发手册
  - RESTful API 设计规范
  - 前后端分离架构
  - 微服务设计原则
  
  **输出要求:**
  - 代码必须完整可运行
  - 包含必要的注释和文档
  - 遵循命名规范
  - 考虑性能和安全性

# Skills 集合
skills:
  # 后端开发
  - name: backend_crud
    display_name: CRUD 代码生成
    description: 自动生成增删改查代码
    type: generation
    enabled: true
    config:
      frameworks:
        - spring-boot
        - spring-data-jpa
      include_validation: true
      include_documentation: true
  
  - name: api_design
    display_name: API 设计
    description: 设计 RESTful API 接口
    type: generation
    enabled: true
    config:
      follow_restful: true
      include_swagger: true
      include_error_handling: true
  
  # 前端开发
  - name: frontend_component
    display_name: 前端组件生成
    description: 生成 React/Vue 组件
    type: generation
    enabled: true
    config:
      framework: react
      typescript: true
      include_styled_components: true
  
  - name: state_management
    display_name: 状态管理
    description: 实现状态管理逻辑
    type: generation
    enabled: true
    config:
      library: redux-toolkit
      include_async_actions: true
  
  # 数据库设计
  - name: database_schema
    display_name: 数据库设计
    description: 设计数据库表结构
    type: generation
    enabled: true
    config:
      database: postgresql
      include_indexes: true
      include_relationships: true
  
  - name: query_optimization
    display_name: 查询优化
    description: 优化 SQL 查询
    type: analysis
    enabled: true
    config:
      check_n_plus_one: true
      suggest_indexes: true
  
  # 测试
  - name: test_generation
    display_name: 测试生成
    description: 生成单元测试和集成测试
    type: generation
    enabled: true
    config:
      backend_framework: junit5
      frontend_framework: jest
      coverage_target: 80
  
  # 部署
  - name: docker_compose
    display_name: Docker Compose 生成
    description: 生成 Docker Compose 配置
    type: generation
    enabled: true
    config:
      include_database: true
      include_redis: true
      include_nginx: true
  
  - name: kubernetes_manifest
    display_name: Kubernetes 配置
    description: 生成 Kubernetes 部署配置
    type: generation
    enabled: true
    config:
      include_hpa: true
      include_configmap: true
      include_secret: true
  
  # 文档
  - name: api_documentation
    display_name: API 文档
    description: 生成 API 文档
    type: generation
    enabled: true
    config:
      format: markdown
      include_examples: true
      include_auth_requirements: true
  
  - name: architecture_documentation
    display_name: 架构文档
    description: 生成架构设计文档
    type: generation
    enabled: true
    config:
      include_diagrams: true
      include_decision_records: true

# 工具集
tools:
  maven:
    enabled: true
    version: 3.9
  
  node:
    enabled: true
    version: 18
  
  docker:
    enabled: true
    version: 24
  
  kubectl:
    enabled: true
    version: 1.28

# 环境配置
environment:
  java:
    version: "17"
    maven:
      version: "3.9.5"
  
  node:
    version: "18.17.0"
    package_manager: "npm"
  
  database:
    type: "postgresql"
    version: "15"
  
  cache:
    type: "redis"
    version: "7"

# 代码规范
code_standards:
  java:
    style_guide: "alibaba-java-coding-guidelines"
    checkstyle: "google_checks.xml"
    pmd: "rulesets/java/quickstart.xml"
  
  javascript:
    style_guide: "airbnb"
    eslint: "airbnb-base"
  
  typescript:
    style_guide: "airbnb-typescript"
    eslint: "airbnb-typescript/base"

# 输出配置
output:
  format:
    - code
    - markdown
    - json
  
  include:
    - comments
    - examples
    - tests
    - documentation
  
  structure:
    follow_project_structure: true
    create_backup: true

# 安全配置
security:
  check_vulnerabilities: true
  check_hardcoded_secrets: true
  check_sql_injection: true
  check_xss: true
  enforce_https: true

# 性能配置
performance:
  optimize_queries: true
  enable_caching: true
  lazy_loading: true
  pagination_enabled: true

# 监控配置
monitoring:
  include_metrics: true
  include_logging: true
  include_tracing: true
  alerting_enabled: true

使用完整智能体

# 启动 CodeBuddy
codebuddy

# 初始化项目
> /init

# 使用 Java 全栈智能体创建完整功能
> 使用 java-fullstack-agent 智能体创建一个用户管理功能:
  
  需求:
  1. 后端 API(用户 CRUD、认证、授权)
  2. 前端页面(用户列表、详情、编辑)
  3. 数据库表结构
  4. 单元测试
  5. API 文档
  6. Docker 部署配置
  
  技术栈:
  - Spring Boot 3.x + JPA + PostgreSQL
  - React 18 + TypeScript + Ant Design
  - JWT 认证
  - Docker Compose

这将会自动生成:

  • 后端完整的代码结构
  • 前端组件和页面
  • 数据库迁移脚本
  • 单元测试代码
  • API 文档
  • Docker Compose 配置
  • 部署脚本

斜杠命令系统

斜杠命令是提升效率的神器,可以将复杂操作封装为简单指令。

项目级命令

在项目中创建共享命令:

# 创建命令目录
mkdir -p .codebuddy/commands

# 创建代码审查命令
cat > .codebuddy/commands/review.md << 'EOF'
请对当前代码进行全面审查,重点关注:
1. 安全漏洞(如 SQL 注入、XSS)
2. 性能问题(如 N+1 查询、内存泄漏)
3. 代码规范(如命名、格式)
4. 业务逻辑错误
EOF

# 创建性能优化命令
cat > .codebuddy/commands/optimize.md << 'EOF'
分析当前代码的性能瓶颈,并提供具体的优化建议:
1. 识别不必要的计算
2. 建议缓存策略
3. 推荐索引优化
4. 并行化机会
EOF

参数化命令

使用 $ARGUMENTS 占位符创建灵活的命令:

# 创建问题修复命令
cat > .codebuddy/commands/fix-issue.md << 'EOF'
修复工单 #$ARGUMENTS 中描述的问题。

步骤:
1. 理解问题根因
2. 在代码库中定位相关代码
3. 实现修复方案
4. 添加回归测试
5. 更新相关文档
6. 生成规范的提交信息
EOF

# 使用方法
/fix-issue 123

个人级命令

创建在所有项目中都有效的个人命令:

# 创建个人命令目录
mkdir -p ~/.codebuddy/commands

# 创建安全审查命令
cat > ~/.codebuddy/commands/security-audit.md << 'EOF'
对代码进行安全审计,检查:
- 敏感信息泄露风险
- 不安全的第三方库
- 配置文件暴露风险
- API 权限配置
EOF

命令组织技巧

.codebuddy/
├── commands/
│   ├── review/
│   │   ├── frontend.md      # 前端代码审查
│   │   └── backend.md       # 后端代码审查
│   ├── test/
│   │   ├── unit.md          # 单元测试生成
│   │   └── integration.md   # 集成测试生成
│   └── refactor/
│       └── cleanup.md       # 代码清理
└── agents/
    └── custom-agent.yaml

RAG 知识库构建

RAG (Retrieval-Augmented Generation) 技术让 CodeBuddy 能够利用企业私有知识,提供更精准的代码建议。

为什么需要 RAG

解决 AI 编程的三大痛点:

  1. 知识时效性: AI 模型训练数据滞后,无法覆盖最新技术动态
  2. 上下文理解局限: 难以捕捉跨文件依赖关系
  3. 幻觉与安全风险: 可能生成不符合企业规范的代码

创建企业知识库

步骤 1: 准备知识文档

支持的文档格式:

  • Markdown (.md)
  • Text (.txt)
  • Word (.docx)
  • PDF (.pdf)
  • 代码文件 (.js, .py, .java 等)
步骤 2: 上传文档

在 CodeBuddy IDE 中:

  1. 打开知识库管理面板
  2. 创建新的知识库
  3. 上传相关文档
  4. 等待索引完成
步骤 3: 配置知识库
# .codebuddy/knowledge-base.yaml
name: Enterprise Standards
description: 企业编码规范和最佳实践

documents:
  - coding-standards.md
  - api-specifications.md
  - security-guidelines.md
  - architecture-docs/

embedding_model: text-embedding-ada-002
chunk_size: 1000
chunk_overlap: 200

知识库最佳实践

  1. 文档组织: 按主题分类,保持结构清晰
  2. 定期更新: 及时添加新的规范和文档
  3. 版本控制: 知识库文档纳入版本管理
  4. 质量监控: 定期评估知识库的有效性

使用知识库

# 启用知识库
codebuddy --knowledge-base enterprise-standards

# 查询知识库
codebuddy "根据我们的编码规范,实现用户认证功能"

性能优化技巧

1. 项目初始化优化

使用 /init 命令预先构建项目知识图谱:

# 首次使用项目时
codebuddy
> /init

# 项目结构发生重大变化时
> /clear
> /init

优势:

  • ✅ 理解更准确: AI 能更准确理解代码结构和业务逻辑
  • ✅ 响应更快速: 避免重复扫描文件
  • ✅ 建议更精准: 基于全局视图提供更符合项目架构的建议
  • ✅ 成本优化: 减少 30-50% 的 Token 消耗

2. 上下文管理

有效使用 @ 引用
# 引用单个文件
@src/utils/helpers.js 解释这个函数的用途

# 引用多个文件
@src/api/user.js @src/models/user.js 分析用户认证流程

# 引用整个代码库
#Codebase 这个项目的整体架构是什么?
上下文窗口优化
  • 🎯 只包含相关文件
  • 📦 使用模块化引用
  • 🔍 避免冗余信息
  • 💾 及时清理不必要的历史对话

3. 并行任务处理

利用 CodeBuddy 的多任务并行能力:

# 终端 1: 处理前端
codebuddy "重构 React 组件使用 Hooks"

# 终端 2: 处理后端
codebuddy "优化 API 响应时间"

# 终端 3: 生成文档
codebuddy "为 API 生成 Swagger 文档"

4. 缓存策略

# 启用缓存
codebuddy --cache-enabled

# 清除缓存
codebuddy --cache-clear

企业级部署

私有化部署

企业可以部署私有化的 CodeBuddy 服务:

# docker-compose.yml
version: '3.8'
services:
  codebuddy:
    image: tencent/codebuddy-enterprise:latest
    ports:
      - "8080:8080"
    environment:
      - MODEL_ENDPOINT=https://your-model-endpoint
      - DATABASE_URL=postgresql://user:pass@db:5432/codebuddy
      - REDIS_URL=redis://redis:6379
    volumes:
      - ./data:/app/data
      - ./config:/app/config
    depends_on:
      - db
      - redis

  db:
    image: postgres:15
    environment:
      - POSTGRES_DB=codebuddy
      - POSTGRES_USER=user
      - POSTGRES_PASSWORD=pass

  redis:
    image: redis:7

团队协作配置

统一编码规范

创建团队共享的配置文件:

// .codebuddy/team-config.json
{
  "codeStyle": {
    "language": "TypeScript",
    "indentation": "spaces",
    "indentSize": 2,
    "quotes": "single",
    "semicolons": true
  },
  "reviewRules": [
    "no-console",
    "no-any",
    "prefer-const"
  ],
  "testFramework": "jest",
  "documentationFormat": "JSDoc"
}
权限管理
# .codebuddy/permissions.yaml
roles:
  - name: developer
    permissions:
      - read_code
      - write_code
      - run_tests
      - generate_documentation
  
  - name: senior_developer
    permissions:
      - read_code
      - write_code
      - run_tests
      - generate_documentation
      - refactor_code
      - deploy_staging
  
  - name: tech_lead
    permissions:
      - all

CI/CD 集成

GitHub Actions 示例
# .github/workflows/codebuddy-review.yml
name: CodeBuddy Review
on:
  pull_request:
    types: [opened, synchronize]

jobs:
  review:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Install CodeBuddy
        run: npm install -g @tencent-ai/codebuddy-code
      
      - name: Run Code Review
        run: |
          codebuddy -p --dangerously-skip-permissions \
            "审查这个 PR 的代码变更,重点检查安全漏洞和性能问题" \
            > review-report.txt
      
      - name: Comment Review
        uses: actions/github-script@v6
        with:
          script: |
            const fs = require('fs');
            const report = fs.readFileSync('review-report.txt', 'utf8');
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: report
            });

高级调试技巧

1. 查看详细日志

# 启用详细日志
export DEBUG=codebuddy:*
codebuddy

# 或在命令中指定
codebuddy --log-level debug

2. 对话历史恢复

# 恢复最近的对话
codebuddy --continue

# 恢复特定对话
codebuddy --resume <session-id>

# 在非交互模式下继续
codebuddy --continue --print "继续我的任务"

3. 性能分析

# 分析响应时间
codebuddy --profile

# 统计 Token 使用
codebuddy --stats

4. 错误排查

常见错误及解决方案

错误 1: 模型响应超时

# 增加超时时间
codebuddy --timeout 120

错误 2: 上下文窗口溢出

# 减少上下文大小
codebuddy --context-size 8000

错误 3: 权限拒绝

# 使用自动授权模式
codebuddy --permission-mode auto

实战案例

案例 1: 从零构建 RESTful API

场景: 使用 Node.js + Express + MongoDB 构建一个完整的电商后端 API

原始需求

用户希望构建一个电商平台的后端 API,需要实现:

  • 用户注册、登录、JWT 认证
  • 商品 CRUD 操作
  • 购物车管理
  • 订单处理
  • 支付集成(模拟)
步骤 1: 项目初始化
# 创建项目目录
mkdir ecommerce-api
cd ecommerce-api

# 初始化 Node.js 项目
npm init -y

# 安装依赖
npm install express mongoose dotenv jsonwebtoken bcryptjs
npm install -D nodemon jest supertest

使用 CodeBuddy 自动生成配置文件:

codebuddy
> /init
> 生成 package.json 配置,包含完整的脚本命令
> 生成 .env.example 文件,列出所有环境变量

生成的 package.json:

{
  "name": "ecommerce-api",
  "version": "1.0.0",
  "description": "电商后端 API",
  "main": "src/server.js",
  "scripts": {
    "start": "node src/server.js",
    "dev": "nodemon src/server.js",
    "test": "jest --coverage",
    "test:watch": "jest --watch",
    "lint": "eslint src/",
    "lint:fix": "eslint src/ --fix"
  },
  "dependencies": {
    "express": "^4.18.2",
    "mongoose": "^8.0.0",
    "dotenv": "^16.3.1",
    "jsonwebtoken": "^9.0.2",
    "bcryptjs": "^2.4.3"
  },
  "devDependencies": {
    "nodemon": "^3.0.1",
    "jest": "^29.7.0",
    "supertest": "^6.3.3"
  }
}
步骤 2: 创建数据库模型

使用 CodeBuddy 生成 Mongoose 模型:

> @schemas/user.schema.js 基于以下需求生成用户模型:
   - 用户名、邮箱、密码(加密)
   - 用户角色(普通用户、管理员)
   - 创建时间、更新时间
   - 索引优化

生成的 User 模型:

// src/models/User.js
const mongoose = require('mongoose');
const bcrypt = require('bcryptjs');

const userSchema = new mongoose.Schema({
  username: {
    type: String,
    required: true,
    unique: true,
    trim: true,
    minlength: 3,
    maxlength: 50
  },
  email: {
    type: String,
    required: true,
    unique: true,
    trim: true,
    lowercase: true,
    match: [/^\w+([.-]?\w+)*@\w+([.-]?\w+)*(\.\w{2,3})+$/, '请输入有效的邮箱地址']
  },
  password: {
    type: String,
    required: true,
    minlength: 6,
    select: false
  },
  role: {
    type: String,
    enum: ['user', 'admin'],
    default: 'user'
  },
  isActive: {
    type: Boolean,
    default: true
  }
}, {
  timestamps: true
});

// 创建索引
userSchema.index({ email: 1 });
userSchema.index({ username: 1 });

// 密码加密中间件
userSchema.pre('save', async function(next) {
  if (!this.isModified('password')) return next();
  
  try {
    const salt = await bcrypt.genSalt(10);
    this.password = await bcrypt.hash(this.password, salt);
    next();
  } catch (error) {
    next(error);
  }
});

// 验证密码方法
userSchema.methods.comparePassword = async function(candidatePassword) {
  return await bcrypt.compare(candidatePassword, this.password);
};

// 生成 JWT Token
userSchema.methods.generateToken = function() {
  return jwt.sign(
    { id: this._id, role: this.role },
    process.env.JWT_SECRET,
    { expiresIn: process.env.JWT_EXPIRE || '7d' }
  );
};

module.exports = mongoose.model('User', userSchema);

类似地生成 Product 模型:

// src/models/Product.js
const mongoose = require('mongoose');

const productSchema = new mongoose.Schema({
  name: {
    type: String,
    required: true,
    trim: true,
    maxlength: 200
  },
  description: {
    type: String,
    required: true,
    maxlength: 2000
  },
  price: {
    type: Number,
    required: true,
    min: 0
  },
  category: {
    type: String,
    required: true,
    enum: ['electronics', 'clothing', 'books', 'home', 'other']
  },
  stock: {
    type: Number,
    required: true,
    min: 0,
    default: 0
  },
  images: [{
    type: String
  }],
  rating: {
    type: Number,
    default: 0,
    min: 0,
    max: 5
  },
  reviews: [{
    user: {
      type: mongoose.Schema.Types.ObjectId,
      ref: 'User'
    },
    rating: Number,
    comment: String,
    createdAt: {
      type: Date,
      default: Date.now
    }
  }],
  isActive: {
    type: Boolean,
    default: true
  }
}, {
  timestamps: true
});

// 创建复合索引
productSchema.index({ category: 1, price: 1 });
productSchema.index({ name: 'text', description: 'text' });

// 虚拟字段
productSchema.virtual('isInStock').get(function() {
  return this.stock > 0;
});

// 实例方法: 更新库存
productSchema.methods.updateStock = function(quantity) {
  this.stock -= quantity;
  if (this.stock < 0) this.stock = 0;
  return this.save();
};

module.exports = mongoose.model('Product', productSchema);
步骤 3: 实现认证中间件

使用 CodeBuddy 生成认证中间件:

> @middlewares/auth.js 生成 JWT 认证中间件,包含:
   - Token 验证
   - 角色检查
   - 错误处理
// src/middlewares/auth.js
const jwt = require('jsonwebtoken');
const User = require('../models/User');

// 验证 Token
exports.authenticate = async (req, res, next) => {
  try {
    const token = req.header('Authorization')?.replace('Bearer ', '');
    
    if (!token) {
      return res.status(401).json({
        success: false,
        message: '未提供认证令牌'
      });
    }

    const decoded = jwt.verify(token, process.env.JWT_SECRET);
    
    const user = await User.findById(decoded.id).select('-password');
    if (!user || !user.isActive) {
      return res.status(401).json({
        success: false,
        message: '用户不存在或已被禁用'
      });
    }

    req.user = user;
    next();
  } catch (error) {
    if (error.name === 'JsonWebTokenError') {
      return res.status(401).json({
        success: false,
        message: '无效的令牌'
      });
    }
    if (error.name === 'TokenExpiredError') {
      return res.status(401).json({
        success: false,
        message: '令牌已过期'
      });
    }
    return res.status(500).json({
      success: false,
      message: '认证失败',
      error: error.message
    });
  }
};

// 角色授权
exports.authorize = (...roles) => {
  return (req, res, next) => {
    if (!roles.includes(req.user.role)) {
      return res.status(403).json({
        success: false,
        message: `需要 ${roles.join(' 或 ')} 权限`
      });
    }
    next();
  };
};

// 可选认证(允许游客访问)
exports.optionalAuth = async (req, res, next) => {
  try {
    const token = req.header('Authorization')?.replace('Bearer ', '');
    
    if (token) {
      const decoded = jwt.verify(token, process.env.JWT_SECRET);
      const user = await User.findById(decoded.id).select('-password');
      if (user && user.isActive) {
        req.user = user;
      }
    }
    next();
  } catch (error) {
    // 忽略错误,继续执行
    next();
  }
};
步骤 4: 创建控制器

用户认证控制器:

// src/controllers/authController.js
const User = require('../models/User');
const crypto = require('crypto');

// 用户注册
exports.register = async (req, res) => {
  try {
    const { username, email, password, role } = req.body;

    // 检查用户是否已存在
    const existingUser = await User.findOne({
      $or: [{ email }, { username }]
    });

    if (existingUser) {
      return res.status(400).json({
        success: false,
        message: '用户名或邮箱已被使用'
      });
    }

    // 创建用户
    const user = await User.create({
      username,
      email,
      password,
      role: role || 'user'
    });

    // 生成 Token
    const token = user.generateToken();

    res.status(201).json({
      success: true,
      message: '注册成功',
      data: {
        user: {
          id: user._id,
          username: user.username,
          email: user.email,
          role: user.role
        },
        token
      }
    });
  } catch (error) {
    res.status(500).json({
      success: false,
      message: '注册失败',
      error: error.message
    });
  }
};

// 用户登录
exports.login = async (req, res) => {
  try {
    const { email, password } = req.body;

    // 查找用户(包含密码字段)
    const user = await User.findOne({ email }).select('+password');

    if (!user || !user.isActive) {
      return res.status(401).json({
        success: false,
        message: '邮箱或密码错误'
      });
    }

    // 验证密码
    const isMatch = await user.comparePassword(password);

    if (!isMatch) {
      return res.status(401).json({
        success: false,
        message: '邮箱或密码错误'
      });
    }

    // 生成 Token
    const token = user.generateToken();

    res.json({
      success: true,
      message: '登录成功',
      data: {
        user: {
          id: user._id,
          username: user.username,
          email: user.email,
          role: user.role
        },
        token
      }
    });
  } catch (error) {
    res.status(500).json({
      success: false,
      message: '登录失败',
      error: error.message
    });
  }
};

// 获取当前用户信息
exports.getMe = async (req, res) => {
  try {
    const user = await User.findById(req.user.id);

    res.json({
      success: true,
      data: {
        user: {
          id: user._id,
          username: user.username,
          email: user.email,
          role: user.role,
          createdAt: user.createdAt
        }
      }
    });
  } catch (error) {
    res.status(500).json({
      success: false,
      message: '获取用户信息失败',
      error: error.message
    });
  }
};

// 更新用户信息
exports.updateProfile = async (req, res) => {
  try {
    const { username, email } = req.body;
    const user = await User.findById(req.user.id);

    // 检查用户名/邮箱是否被占用
    if (username && username !== user.username) {
      const existingUser = await User.findOne({ username });
      if (existingUser) {
        return res.status(400).json({
          success: false,
          message: '用户名已被使用'
        });
      }
      user.username = username;
    }

    if (email && email !== user.email) {
      const existingUser = await User.findOne({ email });
      if (existingUser) {
        return res.status(400).json({
          success: false,
          message: '邮箱已被使用'
        });
      }
      user.email = email;
    }

    await user.save();

    res.json({
      success: true,
      message: '更新成功',
      data: {
        user: {
          id: user._id,
          username: user.username,
          email: user.email,
          role: user.role
        }
      }
    });
  } catch (error) {
    res.status(500).json({
      success: false,
      message: '更新失败',
      error: error.message
    });
  }
};

商品控制器:

// src/controllers/productController.js
const Product = require('../models/Product');

// 获取所有商品(支持分页、筛选、排序)
exports.getProducts = async (req, res) => {
  try {
    const { page = 1, limit = 10, category, minPrice, maxPrice, search, sort } = req.query;

    // 构建查询条件
    const query = { isActive: true };

    if (category) {
      query.category = category;
    }

    if (minPrice !== undefined || maxPrice !== undefined) {
      query.price = {};
      if (minPrice !== undefined) query.price.$gte = Number(minPrice);
      if (maxPrice !== undefined) query.price.$lte = Number(maxPrice);
    }

    if (search) {
      query.$text = { $search: search };
    }

    // 构建排序
    let sortOption = {};
    if (sort) {
      const sortFields = sort.split(',');
      sortFields.forEach(field => {
        if (field.startsWith('-')) {
          sortOption[field.substring(1)] = -1;
        } else {
          sortOption[field] = 1;
        }
      });
    } else {
      sortOption = { createdAt: -1 };
    }

    // 执行查询
    const products = await Product.find(query)
      .sort(sortOption)
      .skip((page - 1) * limit)
      .limit(Number(limit));

    const total = await Product.countDocuments(query);

    res.json({
      success: true,
      data: {
        products,
        pagination: {
          page: Number(page),
          limit: Number(limit),
          total,
          pages: Math.ceil(total / limit)
        }
      }
    });
  } catch (error) {
    res.status(500).json({
      success: false,
      message: '获取商品列表失败',
      error: error.message
    });
  }
};

// 获取单个商品详情
exports.getProduct = async (req, res) => {
  try {
    const product = await Product.findById(req.params.id);

    if (!product || !product.isActive) {
      return res.status(404).json({
        success: false,
        message: '商品不存在'
      });
    }

    res.json({
      success: true,
      data: { product }
    });
  } catch (error) {
    res.status(500).json({
      success: false,
      message: '获取商品详情失败',
      error: error.message
    });
  }
};

// 创建商品(仅管理员)
exports.createProduct = async (req, res) => {
  try {
    const product = await Product.create({
      ...req.body,
      createdBy: req.user.id
    });

    res.status(201).json({
      success: true,
      message: '商品创建成功',
      data: { product }
    });
  } catch (error) {
    res.status(500).json({
      success: false,
      message: '创建商品失败',
      error: error.message
    });
  }
};

// 更新商品(仅管理员)
exports.updateProduct = async (req, res) => {
  try {
    const product = await Product.findByIdAndUpdate(
      req.params.id,
      req.body,
      { new: true, runValidators: true }
    );

    if (!product) {
      return res.status(404).json({
        success: false,
        message: '商品不存在'
      });
    }

    res.json({
      success: true,
      message: '商品更新成功',
      data: { product }
    });
  } catch (error) {
    res.status(500).json({
      success: false,
      message: '更新商品失败',
      error: error.message
    });
  }
};

// 删除商品(仅管理员)
exports.deleteProduct = async (req, res) => {
  try {
    const product = await Product.findByIdAndUpdate(
      req.params.id,
      { isActive: false },
      { new: true }
    );

    if (!product) {
      return res.status(404).json({
        success: false,
        message: '商品不存在'
      });
    }

    res.json({
      success: true,
      message: '商品删除成功'
    });
  } catch (error) {
    res.status(500).json({
      success: false,
      message: '删除商品失败',
      error: error.message
    });
  }
};

// 添加商品评论
exports.addReview = async (req, res) => {
  try {
    const { rating, comment } = req.body;
    const product = await Product.findById(req.params.id);

    if (!product) {
      return res.status(404).json({
        success: false,
        message: '商品不存在'
      });
    }

    // 检查是否已评论
    const alreadyReviewed = product.reviews.find(
      review => review.user.toString() === req.user.id.toString()
    );

    if (alreadyReviewed) {
      return res.status(400).json({
        success: false,
        message: '您已经评论过该商品'
      });
    }

    // 添加评论
    product.reviews.push({
      user: req.user.id,
      rating,
      comment
    });

    // 更新商品评分
    product.rating = product.reviews.reduce((acc, item) => item.rating + acc, 0) / product.reviews.length;

    await product.save();

    res.json({
      success: true,
      message: '评论添加成功',
      data: { product }
    });
  } catch (error) {
    res.status(500).json({
      success: false,
      message: '添加评论失败',
      error: error.message
    });
  }
};
步骤 5: 定义路由
// src/routes/authRoutes.js
const express = require('express');
const router = express.Router();
const { authenticate } = require('../middlewares/auth');
const authController = require('../controllers/authController');

router.post('/register', authController.register);
router.post('/login', authController.login);
router.get('/me', authenticate, authController.getMe);
router.put('/profile', authenticate, authController.updateProfile);

module.exports = router;
// src/routes/productRoutes.js
const express = require('express');
const router = express.Router();
const { authenticate, authorize } = require('../middlewares/auth');
const productController = require('../controllers/productController');

// 公开路由
router.get('/', productController.getProducts);
router.get('/:id', productController.getProduct);

// 需要认证的路由
router.post('/:id/reviews', authenticate, productController.addReview);

// 管理员路由
router.post('/', authenticate, authorize('admin'), productController.createProduct);
router.put('/:id', authenticate, authorize('admin'), productController.updateProduct);
router.delete('/:id', authenticate, authorize('admin'), productController.deleteProduct);

module.exports = router;
步骤 6: 主应用入口
// src/server.js
require('dotenv').config();
const express = require('express');
const mongoose = require('mongoose');
const cors = require('cors');

// 导入路由
const authRoutes = require('./routes/authRoutes');
const productRoutes = require('./routes/productRoutes');

// 创建 Express 应用
const app = express();

// 中间件
app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

// 请求日志中间件
app.use((req, res, next) => {
  console.log(`${req.method} ${req.path} - ${new Date().toISOString()}`);
  next();
});

// 健康检查
app.get('/health', (req, res) => {
  res.json({ status: 'OK', timestamp: new Date() });
});

// API 路由
app.use('/api/auth', authRoutes);
app.use('/api/products', productRoutes);

// 404 处理
app.use((req, res) => {
  res.status(404).json({
    success: false,
    message: '路由不存在'
  });
});

// 错误处理中间件
app.use((err, req, res, next) => {
  console.error(err.stack);
  res.status(err.status || 500).json({
    success: false,
    message: err.message || '服务器内部错误',
    ...(process.env.NODE_ENV === 'development' && { stack: err.stack })
  });
});

// 数据库连接
mongoose.connect(process.env.MONGODB_URI)
  .then(() => console.log('MongoDB 连接成功'))
  .catch(err => console.error('MongoDB 连接失败:', err));

// 启动服务器
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`服务器运行在端口 ${PORT}`);
});

module.exports = app;
步骤 7: 使用 CodeBuddy 生成测试
> @tests/auth.test.js 为认证控制器生成完整的单元测试
> @tests/product.test.js 为商品控制器生成完整的单元测试

生成的测试示例:

// tests/auth.test.js
const request = require('supertest');
const mongoose = require('mongoose');
const app = require('../src/server');
const User = require('../src/models/User');

describe('Auth API Tests', () => {
  beforeAll(async () => {
    await mongoose.connect(process.env.MONGODB_URI_TEST);
  });

  afterEach(async () => {
    await User.deleteMany({});
  });

  afterAll(async () => {
    await mongoose.connection.close();
  });

  describe('POST /api/auth/register', () => {
    it('应该成功注册新用户', async () => {
      const response = await request(app)
        .post('/api/auth/register')
        .send({
          username: 'testuser',
          email: 'test@example.com',
          password: 'password123'
        });

      expect(response.status).toBe(201);
      expect(response.body.success).toBe(true);
      expect(response.body.data).toHaveProperty('token');
      expect(response.body.data.user.email).toBe('test@example.com');
    });

    it('应该拒绝重复的邮箱', async () => {
      await User.create({
        username: 'user1',
        email: 'test@example.com',
        password: 'password123'
      });

      const response = await request(app)
        .post('/api/auth/register')
        .send({
          username: 'user2',
          email: 'test@example.com',
          password: 'password123'
        });

      expect(response.status).toBe(400);
      expect(response.body.message).toContain('已被使用');
    });

    it('应该验证密码长度', async () => {
      const response = await request(app)
        .post('/api/auth/register')
        .send({
          username: 'testuser',
          email: 'test@example.com',
          password: '123'
        });

      expect(response.status).toBe(400);
    });
  });

  describe('POST /api/auth/login', () => {
    beforeEach(async () => {
      await User.create({
        username: 'testuser',
        email: 'test@example.com',
        password: 'password123'
      });
    });

    it('应该成功登录', async () => {
      const response = await request(app)
        .post('/api/auth/login')
        .send({
          email: 'test@example.com',
          password: 'password123'
        });

      expect(response.status).toBe(200);
      expect(response.body.success).toBe(true);
      expect(response.body.data).toHaveProperty('token');
    });

    it('应该拒绝错误的密码', async () => {
      const response = await request(app)
        .post('/api/auth/login')
        .send({
          email: 'test@example.com',
          password: 'wrongpassword'
        });

      expect(response.status).toBe(401);
      expect(response.body.message).toContain('邮箱或密码错误');
    });
  });

  describe('GET /api/auth/me', () => {
    let token;

    beforeEach(async () => {
      const user = await User.create({
        username: 'testuser',
        email: 'test@example.com',
        password: 'password123'
      });
      token = user.generateToken();
    });

    it('应该返回当前用户信息', async () => {
      const response = await request(app)
        .get('/api/auth/me')
        .set('Authorization', `Bearer ${token}`);

      expect(response.status).toBe(200);
      expect(response.body.data.user.email).toBe('test@example.com');
    });

    it('应该拒绝没有 token 的请求', async () => {
      const response = await request(app)
        .get('/api/auth/me');

      expect(response.status).toBe(401);
    });
  });
});
步骤 8: 使用自定义斜杠命令优化工作流
# 创建项目级命令
mkdir -p .codebuddy/commands

# 创建数据库重置命令
cat > .codebuddy/commands/reset-db.md << 'EOF'
清空数据库中的所有测试数据,并插入初始测试数据:
1. 创建 3 个测试用户(1 个管理员,2 个普通用户)
2. 创建 20 个测试商品(涵盖所有分类)
3. 返回所有创建的数据的详细信息
EOF

# 创建生成 API 文档命令
cat > .codebuddy/commands/gen-api-doc.md << 'EOF'
扫描所有路由文件,生成完整的 API 文档:
1. 提取所有路由端点
2. 生成请求示例
3. 生成响应示例
4. 输出 Markdown 格式文档
EOF

# 使用命令
/reset-db
/gen-api-doc

本案例关键点总结:

  1. ✅ 使用 /init 初始化项目上下文
  2. ✅ 通过 @文件名 精准引用相关文件
  3. ✅ 利用 CodeBuddy 自动生成模型、控制器、测试
  4. ✅ 使用自定义斜杠命令简化重复操作
  5. ✅ 生成完整的测试用例确保代码质量
  6. ✅ 自动化文档生成

案例 2: React 组件重构与优化

场景: 将一个复杂的、性能低下的 React 列表组件重构为高性能版本

原始代码(存在性能问题)
// src/components/UserList.jsx
import React, { useState, useEffect } from 'react';
import { getUserList } from '../api/user';

const UserList = ({ filters, onUserSelect }) => {
  const [users, setUsers] = useState([]);
  const [loading, setLoading] = useState(false);
  const [selectedUsers, setSelectedUsers] = useState(new Set());

  // 问题 1: 不合理的依赖导致频繁重新渲染
  useEffect(() => {
    fetchUsers();
  }, [filters, onUserSelect]); // onUserSelect 每次渲染都会改变

  // 问题 2: 同步的 fetch 导致界面卡顿
  const fetchUsers = async () => {
    setLoading(true);
    const data = await getUserList(filters);
    setUsers(data);
    setLoading(false);
  };

  // 问题 3: 每次渲染都创建新的函数和对象
  const handleUserClick = (userId) => {
    const newSelected = new Set(selectedUsers);
    if (newSelected.has(userId)) {
      newSelected.delete(userId);
    } else {
      newSelected.add(userId);
    }
    setSelectedUsers(newSelected);
  };

  // 问题 4: 没有使用虚拟滚动,大量数据时性能差
  // 问题 5: 内联样式对象每次渲染都重新创建
  return (
    <div style={{ padding: '20px' }}>
      {loading ? (
        <div style={{ textAlign: 'center' }}>加载中...</div>
      ) : (
        <div>
          {users.map((user) => (
            <div
              key={user.id}
              style={{
                padding: '10px',
                margin: '5px 0',
                border: '1px solid #ddd',
                cursor: 'pointer',
                backgroundColor: selectedUsers.has(user.id) ? '#e6f7ff' : 'white'
              }}
              onClick={() => handleUserClick(user.id)}
            >
              <div style={{ fontWeight: 'bold' }}>{user.name}</div>
              <div style={{ color: '#666' }}>{user.email}</div>
            </div>
          ))}
        </div>
      )}
    </div>
  );
};

export default UserList;
使用 CodeBuddy 进行重构

步骤 1: 代码分析

codebuddy
> @src/components/UserList.jsx 分析这个组件的性能问题:
   1. 识别所有导致不必要的重新渲染的原因
   2. 找出内存泄漏的风险点
   3. 评估在 1000+ 数据量下的性能表现

CodeBuddy 分析结果:

# UserList 组件性能分析报告

## 主要问题

1. **不合理的 useEffect 依赖**
   - onUserSelect 作为依赖会导致每次父组件渲染时都重新获取数据
   - 影响: 不必要的 API 调用和网络请求

2. **同步的数据处理**
   - fetchUsers 在 useEffect 中同步调用
   - 影响: 阻塞 UI 线程,导致界面卡顿

3. **函数重复创建**
   - handleUserClick 每次渲染都创建新函数
   - 影响: 子组件不必要的重新渲染

4. **缺少虚拟滚动**
   - 直接渲染所有用户项
   - 影响: 1000+ 数据时严重性能问题

5. **内联样式对象**
   - 每个 item 都创建新的样式对象
   - 影响: 增加内存分配和垃圾回收压力

6. **缺少请求取消**
   - 组件卸载时未取消正在进行的请求
   - 影响: 可能导致内存泄漏和状态更新错误

## 优化建议优先级

- 高优先级: 问题 4(虚拟滚动)、问题 6(请求取消)
- 中优先级: 问题 1(依赖优化)、问题 3(函数稳定化)
- 低优先级: 问题 2(异步处理)、问题 5(样式优化)

步骤 2: 使用 CodeBuddy 生成优化后的代码

> 基于以上分析,重构 UserList 组件:
   1. 使用 useMemo 和 useCallback 优化性能
   2. 添加请求取消功能
   3. 实现虚拟滚动
   4. 优化样式处理
   5. 添加错误边界和加载状态优化

重构后的代码:

// src/components/UserList.jsx
import React, { useState, useEffect, useCallback, useMemo, useRef } from 'react';
import { getUserList } from '../api/user';
import VirtualizedList from './VirtualizedList';
import styles from './UserList.module.css';

// 使用常量避免重复创建
const LIST_ITEM_HEIGHT = 80;
const OVERSCAN_COUNT = 5;

const UserList = React.memo(({ filters, onUserSelect }) => {
  // 状态管理
  const [users, setUsers] = useState([]);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);
  const [selectedUsers, setSelectedUsers] = useState(new Set());
  const [totalCount, setTotalCount] = useState(0);

  // Ref 用于存储取消令牌
  const abortControllerRef = useRef(null);

  // 优化: 使用 useCallback 稳定化函数
  const handleUserClick = useCallback((userId) => {
    setSelectedUsers(prev => {
      const newSelected = new Set(prev);
      if (newSelected.has(userId)) {
        newSelected.delete(userId);
      } else {
        newSelected.add(userId);
      }
      return newSelected;
    });
  }, []);

  // 优化: 稳定化的回调函数
  const stableOnUserSelect = useCallback((user) => {
    onUserSelect?.(user);
  }, [onUserSelect]);

  // 优化: 仅在 filters 变化时重新获取数据
  const fetchUsers = useCallback(async (signal) => {
    try {
      setLoading(true);
      setError(null);
      
      const response = await getUserList(filters, { signal });
      
      // 检查请求是否被取消
      if (signal.aborted) return;

      setUsers(response.users || []);
      setTotalCount(response.totalCount || 0);
    } catch (err) {
      // 忽略取消错误
      if (err.name === 'AbortError') return;
      
      setError(err.message || '获取用户列表失败');
      console.error('Fetch users error:', err);
    } finally {
      if (!signal.aborted) {
        setLoading(false);
      }
    }
  }, [filters]); // 仅依赖 filters

  // 优化: 正确的依赖管理
  useEffect(() => {
    // 取消之前的请求
    if (abortControllerRef.current) {
      abortControllerRef.current.abort();
    }

    // 创建新的 AbortController
    abortControllerRef.current = new AbortController();
    const { signal } = abortControllerRef.current;

    // 获取数据
    fetchUsers(signal);

    // 清理函数
    return () => {
      if (abortControllerRef.current) {
        abortControllerRef.current.abort();
      }
    };
  }, [fetchUsers]); // 仅依赖 fetchUsers

  // 优化: 使用 useMemo 缓存计算结果
  const listData = useMemo(() => {
    return users.map(user => ({
      id: user.id,
      data: user,
      isSelected: selectedUsers.has(user.id)
    }));
  }, [users, selectedUsers]);

  // 优化: 渲染项组件
  const renderItem = useCallback((item, index) => {
    const { data: user, isSelected } = item;
    
    return (
      <div
        className={`${styles.userItem} ${isSelected ? styles.selected : ''}`}
        onClick={() => handleUserClick(user.id)}
        onDoubleClick={() => stableOnUserSelect(user)}
      >
        <div className={styles.userName}>{user.name}</div>
        <div className={styles.userEmail}>{user.email}</div>
        <div className={styles.userMeta}>
          <span>角色: {user.role}</span>
          <span>状态: {user.isActive ? '活跃' : '禁用'}</span>
        </div>
      </div>
    );
  }, [handleUserClick, stableOnUserSelect]);

  // 优化: 空状态和错误处理
  if (error && !users.length) {
    return (
      <div className={styles.errorContainer}>
        <div className={styles.errorIcon}>⚠️</div>
        <div className={styles.errorMessage}>{error}</div>
        <button 
          className={styles.retryButton}
          onClick={() => fetchUsers(new AbortController().signal)}
        >
          重试
        </button>
      </div>
    );
  }

  if (!loading && !users.length) {
    return (
      <div className={styles.emptyContainer}>
        <div className={styles.emptyIcon}>📭</div>
        <div className={styles.emptyMessage}>暂无用户数据</div>
      </div>
    );
  }

  return (
    <div className={styles.container}>
      {/* 统计信息 */}
      <div className={styles.header}>
        <span className={styles.totalCount}>{totalCount} 位用户
        </span>
        <span className={styles.selectedCount}>
          已选择 {selectedUsers.size}</span>
      </div>

      {/* 加载状态 */}
      {loading && (
        <div className={styles.loadingOverlay}>
          <div className={styles.spinner} />
          <div className={styles.loadingText}>加载中...</div>
        </div>
      )}

      {/* 虚拟滚动列表 */}
      <VirtualizedList
        items={listData}
        renderItem={renderItem}
        itemHeight={LIST_ITEM_HEIGHT}
        overscanCount={OVERSCAN_COUNT}
        className={styles.list}
      />
    </div>
  );
});

UserList.displayName = 'UserList';

export default UserList;

配套的样式文件:

/* src/components/UserList.module.css */
.container {
  display: flex;
  flex-direction: column;
  height: 100%;
  padding: 20px;
  background: #f5f5f5;
}

.header {
  display: flex;
  justify-content: space-between;
  padding: 12px 16px;
  margin-bottom: 16px;
  background: white;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}

.totalCount,
.selectedCount {
  font-size: 14px;
  color: #666;
  font-weight: 500;
}

.selectedCount {
  color: #1890ff;
}

.list {
  flex: 1;
  overflow-y: auto;
  border-radius: 8px;
  background: white;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}

.userItem {
  padding: 16px;
  margin: 8px;
  border: 1px solid #e8e8e8;
  border-radius: 6px;
  cursor: pointer;
  transition: all 0.2s ease;
  background: white;
}

.userItem:hover {
  border-color: #1890ff;
  box-shadow: 0 2px 8px rgba(24, 144, 255, 0.15);
  transform: translateY(-1px);
}

.userItem.selected {
  background: #e6f7ff;
  border-color: #1890ff;
}

.userName {
  font-size: 16px;
  font-weight: 600;
  color: #333;
  margin-bottom: 4px;
}

.userEmail {
  font-size: 14px;
  color: #666;
  margin-bottom: 8px;
}

.userMeta {
  display: flex;
  gap: 16px;
  font-size: 12px;
  color: #999;
}

.loadingOverlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background: rgba(255, 255, 255, 0.9);
  z-index: 10;
}

.spinner {
  width: 32px;
  height: 32px;
  border: 3px solid #f0f0f0;
  border-top-color: #1890ff;
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

.loadingText {
  margin-top: 12px;
  color: #666;
  font-size: 14px;
}

.errorContainer,
.emptyContainer {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 60px 20px;
  text-align: center;
}

.errorIcon,
.emptyIcon {
  font-size: 48px;
  margin-bottom: 16px;
}

.errorMessage,
.emptyMessage {
  font-size: 16px;
  color: #666;
  margin-bottom: 20px;
}

.retryButton {
  padding: 8px 24px;
  background: #1890ff;
  color: white;
  border: none;
  border-radius: 4px;
  font-size: 14px;
  cursor: pointer;
  transition: background 0.2s;
}

.retryButton:hover {
  background: #40a9ff;
}

虚拟滚动组件:

// src/components/VirtualizedList.jsx
import React, { useState, useRef, useEffect, useCallback } from 'react';
import styles from './VirtualizedList.module.css';

const VirtualizedList = ({
  items,
  renderItem,
  itemHeight,
  overscanCount = 3,
  className = ''
}) => {
  const [scrollTop, setScrollTop] = useState(0);
  const [containerHeight, setContainerHeight] = useState(0);
  const containerRef = useRef(null);

  // 监听容器大小变化
  useEffect(() => {
    const container = containerRef.current;
    if (!container) return;

    const resizeObserver = new ResizeObserver(entries => {
      for (const entry of entries) {
        setContainerHeight(entry.contentRect.height);
      }
    });

    resizeObserver.observe(container);
    return () => resizeObserver.disconnect();
  }, []);

  // 处理滚动事件
  const handleScroll = useCallback((e) => {
    setScrollTop(e.target.scrollTop);
  }, []);

  // 计算可见范围
  const { startIndex, endIndex } = useMemo(() => {
    const visibleCount = Math.ceil(containerHeight / itemHeight);
    const start = Math.max(0, Math.floor(scrollTop / itemHeight) - overscanCount);
    const end = Math.min(
      items.length - 1,
      Math.ceil((scrollTop + containerHeight) / itemHeight) + overscanCount
    );
    return { startIndex: start, endIndex: end };
  }, [scrollTop, containerHeight, itemHeight, overscanCount, items.length]);

  // 计算总高度
  const totalHeight = useMemo(() => {
    return items.length * itemHeight;
  }, [items.length, itemHeight]);

  // 计算偏移量
  const offsetY = useMemo(() => {
    return startIndex * itemHeight;
  }, [startIndex, itemHeight]);

  // 获取可见项
  const visibleItems = useMemo(() => {
    return items.slice(startIndex, endIndex + 1);
  }, [items, startIndex, endIndex]);

  return (
    <div
      ref={containerRef}
      className={`${styles.virtualList} ${className}`}
      onScroll={handleScroll}
    >
      <div
        className={styles.spacer}
        style={{ height: totalHeight }}
      >
        <div
          className={styles.content}
          style={{
            transform: `translateY(${offsetY}px)`
          }}
        >
          {visibleItems.map((item, index) => (
            <div
              key={item.id || index}
              style={{ height: itemHeight }}
            >
              {renderItem(item, startIndex + index)}
            </div>
          ))}
        </div>
      </div>
    </div>
  );
};

export default VirtualizedList;

步骤 3: 使用 CodeBuddy 生成性能测试

> 为重构后的 UserList 组件生成性能测试:
   1. 测试 1000+ 数据量下的渲染性能
   2. 测试频繁筛选时的性能
   3. 测试内存使用情况
   4. 生成性能对比报告

生成的性能测试代码:

// src/components/__tests__/UserList.performance.test.jsx
import React from 'react';
import { render, screen, waitFor } from '@testing-library/react';
import UserList from '../UserList';
import * as userApi from '../../api/user';

// Mock API
jest.mock('../../api/user');

// 生成大量测试数据
const generateMockUsers = (count) => {
  return Array.from({ length: count }, (_, i) => ({
    id: `user-${i}`,
    name: `用户 ${i + 1}`,
    email: `user${i + 1}@example.com`,
    role: i % 3 === 0 ? 'admin' : 'user',
    isActive: i % 10 !== 0
  }));
};

describe('UserList Performance Tests', () => {
  beforeEach(() => {
    jest.useFakeTimers();
  });

  afterEach(() => {
    jest.useRealTimers();
  });

  describe('大规模数据渲染性能', () => {
    it('应该在 100ms 内渲染 1000 条数据', async () => {
      const mockUsers = generateMockUsers(1000);
      userApi.getUserList.mockResolvedValue({
        users: mockUsers,
        totalCount: 1000
      });

      const startTime = performance.now();
      
      render(<UserList filters={{}} />);
      
      await waitFor(() => {
        expect(screen.queryByText('加载中...')).not.toBeInTheDocument();
      });
      
      const endTime = performance.now();
      const renderTime = endTime - startTime;

      console.log(`1000 条数据渲染时间: ${renderTime.toFixed(2)}ms`);
      expect(renderTime).toBeLessThan(100);
    });

    it('应该在 200ms 内渲染 10000 条数据', async () => {
      const mockUsers = generateMockUsers(10000);
      userApi.getUserList.mockResolvedValue({
        users: mockUsers,
        totalCount: 10000
      });

      const startTime = performance.now();
      
      render(<UserList filters={{}} />);
      
      await waitFor(() => {
        expect(screen.queryByText('加载中...')).not.toBeInTheDocument();
      });
      
      const endTime = performance.now();
      const renderTime = endTime - startTime;

      console.log(`10000 条数据渲染时间: ${renderTime.toFixed(2)}ms`);
      expect(renderTime).toBeLessThan(200);
    });
  });

  describe('频繁筛选性能', () => {
    it('应该在 50ms 内响应筛选变化', async () => {
      const mockUsers = generateMockUsers(1000);
      userApi.getUserList.mockResolvedValue({
        users: mockUsers,
        totalCount: 1000
      });

      const { rerender } = render(
        <UserList filters={{ role: 'user' }} />
      );

      await waitFor(() => {
        expect(screen.queryByText('加载中...')).not.toBeInTheDocument();
      });

      const startTime = performance.now();
      
      // 快速切换筛选条件
      for (let i = 0; i < 5; i++) {
        rerender(<UserList filters={{ role: i % 2 === 0 ? 'user' : 'admin' }} />);
        await waitFor(() => {
          expect(screen.queryByText('加载中...')).not.toBeInTheDocument();
        });
      }
      
      const endTime = performance.now();
      const filterTime = endTime - startTime;

      console.log(`5 次筛选切换总时间: ${filterTime.toFixed(2)}ms`);
      expect(filterTime).toBeLessThan(250); // 平均每次 < 50ms
    });
  });

  describe('内存使用', () => {
    it('不应该有明显的内存泄漏', async () => {
      const mockUsers = generateMockUsers(1000);
      userApi.getUserList.mockResolvedValue({
        users: mockUsers,
        totalCount: 1000
      });

      const getMemoryUsage = () => {
        if (performance.memory) {
          return performance.memory.usedJSHeapSize;
        }
        return null;
      };

      const initialMemory = getMemoryUsage();
      
      // 渲染和卸载多次
      for (let i = 0; i < 10; i++) {
        const { unmount } = render(<UserList filters={{}} />);
        
        await waitFor(() => {
          expect(screen.queryByText('加载中...')).not.toBeInTheDocument();
        });
        
        unmount();
      }

      // 等待垃圾回收
      await new Promise(resolve => setTimeout(resolve, 1000));

      const finalMemory = getMemoryUsage();

      if (initialMemory && finalMemory) {
        const memoryIncrease = (finalMemory - initialMemory) / 1024 / 1024;
        console.log(`内存增长: ${memoryIncrease.toFixed(2)}MB`);
        
        // 内存增长不应超过 10MB
        expect(memoryIncrease).toBeLessThan(10);
      }
    });
  });

  describe('滚动性能', () => {
    it('应该流畅滚动,不出现卡顿', async () => {
      const mockUsers = generateMockUsers(10000);
      userApi.getUserList.mockResolvedValue({
        users: mockUsers,
        totalCount: 10000
      });

      const { container } = render(<UserList filters={{}} />);
      
      await waitFor(() => {
        expect(screen.queryByText('加载中...')).not.toBeInTheDocument();
      });

      const listContainer = container.querySelector('.list');
      
      const frameTimes = [];
      let frameCount = 0;

      const measureFrame = () => {
        const start = performance.now();
        
        return new Promise(resolve => {
          requestAnimationFrame(() => {
            const end = performance.now();
            frameTimes.push(end - start);
            frameCount++;
            
            if (frameCount < 60) {
              measureFrame().then(resolve);
            } else {
              resolve();
            }
          });
        });
      };

      // 模拟滚动
      if (listContainer) {
        listContainer.scrollTop = 0;
        
        for (let i = 0; i < 100; i++) {
          listContainer.scrollTop = i * 100;
          await new Promise(resolve => setTimeout(resolve, 16));
        }
      }

      const avgFrameTime = frameTimes.reduce((a, b) => a + b, 0) / frameTimes.length;
      
      console.log(`平均帧时间: ${avgFrameTime.toFixed(2)}ms`);
      console.log(`预期 FPS: ${1000 / avgFrameTime.toFixed(0)}`);
      
      // 平均帧时间应小于 16.67ms (60 FPS)
      expect(avgFrameTime).toBeLessThan(16.67);
    });
  });
});

本案例关键点总结:

  1. ✅ 使用 CodeBuddy 深度分析性能问题
  2. ✅ 应用 React 性能优化最佳实践
  3. ✅ 实现虚拟滚动处理大数据量
  4. ✅ 使用 useMemo、useCallback、React.memo 优化
  5. ✅ 添加请求取消防止内存泄漏
  6. ✅ 生成完整的性能测试验证优化效果

案例 3: 自动化 CI/CD 工作流

场景: 使用 CodeBuddy Code 构建完整的 CI/CD 自动化流程

项目结构
project/
├── .github/
│   └── workflows/
│       ├── ci.yml
│       ├── cd.yml
│       └── code-review.yml
├── .codebuddy/
│   ├── commands/
│   │   ├── test.md
│   │   ├── build.md
│   │   └── deploy.md
│   └── agents/
│       └── ci-agent.yaml
├── src/
├── tests/
└── Dockerfile
步骤 1: 创建 CodeBuddy CI 智能体
# .codebuddy/agents/ci-agent.yaml
name: CI Agent
description: 专门用于 CI/CD 流程的智能体
system_prompt: |
  你是 CI/CD 专家,专注于:
  - 代码质量检查
  - 自动化测试执行
  - 构建和部署优化
  - 性能监控和告警

capabilities:
  - code_analysis
  - test_execution
  - build_optimization
  - deployment_automation

tools:
  - eslint
  - jest
  - docker
  - kubernetes
步骤 2: 创建自定义命令
# 创建测试命令
cat > .codebuddy/commands/test.md << 'EOF'
执行完整的测试流程:
1. 运行单元测试,生成覆盖率报告
2. 运行集成测试
3. 运行端到端测试
4. 汇总测试结果
5. 如果测试失败,提供详细的失败原因分析
EOF

# 创建构建命令
cat > .codebuddy/commands/build.md << 'EOF'
执行构建流程:
1. 清理旧的构建产物
2. 执行依赖检查和安全扫描
3. 构建生产版本
4. 生成构建报告
5. 优化构建产物大小
EOF

# 创建部署命令
cat > .codebuddy/commands/deploy.md << 'EOF'
执行部署流程:
1. 验证部署前检查清单
2. 构建并推送 Docker 镜像
3. 更新 Kubernetes 部署配置
4. 执行灰度发布
5. 验证部署健康状态
6. 准备回滚方案
EOF
步骤 3: GitHub Actions CI 配置
# .github/workflows/ci.yml
name: CI Pipeline

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

jobs:
  code-quality:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '18'
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Install CodeBuddy
        run: npm install -g @tencent-ai/codebuddy-code

      - name: Run CodeBuddy Code Review
        run: |
          codebuddy -p --dangerously-skip-permissions \
            --agent ci-agent \
            "对当前的代码变更进行全面审查,重点关注:
             1. 代码规范问题
             2. 潜在的安全漏洞
             3. 性能问题
             4. 测试覆盖率不足的文件
             生成详细的审查报告" \
            > code-review-report.txt

      - name: Upload Code Review Report
        uses: actions/upload-artifact@v3
        with:
          name: code-review-report
          path: code-review-report.txt

      - name: Comment PR with Review Results
        if: github.event_name == 'pull_request'
        uses: actions/github-script@v6
        with:
          script: |
            const fs = require('fs');
            const report = fs.readFileSync('code-review-report.txt', 'utf8');
            
            // 添加评论
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: `## 🤖 CodeBuddy 代码审查报告\n\n${report}`
            });

  test:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '18'
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Install CodeBuddy
        run: npm install -g @tencent-ai/codebuddy-code

      - name: Run tests with CodeBuddy
        run: |
          codebuddy -p --dangerously-skip-permissions \
            "/test" \
            > test-results.txt

      - name: Upload test results
        uses: actions/upload-artifact@v3
        if: always()
        with:
          name: test-results
          path: test-results.txt

      - name: Upload coverage reports
        uses: codecov/codecov-action@v3
        if: always()
        with:
          files: ./coverage/lcov.info

  security-scan:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Run npm audit
        run: npm audit --audit-level=moderate

      - name: Install CodeBuddy
        run: npm install -g @tencent-ai/codebuddy-code

      - name: Run security scan with CodeBuddy
        run: |
          codebuddy -p --dangerously-skip-permissions \
            "进行安全扫描,检查:
             1. 硬编码的密钥和密码
             2. SQL 注入风险
             3. XSS 漏洞
             4. 不安全的依赖
             生成安全报告" \
            > security-report.txt

      - name: Upload security report
        uses: actions/upload-artifact@v3
        with:
          name: security-report
          path: security-report.txt

  build:
    runs-on: ubuntu-latest
    needs: [code-quality, test, security-scan]
    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '18'
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Install CodeBuddy
        run: npm install -g @tencent-ai/codebuddy-code

      - name: Build with CodeBuddy
        run: |
          codebuddy -p --dangerously-skip-permissions \
            "/build" \
            > build-report.txt

      - name: Upload build artifacts
        uses: actions/upload-artifact@v3
        with:
          name: build-artifacts
          path: dist/

      - name: Upload build report
        uses: actions/upload-artifact@v3
        with:
          name: build-report
          path: build-report.txt
步骤 4: GitHub Actions CD 配置
# .github/workflows/cd.yml
name: CD Pipeline

on:
  push:
    branches: [main]
    tags: ['v*']

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

jobs:
  build-and-push:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write

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

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v2

      - name: Log in to Container Registry
        uses: docker/login-action@v2
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Extract metadata
        id: meta
        uses: docker/metadata-action@v4
        with:
          images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
          tags: |
            type=ref,event=branch
            type=ref,event=pr
            type=semver,pattern={{version}}
            type=semver,pattern={{major}}.{{minor}}
            type=semver,pattern={{major}}

      - name: Build and push Docker image
        uses: docker/build-push-action@v4
        with:
          context: .
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
          cache-from: type=gha
          cache-to: type=gha,mode=max

  deploy-staging:
    runs-on: ubuntu-latest
    needs: build-and-push
    if: github.ref == 'refs/heads/develop'
    environment:
      name: staging
      url: https://staging.example.com

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

      - name: Install CodeBuddy
        run: npm install -g @tencent-ai/codebuddy-code

      - name: Deploy to staging
        run: |
          codebuddy -p --dangerously-skip-permissions \
            "/deploy" \
            --env staging \
            > deploy-staging-report.txt

      - name: Run smoke tests
        run: |
          curl -f https://staging.example.com/health || exit 1

      - name: Upload deploy report
        uses: actions/upload-artifact@v3
        with:
          name: deploy-staging-report
          path: deploy-staging-report.txt

  deploy-production:
    runs-on: ubuntu-latest
    needs: build-and-push
    if: startsWith(github.ref, 'refs/tags/v')
    environment:
      name: production
      url: https://example.com

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

      - name: Install CodeBuddy
        run: npm install -g @tencent-ai/codebuddy-code

      - name: Create deployment plan
        run: |
          codebuddy -p --dangerously-skip-permissions \
            "为生产环境部署制定详细计划,包括:
             1. 灰度发布策略
             2. 监控指标
             3. 回滚方案
             4. 风险评估" \
            > deployment-plan.txt

      - name: Review deployment plan
        run: cat deployment-plan.txt

      - name: Deploy to production
        run: |
          codebuddy -p --dangerously-skip-permissions \
            "/deploy" \
            --env production \
            --plan deployment-plan.txt \
            > deploy-production-report.txt

      - name: Run health checks
        run: |
          for i in {1..10}; do
            if curl -f https://example.com/health; then
              echo "Health check passed"
              exit 0
            fi
            echo "Health check failed, retrying... ($i/10)"
            sleep 30
          done
          echo "Health check failed after 10 attempts"
          exit 1

      - name: Monitor deployment
        run: |
          codebuddy -p --dangerously-skip-permissions \
            "监控生产环境部署后的指标:
             1. 错误率
             2. 响应时间
             3. 资源使用情况
             持续监控 30 分钟" \
            --duration 30m

      - name: Notify team
        if: always()
        uses: actions/github-script@v6
        with:
          script: |
            const fs = require('fs');
            const report = fs.readFileSync('deploy-production-report.txt', 'utf8');
            
            // 发送通知(可以使用 Slack、Teams 等)
            console.log('Deployment notification:', report);
步骤 5: 创建 Dockerfile
# 使用 CodeBuddy 优化的 Dockerfile
FROM node:18-alpine AS builder

# 安装 CodeBuddy
RUN npm install -g @tencent-ai/codebuddy-code

# 设置工作目录
WORKDIR /app

# 复制依赖文件
COPY package*.json ./

# 使用 CodeBuddy 优化依赖安装
RUN codebuddy -p "分析 package.json,优化依赖安装策略" && \
    npm ci --only=production

# 复制源代码
COPY . .

# 使用 CodeBuddy 进行构建优化
RUN codebuddy -p "/build" && \
    npm run build

# 生产镜像
FROM node:18-alpine

WORKDIR /app

# 复制构建产物
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY package*.json ./

# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD node healthcheck.js || exit 1

# 启动应用
CMD ["node", "dist/server.js"]
步骤 6: Kubernetes 部署配置
# k8s/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-deployment
  labels:
    app: myapp
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
        version: v1.0.0
    spec:
      containers:
      - name: app
        image: ghcr.io/username/myapp:latest
        ports:
        - containerPort: 3000
        env:
        - name: NODE_ENV
          value: "production"
        - name: PORT
          value: "3000"
        resources:
          requests:
            memory: "256Mi"
            cpu: "250m"
          limits:
            memory: "512Mi"
            cpu: "500m"
        livenessProbe:
          httpGet:
            path: /health
            port: 3000
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /ready
            port: 3000
          initialDelaySeconds: 5
          periodSeconds: 5

---
apiVersion: v1
kind: Service
metadata:
  name: app-service
spec:
  selector:
    app: myapp
  ports:
  - protocol: TCP
    port: 80
    targetPort: 3000
  type: LoadBalancer
步骤 7: 使用 CodeBuddy 生成监控脚本
codebuddy -p "生成 Kubernetes 监控脚本,包括:
 1. Pod 健康状态检查
 2. 资源使用监控
  3. 日志聚合
  4. 告警配置" \
  > k8s/monitor.sh

生成的监控脚本:

#!/bin/bash
# k8s/monitor.sh

NAMESPACE="production"
APP_NAME="myapp"

echo "📊 开始监控应用..."

# 获取 Pod 状态
echo "📋 Pod 状态:"
kubectl get pods -n $NAMESPACE -l app=$APP_NAME

# 获取资源使用
echo "💾 资源使用情况:"
kubectl top pods -n $NAMESPACE -l app=$APP_NAME

# 检查日志
echo "📝 最近日志:"
kubectl logs -n $NAMESPACE -l app=$APP_NAME --tail=50

# 检查事件
echo "⚠️  最近事件:"
kubectl get events -n $NAMESPACE --sort-by='.lastTimestamp' | tail -20

# 检查 HPA 状态
echo "📈 HPA 状态:"
kubectl get hpa -n $NAMESPACE

# 健康检查
echo "🏥 健康检查:"
kubectl exec -n $NAMESPACE -l app=$APP_NAME -- curl -f http://localhost:3000/health

echo "✅ 监控完成!"

本案例关键点总结:

  1. ✅ 使用 CodeBuddy 智能体自动化 CI/CD 流程
  2. ✅ 创建自定义命令封装复杂操作
  3. ✅ 集成 CodeBuddy 到 GitHub Actions
  4. ✅ 自动化代码审查、测试、构建、部署
  5. ✅ 实现灰度发布和回滚机制
  6. ✅ 生成监控和告警脚本

总结与进阶路径

掌握层次

层次 技能 标志
入门 基础补全、对话交互 能独立完成日常编码任务
熟练 自定义命令、MCP 集成 能优化团队工作流
精通 智能体开发、RAG 构建 能构建企业级解决方案
专家 性能优化、架构设计 能主导 AI 编程转型

持续学习资源


开启你的 AI 编程进阶之旅! 🚀

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐