
深度揭秘 5W 分析 OPS 闭环 57 子环节 OODER Studi
在前一篇《做一款 AI-IDE 有多难》中我们提出了"6 步 OPS 闭环"的概念图。但抽象的 6 步永远只是 PPT,真正决定 AI-IDE 能不能"自主跑业务"的是 6 步之内的每一个细节环节——LLM 怎么超时熔断?工具调用怎么并行?编译失败怎么降级?检测不通过怎么回灌?审计怎么留痕?
这篇文章基于 OODER Studio 的真实源码,把 6 步拆成 57 个可被独立观测、独立修复、独立审计的子环节,并对每一个环节做 5W 分析(What / Why / Where / When / Who),让你看清这条"AI 工业流水线"到底是怎么转的。
本文阅读路径建议:① 先看下方全景图建立宏观印象 → ② 看 5W 罗盘理解分析方法 → ③ 选你最感兴趣的 Step 跳读详表 → ④ 末尾总结给出企业实施清单。

步骤 | 核心入口 | 子环节数 | 关键代价 |
|---|---|---|---|
Step 1 用户/AI 请求 · FC-Loop 调度 | FunctionCallingLoopExecutor.java | 10 | LLM Token / 工具并发线程 |
Step 2 Harness Pipeline 6 阶段 | NlpHarnessPipeline.java | 13 | 三引擎并行 / 置信度计算 |
Step 3 编译沙箱 | CompileTool.java + AggRootBuild.java | 8 | javac 内存编译 / DSM Reload |
Step 4 AggRoot 校验 | AggRootBuildAuditor.java | 7 | 全过程留痕 |
Step 5 热部署推送 | PageChannelManager.java | 7 | WebSocket × ACK |
Step 6 运行时验证 | ThreeDimensionDetector.java | 12 | 静态评分 + 浏览器 Agent |
合计 | 57 | — | |


