ECC swift-reviewer:面向 Kiro 的分层 Swift 代码审查代理设计与全量审查标准
2026/9/7 19:39:11 网站建设 项目流程

ECC swift-reviewer:面向 Kiro 的分层 Swift 代码审查代理设计与全量审查标准

【免费下载链接】ECCThe agent harness performance optimization system. Skills, instincts, memory, security, and research-first development for Claude Code, Codex, Opencode, Cursor and beyond.项目地址: https://gitcode.com/GitHub_Trending/ev/ECC

本篇指南以 ECC 仓库中 Kiro 代理定义文件 .kiro/agents/swift-reviewer.md 为主体,完整解析这位"资深 Swift 代码审查者"的调用流程、CRITICAL/HIGH/MEDIUM 三级审查标准、诊断命令集与审批决策规则,并结合仓库中同名的 Claude Code 版本代理 agents/swift-reviewer.md、配套技能 skills/swift-actor-persistence/SKILL.md、skills/swift-protocol-di-testing/SKILL.md 以及 rules/swift/security.md 做源码级佐证。读完后,你将掌握一套可直接落地到 Swift 项目的 AI 审查流程:从swift build/swiftlint/swift test前置检查,到逐条对齐安全、错误处理、并发、内存、协议导向设计的审查清单,再到 Approve/Warning/Block 的审批判定。

代理定位与配置

.kiro/agents/swift-reviewer.md采用 Kiro 的 Markdown 代理定义格式:YAML frontmatter 声明元信息,正文即注入给模型的系统提示词。其 frontmatter 完整内容如下:

name: swift-reviewer description: Expert Swift code reviewer specializing in protocol-oriented design, value semantics, ARC memory management, Swift Concurrency, and idiomatic patterns. Use for all Swift code changes. MUST BE USED for Swift projects. allowedTools: - read - shell

各字段的作用可以直接从配置本身读出:

  • name:代理在 Kiro 中的注册名,用于在会话中按名称调用;
  • description:触发描述。特别值得注意的是其中的强制性措辞——"Use for all Swift code changes. MUST BE USED for Swift projects.",即凡是涉及 Swift 代码变更的场景都应路由到该代理,这是 ECC 代理体系中典型的"单用途专家代理"命名法(仓库agents/目录下还有python-reviewerrust-reviewer等同构定义);
  • allowedTools:只授予read(读文件)与shell(执行诊断命令)两类工具。这一定权策略是刻意的:审查者只需要"看代码 + 跑验证命令",不需要写文件,从而在工具层面限制了审查过程中的副作用。

Kiro 同时为该代理提供了一份 JSON 清单 .kiro/agents/swift-reviewer.json,从源码结构看这是 Kiro 代理定义的双格式表示:JSON 中allowedTools["fs_read", "shell"]tools["@builtin"]mcpServershooks均为空对象,prompt字段则完整内嵌了与 Markdown 版本逐字相同的系统提示词。两份文件描述同一代理,便于不同加载机制消费。

调用流程:先跑验证,再谈审查

文档正文开头定义了代理被调用时的 5 步标准动作:

  1. 运行swift buildswiftlint lint --quiet(如已安装)和swift test——任何一项失败就立即停止并报告,不进入逐行审查;
  2. 运行git diff HEAD~1 -- '*.swift'查看最近一次提交的 Swift 文件变更(PR 场景改用git diff main...HEAD -- '*.swift');
  3. 审查范围锁定为被修改的.swift文件,而不是全量代码;
  4. 若项目有 CI 或合并要求,审查默认假设 CI 为绿色、合并冲突已解决;如果 diff 本身暗示 CI 可能失败(例如测试改动与实现不匹配),需要明确指出;
  5. 开始按审查标准逐项检查。

这套流程体现了一个务实的审查经济学:构建与测试失败时,代码级的风格问题毫无意义,所以第一步是"硬闸门"(hard gate);第二步用git diff限定审查面,避免 AI 审查常见的"全库漫游、泛泛而谈"问题。

分层审查标准

文档将审查项组织为 CRITICAL → HIGH → MEDIUM 三个严重度层级,共 8 个专项。以下完整继承原文标准,并逐条给出判定依据与仓库佐证。

CRITICAL - Safety(安全)

任何一条命中即触发 Block:

