一个人 + Claude = 全栈开发团队:从零构建 AI 自动化开发系统的技术实现

一个人 + Claude = 全栈开发团队:从零构建 AI 自动化开发系统的技术实现

背景

作为独立开发者,我用 3 周时间构建了一套 AI 驱动的自动化开发系统 AutoDev。它能接收一句话需求,自动完成需求分析、架构设计、编码、测试、代码审查和部署的完整流程。

本文分享核心技术实现,包括:

  • 14 阶段 Pipeline 状态机设计
  • Agentic Loop 模式的 AI Agent 实现
  • 测试失败自动回退的迭代循环机制
  • 人机协作的三种运行模式

整体架构

scss 复制代码
┌─────────────────────────────────────────────────────┐
│                    FastAPI Server                     │
├─────────────────────────────────────────────────────┤
│  API Layer (REST + SSE)                              │
├─────────────────────────────────────────────────────┤
│  Pipeline Engine (状态机)                             │
├──────────┬──────────┬──────────┬────────────────────┤
│ Analysis │  Design  │  Coding  │ Testing / Review   │
│  Agent   │  Agent   │  Agent   │     Agent          │
├──────────┴──────────┴──────────┴────────────────────┤
│  BaseAgent (Agentic Loop)                            │
├─────────────────────────────────────────────────────┤
│  Claude API  │  Docker Sandbox  │  Git Service       │
└─────────────────────────────────────────────────────┘

技术栈:Python 3.11 + FastAPI + Anthropic Claude API + SQLAlchemy 2.0 + Docker SDK + GitPython

核心实现 1:Pipeline 状态机

Pipeline 的核心是一个有限状态机。每个阶段有明确的合法转换路径:

ini 复制代码
class PipelineStage(str, Enum):
    PENDING = "pending"
    ANALYSIS = "analysis"
    ANALYSIS_REVIEW = "analysis_review"  # 人工审核
    DESIGN = "design"
    DESIGN_REVIEW = "design_review"      # 人工审核
    CODING = "coding"
    TESTING = "testing"
    CODE_REVIEW = "code_review"
    DEPLOY_STAGING = "deploy_staging"
    STAGING_REVIEW = "staging_review"    # 人工审核
    DEPLOY_PRODUCTION = "deploy_production"
    COMPLETED = "completed"
    FAILED = "failed"
    CANCELLED = "cancelled"

# 状态转换规则
TRANSITIONS: dict[PipelineStage, list[PipelineStage]] = {
    PipelineStage.TESTING: [
        PipelineStage.CODE_REVIEW,  # 测试通过
        PipelineStage.CODING,       # 测试失败,回退重新编码
        PipelineStage.FAILED,
    ],
    PipelineStage.CODE_REVIEW: [
        PipelineStage.DEPLOY_STAGING,  # 审查通过
        PipelineStage.CODING,          # 发现严重问题,回退
        PipelineStage.FAILED,
    ],
    # ... 其他阶段
}

关键设计点:

  1. 回退路径是一等公民:TESTING 和 CODE_REVIEW 都可以回退到 CODING,这不是异常处理,而是正常流程的一部分。
  2. 转换合法性校验 :任何状态变更都必须通过 is_valid_transition() 检查,防止非法跳转。
  3. 重试配置独立定义
yaml 复制代码
RETRY_CONFIG: dict[PipelineStage, int] = {
    PipelineStage.CODING: 3,       # 编码最多重试 3 次
    PipelineStage.TESTING: 2,      # 测试最多重试 2 次
    PipelineStage.CODE_REVIEW: 1,  # 代码审查最多重试 1 次
}

ROLLBACK_MAP: dict[PipelineStage, PipelineStage] = {
    PipelineStage.TESTING: PipelineStage.CODING,
    PipelineStage.CODE_REVIEW: PipelineStage.CODING,
}

核心实现 2:Agentic Loop

每个 AI Agent 都基于同一个 BaseAgent 抽象类,实现经典的 Agentic Loop 模式:

