最近在 GitHub 上有个项目突然火了起来,名字叫《Claude's plan》。不少开发者看到标题的第一反应可能是:这又是哪个 AI 助手的新功能计划?但实际上,它解决的是一个更实际的问题—— 如何让大型语言模型在复杂任务中真正实现“规划-执行-验证”的闭环

如果你曾经尝试过让 Claude、GPT-4 或其他大模型帮你完成多步骤任务(比如写一个完整项目、调试复杂代码、或者分析大型代码库),可能会发现一个痛点:模型经常在中间步骤“跑偏”,或者忘记最初的目标。而《Claude's plan》正是针对这个问题的一个工程化解决方案。

1. 这篇文章真正要解决的问题

在实际开发中,我们越来越依赖 AI 助手来完成代码生成、重构、调试等任务。但当任务复杂度上升时,单纯依靠单次对话往往不够可靠。比如:

  • 场景1 :你需要让 AI 帮你从一个老旧项目迁移到新框架,涉及依赖更新、API 调整、配置文件修改等多个步骤。
  • 场景2 :你希望 AI 分析一个大型代码库的安全漏洞,需要遍历不同模块、检查依赖关系、识别潜在风险。

在这些场景下,如果只是简单提问“帮我把这个项目从 Spring Boot 2.x 升级到 3.x”,模型可能会给你一个概览,但很难给出可落地的完整方案。

《Claude's plan》的核心价值在于: 它将复杂任务分解为可执行的子任务序列,并为每个步骤提供明确的输入输出规范,让 AI 的“规划”能力变得可验证、可迭代

2. 基础概念与核心原理

2.1 什么是任务规划(Task Planning)

在 AI 领域,任务规划指的是将高层目标分解为一系列可执行动作的过程。传统的自动化脚本是硬编码的流程,而基于 LLM 的任务规划则是动态生成的。

《Claude's plan》的实现基于几个关键概念:

  • 目标定义(Goal Specification) :明确描述最终要达成的结果
  • 步骤分解(Step Decomposition) :将大目标拆解为原子性的子任务
  • 依赖管理(Dependency Management) :确保步骤按正确顺序执行
  • 验证机制(Verification Mechanism) :检查每个步骤的执行结果是否符合预期

2.2 《Claude's plan》的架构设计

从项目结构来看,它采用了典型的 Agent 架构模式:

输入层(用户需求) → 规划器(Planner) → 执行器(Executor) → 验证器(Verifier) → 输出层(最终结果)

其中最具特色的是它的 规划器模块 ,不仅生成步骤列表,还会为每个步骤定义:

  • 前置条件 :执行该步骤前必须满足的条件
  • 预期输出 :步骤完成后应该达成的具体结果
  • 验证方法 :如何检查步骤执行是否正确
  • 回退策略 :如果步骤失败该如何处理

3. 环境准备与前置条件

要理解或使用《Claude's plan》的相关理念,你需要准备以下环境:

3.1 基础开发环境

# 检查 Python 版本(推荐 3.8+)
python --version

# 检查 Git
git --version

# 创建项目目录
mkdir claude-plan-demo && cd claude-plan-demo

3.2 API 访问配置

由于项目涉及与 LLM 的交互,你需要配置相应的 API 访问权限:

# config.py
import os

# Anthropic Claude API 配置(如果使用 Claude)
ANTHROPIC_API_KEY = os.getenv('ANTHROPIC_API_KEY')

# 或者 OpenAI GPT 配置
OPENAI_API_KEY = os.getenv('OPENAI_API_KEY')
OPENAI_API_BASE = os.getenv('OPENAI_API_BASE', 'https://api.openai.com/v1')

# 模型选择配置
MODEL_CONFIG = {
    'planning_model': 'claude-3-sonnet-20240229',  # 用于规划任务的模型
    'execution_model': 'claude-3-haiku-20240307',   # 用于执行具体步骤的模型
}

3.3 依赖包安装

项目核心依赖包括:

# requirements.txt
openai>=1.0.0
anthropic>=0.5.0
pydantic>=2.0.0
python-dotenv>=1.0.0
requests>=2.28.0

安装命令:

pip install -r requirements.txt

4. 核心流程拆解

4.1 任务解析与目标澄清

第一步是让模型准确理解用户意图。这不仅仅是简单的文本理解,还包括:

  • 范围界定 :明确任务的边界在哪里
  • 成功标准 :定义什么是"完成"
  • 约束条件 :识别技术限制、时间要求等
# task_parser.py
from pydantic import BaseModel
from typing import List, Optional

