AI Coding Platform 六层架构设计:对标 Claude Code 的企业落地之路

AI Coding Platform 六层架构设计:对标 Claude Code 的企业落地之路

2024 年,Claude Code / Cursor / Devin 把 AI 编程推到新高度。但企业不能直接用------安全、成本、定制化都是硬约束。本文记录我们如何设计一个企业级 AI 原生编程平台,以及每一层为什么存在。


一、企业为什么不能直接用 Claude Code

先说结论:Claude Code 是优秀的产品,但企业场景有三个硬伤。

维度 Claude Code 企业需求
代码安全 代码发送到 Anthropic 服务器 代码不能出内网
模型选择 只能用 Claude 需要对接内部模型 / 国产模型
成本管控 按 Token 计费,不可控 需要配额、审批、成本归因
流程集成 独立工具 需要对接内部 GitLab、飞书、Jenkins
权限管控 本地文件系统全部可访问 需要限制 Agent 可操作范围

所以我们的目标不是"复制 Claude Code",而是"在企业约束下提供同等能力"。


二、六层架构总览

yaml 复制代码
┌─────────────────────────────────────────────────────────────────┐
│  Layer 1: Web 工作台                                              │
│  React + Monaco Editor,三栏布局(对话/文件树/编辑器+预览)        │
├─────────────────────────────────────────────────────────────────┤
│  Layer 2: Copilot Service (:8003)                                │
│  对话治理 · 智能路由 · 配额管控 · SSE 适配 · 沙箱代理             │
├─────────────────────────────────────────────────────────────────┤
│  Layer 3: Gateway (:7080)                                        │
│  JWT/API Key 鉴权 · 路由分发 · SSE 长连接透传                    │
├─────────────────────────────────────────────────────────────────┤
│  Layer 4: Manager (:7081)                                        │
│  Agent/Tool/Model/Workflow 配置管理 · 版本控制                    │
├─────────────────────────────────────────────────────────────────┤
│  Layer 5: Runtime (:7082)                                        │
│  ReAct Loop · DAG 调度 · Multi-Agent · 上下文压缩 · 工具执行     │
├─────────────────────────────────────────────────────────────────┤
│  Layer 6: Infrastructure                                         │
│  Docker Sandbox · Model Gateway · RAG · MCP Servers · PostgreSQL │
└─────────────────────────────────────────────────────────────────┘

为什么是六层而不是三层

最初方案是三层(前端 / BFF / Agent 执行)。实际跑起来发现:

  1. BFF 和 Copilot 职责重叠 --- Copilot 本身已经做了路由、编排、配额,再加 BFF 变成三层转发
  2. Manager 和 Runtime 不能合并 --- 改 Agent 配置(低频)和执行 Agent(高频高资源)混在一起,互相影响
  3. Infrastructure 必须独立 --- 沙箱、模型网关、RAG 都是有状态服务,生命周期与上层不同

每一层存在的理由都是"职责不同导致运维需求不同"。


三、Layer 2 深入:Copilot 为什么是核心

3.1 Copilot 不是 BFF,是"智能入口层"

Copilot 做的事情远超一个普通 BFF:

python 复制代码
class CopilotOrchestrator:
    """Copilot 核心编排逻辑"""

    async def handle_message(self, user_msg: str, session: Session):
        # 阶段 1:配额检查
        if not await self.quota_manager.check(session.tenant_id):
            yield QuotaExceededEvent()
            return

        # 阶段 2:四阶段智能路由
        route = await self.routing_engine.decide(
            message=user_msg,
            history=session.history,
            app_type=session.app_type  # coding_platform
        )

        # 阶段 3:按路由结果分发
        match route.decision:
            case "simple_qa":
                # 简单问题 Copilot 自己回答,不走 Runtime
                async for chunk in self.direct_answer(user_msg):
                    yield chunk
            case "coding":
                # 编程任务转发到 Runtime
                async for event in self.forward_to_runtime(route.agent_id, user_msg):
                    yield self.adapt_sse_format(event)
            case "prd":
                # 需求任务走 PRD Agent
                async for event in self.forward_to_runtime(route.prd_agent_id, user_msg):
                    yield chunk

3.2 四阶段路由决策

路由不是简单的关键词匹配,而是四阶段逐步收敛:

阶段 做什么 示例
1. 会话状态检查 是否有进行中的任务需要恢复 上次 coding 中断了→resume
2. 意图分类 LLM 判断属于哪类任务 "帮我写个登录页面"→coding
3. Agent 匹配 按意图选择最合适的 Agent coding → Coding Agent
4. 执行模式决策 单 Agent / Coordinator / Workflow 简单需求→单 Agent

为什么 Copilot 做路由而不是 Runtime? 因为路由是"决策",Runtime 是"执行"。决策需要看全局(配额、历史、用户偏好),执行只需要看当前任务。

3.3 Trade-off:多一跳值不值

Copilot 和 Runtime 之间多了一次 HTTP 调用,增加约 5ms 延迟。