审查项判定与整改建议
强制解包生产代码路径中的value!——改用guard letif let??
强制 try无合理理由的try!——改用do/catch或以throws向上传播
强制转换未做前置类型检查的as!——改用as?配合条件绑定
硬编码密钥源码中出现 API key、密码、token——改用 Keychain 或环境变量
UserDefaults 存敏感数据敏感数据写入UserDefaults——改用 Keychain Services
SQL/命令注入在查询语句或 shell 命令中使用字符串插值
路径穿越用户可控路径未经校验
不安全反序列化解码不可信数据时没有校验或大小限制

其中"硬编码密钥"与"UserDefaults 存密钥"两条,在仓库的 Swift 安全规则 rules/swift/security.md 中有更完整的展开:该文件声明敏感数据(token、密码、密钥)必须走 Keychain Services,构建期密钥用环境变量或.xcconfig,并给出环境变量取值的示例代码:

let apiKey = ProcessInfo.processInfo.environment["API_KEY"] guard let apiKey, !apiKey.isEmpty else { fatalError("API_KEY not configured") }

同时该文件还强调了传输安全(ATS 默认强制开启、关键端点做证书固定)与输入校验(外部来源数据——API、深链、粘贴板——须先校验再处理)。这些正是审查代理在实际执行 "CRITICAL - Safety" 检查时可以直接对标的规则文件。

CRITICAL - Error Handling(错误处理)

审查项说明
被吞掉的错误catch {}块,或用try?丢弃有意义的错误
缺少错误上下文直接重新抛出,而没有包装成领域特定错误
fatalError()用于可恢复条件调用方本可以处理的错误应使用throw
assert用于必要不变式assert在 release 构建中会被剥离——应改用precondition

第 4 条值得展开:Swift 中assert只在调试构建生效,若某个不变式在 release 下也必须成立(例如数组索引合法性),用assert会导致检查在发布版中"静默消失"。precondition在调试与发布构建中都会强制检查,因此"必要不变式"必须用后者。

HIGH - Concurrency(并发)

Swift Concurrency 是当前 Swift 项目缺陷最集中的区域,文档列出 6 条:

  • 数据竞争:可变共享状态没有 actor 隔离或同步手段;
  • @Sendable违规:非Sendable类型跨越隔离边界传递;
  • 阻塞主 actor:在@MainActor上执行同步 I/O 或Thread.sleep
  • 无取消的非结构化Task {}:fire-and-forget 任务泄漏;
  • actor 重入问题:跨await挂起点时对状态一致性做了错误假设——actor 在await处挂起时允许其他任务进入,"读-改-写"跨挂起点时可能观察到中间状态;
  • 缺失@MainActor:UI 更新在主 actor 之外执行。

HIGH - Memory Management(内存管理)

ARC 引用计数模型下的四个经典陷阱:

  • 强引用循环:长生命周期上下文中闭包强捕获self——使用[weak self]
  • Delegate 强引用:delegate 属性未声明weak,形成保留环;
  • 逃逸闭包缺少捕获列表:没有显式声明捕获语义;
  • 大值类型拷贝:过大的struct在每次赋值时整体复制。

HIGH - Code Quality(代码质量)

  • 超大函数:超过 50 行;
  • 深层嵌套:超过 4 层;
  • 演进枚举上的通配 switchdefault:会掩盖未来新增的 case——应使用@unknown default(它会提示开发者该 default 分支可能不再必要);
  • 死代码:未使用的函数、import 或变量。

HIGH - Protocol-Oriented Design(协议导向设计)

这是该代理区别于通用代码审查器的核心特色(frontmatter 中 "protocol-oriented design, value semantics" 即指向此节):

  • 协议已足够却用类继承:优先协议遵循 + 默认扩展实现复用;
  • Any/AnyObject滥用:改用带约束的泛型或any Protocol/some Protocol
  • 缺失协议遵循:类型本应遵循EquatableHashableCodableSendable却没有。

MEDIUM - Performance(性能)

  • 热路径上的不必要分配:在紧凑循环内创建对象;
  • 缺少reserveCapacity:已知最终容量却逐元素增长数组;
  • 循环内字符串插值:重复触发String分配;
  • N+1 查询:在循环内发起数据库或网络调用。