class TaskSpecification(BaseModel):
    goal: str
    constraints: List[str]
    success_criteria: List[str]
    expected_output_format: Optional[str] = None

def parse_user_input(user_input: str) -> TaskSpecification:
    """
    解析用户输入,提取关键任务信息
    """
    # 这里可以集成 LLM 来帮助解析复杂需求
    prompt = f"""
    请分析以下用户需求,提取关键信息:
    
    用户输入:{user_input}
    
    请返回:
    1. 主要目标(goal)
    2. 约束条件(constraints)
    3. 成功标准(success_criteria)
    4. 输出格式要求(如果有)
    """
    
    # 调用 LLM 进行解析(伪代码)
    # response = llm_completion(prompt)
    # 解析 response 并填充 TaskSpecification
    
    return TaskSpecification(
        goal="示例目标",
        constraints=["时间限制", "技术约束"],
        success_criteria=["功能完整", "性能达标"]
    )

4.2 步骤生成与排序

生成任务步骤时,需要考虑步骤间的依赖关系:

# planner.py
class TaskStep(BaseModel):
    step_id: int
    description: str
    dependencies: List[int]  # 依赖的步骤ID
    expected_duration: str
    required_tools: List[str]
    validation_criteria: str

def generate_task_plan(task_spec: TaskSpecification) -> List[TaskStep]:
    """
    基于任务规格生成执行计划
    """
    planning_prompt = f"""
    任务目标:{task_spec.goal}
    约束条件:{task_spec.constraints}
    成功标准:{task_spec.success_criteria}
    
    请将这个任务分解为具体的执行步骤,每个步骤应该:
    1. 有明确的输入输出
    2. 可以独立验证
    3. 明确依赖关系
    4. 估计所需时间
    5. 列出需要的工具或资源
    """
    
    # 调用规划模型生成步骤
    # steps = call_planning_model(planning_prompt)
    
    return [
        TaskStep(
            step_id=1,
            description="环境准备和依赖检查",
            dependencies=[],
            expected_duration="10分钟",
            required_tools=["python", "git"],
            validation_criteria="所有依赖包正确安装"
        ),
        # 更多步骤...
    ]

4.3 步骤执行与状态跟踪

每个步骤的执行都需要记录状态和结果:

# executor.py
class StepExecutionResult(BaseModel):
    step_id: int
    status: str  # pending, running, completed, failed
    output: Optional[str] = None
    error_message: Optional[str] = None
    start_time: Optional[str] = None
    end_time: Optional[str] = None

class TaskExecutor:
    def __init__(self, plan: List[TaskStep]):
        self.plan = plan
        self.results: Dict[int, StepExecutionResult] = {}
        self.completed_steps = set()
    
    def can_execute_step(self, step: TaskStep) -> bool:
        """检查步骤是否满足执行条件"""
        return all(dep in self.completed_steps for dep in step.dependencies)
    
    def execute_step(self, step: TaskStep) -> StepExecutionResult:
        """执行单个步骤"""
        if not self.can_execute_step(step):
            return StepExecutionResult(
                step_id=step.step_id,
                status="failed",
                error_message="依赖步骤未完成"
            )
        
        # 记录开始时间
        result = StepExecutionResult(
            step_id=step.step_id,
            status="running",
            start_time=datetime.now().isoformat()
        )
        
        try:
            # 执行具体操作
            output = self._execute_single_step(step)
            result.status = "completed"
            result.output = output
        except Exception as e:
            result.status = "failed"
            result.error_message = str(e)
        
        result.end_time = datetime.now().isoformat()
        return result
    
    def _execute_single_step(self, step: TaskStep) -> str:
        """执行具体的步骤逻辑"""
        # 这里根据步骤描述调用相应的工具或API
        if "环境准备" in step.description:
            return self._setup_environment()
        elif "代码分析" in step.description:
            return self._analyze_code()
        # 更多步骤处理逻辑...
        
        return "步骤执行完成"

5. 完整示例与代码实现

让我们通过一个具体场景来演示《Claude's plan》的工作流程: 将一个简单的 Flask 应用迁移到 FastAPI

5.1 项目结构准备

首先创建示例项目:

# 创建原始 Flask 项目
mkdir flask-to-fastapi-migration
cd flask-to-fastapi-migration

# 原始 Flask 应用结构
mkdir -p src/flask_app
touch src/flask_app/__init__.py
touch src/flask_app/app.py
touch src/flask_app/models.py
touch requirements.txt

原始 Flask 应用代码:

# src/flask_app/app.py
from flask import Flask, jsonify, request
from .models import User

app = Flask(__name__)