换来的收益:

  • Copilot 可以拦截危险请求(不到 Runtime 就终止)
  • Copilot 可以做 SSE 格式适配(Runtime 输出的原始事件 → 前端友好格式)
  • Copilot 可以合并多个 Runtime 的结果(未来多 Agent 并行场景)
  • Copilot 挂了不影响 Runtime 正在执行的任务(反向也成立)

对于一次 AI 编程交互(通常 10-60 秒),5ms 可以忽略。


四、三阶段解耦编排

4.1 为什么不用一个 Agent 搞定全部

最初尝试过"全能 Coding Agent"------一个 Agent 负责从理解需求到写代码到测试。问题:

  1. Prompt 膨胀 --- 系统提示词超过 8K tokens,什么都想让它做,什么都做不好
  2. 无法迭代 --- 用户说"需求不对"要从头来,之前的代码工作全白费
  3. 不可控 --- 用户不知道 Agent 当前在做什么,是在分析需求还是在写代码

4.2 三阶段设计

arduino 复制代码
用户输入需求
    │
    ▼
┌──────────────────┐
│  PRD Agent        │  "帮我把需求说清楚"
│  · 澄清模糊点    │
│  · 输出结构化 PRD │  ← 用户可以在这反复迭代
│  · 用户确认后传递 │
└────────┬─────────┘
         │ 定稿的 PRD
         ▼
┌──────────────────┐
│  Spec Agent       │  "帮我出技术方案"
│  · 生成 spec.md   │
│  · 生成 plan.md   │  ← 用户可以在这反复迭代
│  · 生成 tasks.md  │
└────────┬─────────┘
         │ 三文档
         ▼
┌──────────────────┐
│  Coding Agent     │  "按方案写代码"
│  · 按 task 逐个实现│
│  · 编译验证       │  ← 报错自动修复
│  · 测试通过       │
└──────────────────┘

4.3 关键设计:编排权归 Copilot

三个 Agent 之间没有直接调用关系。流转由 Copilot 控制:

python 复制代码
# Copilot 阶段机(简化)
class PhaseStateMachine:
    async def transition(self, session, user_msg):
        current_phase = session.phase  # prd / spec / coding / debug

        if current_phase == "prd" and self.is_prd_confirmed(session):
            # PRD 确认后,自动进入 Spec 阶段
            session.phase = "spec"
            prd_bundle = await self.prd_client.get_bundle(session.id)
            return SpecAgentRequest(prd=prd_bundle)

        elif current_phase == "spec" and self.is_spec_approved(session):
            # Spec 三文档确认后,进入 Coding 阶段
            session.phase = "coding"
            spec_docs = await self.spec_client.get_docs(session.id)
            return CodingAgentRequest(spec=spec_docs)

为什么不用固定 DAG 串联? 因为用户需要在任意阶段"退回去"------说了半天发现需求不对,要回到 PRD 阶段重新来。固定 DAG 做不到这种灵活性。


五、四级上下文压缩

AI 编程最大的成本杀手不是模型调用次数,而是上下文长度。一次复杂的编程对话可能累积 100K+ tokens 的历史。

5.1 四级管道

yaml 复制代码
Token 占用增长
  │
  │  ┌─── 阈值 1 (60%) ──→ Level 1: Snip Compact
  │  │                      找到 snip 标记,删除标记前的消息
  │  │                      零 API 调用,最轻量
  │  │
  │  ├─── 阈值 2 (75%) ──→ Level 2: Micro Compact
  │  │                      利用 API cache editing,
  │  │                      删除特定工具调用的结果(保留结构)
  │  │
  │  ├─── 阈值 3 (85%) ──→ Level 3: Context Collapse
  │  │                      将多轮工具调用折叠为摘要,
  │  │                      原始消息保留(读时投影)
  │  │
  │  └─── 阈值 4 (95%) ──→ Level 4: Auto Compact
  │                         LLM 生成对话摘要替换全部历史,
  │                         最重但也是最后防线
  ▼

5.2 设计原则:渐进降级

  • 能不调 API 就不调 --- Level 1/2 零额外 Token 消耗
  • 能保留结构就保留 --- Level 3 折叠而非删除,需要时可展开
  • 最后才做全量摘要 --- Level 4 不可逆,信息必然丢失

5.3 实测数据

场景 无压缩 有压缩 节省
10 轮简单对话 12K tokens 12K(未触发) 0%
30 轮编程会话 85K tokens 38K tokens 55%
50 轮复杂重构 180K tokens 72K tokens 60%

六、五层安全防御

6.1 为什么 AI Agent 比传统 API 更危险

传统 API:参数固定,行为可预测。 AI Agent:模型决定调什么工具、传什么参数,行为不可预测

一个真实案例:Coding Agent 在修复 bug 时,决定"清理测试数据",执行了 rm -rf /tmp/test_*。恰好 /tmp/test_data_production_backup 也匹配了这个模式。

6.2 五层设计