定位:这是整条闭环的"入口与心跳"。FunctionCallingLoopExecutor 类负责把一句话变成一连串 LLM 推理 + 工具调用,并保证:① 不会无限循环;② 不会 Token 爆炸;③ 工具失败可降级;④ LLM "只说不做"会被强制纠正。
# | 环节 | WHAT | WHY | WHERE | WHEN | WHO |
|---|---|---|---|---|---|---|
1.1 | LLM 可用性预检 | 校验 llmService.isAvailable() | 避免空跑,提前给出明确错误 | executeLoop() 行 119-134 | 每次 FC-Loop 启动首检 | UnifiedLlmService |
1.2 | 会话 ID 解析 + 审计登记 | 提取 sessionId/conversationId/sceneId,写入 ContextAuditLog STARTED | 留痕是闭环的前提,所有后续异常都可回溯 | 行 153-159 | 进入主循环前 | ContextAuditLog |
1.3 | 初始消息构造 | 组装 system + user 两条消息 | 所有 LLM 调用的最小种子 | 行 162-164 | 第一次 LLM 调用前 | 本地代码 |
1.4 | 流式调用 + Reasoning 透传 | 调 callLlmWithReasoning(),失败回退 callLlmSync() | 双轨:分别走 onReasoning 与 onContent 回调,前端可分区渲染 | 行 850-934 + 936 | FC-Loop 入口、每轮工具回填后 | LLM(DeepSeek-R1) |
1.5 | ToolCall 解析 + 文本兜底 | 结构化失败时由 parseTextToolCalls() 匹配<tool_call>/```json```/中文"调用工具XXX" | 不同模型的 FC 实现千差万别,三种降级解析保底 | parseTextToolCalls() 行 789 | 无结构化 ToolCall 但文本含工具意图 | 本地解析器 |
1.6 | 并行 ToolCall 调度 | CompletableFuture.supplyAsync 并行执行 | 3 个工具串行 = 3× 延迟;并行 = max | 行 221-277,线程池 fc-tool-exec-N | 本轮 ToolCalls 非空 | 线程池 |
1.7 | 超时熔断(单/批双层) | 单工具 60s、批 60s 双层超时 | 防止慢工具拖死整轮 | TIMEOUT_SCHEDULER + allOf().get | 每次工具启动 + 批结束 | 调度器线程 |
1.8 | 结果回填两路径 | structured 模式造 tool_calls 消息;text 模式文字合成 | 把工具结果转成 LLM 可理解的下一轮输入 | appendToolResultMessages() 行 704 | 每个工具返回后 | 本地代码 |
1.9 | 上下文压缩(200K 阈值) | 保留首尾,中间结构化摘要 | 避免 Token 爆炸 → API 报错 / 高额费用 | compressMessages() 行 1113 | 估算 input tokens > 200000 | 本地摘要器 |
1.10 | 意图无动作引导兜底 | "要读取" 但 0 个 ToolCall → 注入强制引导消息 | 大模型常"嘴上承诺",最后一道防线 | containsIntentButNoAction() 行 657 | round=0 且含意图关键词 | 本地分析器 |
T+0ms 用户消息 → 1.1 LLM 预检 → 1.2 审计登记T+5ms 1.3 初始消息构造T+50ms 1.4 LLM 流式开始 → reasoning 吐字T+800ms 1.4 返回 3 个 ToolCallT+810ms 1.6 三个并行 (fc-tool-exec-1/2/3)T+1700ms 全部完成(最慢 890ms)T+1750ms 1.4 下一轮 LLM 调用T+2400ms 1.4 最终回答 → 循环结束定位:把"LLM 一句话"翻译为"NlpComponent + Java 类名清单"的关键引擎。每阶段强制 StageContract 四段式契约。
# | 环节 | WHAT | WHY | WHERE | WHEN | WHO |
|---|---|---|---|---|---|---|
2.1 | Pipeline 初始化 | 注册 6 Stage + FeedbackHarness | 启动期固化,运行期不组装 | initializeStages() 行 38-45 | Spring 启动 | Spring 容器 |
2.2 | StageContract 四段式 | validate→process→validate→fallback | "可能失败的 LLM 推理" → "必有结果的工程组件" | executeInternal() 行 75-129 | 每个 Stage 进入 | Stage 自身 |
2.3 | S1 意图分析 | NL → JSONObject{formName, layout, fields, actions} | 管线语义起点 | IntentAnalysisStage 行 234 | Pipeline 第 1 步 | nlpService |
2.4 | S2 组件选择 | 意图 → 组件清单(BLOCK/LABEL/FORM/…) | 抽象意图绑定到 23+ 组件库 | ComponentSelectionStage 行 357 | S1 完成后 | 组件库 |
2.5 | S3 事件设计 | 组件 → 事件清单 | 无事件 = 静态原型 | EventDesignStage 行 465 | S2 完成后 | EventTemplate 库 |
2.6 | S4 样式生成 | JSONObject{global, components...} | 样式与结构分离 | StyleGenerationStage 行 536 | S3 完成后 | StyleTemplate 库 |
2.7 | S5 布局组合 | 扁平组件 → 嵌套树 + dataBinding | 建立页面空间关系 | LayoutCompositionStage 行 607 | S4 完成后 | 本地组装器 |
2.8 | S6 代码生成 | 五维输入 → Java DSL | Pipeline "出货物" | CodeGenerationStage 行 709 | S5 完成后 | 本地代码生成器 |
2.9 | DisclosureLevel 升级 | confidence 跨阈值 → SKELETON/STRUCTURED/COMPLETE | 低置信不硬塞结果 | executeInternal 行 102-105 | 每个 Stage 出口 | 本地评分器 |
2.10 | Clarification 短路 | confidence≤0.60 → 返回澄清问题 | 宁可问回去,不猜错往下 | createClarificationResponse 行 151 | 置信度过低 | 本地 → 用户 |
2.11 | ViewJavaSrcMeta 归集 | 6 个 ClassList:view/repo/agg/child/service/rootServices | 对应 DDD 6 类 Java 的"翻译表" | ViewJavaSrcMeta 行 28 | S6 → 编译前 | 本地归集器 |
2.12 | BuildLevel 预处理 | MINIMAL / SIMPLE / NORMAL / FULL / DDD | 避免对 "TODO 列表" 用完整 DDD | BuildLevelPreprocessor 行 42 | codegen 前 | 本地分类器 |
2.13 | 轨迹回写 | feedbackHarness.recordTrace() | 全管线可观测与可回放 | FeedbackHarness 行 87/93/127 | 每个 Stage 出口 | FeedbackHarness |
定位:把 DSL 编译为 JVM 可执行字节码。CompileTool 是入口,AggRootBuild 是 6 步 Java 流,CompileLoopWithLlmFallback 提供 3 轮降级。
# | 环节 | WHAT | WHY | WHERE | WHEN | WHO |
|---|---|---|---|---|---|---|
3.1 | action 路由 + project 解析 | build/compile/clear;三级回退 | 同一工具复用三模式 | execute() 行 66 | LLM 调用 compile_project | CompileTool |
3.2 | 动态编译源码 | DSMFactory.compileProject | .java 文件 → 字节码 | 行 124 | action=build | DSMFactory |
3.3 | 物化 UIModule | EngineFactory.buildCustomModule | 组件描述 → 前端可渲染 | 行 130 | 编译成功后 | EngineFactory |
3.4 | 容器热刷新 | dsm.reload() | 新字节码生效,无需重启 | 行 140 | 模块构建完 | DSM 容器 |
3.5 | AggRootBuild 6 步 Java | SPI→View→Repo→Agg→API→AggRoot | DDD 标准建造顺序 | AggRootBuild.build 行 225 | 持久层模式触发 | AggRootBuild |
3.6 | 增量编译 | D2CGenerator.dynCompile | 只编译变化的源码 | 行 207/215/266/285/299 | 每步 AggRootBuild | 内存 javac |
3.7 | 编译失败降级(3 轮) | LLM 重写失败源码再编译 | 修复 90% 语法/类型错误 | CompileLoopWithLlmFallback 行 52 | 编译失败 | LLM + 编译器 |
3.8 | 推送 reloadPage | 遍历所有页面推 reload 命令 | 自动加载新模块 | pushReloadToOpenPages 行 199 | 编译成功 | PageChannel |
定位:编译/生成的"贴身审计员"。每一步起止、错、降级都被精确记录。
# | 环节 | WHAT | WHY | WHERE | WHEN | WHO |
|---|---|---|---|---|---|---|
4.1 | BuildId 注册 | BUILD- + 时间戳 | 一次 build 一个 ID,对账用 | 行 21 | build 启动 | 本地 |
4.2 | Step 起始记录 | stepRecords[step] = {startTime} | 延迟分析基础 | recordStepStart 行 26 | 每步进入 | 本地 |
4.3 | Step 结束记录 | fill endTime/success/detail | 耗时 + 结果 | recordStepEnd 行 34 | 每步正常退出 | 本地 |
4.4 | Step 异常记录 | fill error + failedStep | 抛异常持久化 | recordStepError 行 52 | 每步抛异常 | 本地 |
4.5 | LLM 降级审计 | className + reason | 记录 AI 改过的类 | recordLlmFallback 行 76 | 降级触发 | LLM |
4.6 | 编译循环审计 | round/success/fail 数 | 量化 retry 收敛 | recordCompileLoop 行 81 | CompileLoop 每轮 | 本地 |
4.7 | 审计报告输出 | JSON + 可读文本 | 回流监控系统 | toAuditJson 行 86 | 流水线终态 | Auditor |
定位:把"新模块"最快推送到所有 Designer 页面,ACK 确认到达。
# | 环节 | WHAT | WHY | WHERE | WHEN | WHO |
|---|---|---|---|---|---|---|
5.1 | 通道创建 + 环境注册 | WebSocket → pageEnv.registerPage | 每页一通道 | createChannel 行 35 | 浏览器打开 Designer | WebSocket |
5.2 | 6 类命令工厂 | 6 种 PageCommand | 有限指令集,安全可控 | PageCommand.java | 编译完成 / 工具 | 本地 |
5.3 | fire-and-forget | 直接 sendMessage | 高频命令省往返 | pushCommand 行 67 | requireAck=false | WebSocket |
5.4 | ACK 协议 | pendingAcks + 10s 超时 | 关键命令确认到达 | pushCommandWithAck 行 90 | requireAck=true | WebSocket |
5.5 | ACK 回收 | future.complete | 让上游等待 | handleAck 行 112 | 前端回 ack | WebSocket |
5.6 | 事件回流 | selection/autoSave/ping | 后端感知前端状态 | 行 124 | 用户操作 Designer | WebSocket |
5.7 | 通道生命周期 | getActivePageIds/count | 运维监控 | 行 132/142 | 定时器 | 本地 |
定位:"编译通过"≠"业务对了"。三维度量化评分,不达标自动回灌 LLM 修复。
# | 环节 | WHAT | WHY | WHERE | WHEN | WHO |
|---|---|---|---|---|---|---|
6.1 | 技能注册路由 | canExecute 路由 7 大工具 | 统一入口 | 行 34+45 | LLM 调用 debug_xxx | SkillExecutor |
6.2 | 调试会话创建 | DebugContextManager.createContext | 多轮共享上下文 | 行 59 | 首次 debug_open | DebugManager |
6.3 | 三维调度器 | DetectionPlan → D1/D2/D3 | 按意图选检测深度 | ThreeDimensionDetector 行 30 | 质量评估 | 调度器 |
6.4 | D1 四分离总分 | 统计 4 维评分聚合 | 四分离是体系灵魂 | FourSepCompleteness 行 15 | detect | D1 Detector |
6.5 | D1 四维子打分 | 按 category 对 4 维评分 | 不同组件必填项不同 | 行 76/120/144/193 | 每组件遍历 | D1 Detector |
6.6 | D1 全空 fatal | 四维同时空 → fatal | "啥都没设" = 漏生成 | 行 62-73 | 每组件 | D1 Detector |
6.7 | D2 可见性审计 | zeroSize/displayNone | 编译过但不可见也没用 | VisibilityAudit 行 16 | detect | D2 Detector |
6.8 | D3 事件-行为匹配 | EventBehaviorSpec 静态规则 | 有事件没行为 = 哑按钮 | EventBehaviorMatch | detect | D3 Detector |
6.9 | 模拟动作/DOM 检查 | 下发指令给浏览器 Agent | 真正点击,比静态更准 | 行 88/103 | LLM 触发 | 浏览器 Agent |
6.10 | 错误/截图采集 | Agent 回填 | 编译报错喂给 LLM | 行 120/131 | LLM 触发 | 浏览器 Agent |
6.11 | 事件触发+追踪 | triggerRecord/traceRecord | 触发才暴露 | 行 144/174 | LLM 触发 | 浏览器 Agent |
6.12 | 综合报告+短路 | overallScore + criticalIssues | 低分 — 回灌 FC-Loop 修复 | 行 56 | 检测完成 | 报告器 → FC-Loop |
把这条流水线讲完,我们能提炼出 6 条 AI-IDE 工程哲学:
# | 哲学 | 对应环节 |
|---|---|---|
1 | 留痕一切:任何决策、任何失败、任何降级都必须可回放 | 1.2 / 2.13 / 4.1-4.7 |
2 | 三层熔断:单工具超时 → 批超时 → 整轮 Message 压缩 | 1.7 / 1.9 / 3.7 轮次限 |
3 | 可治理的 LLM:StageContract 四段式把任意自由输出归一为工程契约 | 2.2 / 2.9 / 2.10 |
4 | 强制闭环:6.12 的反向回灌让流水线"自动迭代直到达标" | 6.12 → 1.4 再循环 |
5 | 前后端实时同步:WebSocket ACK 协议保证"AI 改了、前端收到了、用户看到了" | 5.4 / 5.5 / 5.6 |
6 | DDD 对齐的元数据:ViewJavaSrcMeta 的 6 个 ClassList 是 LLM 与 Java 工程的翻译表 | 2.11 / 3.5 / 4.1-4.7 |
模块 | 绝对路径 |
|---|---|
FC-Loop 核心 | e:\github\a2ui\ooder-pro\src\main\java\net\ooder\studio\chat\engine\FunctionCallingLoopExecutor.java |
Harness Pipeline 6 阶段 | e:\github\a2ui\ouc\ouc-core\src\main\java\net\ooder\engine\llm\harness\NlpHarnessPipeline.java |
HarnessResult 输出模型 | e:\github\a2ui\ouc\ouc-core\src\main\java\net\ooder\engine\llm\harness\HarnessResult.java |
StageContract 契约接口 | e:\github\a2ui\ouc\ouc-core\src\main\java\net\ooder\engine\llm\harness\StageContract.java |
ViewJavaSrcMeta 六类归集 | e:\github\a2ui\ouc\ouc-core\src\main\java\net\ooder\engine\codegen\java\ViewJavaSrcMeta.java |
AggRootBuild 6 步 Java 流 | e:\github\a2ui\ouc\ouc-core\src\main\java\net\ooder\engine\codegen\java\AggRootBuild.java |
Step 枚举 | e:\github\a2ui\ouc\ouc-core\src\main\java\net\ooder\engine\codegen\java\Step.java |
CompileTool 编译沙箱 | e:\github\a2ui\ooder-pro\src\main\java\net\ooder\studio\chat\knowledge\tool\CompileTool.java |
CompileLoopWithLlmFallback | e:\github\a2ui\ouc\ouc-core\src\main\java\net\ooder\engine\codegen\nlp\CompileLoopWithLlmFallback.java |
AggRootBuildAuditor | e:\github\a2ui\ouc\ouc-core\src\main\java\net\ooder\engine\codegen\nlp\AggRootBuildAuditor.java |
BuildLevelPreprocessor | e:\github\a2ui\ouc\ouc-core\src\main\java\net\ooder\engine\codegen\nlp\BuildLevelPreprocessor.java |
PageChannel 管理 | e:\github\a2ui\ooder-pro\src\main\java\net\ooder\studio\chat\page\PageChannelManager.java |
PageChannel 单通道 | e:\github\a2ui\ooder-pro\src\main\java\net\ooder\studio\chat\page\PageChannel.java |
PageCommand 6 类命令 | e:\github\a2ui\ooder-pro\src\main\java\net\ooder\studio\chat\page\PageCommand.java |
RuntimeDebug 沙箱 | e:\github\a2ui\ooder-pro\src\main\java\net\ooder\studio\debug\skill\RuntimeDebugSkillExecutor.java |
ThreeDimensionDetector | e:\github\a2ui\ooder-pro\src\main\java\net\ooder\studio\debug\detection\ThreeDimensionDetector.java |
FourSepCompletenessDetector | e:\github\a2ui\ooder-pro\src\main\java\net\ooder\studio\debug\detection\FourSepCompletenessDetector.java |
VisibilityAuditDetector | e:\github\a2ui\ooder-pro\src\main\java\net\ooder\studio\debug\detection\VisibilityAuditDetector.java |
EventBehaviorMatchDetector | e:\github\a2ui\ooder-pro\src\main\java\net\ooder\studio\debug\detection\EventBehaviorMatchDetector.java |
FeedbackHarness 轨迹 | e:\github\a2ui\ouc\ouc-core\src\main\java\net\ooder\engine\llm\harness\FeedbackHarness.java |
CollaborativeHarnessStrategy | e:\github\a2ui\ouc\ouc-core\src\main\java\net\ooder\engine\llm\harness\CollaborativeHarnessStrategy.java |
最后一句:一台机器上有 57 个齿轮同时转动,没有一个是多余的。每个齿轮的卡顿或缺失,都有可能让 AI-IDE 从"一个神奇的 Demo"退化为"一个昂贵的玩具"。这就是为什么做一款真正可用的 AI-IDE 这么难,也正是它如此迷人之处。
© OODER Studio · A2UI · AI-IDE 技术深究系列
本文基于 v3.5 源码 · GitHub 路径可验证 · 57 环节均为 derived from source code analysis
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 [email protected] 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 [email protected] 删除。