MEDIUM - Best Practices(最佳实践)

  • 可用let时用了var:优先不可变绑定;
  • 可用struct时用了class:数据模型优先值类型;
  • 生产代码中的print():应使用os.Logger或结构化日志;
  • 缺失访问控制:类型默认为internal,而本应是private
  • 公开 API 无文档public成员缺少///文档注释;
  • 魔法数字/字符串:应使用命名常量或枚举。

诊断命令集

文档给出了一组可直接复制执行的诊断命令:

swift build if command -v swiftlint >/dev/null 2>&1; then swiftlint lint --quiet; else echo "[info] swiftlint not installed"; fi swift test swift package resolve

要点解读:

  • swift buildswift test是 SwiftPM 项目的标准构建/测试入口,覆盖所有 SPM 可构建目标;
  • swiftlint一行使用了command -v做存在性探测——代理不能假设开发者机器上装了 SwiftLint,因此"可选工具"都采用"有则运行、无则降级提示"的写法;
  • swift package resolve重新解析依赖图,用于排除"依赖声明与 lockfile 不一致"这类导致本地构建偶发失败的问题。

审批决策标准

审查结论收敛为三档:

  • Approve(通过):无 CRITICAL 或 HIGH 问题;
  • Warning(警告):仅存在 MEDIUM 问题——代码可以合并,但列出改进建议;
  • Block(阻断):发现任一 CRITICAL 或 HIGH 问题。

文档结尾还给出审查心态基准:"Would this code pass review at a top Swift shop or well-maintained open-source project?"——即所有规则最终服从同一个判定:代码能否经受住头部 Swift 团队或高质量开源项目的评审。

纵深对照:Claude Code 版本代理的增量条款