python 复制代码
class BaseAgent(ABC):
    def __init__(self, name, client, model, max_turns=20, sandbox=None):
        self.name = name
        self.client = client  # anthropic.AsyncAnthropic
        self.model = model
        self.max_turns = max_turns
        self.sandbox = sandbox

    @abstractmethod
    def system_prompt(self) -> str: ...

    @abstractmethod
    def define_tools(self) -> list[AgentTool]: ...

    async def run(self, task: str, context: dict | None = None) -> dict:
        messages = []
        if context:
            messages.append({"role": "user", "content": self._format_context(context)})
            messages.append({"role": "assistant", "content": "已收到上下文信息,请继续。"})
        messages.append({"role": "user", "content": task})

        tools_param = self._build_tools_param()
        tool_calls_count = 0

        for turn in range(self.max_turns):
            response = await self.client.messages.create(
                model=self.model,
                max_tokens=8096,
                system=self.system_prompt(),
                tools=tools_param,
                messages=messages,
            )

            # 不可变:构建新列表而非 append
            messages = [*messages, {"role": "assistant", "content": response.content}]

            tool_use_blocks = [b for b in response.content if b.type == "tool_use"]

            if not tool_use_blocks:
                # 没有工具调用 = 任务完成
                return {"result": self._extract_text_result(response),
                        "tool_calls_count": tool_calls_count}

            # 执行工具调用
            tool_results = []
            for block in tool_use_blocks:
                tool_calls_count += 1
                output = await self.execute_tool(block.name, block.input)
                tool_results.append({
                    "type": "tool_result",
                    "tool_use_id": block.id,
                    "content": output,
                })

            messages = [*messages, {"role": "user", "content": tool_results}]

        return {"result": last_text, "warning": f"已达到最大循环次数 {self.max_turns}"}

这个模式的核心思想:Agent 自己决定什么时候完成。它可以调用工具(读文件、写文件、执行命令),根据工具返回结果决定下一步做什么,直到它认为任务完成(不再调用工具)。

每个具体 Agent 只需要实现两个方法:

  • system_prompt():定义角色和行为规范
  • define_tools():定义可用工具集

比如 Coding Agent 有 write_fileread_filerun_commandsearch_code 等工具;Testing Agent 有 run_testsread_test_output 等工具。

核心实现 3:迭代循环(自动回退)

这是让系统从"能跑"到"能用"的关键机制。Pipeline Engine 在 TESTING 和 CODE_REVIEW 阶段完成后,会检查结果中是否包含失败信号:

python 复制代码
async def run_stage(self, pipeline_id: str) -> None:
    # ... 执行 Agent ...
    result = await agent.run(task=..., context=...)

    # 编码完成后自动 git commit
    if stage == PipelineStage.CODING:
        await self._auto_commit(pipeline_id)

    # 迭代循环:检查结果,发现问题自动回退
    if stage in (PipelineStage.TESTING, PipelineStage.CODE_REVIEW):
        feedback = self._check_stage_result_for_issues(stage, result)
        if feedback:
            await self._retry_with_feedback(pipeline_id, stage, feedback)
            return

检测策略针对不同阶段有所区分:

  • TESTING :检测 failederrortraceback 等测试失败信号
  • CODE_REVIEW :检测 严重critical安全漏洞must fix 等严重问题关键词

回退时会把失败信息作为上下文传给 Coding Agent,让它知道"上次哪里出了问题":

python 复制代码
async def _retry_with_feedback(self, pipeline_id, stage, feedback):
    retry_count = await self._get_retry_count(pipeline_id, stage)
    max_retries = RETRY_CONFIG.get(stage, 0)

    if retry_count >= max_retries:
        # 超过重试上限,继续推进(不阻塞流程)
        await self._auto_advance(pipeline_id, stage)
        return

    # 保存反馈到上下文,回退到 CODING
    rollback_target = ROLLBACK_MAP[stage]
    await self.context.save_context(pipeline_id, f"{stage.value}_feedback", feedback)
    await self.advance(pipeline_id, rollback_target)
    await self.run_stage(pipeline_id)  # 立即执行回退后的阶段

实际验证中,一个典型的迭代过程:

  1. Coding Agent 写完代码,自动 commit
  2. Testing Agent 跑测试,发现一个断言失败
  3. 引擎检测到失败信号,回退到 CODING
  4. Coding Agent 收到"测试失败:assert response.status_code == 200, got 404"的反馈
  5. 重新修改代码,再次 commit
  6. Testing Agent 再跑,通过

核心实现 4:三种人机协作模式

python 复制代码
async def create_pipeline(self, project_id, requirement_text, *,
                          run_mode="manual", **kwargs) -> str:
    """
    run_mode:
        - "manual": 所有审核阶段暂停等人确认
        - "trust": 跳过所有审核阶段,全自动
        - "collaborative": AI 自主编码测试,设计方案暂停确认
    """

