ECC 中 Kiro 专用 Agent:cpp-build-resolver 的 C++ 构建与 CMake 错误最小化修复体系
ECC(Everything Claude Code)为 Kiro IDE 提供了一套开箱即用的 Agent、Skill、Hook 与 Steering 组件,其中 cpp-build-resolver 是专为 C++ 构建失败场景设计的修复 Agent。本文基于该 Agent 的定义文件逐节展开其诊断命令序列、五步修复工作流、常见错误修复模式速查表、CMake 排障技巧与结构化报告规范,并结合 ECC 仓库中的对应 CLI 配置、安装脚本与配套的 cpp-reviewer、cpp-coding-standards 等组件,说明如何把它接入一个 C++ 项目的日常构建修复流程。
一、组件定位:一个"只读文件系统 + 可执行 Shell"的修复专家
cpp-build-resolver 的定义采用 YAML frontmatter 声明 Agent 元数据(cpp-build-resolver.md):
---
name: cpp-build-resolver
description: C++ build, CMake, and compilation error resolution specialist. Fixes build errors, linker issues, and template errors with minimal changes. Use when C++ builds fail.
allowedTools:
- fs_read
- shell
---
从 frontmatter 可以看到两个关键设计决策:
- 工具白名单极窄:
allowedTools只允许fs_read(读文件)与shell(执行命令)。Agent 的修复动作全部通过 CMake/编译器命令与文件修改完成,配置上排除了任何与构建无关的杂项工具,从机制上约束它"只做修复"。 - 触发条件明确:description 中写明 "Use when C++ builds fail",即 C++ 构建失败时启用,避免与代码审查类 Agent 的职责重叠。
同一个 Agent 在仓库中同时维护两种格式:
| 格式 | 文件 | 使用场景 |
|---|---|---|
Markdown(.md) |
.kiro/agents/cpp-build-resolver.md | Kiro IDE 中自动选择或显式调用 |
JSON(.json) |
.kiro/agents/cpp-build-resolver.json | kiro-cli 中通过 /agent swap 切换 |
JSON 版本 的结构包含 name、description、allowedTools(fs_read、shell)、hooks(空,表示该 Agent 不挂载 CLI 钩子)与 prompt 字段——prompt 的内容与 Markdown 正文完全一致,保证 IDE 与 CLI 两种入口下 Agent 行为相同。README 对两种格式的解释是:"IDE 用 Markdown 文件,CLI 用 JSON 文件,两者都提供以获得最大兼容性",且 Agent 使用的模型由 Kiro 当前的模型选择决定,而非 Agent 配置本身。
安装方式:ECC 的 Kiro 集成通过 .kiro/install.sh 一键部署到任意 Kiro 项目:
cd .kiro
# 安装到指定项目
./install.sh /path/to/your/project
# 安装到当前目录
./install.sh
# 全局安装(对所有 Kiro 项目生效)
./install.sh ~
从 install.sh 的源码结构看,安装器对 agents 目录下的 *.json 与 *.md 文件执行非破坏性拷贝——if [ ! -f "$TARGET/.kiro/agents/$local_name" ] 表明目标位置已存在同名文件时会跳过,因此安装后对 cpp-build-resolver 提示词的任何本地化修改都不会被重装覆盖。
二、核心职责:Agent 被授权处理哪五类问题
文档在 "Core Responsibilities" 一节列出了 Agent 的五项核心职责,这也界定了它的修复边界:
- 诊断 C++ 编译错误(diagnose compilation errors)
- 修复 CMake 配置问题
- 解决链接器错误(undefined reference、multiple definition)
- 处理模板实例化错误
- 修复头文件包含与依赖问题
注意职责清单里没有"重构"和"优化"——这与后文的 "Key Principles" 中"Surgical fixes only"形成呼应:该 Agent 被设计为止损工具而非改进工具。
三、诊断命令序列:按固定顺序收集证据
文档规定诊断阶段按以下顺序执行四条命令(原文 L21-L30):
cmake --build build 2>&1 | head -100
cmake -B build -S . 2>&1 | tail -30
clang-tidy src/*.cpp -- -std=c++17 2>/dev/null || echo "clang-tidy not available"
cppcheck --enable=all src/ 2>/dev/null || echo "cppcheck not available"
四条命令各自的作用与顺序设计值得拆解:
cmake --build build 2>&1 | head -100:触发实际构建并捕获前 100 行输出。2>&1合并 stderr(编译错误通常输出到 stderr),head -100防止级联错误刷屏——C++ 编译失败时错误往往连锁放大,前 100 行通常已包含根因错误。cmake -B build -S . 2>&1 | tail -30:重新配置(configure)并只看最后 30 行。CMake 的 configure 阶段错误(找不到依赖、CMakeLists.txt语法错误)会打印在项目末尾的CMake Error块中,因此用tail而不是head。clang-tidy ... || echo "clang-tidy not available"与 4.cppcheck --enable=all src/ ... || echo "cppcheck not available":静态分析作为辅助证据,且都带有2>/dev/null || echo兜底——工具不存在时不中断诊断流程,只打印提示。这是一种"渐进增强"式写法:核心诊断能力(CMake 构建)不依赖任何可选工具。
对比同仓库的 cpp-reviewer Agent,它使用的是更精细的静态分析参数(clang-tidy --checks='*,-llvmlibc-*'、cppcheck --enable=all --suppress=missingIncludeSystem),因为审查场景需要完整静态分析结果;而 build-resolver 场景下静态分析只是辅助,宽松的参数足以定位问题。
四、五步修复工作流:每修一处,必验一次
文档定义的修复循环(原文 L32-L40):
1. cmake --build build -> Parse error message
2. Read affected file -> Understand context
3. Apply minimal fix -> Only what's needed
4. cmake --build build -> Verify fix
5. ctest --test-dir build -> Ensure nothing broke
这个循环的工程要点:
- 第 1 步是"解析"而非"运行":Agent 先拿到完整错误信息再动手,避免凭错误文本的开头猜根因。
- 第 2 步强制读源文件:错误消息只给出文件与行号,上下文(例如一个前向声明、一个宏展开)必须通过
fs_read读原文件才能确认——这正是allowedTools里保留fs_read的用武之地。 - 第 3 步"最小修复":只改必需的部分,禁止顺手重构。
- 第 4 步即时验证:每次只做一个修复并立即重新构建,符合 "One fix at a time, verify after each" 原则(见下节),使错误的因果归因保持单一。
- 第 5 步回归测试:
ctest --test-dir build确保修复没有破坏已有行为。--test-dir参数用于直接指向构建目录,免去进入子目录;配套的 cpp-testing skill 给出了该命令的完整用法族:ctest --test-dir build --output-on-failure(失败时打印输出)、ctest --test-dir build -R "UserStoreTest.*"(正则过滤用例),与 Agent 工作流第 5 步直接衔接。
五、常见错误修复模式速查表
文档内置了一张 10 行的 "Error → Cause → Fix" 速查表(原文 L42-L55),这是 Agent 定位根因的主要知识来源,完整如下:
| Error | Cause | Fix |
|---|---|---|
undefined reference to X |
缺少实现或库 | 添加源文件或链接库 |
no matching function for call |
参数类型错误 | 修正类型或添加重载 |
expected ';' |
语法错误 | 修正语法 |
use of undeclared identifier |
缺少 include 或拼写错误 | 添加 #include 或修正名称 |
multiple definition of |
符号重复定义 | 使用 inline、移入 .cpp、或添加头文件保护 |
cannot convert X to Y |
类型不匹配 | 添加转换或修正类型 |
incomplete type |
需要完整类型处使用了前向声明 | 添加 #include |
template argument deduction failed |
模板参数错误 | 修正模板参数 |
no member named X in Y |
成员名拼写错误或类用错 | 修正成员名 |
CMake Error |
配置问题 | 修正 CMakeLists.txt |
这张表覆盖了 C++ 构建失败中最高频的四类根因:链接层(undefined reference / multiple definition)、类型系统层(no matching function / cannot convert / incomplete type)、预处理器层(undeclared identifier,多数是漏 include 而非真拼错)、构建系统层(CMake Error)。其中 multiple definition of 的三选一修复路径(inline / 移入 .cpp / 头文件保护)尤其典型:它对应"头文件里写了非内联函数体"这一常见误用,与 cpp-coding-standards skill 中强调的"头文件只放声明"原则一致。
六、CMake 深度排障:三条命令分别解决什么问题
当构建反复失败、错误信息不足以定位时,文档给出三条 CMake 排障命令(原文 L57-L63):
cmake -B build -S . -DCMAKE_VERBOSE_MAKEFILE=ON
cmake --build build --verbose
cmake --build build --clean-first
-DCMAKE_VERBOSE_MAKEFILE=ON:重新配置时打开详细 Makefile 生成开关,之后生成的构建脚本会打印每条完整的编译器/链接器命令行。定位"某条编译命令缺少-I路径"或"链接顺序不对"这类问题时,完整命令行是唯一可靠的证据。--verbose:构建时直接输出每条实际执行的命令(含完整编译参数),与上一条配合使用,覆盖"配置已缓存、只想看构建细节"的场景。--clean-first:先清理再构建,用于排除陈旧构建产物(过期的.o、过期的 CMake 缓存)造成的"错误信息指向已删除代码"的假象。当错误指向不存在的行号或文件时,这是首选动作。
七、关键原则:把"最小化"写进纪律
文档 "Key Principles" 一节的五条纪律(原文 L65-L71)是这个 Agent 区别于通用"帮我修一下"提示词的核心:
- Surgical fixes only——只修错误,不做重构;
- 未经批准绝不用
#pragma抑制警告; - 非必要绝不修改函数签名;
- 修根因,不修症状(Fix root cause over suppressing symptoms);
- 一次一个修复,每步验证(One fix at a time, verify after each)。
这几条共同压制了 LLM 修复构建错误时最典型的三类失败模式:顺手重构引入新错误、用 #pragma 或改签名"绕过"编译器报错、连续堆叠多个修改后无法归因。它们与 cpp-reviewer 的审查标准形成互补分工:reviewer 依据 C++ Core Guidelines 检查内存安全(raw new/delete、use-after-free)、并发(数据竞争、std::lock_guard 缺失)等 CRITICAL/HIGH 级问题并给出 Approve/Warning/Block 结论;build-resolver 只负责让构建变绿,两者通过同一套 cpp-coding-standards skill 共享代码标准依据——cpp-build-resolver 文档末尾明确指向该 skill 获取详细的 C++ 模式与代码示例。
八、停止条件与结构化报告
停止条件
文档规定三种情况下必须停下并报告(原文 L73-L78):
- 同一错误在 3 次修复尝试后仍然存在;
- 修复引入的错误比它解决的更多;
- 错误需要超出当前范围的架构级改动。
这三条构成了"失败熔断":第 1 条防止无限重试烧掉上下文与时间,第 2 条防止修复过程单调恶化,第 3 条明确告知 Agent"这不是你的职责范围"——需要架构变更时,应该由 architect 或 planner 类 Agent 接手,而不是让一个"最小修改"Agent 越界。
输出格式
修复过程要求以固定格式逐条报告(原文 L80-L89):
[FIXED] src/handler/user.cpp:42
Error: undefined reference to `UserService::create`
Fix: Added missing method implementation in user_service.cpp
Remaining errors: 3
结束时输出一行汇总:
Build Status: SUCCESS/FAILED | Errors Fixed: N | Files Modified: list
每条 [FIXED] 记录包含文件行号、原始错误、具体修复动作与剩余错误数四个字段;汇总行的 Files Modified: list 使调用方(人或上游 Agent)能精确知道本次修复的 diff 边界,便于随后用 git diff 复核或交给 cpp-reviewer 复审。这种"逐条 + 汇总"的机器可读格式,正是该 Agent 能被纳入自动化验证循环(例如 ECC 的 verification-loop skill:构建 → 类型检查 → lint → 测试 → 安全扫描 → diff 审查,迭代直至全部通过)而不产生歧义的原因。
九、在 ECC 的 Kiro 生态中如何落地
把 cpp-build-resolver 放入 ECC 的 Kiro 集成整体看,它在 C++ 开发闭环中的位置如下:
- 编写阶段:Steering 文件 cpp-patterns.md 以
fileMatch: "*.cpp,*.hpp,*.h,*.cc,*.cxx"模式在编辑 C++ 文件时自动加载,预先注入 RAII、智能指针、Rule of Five 等规则,从源头减少构建错误; - 构建失败:调用
cpp-build-resolver执行本文所述的五步工作流; - 修复后审查:切到 cpp-reviewer 对修改过的 C++ 文件做记忆安全与现代化 C++ 惯例审查;
- 测试回归:按 cpp-testing skill 配置 GoogleTest + CTest,
ctest --test-dir build --output-on-failure验证回归,必要时用-fsanitize=address构建捕获内存问题。
调用方式因入口而异:Kiro IDE 中可通过 / 菜单自动选择或直接输入 /cpp-build-resolver;kiro-cli 中执行 /agent swap 从 33 个 Agent 中切换,或以 kiro-cli --agent cpp-build-resolver 直接启动。Agent 的模型由 Kiro 当前选择的模型决定,配置中不含模型绑定,这一点对评估其输出一致性时是一个需要注意的前提。
小结
cpp-build-resolver 展示了 ECC 构建类 Agent 的完整设计范式:用 fs_read + shell 的最小工具白名单限定行为面;用固定的四命令诊断序列与五步"修复-验证"循环提供可复现的操作流程;用 10 行错误模式表沉淀高频根因知识;用三条纪律和三个停止条件约束 LLM 的修改半径;最后用机器可读的报告格式让修复结果可被 diff 复核与下游 Agent 消费。对于 C++/CMake 项目,这套组件配合 install.sh 的非破坏性安装即可整体引入,且所有文件安装后均可按团队习惯自定义而不会被重装覆盖。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00