@app.route('/users', methods=['GET'])
def get_users():
    users = User.get_all()
    return jsonify([user.to_dict() for user in users])

@app.route('/users', methods=['POST'])
def create_user():
    data = request.json
    user = User.create(data['name'], data['email'])
    return jsonify(user.to_dict()), 201

@app.route('/users/<int:user_id>', methods=['GET'])
def get_user(user_id):
    user = User.get_by_id(user_id)
    if user:
        return jsonify(user.to_dict())
    return jsonify({'error': 'User not found'}), 404

if __name__ == '__main__':
    app.run(debug=True)
# src/flask_app/models.py
class User:
    _users = []
    _next_id = 1
    
    def __init__(self, user_id, name, email):
        self.id = user_id
        self.name = name
        self.email = email
    
    @classmethod
    def create(cls, name, email):
        user = cls(cls._next_id, name, email)
        cls._users.append(user)
        cls._next_id += 1
        return user
    
    @classmethod
    def get_all(cls):
        return cls._users.copy()
    
    @classmethod
    def get_by_id(cls, user_id):
        for user in cls._users:
            if user.id == user_id:
                return user
        return None
    
    def to_dict(self):
        return {
            'id': self.id,
            'name': self.name,
            'email': self.email
        }

5.2 迁移计划生成

使用规划器生成迁移步骤:

# migration_planner.py
def generate_migration_plan():
    """生成从 Flask 到 FastAPI 的迁移计划"""
    task_description = """
    将现有的 Flask 用户管理应用迁移到 FastAPI。
    需要保持所有现有功能,包括:
    - GET /users 获取所有用户
    - POST /users 创建新用户  
    - GET /users/{id} 获取特定用户
    同时要确保代码符合 FastAPI 的最佳实践。
    """
    
    plan = [
        {
            "step_id": 1,
            "description": "分析现有 Flask 应用结构和依赖",
            "dependencies": [],
            "tools": ["python", "code_analysis"],
            "validation": "生成应用结构报告"
        },
        {
            "step_id": 2, 
            "description": "安装 FastAPI 和相关依赖",
            "dependencies": [1],
            "tools": ["pip", "requirements_management"],
            "validation": "依赖安装成功"
        },
        {
            "step_id": 3,
            "description": "创建 FastAPI 应用基础结构",
            "dependencies": [2],
            "tools": ["python", "fastapi"],
            "validation": "基础应用能正常运行"
        },
        {
            "step_id": 4,
            "description": "迁移数据模型到 Pydantic",
            "dependencies": [3],
            "tools": ["python", "pydantic"],
            "validation": "模型定义正确"
        },
        {
            "step_id": 5,
            "description": "重写路由处理器",
            "dependencies": [4],
            "tools": ["python", "fastapi"],
            "validation": "所有端点功能正常"
        },
        {
            "step_id": 6,
            "description": "更新启动配置和文档",
            "dependencies": [5],
            "tools": ["python", "uvicorn"],
            "validation": "应用完整可运行"
        }
    ]
    
    return plan

5.3 逐步执行迁移

执行第一步:分析现有应用

# step_executors.py
def analyze_flask_app(flask_app_path: str) -> dict:
    """分析 Flask 应用结构"""
    import ast
    import os
    
    analysis_result = {
        'routes': [],
        'models': [],
        'dependencies': [],
        'file_structure': []
    }
    
    # 分析文件结构
    for root, dirs, files in os.walk(flask_app_path):
        for file in files:
            if file.endswith('.py'):
                filepath = os.path.join(root, file)
                analysis_result['file_structure'].append(filepath)
                
                # 简单分析 Python 文件内容
                with open(filepath, 'r', encoding='utf-8') as f:
                    try:
                        tree = ast.parse(f.read())
                        # 提取路由信息等
                        analysis_result = _extract_flask_info(tree, analysis_result)
                    except SyntaxError:
                        print(f"语法错误在文件: {filepath}")
    
    return analysis_result

def _extract_flask_info(tree, analysis_result):
    """从 AST 中提取 Flask 特定信息"""
    for node in ast.walk(tree):
        # 查找 @app.route 装饰器
        if isinstance(node, ast.FunctionDef):
            for decorator in node.decorator_list:
                if (isinstance(decorator, ast.Call) and 
                    isinstance(decorator.func, ast.Attribute) and
                    decorator.func.attr == 'route'):
                    # 找到路由定义
                    route_info = {
                        'function_name': node.name,
                        'methods': ['GET']  # 默认方法
                    }
                    
                    # 提取路由路径
                    if decorator.args:
                        route_info['path'] = ast.literal_eval(decorator.args[0])
                    
                    # 提取 HTTP 方法
                    for keyword in decorator.keywords:
                        if keyword.arg == 'methods':
                            route_info['methods'] = [ast.literal_eval(arg) for arg in keyword.value.elts]
                    
                    analysis_result['routes'].append(route_info)
    
    return analysis_result