_auto_advance() 中通过 skip_stages 集合控制:

ini 复制代码
async def _auto_advance(self, pipeline_id, current_stage):
    run_mode = await self.context.get_context(pipeline_id, "run_mode")

    if run_mode == "trust":
        skip_stages = HUMAN_REVIEW_STAGES  # 跳过所有审核
    elif run_mode == "collaborative":
        skip_stages = {PipelineStage.ANALYSIS_REVIEW, PipelineStage.STAGING_REVIEW}
    else:
        skip_stages = set()  # manual 模式不跳过

    next_stage = self._determine_next_stage(current_stage)
    if next_stage in HUMAN_REVIEW_STAGES and next_stage in skip_stages:
        # 跳过审核,直接推进到下一个执行阶段
        next_stage = self._determine_next_stage(next_stage)

    await self.advance(pipeline_id, next_stage)
    await self.run_stage(pipeline_id)

设计思路:信任是逐步建立的。新项目用 manual 模式,观察 AI 的输出质量;验证过的场景切 collaborative;完全信任后用 trust 全自动。

部署与 Git 分支策略

部署阶段不需要 AI Agent,而是直接执行 Git 操作:

  • deploy_staging:将 feature 分支合并到 test 分支,部署测试环境
  • deploy_production:将 feature 分支合并到 dev 分支,部署生产环境

一个踩坑点:合并前必须清理工作区。Pipeline 运行过程中可能产生未提交的文件(测试产物等),导致 git checkout 失败。解决方案是合并前自动 git stash

事件系统

基于 asyncio.Queue 的轻量级事件总线,支持 SSE 推送到前端:

ruby 复制代码
class EventBus:
    def publish(self, event: Event): ...
    async def subscribe(self, pipeline_id: str) -> AsyncGenerator[Event]: ...

前端通过 GET /api/pipelines/{id}/events 订阅 SSE,实时显示 Pipeline 进度。无 Redis 依赖,单进程内足够用。

项目数据

指标 数值
核心代码 ~2000 行 Python
文件数 18 个核心模块
Pipeline 阶段 14 个
AI Agent 5 个(分析、设计、编码、测试、审查)
单次 Pipeline 耗时 10-30 分钟
开发周期 3 周(业余时间)
前端 React 19,6 个页面

经验总结

什么有效

  1. 状态机是正确的抽象。Pipeline 流程天然适合状态机建模,比 if-else 链清晰得多。
  2. Agent 职责单一。每个 Agent 只做一件事,system prompt 短而精确,输出质量明显好于"一个 Agent 做所有事"。
  3. 回退是正常流程。把"失败重试"设计为状态机的合法路径,而不是异常处理,代码更简洁。
  4. 不可变数据 。所有 Pydantic 模型 frozen=True,消息列表用 spreading 而非 append,减少了大量隐蔽 bug。

什么需要改进

  1. 测试覆盖不足。核心模块目前零测试覆盖,靠端到端验证兜底,不够稳健。
  2. Agent 输出不稳定。同样的输入,不同次运行可能产生不同质量的输出。需要更好的 prompt engineering 或输出校验。
  3. 单进程瓶颈。当前无法并发执行多个 Pipeline,需要引入任务队列。

下一步

  • 补充核心模块单元测试(目标 80% 覆盖率)
  • 优化 Agent prompt,提高输出稳定性
  • 引入 Celery 支持并发 Pipeline
  • 开源

完整代码即将开源,关注后续更新。

相关推荐
用户2160719532951 小时前
AQS、ReentrantLock详解
后端
Rust研习社1 小时前
Rust Clippy 实用指南:写出更优雅、安全的 Rust 代码
后端·rust·编程语言
小撒的私房菜1 小时前
Agent = Model + Harness:这个公式,让我重新理解了 AI 工程
人工智能·后端
掘金者阿豪1 小时前
Go 语言操作金仓数据库(下篇):SQL 执行、类型映射与超时控制
后端
IVEN_1 小时前
全栈开发必看:从内存变量到关系型数据库的完整旅程
后端
MacroZheng1 小时前
横空出世!IDEA最强MyBatis插件来了,功能很全!
java·后端·mybatis
codebetter1 小时前
X86 Windows Docker Desktop 运行 arm64 容器
后端
掘金者阿豪1 小时前
Go 语言操作金仓数据库(上篇):环境搭建与连接管理
后端
何陋轩1 小时前
Spring AI Function Calling:让AI调用你的Java方法
人工智能·后端·ai编程