一个人 + 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,
],
# ... 其他阶段
}
关键设计点:
- 回退路径是一等公民:TESTING 和 CODE_REVIEW 都可以回退到 CODING,这不是异常处理,而是正常流程的一部分。
- 转换合法性校验 :任何状态变更都必须通过
is_valid_transition()检查,防止非法跳转。 - 重试配置独立定义:
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_file、read_file、run_command、search_code 等工具;Testing Agent 有 run_tests、read_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 :检测
failed、error、traceback等测试失败信号 - 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) # 立即执行回退后的阶段
实际验证中,一个典型的迭代过程:
- Coding Agent 写完代码,自动 commit
- Testing Agent 跑测试,发现一个断言失败
- 引擎检测到失败信号,回退到 CODING
- Coding Agent 收到"测试失败:assert response.status_code == 200, got 404"的反馈
- 重新修改代码,再次 commit
- 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 个页面 |
经验总结
什么有效
- 状态机是正确的抽象。Pipeline 流程天然适合状态机建模,比 if-else 链清晰得多。
- Agent 职责单一。每个 Agent 只做一件事,system prompt 短而精确,输出质量明显好于"一个 Agent 做所有事"。
- 回退是正常流程。把"失败重试"设计为状态机的合法路径,而不是异常处理,代码更简洁。
- 不可变数据 。所有 Pydantic 模型
frozen=True,消息列表用 spreading 而非 append,减少了大量隐蔽 bug。
什么需要改进
- 测试覆盖不足。核心模块目前零测试覆盖,靠端到端验证兜底,不够稳健。
- Agent 输出不稳定。同样的输入,不同次运行可能产生不同质量的输出。需要更好的 prompt engineering 或输出校验。
- 单进程瓶颈。当前无法并发执行多个 Pipeline,需要引入任务队列。
下一步
- 补充核心模块单元测试(目标 80% 覆盖率)
- 优化 Agent prompt,提高输出稳定性
- 引入 Celery 支持并发 Pipeline
- 开源
完整代码即将开源,关注后续更新。