执行后续步骤:创建 FastAPI 应用

# fastapi_creator.py
def create_fastapi_app(analysis_result: dict) -> str:
    """基于分析结果创建 FastAPI 应用代码"""
    
    # 生成 FastAPI 主应用文件
    fastapi_code = '''from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import List, Optional

app = FastAPI(title="用户管理API", version="1.0.0")

# 数据模型
class User(BaseModel):
    id: int
    name: str
    email: str

class UserCreate(BaseModel):
    name: str
    email: str

# 模拟数据库
users_db = []
next_id = 1

@app.get("/users", response_model=List[User])
async def get_users():
    """获取所有用户"""
    return users_db

@app.post("/users", response_model=User, status_code=201)
async def create_user(user: UserCreate):
    """创建新用户"""
    global next_id
    new_user = User(id=next_id, name=user.name, email=user.email)
    users_db.append(new_user)
    next_id += 1
    return new_user

@app.get("/users/{user_id}", response_model=User)
async def get_user(user_id: int):
    """根据ID获取用户"""
    for user in users_db:
        if user.id == user_id:
            return user
    raise HTTPException(status_code=404, detail="用户不存在")

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000)
'''

    return fastapi_code

6. 运行结果与效果验证

6.1 验证迁移结果

创建测试脚本来验证迁移是否成功:

# test_migration.py
import requests
import json

def test_fastapi_app():
    """测试迁移后的 FastAPI 应用"""
    base_url = "http://localhost:8000"
    
    # 测试创建用户
    create_response = requests.post(
        f"{base_url}/users",
        json={"name": "测试用户", "email": "test@example.com"}
    )
    assert create_response.status_code == 201
    user_data = create_response.json()
    assert user_data["name"] == "测试用户"
    
    # 测试获取用户列表
    list_response = requests.get(f"{base_url}/users")
    assert list_response.status_code == 200
    users = list_response.json()
    assert len(users) == 1
    assert users[0]["name"] == "测试用户"
    
    # 测试获取特定用户
    user_id = user_data["id"]
    get_response = requests.get(f"{base_url}/users/{user_id}")
    assert get_response.status_code == 200
    assert get_response.json()["email"] == "test@example.com"
    
    # 测试不存在的用户
    not_found_response = requests.get(f"{base_url}/users/999")
    assert not_found_response.status_code == 404
    
    print("所有测试通过!迁移成功。")

if __name__ == "__main__":
    test_fastapi_app()

6.2 性能对比测试

# performance_test.py
import time
import requests
import statistics

def benchmark_endpoint(url, method="GET", data=None, iterations=100):
    """基准测试端点性能"""
    times = []
    
    for i in range(iterations):
        start_time = time.time()
        
        if method == "GET":
            response = requests.get(url)
        elif method == "POST":
            response = requests.post(url, json=data)
        
        end_time = time.time()
        
        if response.status_code == 200 or response.status_code == 201:
            times.append((end_time - start_time) * 1000)  # 转换为毫秒
    
    if times:
        return {
            'avg_time': statistics.mean(times),
            'min_time': min(times),
            'max_time': max(times),
            'std_dev': statistics.stdev(times) if len(times) > 1 else 0
        }
    return None

# 对比 Flask 和 FastAPI 性能
def compare_performance():
    flask_url = "http://localhost:5000/users"
    fastapi_url = "http://localhost:8000/users"
    
    print("性能对比测试:")
    print("Flask 性能:", benchmark_endpoint(flask_url))
    print("FastAPI 性能:", benchmark_endpoint(fastapi_url))

7. 常见问题与排查思路

在实际使用《Claude's plan》模式时,可能会遇到以下典型问题:

问题现象 可能原因 排查方式 解决方案
规划步骤过于笼统 任务描述不够具体 检查任务规格中的成功标准是否明确 添加具体的验收条件和约束
步骤执行顺序错误 依赖关系分析不准确 检查步骤间的依赖关系图 手动调整依赖关系或添加显式排序
模型生成代码有语法错误 提示词不够精确 检查执行步骤的提示词模板 添加代码规范要求和语法检查步骤
迁移后功能不一致 验证测试覆盖不全 检查测试用例是否覆盖所有边界情况 补充集成测试和边界测试
性能下降 新框架配置不当 对比迁移前后的性能指标 优化新框架配置和代码实现

