feat: 新增 Skills+沙箱+DB 自动代码审查智能体示例 (#92)#206
Conversation
|
CLA Assistant Lite bot: I have read the CLA Document and I hereby sign the CLA turrillcerza seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #206 +/- ##
==========================================
Coverage ? 87.90237%
==========================================
Files ? 479
Lines ? 44984
Branches ? 0
==========================================
Hits ? 39542
Misses ? 5442
Partials ? 0 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
AI Code Review该行确实包含了 现在进行最终定稿。让我再次重新考虑 让我重新检查一下 现在让我写审查意见。我对这些发现很有信心。让我再考虑一下 让我再重新考虑一下:fixture 的 最终审查意见如下。 发现的问题🚨 Critical
|
新增 examples/skills_code_review_agent:基于 trpc_agent_sdk 的自动代码审查 Agent,组合 Skill(code-review 技能包:SKILL.md + 6 条规则文档 + 沙箱内检查 脚本)、code_executors 沙箱(container 生产默认 / cube(E2B) / local 开发回退, 带超时、输出字节上限、环境变量白名单)、BaseFilter 治理链(命令白名单、 路径/网络/预算 5 项检查,deny 与 needs_human_review 一律不执行并落库)、 SQLAlchemy 存储(cr_review_task / cr_sandbox_run / cr_filter_event / cr_finding / cr_report 五表,按 task_id 可查全链路)与 telemetry 指标。 - 输入:--diff-file / --repo-path / --files / --fixture,支持 rename/binary/CRLF/no-newline 等边界 - 发现项:9 必填字段 + rule_id,(file,line,category) 去重, <0.7 置信度进入人工复核桶 - 脱敏:三层(沙箱内 → 单条 finding → 全文档),48 样本 100% 检出、 报告与 DB 无明文 - 报告:中英双语 Markdown/JSON,含 7 个规定章节 - 全程离线可跑:--model-mode fake / --dry-run,无需 API Key 与 Docker - 测试:examples/skills_code_review_agent/tests 70 项全绿,flake8 通过 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1985563 to
1b8907d
Compare
AI Code Review这非常全面。脱敏测试非常稳健。 现在让我重新考虑一下最后一个真正的问题: 让我重新考虑一下 现在,一个真正的潜在问题: 让我重新考虑一下值得报告的最实质性问题。实际上,仔细看 好的。让我完成审查。基于我的彻底阅读,代码质量很高,测试也很全面。让我找出真正值得报告的问题。 真正的问题 1 (警告) — 真正的问题 2 (警告) — 让我重新考虑一下 所以治理机制是没问题的。让我重新考虑一下是否还有其他真正的问题。 真正的问题 3 (建议) — 让我重新考虑一下 让我最终确定下来。我将报告脱敏字典键的问题作为警告,也许还有 for code_file in files:
if code_file.truncated:
break
return json.loads(code_file.content)这会在第一个未截断的文件上返回。如果文件被截断了,它会中断并进入主机读取流程。由于 让我检查一下 现在让我重新考虑一下 让我也重新考虑一下 让我最终确定报告。我也重新考虑一下 现在让我写下审查意见。让我重新考虑严重性。脱敏字典键的问题:作为键的凭证会泄漏。现实影响是真实存在的,但概率很低。警告等级是合适的。 让我重新考虑一下是否还有我遗漏的更关键的问题。让我重新阅读 但这里有一个真正的问题:当沙箱被阻塞时(第 198-208 行), 让我完成审查。让我重新考虑一下 最终答案。让我重新考虑一下建议的数量 —— 保持在 ≤2 条。我将报告 1 个警告(脱敏键)和 1 个建议(最实质的一条)。 让我重新考虑一下最实质性的建议。 实际上,让我重新考虑一下是否还有其他真正有价值的问题。让我重新考虑一下 但这里有一个真正的微妙问题: 好的,最终定稿。让我再重新考虑一下 鉴于指令要求“如果没有发现明确问题,请直接说明‘未发现明显阻塞问题’”,但这里有一个真正(尽管很小)的问题。让我报告这个脱敏键的缺口作为一个警告,因为设计明确承诺对“全部入库字段”进行递归脱敏,而字典键打破了这一保证——这是一个可验证的、与设计声明相矛盾的缺口。 让我最后再重新考虑一下 我也再重新考虑一下 最终定稿。其实还有一个:让我重新检查一下 现在, 让我最终确定并输出。我将报告:
让我重新考虑一下 —— 其实让我重新考虑一下 正在编写输出。## 发现的问题
|
PR: 基于 Skills + 沙箱 + 数据库的自动代码评审 Agent (#92)
PR: Automatic Code-Review Agent with Skills + Sandbox + Database (#92)
feat/92-code-review-agent→main1b8907da3f4c7af51cd53967985fd17d0ea2df5c(单提交,64 files, +6065 lines)docs/patches/issue-92/0001-feat-Skills-DB-92.patchexamples/skills_code_review_agent/一、摘要 / Summary
中文:新增示例
examples/skills_code_review_agent/——一个可离线验证的自动代码评审Agent 原型。它读取 git diff / PR patch / 本地变更目录,经 code-review Skill
加载规则与脚本,通过 Filter 治理链(真实
BaseFilter+run_filters)放行后,在沙箱(container 生产默认 / Cube-E2B / local 开发回退)中执行检查脚本,将结构化
findings、拦截记录、沙箱日志与监控指标全部写入 SQLAlchemy 五表 schema,最终输出
中英双语
review_report.json+review_report.md。全链路支持--dry-run(fakemodel + local 沙箱),无任何 API Key、无 Docker 也能完整跑通并通过 70 项测试。
English: Adds
examples/skills_code_review_agent/— an offline-verifiableautomatic code-review agent prototype. It ingests a git diff / PR patch / local
change set, loads rules and scripts through a code-review Skill, passes a
Filter governance chain (real
BaseFilter+run_filters), executes checksinside a sandbox (container as production default / Cube-E2B / local as dev
fallback), persists structured findings, filter events, sandbox logs and
telemetry metrics into a five-table SQLAlchemy schema, and renders bilingual
review_report.json+review_report.md. The whole pipeline runs under--dry-run(fake model + local sandbox) with zero API keys and zero Docker,covered by 70 tests.
二、动机 / Motivation
中文:Issue #92 的难点不是“让 LLM 评论代码”,而是把 SDK 的 Skills、
CodeExecutor 沙箱、SQL Storage、Filter、Telemetry 六大能力串成一个可验证系统:
风险识别可复现、执行有安全边界、每一步决策可审计可回放。本 PR 给出一个端到端参考
实现,同时演示了这些 SDK 模块的组合姿势(对齐
examples/claude_agent_with_skills、examples/code_executors、examples/filter_with_agent的既有习惯用法)。English: The hard part of issue #92 is not "LLM comments on code" but wiring
the SDK's Skills, CodeExecutor sandboxes, SQL storage, Filters and Telemetry
into one verifiable system: reproducible risk detection, hard safety
boundaries around execution, and a fully auditable/replayable decision trail.
This PR provides an end-to-end reference implementation, mirroring the idioms of
the existing
claude_agent_with_skills,code_executorsandfilter_with_agentexamples.三、设计 / Design
关键决策 / Key decisions
密钥正则表全部在
skills/code-review/scripts/lib/(纯 Python 标准库)。沙箱内直接执行这份代码;宿主端通过 importlib 加载同一份文件做回退检测与脱敏——检测
逻辑与脱敏规则永不漂移。Sandbox executes these files directly; the host loads
the very same files via importlib for fallback detection and redaction — no
drift possible.
create_sandbox_runtime("container"|"cube"|"local")。container(Docker,create_container_workspace_runtime)为生产默认;cube走 Cube/E2B 云沙箱(惰性导入);local仅为开发 fallback,且用EnvWhitelistLocalProgramRunner强制环境变量白名单(金丝雀测试证明TRPC_AGENT_API_KEY永不进入子进程)。Container is the documented productiondefault; local is dev-only and env-whitelisted.
落为
cr_sandbox_run行(status/exit_code/timed_out/error_type/脱敏 stderr 摘录),随后自动回退到宿主内规则引擎——评审任务永不崩溃(AC4)。
SandboxGovernanceFilter走 SDK 真实BaseFilter/run_filters链,做 5 项前置检查(高风险脚本内容、非白名单命令、禁止路径、网络访问、运行次数/时间预算)。
deny/needs_human_review通过rsp.rsp=PolicyDecision, is_continue=False短路,终端 handler 不被调用;拦截原因写入报告与
cr_filter_event表(AC7 / R8)。finding 二次脱敏 → 报告/入库前全文档扫描。48 条密钥语料 100% 检出(含 AWS、
GitHub classic + fine-grained PAT、GitLab、Slack、OpenAI、JWT、PEM、Azure
conn-string、
:=赋值等),报告与 sqlite 文件字节级扫描无明文(AC5)。(file, line, category)唯一,保最高severity/confidence 代表项并把并列规则合入
extra.also_matched;置信度 < 0.7的启发式结果进入
needs_human_review独立桶(DB 有独立 bucket 列),绝不混入高置信 findings(R6)。
ReviewStoreABC + SDK 可移植列类型;SQLite 默认,换 MySQL/PostgreSQL 只改 SQLAlchemy URL;
init-db幂等(create_all + 前向列迁移)。
--model-mode fake|real|off。fake 与 real驱动完全相同的
LlmAgent+Runner路径;real 用OpenAIModel读TRPC_AGENT_*环境变量。规则检测本身不依赖 LLM,模型只做摘要增强。数据库 Schema / Database schema(5 tables)
cr_review_taskcr_sandbox_runcr_filter_eventcr_findingcr_report四、验收标准对照表 / Acceptance-Criteria Mapping
fixtures/8 条(clean、security、async-leak、db-lifecycle、missing-tests、duplicate、sandbox-failure、secret-redaction);CLIreview --fixture X --dry-run每次产出review_report.json+.md;沙箱失败样本经--inject-sandbox-failure演示失败路径(completed_with_errors,报告照常渲染)tests/test_fixtures_e2e.py(8 fixtures 参数化全跑,逐条断言预期 findings)needs_human_review,不污染高置信 findingstests/test_rules.py(labeled corpus)codereview/store/models.py)+ReviewStore.get_task_bundle(task_id);CLIshow --task-id返回全链路 bundle;init-db幂等tests/test_store.py;tests/test_cli_and_report.pycodereview/sandbox.py:wall-clock 超时击杀、stdout/stderr 字节上限 + 截断标志、环境白名单;失败落cr_sandbox_run行并宿主回退,任务收敛为completed_with_errorstests/test_sandbox_safety.py(超时、截断、金丝雀、强制失败、broken-runtime OSError、workspace 清理)review_report.json/.md与原始 sqlite 文件做字节级明文扫描tests/test_redaction.py;tests/test_fixtures_e2e.py(secret_redaction fixture)--dry-run= fake model + local 沙箱;实测管线 0.3–1.3 s/fixture(含解释器与 SDK 导入的冷启动 ~40 s,env -i空环境验证零 Key 依赖)tests/test_cli_and_report.py::test_dry_run_speed_and_no_api_key(删除全部 Key 环境变量后断言 <120 s)codereview/governance.py(SandboxGovernanceFilter,5 项检查);handler 哨兵证明被拒内容从未执行;拦截原因入报告 +cr_filter_eventtests/test_governance_filter.py(含 pipeline 级 e2e:拦截同时出现在报告与 DB,沙箱运行数为 0,宿主回退仍出 findings)codereview/report.py:Findings 摘要 / 严重级别统计 / 人工复核项 / Filter 拦截摘要 / 监控指标 / 沙箱执行摘要 / 修复建议(编号、可执行、按严重级别排序),中英双语tests/test_cli_and_report.py::test_report_sections_complete具体要求 R1–R9 / Detailed requirements
skills/code-review/:SKILL.md + 6 条规则文档(安全/异步/资源泄漏/测试缺失/密钥泄漏/DB 生命周期)+scripts/(parse_diff.py、run_checks.py、纯标准库lib/)codereview/sandbox.py::create_sandbox_runtime;`--sandbox containercodereview/inputs.py+diff_parser.py;支持 rename、binary、CRLF、\ No newline、删除文件等边界ReviewStoreABC +init_db.py(幂等)(file,line,category)唯一;<0.7 →needs_human_review桶sandbox.py+redaction.py三层脱敏 +cr_sandbox_run失败行governance.py5 项检查;报告**deny**表 +cr_filter_event.reasonscr_report.metrics:total/sandbox 耗时、工具调用数、拦截数、finding 数、severity 分布、error_types 分布;每阶段 tracer span五、离线运行方法 / How to Run Offline
无需 API Key、无需 Docker、无需网络。/ No API key, no Docker, no network.
六、示例输出路径 / Sample-Output Paths
examples/skills_code_review_agent/sample_output/review_report.jsonexamples/skills_code_review_agent/sample_output/review_report.mdreview在输出目录生成review_report.json+review_report.md,并全部落入 SQLite(
cr_report.report存完整 JSON,可按 task id 回放)。examples/skills_code_review_agent/fixtures/*.diff(8 条)。七、已知边界 / Known Boundaries(均已在 README/DESIGN 中声明)
--sandbox可选,但本开发主机无Docker daemon / E2B key,无法实机执行;按题意 local 仅为 dev fallback,文档已
将 container 标注为生产默认。/ Docker & E2B paths are code-complete but not
executable on the dev host; container is the documented production default.
--model-mode real(OpenAIModel viaTRPC_AGENT_*)代码完备但未用真实 Key演练;fake 模式驱动完全相同的
LlmAgent+Runner路径。FP 0%),README 验收表中明示。
八、测试结果 / Test Results
独立验证记录 / independent verification record:
docs/verify/issue-92-verification.md(含验证期加固:密钥正则补强至独立 25 条语料 100% 检出、pipeline 级治理 e2e、CLI 输入错误优雅退出)。
🤖 Generated with Claude Code
评审后更新 / Post-review update(2026-07-19)
独立对抗式评审证实 2 个 major(均为开箱体验)+ 5 个 minor,全部修复:
out/但目录未创建 →_resolve_db_url返回默认 URL 前先os.makedirs(覆盖init-db)。review→out/review.db,show/list/init-db→./review.db,文档流程报 task not found)→ 统一为out/review.db;+1 条 CLI 回归测试(空目录里 review→show→list 全默认参数走通,修复前确认失败)。_persisted标志泄漏进公开报告 JSON → 嵌入报告前剥离下划线内部键(样例报告同步清理)。.env并不会被自动加载 → README/.env.example 改为set -a; source .env; set +a/export 指引(不引入 dotenv 依赖)。python3(Windows 无此名)→ 本地运行时改用sys.executable(容器运行时不变)。SandboxConfig默认container,CLI--sandbox默认auto(检测 docker,缺失时显式警告回退 local);本机(无 docker)实测回退路径日志正确。测试:71/71 全绿(+1),flake8 clean。
(EN) Post-review update 2026-07-19: an independent adversarial review (6 parallel judges, execution-backed verification) confirmed 2 majors (fresh-checkout crash on default DB dir; inconsistent default DB paths across subcommands) and 5 minors — incl. making container the sandbox default with auto-detected, clearly-logged local fallback per the issue's acceptance criteria; all items fixed as listed above, full suite green (pytest 71/71, flake8 clean).