bash 复制代码
请求进入
  │
  ▼ L1: 静态黑名单
  │  rm -rf / | dd if=/dev/zero | mkfs | > /etc/passwd
  │  → 直接拒绝,不经过模型判断
  │
  ▼ L2: 工具白名单(per-Agent)
  │  Coding Agent 只能用: read_file, write_file, run_command, search
  │  不能用: deploy, delete_branch, send_message
  │
  ▼ L3: 人机协同模式
  │  auto: 低风险操作自动执行
  │  ask:  中风险操作弹确认
  │  strict: 所有操作都需确认
  │
  ▼ L4: 风险分类器
  │  基于命令内容自动判断风险等级
  │  write_file("/src/...") → 低风险 → auto
  │  run_command("git push --force") → 高风险 → ask
  │
  ▼ L5: 审计日志
     所有工具调用记录:who/what/when/result
     支持事后审查与回溯

6.3 SSE 中断确认的实现

当 L3/L4 判定需要用户确认时:

css 复制代码
Runtime ──SSE──→ Copilot ──SSE──→ Frontend
                                    │
                              [弹出确认框]
                                    │
                              用户点击"允许"
                                    │
Frontend ──POST──→ Copilot ──POST──→ Runtime
                                    │
                              [继续执行]

Runtime 在等待确认期间不释放会话,用 asyncio.Event 挂起当前执行流:

python 复制代码
class PermissionGate:
    async def request_confirmation(self, action: ToolAction) -> bool:
        # 发送确认请求事件
        await self.sse_writer.write(ConfirmationRequestEvent(action=action))

        # 挂起等待,最多 5 分钟
        try:
            result = await asyncio.wait_for(self.confirmation_event.wait(), timeout=300)
            return result.approved
        except asyncio.TimeoutError:
            return False  # 超时视为拒绝(Fail Closed)

七、Docker 沙箱执行

7.1 为什么需要沙箱

Coding Agent 需要真实执行代码(编译、运行测试、启动预览),但不能直接操作宿主机。

7.2 沙箱生命周期

复制代码
创建 ──→ 运行 ──→ 暂停 ──→ 恢复 ──→ 销毁
 │              │
 │  N分钟无活动  │  用户回来
 └──────────────┘
  • 创建:从模板镜像启动(node-20 / python-312),<3s
  • 暂停docker pause,释放 CPU 但保留内存状态
  • 恢复docker unpause,<1s,用户无感
  • 销毁:TTL 到期(默认 30min 无活动)自动回收

7.3 资源限制

yaml 复制代码
# 每个沙箱的资源限制
resources:
  cpu: "2"          # 最多 2 核
  memory: "2Gi"     # 最多 2GB 内存
  disk: "5Gi"       # 最多 5GB 磁盘
  network: "bridge"  # 隔离网络,只能访问内网白名单
  pids: 256         # 最多 256 个进程(防 fork bomb)

八、回到起点:5ms 换来了什么

六层架构的总网络开销:前端→Copilot→Gateway→Runtime,约 12-15ms。

对比一次 LLM 调用的延迟(3-30 秒),这 15ms 占比 < 0.5%。

但换来的是:

  • 任何一层挂了,其他层不受影响
  • Copilot 可以独立迭代路由逻辑(不碰 Runtime)
  • Runtime 可以独立扩缩容(不影响 Manager)
  • 安全层可以拦截在 Copilot(不需要到 Runtime 才发现问题)
  • 未来可以接入多个 Runtime(不同语言的沙箱、不同模型的 Agent)

架构决策的核心不是"怎么做最快",而是"怎么做最可持续"。


下一篇:双层知识图谱如何让 Bug 定位从 50K Token 降到 15K。

相关推荐
小星星_20261 小时前
Hybrid RAG 落地:向量 + BM25 + Rerank 的工程选择
ai编程
必须会一定会1 小时前
大模型手搓文件对比工具(6):差异不用再手选
java·人工智能·ai编程
鬼鬼鬼2 小时前
从 Prompt 到 Harness:企业级 Agent 工程的完整演进之路
设计模式·架构·ai编程
用户3126874877203 小时前
AI Agent 开发实战(九):Grill Me 反问式规划
llm·ai编程
leeyi3 小时前
pgvector 入门:向量存进你已经在用的 PostgreSQL(第72篇-E58)
aigc·agent·ai编程
小虎AI生活4 小时前
一句话出片,WorkBuddy 加 LibTV,视频制作从"做"变成了"说"
ai编程
仙逆GPT5 小时前
ChatGPT、Codex实战:离开电脑后,怎么用手机继续控制任务?
chatgpt·ai编程·codex·手机控制·remote
不一样的少年_5 小时前
Claude Code 是怎么自己改代码的?答案藏在这 4 个工具里
前端·agent·ai编程
Lazy_zheng7 小时前
从 0 到 1 创建 Claude Code Skill:使用 skill-creator实现发票信息提取
agent·ai编程·claude