7.1 依赖冲突解决

在迁移过程中经常遇到的依赖冲突问题:

# dependency_resolver.py
def resolve_dependency_conflicts(original_reqs, new_reqs):
    """
    解决依赖包版本冲突
    """
    conflicts = []
    
    for pkg in set(original_reqs.keys()) & set(new_reqs.keys()):
        if original_reqs[pkg] != new_reqs[pkg]:
            conflicts.append({
                'package': pkg,
                'original_version': original_reqs[pkg],
                'new_version': new_reqs[pkg],
                'suggestion': _suggest_resolution(pkg, original_reqs[pkg], new_reqs[pkg])
            })
    
    return conflicts

def _suggest_resolution(package, old_ver, new_ver):
    """提供依赖冲突解决建议"""
    # 这里可以集成包兼容性数据库查询
    return f"尝试使用兼容版本:{old_ver} 或 {new_ver} 的最新兼容版本"

8. 最佳实践与工程建议

8.1 规划阶段的最佳实践

  1. 明确边界条件

    • 定义清晰的输入输出规范
    • 设定合理的时间预期
    • 识别技术约束和风险点
  2. 模块化设计

    • 每个步骤保持单一职责
    • 步骤间通过标准接口通信
    • 支持步骤的独立测试和验证

8.2 执行阶段的工程建议

# best_practices.py
class RobustTaskExecutor:
    """增强版的任执行器,包含错误处理和重试机制"""
    
    def __init__(self, max_retries=3, retry_delay=5):
        self.max_retries = max_retries
        self.retry_delay = retry_delay
        self.retry_count = {}
    
    def execute_with_retry(self, step: TaskStep) -> StepExecutionResult:
        """带重试机制的步骤执行"""
        for attempt in range(self.max_retries + 1):
            result = self.execute_step(step)
            
            if result.status == "completed":
                return result
            
            # 记录重试次数
            self.retry_count[step.step_id] = attempt + 1
            
            if attempt < self.max_retries:
                print(f"步骤 {step.step_id} 第 {attempt + 1} 次失败,{self.retry_delay}秒后重试...")
                time.sleep(self.retry_delay)
            else:
                print(f"步骤 {step.step_id} 达到最大重试次数,最终失败")
                result.error_message = f"经过 {self.max_retries} 次重试后仍然失败"
        
        return result

8.3 验证与质量保证

建立多层次的验证体系:

  1. 步骤级验证 :每个步骤执行后立即验证
  2. 集成验证 :关键里程碑点的整体功能验证
  3. 回归测试 :确保新功能不影响现有功能
  4. 性能验证 :对比迁移前后的性能指标
# validation_framework.py
class ValidationFramework:
    """多层次的验证框架"""
    
    def __init__(self):
        self.validators = {
            'syntax': SyntaxValidator(),
            'functionality': FunctionalityValidator(),
            'performance': PerformanceValidator(),
            'security': SecurityValidator()
        }
    
    def validate_step(self, step_id: int, step_output: str, validator_type: str) -> ValidationResult:
        """执行特定类型的验证"""
        validator = self.validators.get(validator_type)
        if validator:
            return validator.validate(step_id, step_output)
        return ValidationResult(success=False, message=f"未知的验证类型: {validator_type}")

9. 总结与后续学习方向

《Claude's plan》所代表的"规划-执行-验证"模式,为复杂 AI 辅助开发任务提供了系统化的解决方案。通过本文的完整示例,你应该能够:

  1. 理解核心概念 :掌握任务分解、依赖管理、验证机制等关键思想
  2. 实施具体迁移 :按照规划步骤完成框架迁移等复杂任务
  3. 建立质量保障 :通过多层次的验证确保迁移成功
  4. 处理常见问题 :能够识别和解决典型的迁移障碍

后续深入学习建议

  1. 扩展规划能力 :研究更复杂的任务依赖图算法
  2. 集成更多工具 :将静态分析、性能测试等工具集成到流程中
  3. 优化提示工程 :改进与 LLM 交互的提示词模板
  4. 建立知识库 :积累常见迁移模式的最佳实践

这种系统化的方法不仅适用于框架迁移,还可以扩展到代码重构、系统优化、安全审计等各种复杂开发任务中。关键在于建立清晰的规划、可靠的执行和严格的验证机制。

在实际项目中,建议从小规模任务开始实践,逐步积累经验后再处理更复杂的场景。记得每次执行后都要总结经验,优化流程,让 AI 真正成为你开发工作中的得力助手。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