ECC Kiro 适配包中的 kotlin-reviewer:Kotlin/Android/KMP 代码审查 Agent 的深度拆解
ECC(Everything Claude Code)的 Kiro 适配包 .kiro/ 中内置了一个专职的 kotlin-reviewer Agent 定义,它把 Kotlin 代码审查中最容易出错的领域——协程取消语义、Flow 收集与生命周期、Compose 重组合陷阱、Clean Architecture 模块边界、Android 安全配置——固化成一份可直接执行的提示词工程:包含明确的 git diff 取数流程、按严重度分级的七大类审查清单、标准化的问题报告格式和“无 CRITICAL/HIGH 才放行”的审批门槛。读完本文,你将理解这个 Agent 的双格式定义(MD + JSON)如何工作、其审查工作流的每一步具体做什么、每条检查规则背后的原理,以及它与 Kiro 的 steering 文件、skills 和 ECC 的 /kotlin-review 命令如何配合落地。
一、kotlin-reviewer 在 ECC Kiro 体系中的定位
ECC 主仓库面向 Claude Code、Codex、Opencode、Cursor 等 Harness,而 .kiro/README.md 描述的是一套独立的 Kiro 分发形态:把 ECC 的 agents、skills、hooks、steering 文件打包成可用一条命令安装到任意 Kiro 项目或全局(~)的组件。其中 Agents 一节明确列出了 kotlin-reviewer 的职责描述:
kotlin-reviewer— Kotlin/Android/KMP code reviewer. Coroutine safety, Compose best practices, clean architecture.
也就是说,它不是一个“通用 code-reviewer 换语言皮肤”,而是针对 Kotlin 生态特有痛点定制的审查角色。在 Kiro 中的调用方式(见 .kiro/README.md):
- IDE 内:在会话中输入
/kotlin-reviewer显式唤起,或由 Kiro 根据任务自动选择; - CLI 内:
kiro-cli --agent kotlin-reviewer直接以该 Agent 启动,或在会话中/agent swap kotlin-reviewer切换; - 配套还有
kotlin-build-resolver(修复 Gradle/KSP/依赖错误)作为“审查 → 修复”的分工搭档。
主仓库的 AGENTS.md 也在语言审查 Agent 表中登记了 kotlin-reviewer | Kotlin code review | Kotlin/Android/KMP projects,两处定义相互印证:该 Agent 是 ECC 十种语言审查矩阵中 Kotlin 一列的 Kiro 落地版本。
二、双格式定义与工具权限边界
Kiro 的 Agent 同时以 Markdown 和 JSON 两种格式存在(README 说明:MD 供 IDE 选择,JSON 供 CLI 的 /agent swap 使用)。两者内容对应关系如下:
Markdown 格式(.kiro/agents/kotlin-reviewer.md):
---
name: kotlin-reviewer
description: Kotlin and Android/KMP code reviewer. Reviews Kotlin code for idiomatic patterns,
coroutine safety, Compose best practices, clean architecture violations, and common Android pitfalls.
allowedTools:
- read
- shell
---
JSON 格式(.kiro/agents/kotlin-reviewer.json):
{
"name": "kotlin-reviewer",
"allowedTools": ["fs_read", "shell"],
"hooks": {},
"prompt": "You are a senior Kotlin and Android/KMP code reviewer ..."
}
两个值得注意的设计点:
- 只读 + 只执行,禁止改写。工具白名单只有
read(JSON 中为fs_read)与shell,提示词正文也强调 “You DO NOT refactor or rewrite code — you report findings only”。这保证了审查 Agent 的产出是可审计的报告而非对代码的隐式修改——审查与重构被强制解耦,与 ECC 中refactor-cleaner、kotlin-build-resolver的分工一致。 - shell 权限服务于 git diff 取数。工作流第一步就要跑
git diff系列命令(下文详述),这是它申请shell工具的正当原因;其余步骤全部落在文件读取上。
需要说明的是,.kiro/README.md 特别指出:“Agent models are determined by your current model selection in Kiro, not by the agent configuration”,即 Agent 实际使用的模型由 Kiro 当前模型选择决定,配置本身不绑定模型。
三、审查工作流:四步取数与结构判定
.kiro 版本的提示词把审查流程显式拆成四步(主仓库 agents/kotlin-reviewer.md 的 Step 1 是泛化的 git diff --staged / git diff,而 .kiro/agents/kotlin-reviewer.md 给出了更精确的文件过滤与降级策略,两者对照如下):
Step 1:Gather Context(按优先级取 diff)
# 1) 先看暂存区与未暂存改动(仅 Kotlin 文件)
git diff --staged -- '*.kt' '*.kts'
git diff -- '*.kt' '*.kts'
# 2) 无本地改动时,取最近一次提交
git diff HEAD~1 -- '*.kt' '*.kts'
# 3) PR 审查场景,取分支相对 main 的全部差异
git diff main...HEAD -- '*.kt' '*.kts'
# 4) HEAD~1 失败(浅克隆或单提交历史)时的兜底
git show --patch HEAD -- '*.kt' '*.kts'
这里的设计意图是:审查范围永远是增量(staged → 最近提交 → PR 分支 → 单提交兜底),而不是全库扫描;同时 -- '*.kt' '*.kts' 路径过滤确保 Gradle KTS 脚本也进入审查视野(KTS 文件里的依赖声明、插件配置正是后文 “Gradle & Build” 类检查的对象)。
Step 2:Understand Project Structure
- 检查
build.gradle.kts/settings.gradle.kts,弄清模块布局(单模块还是domain/data/presentation多模块); - 判定项目类型:Android-only、KMP,还是 Compose Multiplatform。这一步决定后续哪些清单项生效——例如
repeatOnLifecycle只在 Android 语境有意义,commonMain/androidMain源集建议只适用于 KMP。
主仓库版本的 Step 2 还额外要求查看项目内 CLAUDE.md 获取团队约定,并带有一个 Step 2b 安全预检:在通读前先扫描 exported 组件、deep link、intent filter、WebView/网络配置、keystore/token 处理;一旦发现 CRITICAL 级安全问题就中断审查并移交 security-reviewer。.kiro 版本没有单列 Step 2b,但保留了同等约束:“If any CRITICAL security issue is present, stop and escalate to security-reviewer”(写入 Security 清单小节末尾)。
Step 3:Read and Review
完整读取每个改动文件(不是只看 diff 片段),结合周边代码上下文应用下述清单。
Step 4:Report Findings
使用固定输出格式报告,且只报告置信度 >80% 的问题——这条阈值约束直接抑制了 AI 审查中最常见的噪音:低置信度猜测被系统性过滤。
四、七大类审查清单与严重度分级
清单是整个 Agent 的核心资产。.kiro/agents/kotlin-reviewer.md 的原文结构为:CRITICAL → HIGH → MEDIUM → LOW 四级,逐类列出。以下完整继承原清单,并补充每条规则背后的原理。
4.1 Architecture(CRITICAL)
- Domain importing framework —
domain模块不得 import Android、Ktor、Room 或任何框架; - Data layer leaking to UI — Entity/DTO 直接暴露给表现层(必须映射为 domain model);
- ViewModel business logic — 复杂业务逻辑应放在 UseCase,而非 ViewModel;
- Circular dependencies — 模块 A 依赖 B 且 B 依赖 A。
原理:Clean Architecture 的价值在于 domain 层是纯 Kotlin,可被任意平台依赖、可在 JVM 上单测而无需 Android 环境。一旦 import android.content.Context 渗入 domain,测试隔离与 KMP 复用同时失效。这也是输出格式示例中被作为 CRITICAL 范例引用的那一条(见第五节)。
4.2 Coroutines & Flows(HIGH)
- GlobalScope usage — 必须使用结构化作用域(
viewModelScope、coroutineScope); - Catching CancellationException — 必须重新抛出或干脆不捕获;吞掉它会破坏整个结构化并行的取消传播;
- Missing
withContextfor IO — 数据库/网络调用跑在Dispatchers.Main上; - StateFlow with mutable state — StateFlow 内持有可变集合(必须 copy 后发出);
- Flow collection in
init {}— 应使用stateIn()或在受控 scope 中 launch; - Missing
WhileSubscribed— 本可用SharingStarted.WhileSubscribed的场景却写stateIn(scope, SharingStarted.Eagerly)。
主仓库版 agents/kotlin-reviewer.md 在这一节附了一段 BAD/GOOD 对照代码,.kiro 版继承的清单语义完全一致:
// BAD — swallows cancellation
try { fetchData() } catch (e: Exception) { log(e) }
// GOOD — preserves cancellation
try { fetchData() } catch (e: CancellationException) { throw e } catch (e: Exception) { log(e) }
其中两条最具审查价值的细节:StateFlow 内嵌可变集合的问题在于 StateFlow 的 distinctUntilChanged() 语义——集合内容原地 add 后引用不变,value 未变、不触发收集、UI 不刷新;正确做法是不可变更新 _state.update { it.copy(items = it.items + newItem) }。而 WhileSubscribed vs Eagerly 关乎资源生命周期:Eagerly 让上游永远运行,WhileSubscribed 在最后一个订阅者离开(加停顿窗口)后取消上游,对网络/数据库驱动的 Flow 是默认更安全的选择。
4.3 Compose(HIGH)
- Unstable parameters — Composable 接收可变类型参数会引发不必要的重组合;
- Side effects outside LaunchedEffect — 网络/DB 调用必须放在
LaunchedEffect或 ViewModel 中; - NavController passed deep — 应传 lambda 而非深层透传
NavController引用; - Missing
key()in LazyColumn — 列表项缺少稳定 key,导致 diff 失效与性能劣化; rememberwith missing keys — 依赖变化时计算不会重算;- Object allocation in parameters — 参数位置内联创建对象(如每次重组合都 new 一个 lambda)触发重组合。
主仓库版同样附带了该节的对照代码,.kiro 清单继承其判断标准:
// BAD — new lambda every recomposition
Button(onClick = { viewModel.doThing(item.id) })
// GOOD — stable reference
val onClick = remember(item.id) { { viewModel.doThing(item.id) } }
Button(onClick = onClick)
4.4 Kotlin Idioms(MEDIUM)
!!usage — 非空断言;优先?.、?:、requireNotNull、checkNotNull;varwherevalworks — 优先不可变;- Java-style patterns — 静态工具类(应改为顶层函数)、getter/setter(应改为属性);
- String concatenation — 用字符串模板
"Hello $name"而非"Hello " + name; whenwithout exhaustive branches — sealed class/interface 应使用穷尽when;- Mutable collections exposed — 公共 API 返回
List而非MutableList。
这些 MEDIUM 级规则与 Kiro 侧自动加载的 steering 文件 .kiro/steering/kotlin-patterns.md 高度互文——后者在编辑 *.kt 文件时自动注入同样的约束(“Never use !!”、“Always use exhaustive when with sealed types — no else branch”、“Prefer val over var”),相当于“写代码时预防、审代码时拦截”的双保险。
4.5 Android Specific(MEDIUM)
- Context leaks — 在单例/ViewModel 中持有
Activity/Fragment引用; - Missing ProGuard rules — 序列化类缺少
@Keep或 ProGuard 规则; - Hardcoded strings — 面向用户的文案未进
strings.xml或 Compose 资源; - Missing lifecycle handling — Activity 中收集 Flow 未使用
repeatOnLifecycle。
最后一条同样有主仓库版 steering 与 skills 佐证:repeatOnLifecycle(STARTED) { flow.collect { ... } } 是官方推荐的“随生命周期暂停/恢复收集”模式,否则 Fragment 退到后台后 Flow 仍在驱动 UI 状态。
4.6 Security(CRITICAL)
- Exported component exposure — Activity/Service/Receiver 被 export 却缺少防护;
- Insecure crypto/storage — 自研加密、明文存放密钥、弱 keystore 用法;
- Unsafe WebView/network config — JavaScript 桥、明文流量(cleartext)、过宽的信任配置;
- Sensitive logging — token、凭据、PII、密钥被打印进日志。
配套约束:“If any CRITICAL security issue is present, stop and escalate to security-reviewer”——即 kotlin-reviewer 对安全问题只负责发现并上报升级,深度分析与修复交给专职的 security-reviewer(README 中定义为 “Flags secrets, SSRF, injection, unsafe crypto, and OWASP Top 10 vulnerabilities”)。steering 侧 .kiro/steering/kotlin-patterns.md 的 Security 小节给出了对应的正向做法:不要往 BuildConfig/资源里埋密钥(可从 APK 提取)、用 EncryptedSharedPreferences/Android Keystore(Android)或 Keychain(iOS)、Room/SQLDelight 用参数化查询、用 network_security_config.xml 阻断明文流量。
4.7 Gradle & Build(LOW)
- Version catalog not used — 硬编码版本号而非
libs.versions.toml; - Unnecessary dependencies — 引入后从未使用的依赖;
- Missing KMP source sets — 本可放
commonMain的代码却写死在androidMain。
五、报告格式、汇总表与审批门槛
Agent 的产出格式被严格模板化,保证报告可被脚本/CI 解析,也让读者(或下一个 Agent)无需阅读推理过程即可定位问题。
单条 Finding 格式
原文示例(保留原样):
[CRITICAL] Domain module imports Android framework
File: domain/src/main/kotlin/com/app/domain/UserUseCase.kt:3
Issue: `import android.content.Context` — domain must be pure Kotlin with no framework dependencies.
Fix: Move Context-dependent logic to data or platforms layer. Pass data via repository interface.
[HIGH] StateFlow holding mutable list
File: presentation/src/main/kotlin/com/app/ui/ListViewModel.kt:25
Issue: `_state.value.items.add(newItem)` mutates the list inside StateFlow — Compose won't detect the change.
Fix: Use `_state.update { it.copy(items = it.items + newItem) }`
每条 finding 四要素齐全:[严重度] + 一句话标题、文件:行号、Issue(问题+原因)、Fix(最小修复方向)。
结尾汇总表与 Verdict
## Review Summary
| Severity | Count | Status |
|----------|-------|--------|
| CRITICAL | 0 | pass |
| HIGH | 1 | block |
| MEDIUM | 2 | info |
| LOW | 0 | note |
Verdict: BLOCK — HIGH issues must be fixed before merge.
审批标准(Approval Criteria)
- Approve:无 CRITICAL 且无 HIGH;
- Block:存在任一 CRITICAL 或 HIGH —— 合并前必须修复。
这个两档门槛与 ECC 侧 /kotlin-review 命令 的三档表(PASS / WARNING / FAIL)语义一致:commands/kotlin-review.md 额外定义了 “Only MEDIUM issues → WARNING(谨慎合并)”,且其自动化检查段(./gradlew build、./gradlew detekt、./gradlew ktlintCheck、./gradlew test)与 Agent 的报告流程互补——命令层负责跑工具链,Agent 层负责语义级审查,两者都输出同一严重度词汇表(CRITICAL/HIGH/MEDIUM),便于 CI 门禁统一消费。
六、与 ECC 生态的协作:从单点 Agent 到审查管线
单独看 kotlin-reviewer 是一份提示词,放进 .kiro 目录结构里,它其实是一条管线的“判定节点”。从 .kiro/README.md 的组件清单与“Recommended Workflow”可以拼出完整链路:
- 写码期(预防):编辑
*.kt文件时,steering 文件.kiro/steering/kotlin-patterns.md(inclusion: fileMatch,fileMatchPattern: "*.kt")自动加载,注入 ViewModel 单状态对象模式、UseCaseoperator fun invoke模式、supervisorScope用法、expect/actual 规范等,让大部分 MEDIUM 级问题在写代码阶段就被规避; - 技能层(方法论):
.kiro/skills/kotlin-patterns/SKILL.md(“Idiomatic Kotlin patterns, coroutines, null safety, and DSL builders”)与.kiro/skills/kotlin-testing/SKILL.md(Kotest、MockK、coroutine testing、Kover 覆盖率)提供按需/调用的完整方法论;steering 文件末尾的 Reference 节也显式指回kotlin-reviewer与kotlin-build-resolver两个 Agent; - 审查期(判定):
/kotlin-reviewer(IDE)或kiro-cli --agent kotlin-reviewer(CLI)执行第四节的四步工作流,产出第五节的标准化报告; - 升级与修复(分工):CRITICAL 安全问题升级给
security-reviewer;Gradle/KSP/依赖类构建错误交给kotlin-build-resolver;代码改动本身不属于本 Agent 职责。
主仓库侧的等价入口是 /kotlin-review 命令与 agents/kotlin-reviewer.md Agent(二者 frontmatter 中 tools: Read, Grep, Glob, Bash),docs/COMMAND-REGISTRY.json 里也登记了该命令与 kotlin-reviewer Agent 的映射关系。跨 Harness 复用同一份清单语义,正是 ECC “一次定义、多端分发”思路的体现。
七、落地要点与适用前提
把该 Agent 装进团队时的几个实操要点:
- 安装:按
.kiro/README.mdQuick Start,cd .kiro && ./install.sh /path/to/your/project(或./install.sh装到当前目录、./install.sh ~全局安装);安装器是非破坏性拷贝,不会覆盖已有文件,重跑安装不影响本地定制。 - 审查范围是增量的:它依赖 git 工作区状态,所以最合理的触发点是“提交前”“PR 创建前”;对历史代码的存量审计不在其设计目标内(Step 1 的四个 diff 命令都指向增量)。
- 判定标准可量化:Approve/Block 只由 CRITICAL/HIGH 数量决定,MEDIUM/LOW 不阻断合并,适合直接作为 PR 门禁的判定输入;
>80% 置信度与 “只报告不修改” 两条约束则限制了它的副作用面。 - 适用前提:多模块 KMP/Android 项目收益最大(Architecture 类规则才有检查对象);纯 Kotlin JVM 服务端项目主要命中 Coroutines/Idioms/Gradle 三类;KMP 场景下还应注意它与 steering 中
expect/actual、commonMain源集建议的一致性。 - 模型与行为差异:Kiro 侧 Agent 实际模型取决于当前 Kiro 模型选择(README 明示),审查质量会随所选模型波动;配置本身不锁模型。
结语
.kiro/agents/kotlin-reviewer.md 的价值不在任何单条规则,而在于它把“资深 Kotlin 审查者”的工作方式结构化:用 git diff 界定增量、用项目类型判定裁剪清单、用四级严重度统一词汇、用固定模板输出可机读报告、用硬门槛(无 CRITICAL/HIGH 才 Approve)驱动合并决策,并通过 steering(写码期预防)、skills(方法论)、security-reviewer/kotlin-build-resolver(升级与修复)三个协作面组成闭环。对 Kotlin/Android/KMP 团队而言,这份 Agent 定义既是一份可执行的 CI 审查规范,也是一份可直接对照自查的协程、Compose 与架构陷阱清单。
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 StartedRust0624
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