仓库中同名代理 agents/swift-reviewer.md 是面向 Claude Code 的版本(frontmatter 为tools: Read, Grep, Glob, Bash,并声明model: sonnet)。两者共享同一套五级调用流程与审查骨架,但 Claude Code 版本在多条目上更严格,可以作为 Kiro 版本的"增强参考":

  • 安全层新增"ATS disabled"(无合理理由关闭 App Transport Security 视为 CRITICAL);
  • 错误处理层新增"precondition/fatalError用于库代码":precondition在调试与发布构建中都会崩溃,fatalError无条件崩溃,公开 API 边界上应改用throw
  • 代码质量层新增"非穷尽匹配"(需要显式处理时却写了兜底分支);
  • 协议设计层新增"存在类型优于泛型"(参数可用some Protocol或泛型约束时却用了any Protocol);
  • 性能层新增"不必要的@objc桥接"(纯 Swift 足够时避免 Swift 到 Objective-C 的过桥开销);
  • 最佳实践层新增"SwiftLint 警告未处理"(无理由的// swiftlint:disable抑制)与"字符串化 API"(用原始字符串表达本应建模为枚举的值);
  • 诊断命令新增swift-format lint -r .的可选探测(同样先command -v判存再执行,并截取前 30 行输出);
  • 交叉引用不同:Kiro 版本引用技能swift-actor-persistenceswift-protocol-di-testing;Claude Code 版本则引用规则文件swift/coding-styleswift/patternsswift/securityswift/testing(对应仓库 rules/swift/ 目录下的同名.md文件)以及技能swift-concurrency-6-2swiftui-patternsswift-protocol-di-testing

从源码结构看,这种"同一专家、多 Harness 变体"是 ECC 的通用组织方式:核心审查逻辑只维护一份,按宿主工具(Kiro / Claude Code)在 frontmatter 的工具体系、安全基线(Claude Code 版本开头有 Prompt Defense Baseline 反提示注入条款)和诊断命令上做适配。

配套技能:审查标准背后的两个 Swift 模式

文档末行将swift-actor-persistenceswift-protocol-di-testing两个技能作为"详细模式与规则"的延伸引用,二者恰好对应审查标准中"并发"与"代码质量/协议设计"两条 HIGH 线的最佳实践落地。

swift-actor-persistence:用 actor 消除数据竞争

技能 skills/swift-actor-persistence/SKILL.md 展示了一个通用的 actor 仓库模式:内存缓存 + 文件持久化,由编译器强制串行化访问,直接消除"数据竞争"审查项。核心结构如下:

public actor LocalRepository<T: Codable & Identifiable> where T.ID == String { private var cache: [String: T] = [:] private let fileURL: URL public init(directory: URL = .documentsDirectory, filename: String = "data.json") { self.fileURL = directory.appendingPathComponent(filename) // Synchronous load during init (actor isolation not yet active) self.cache = Self.loadSynchronously(from: fileURL) } public func save(_ item: T) throws { cache[item.id] = item try persistToFile() } public func find(by id: String) -> T? { cache[id] } private func persistToFile() throws { let data = try JSONEncoder().encode(Array(cache.values)) try data.write(to: fileURL, options: .atomic) } // ... }

其关键设计决策(技能内以表格形式给出)包括:用 actor 而非"类 + 锁"获得编译器强制的线程安全;字典按 ID 索引实现 O(1) 查找;泛型约束Codable & Identifiable使其可复用于任意模型;文件写入使用.atomic防止崩溃时出现半写文件。调用侧因为 actor 隔离天然全异步:let question = await repository.find(by: "q-001")。对照审查标准可见,"可变共享状态无 actor 隔离""非Sendable类型跨边界"这类 HIGH 项,在此模式下的标准答案就是把状态收进 actor、把跨边界数据类型约束为Sendable。技能同时列出了反模式清单,例如新并发代码用DispatchQueue/NSLock、用nonisolated绕开 actor 隔离等,与审查代理"fire-and-forget 任务泄漏"等条款形成呼应。

swift-protocol-di-testing:协议化依赖注入

技能 skills/swift-protocol-di-testing/SKILL.md 回答另一个审查关切:如何让"文件/网络/外部 API"相关的 Swift 代码可测试。其模式分五步:

  1. 定义小而聚焦的Sendable协议,例如:
public protocol FileAccessorProviding: Sendable { func read(from url: URL) throws -> Data func write(_ data: Data, to url: URL) throws func fileExists(at url: URL) -> Bool }
  1. 提供生产实现(如DefaultFileAccessor封装Data(contentsOf:)与原子写入);
  2. 编写可注入错误的 mock(readError/writeError属性用于模拟失败路径);
  3. 通过带默认值的参数注入——生产代码走默认实现,测试只需注入 mock:
public actor SyncManager { public init( fileSystem: FileSystemProviding = DefaultFileSystemProvider(), fileAccessor: FileAccessorProviding = DefaultFileAccessor() ) { /* ... */ } }
  1. 用 Swift Testing 框架断言错误路径,例如await #expect(throws: SyncError.containerNotAvailable) { try await manager.sync() }

技能的"仅 mock 边界,不 mock 内部类型"原则,恰好是审查标准中"协议滥用"(Any/AnyObject、过度抽象)条款的反面锚点:抽象应发生在外部依赖边界,而不是渗透进每个内部类型。

如何应用这套审查体系

结合以上各部分,在 Swift 项目中使用该代理的完整路径是:

  1. 将 .kiro/agents/swift-reviewer.md 放入项目的.kiro/agents/目录(Kiro 会将其注册为可调用代理;配套 JSON 清单 swift-reviewer.json 一并存在以兼容清单式加载);
  2. 在每次 Swift 变更(提交或 PR)后调用swift-reviewer,它会按"构建/测试闸门 → diff 定位 → 分层审查 → 三档结论"的流程给出结构化结果;
  3. 对审查中反复命中的模式类问题,按文档末行引用的技能深入修复:线程安全问题参考 swift-actor-persistence 的 actor 仓库模式,可测试性问题参考 swift-protocol-di-testing 的边界协议注入模式;
  4. 项目级规则可进一步与 rules/swift/security.md、rules/swift/patterns.md 等规则文件对齐,使代理的审查口径与团队规范文件保持同一来源。

这套设计的可取之处在于把"资深 Swift 审查者的隐性经验"显式化为可版本化、可跨项目复用的资产:frontmatter 限定工具与角色,调用流程保证审查有闸门、有边界,分层标准保证结论可判定(Approve/Warning/Block),配套技能保证每个审查项都有对应的正模式可依。适用前提需要说明:该代理面向 Swift Package Manager 可构建项目(诊断命令基于swift build/swift test),SwiftLint 与 swift-format 均为可选依赖,缺失时自动降级为提示而非失败。

【免费下载链接】ECCThe agent harness performance optimization system. Skills, instincts, memory, security, and research-first development for Claude Code, Codex, Opencode, Cursor and beyond.项目地址: https://gitcode.com/GitHub_Trending/ev/ECC

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询