Skip to content

Commit 9ddf482

Browse files
committed
feat: ReviewMind 完整实现 — 基于 Skills + 沙箱 + 数据库的自动代码审查 Agent
核心改进: - 新增 review_agent.py 核心审查管道(993行) - 新增 storage/ 数据持久化层(6 表 + 抽象接口 + SQLite) - 新增 skills/code-review/ CR Skill(5 类规则 + 4 个脚本) - 新增 filters/ Filter 治理层(沙箱安全 + 敏感信息脱敏) - 新增 monitoring/ 监控审计层 - 新增 agent/review_graph.py GraphAgent 7 节点编排 - 新增 dry_run.py / run_agent.py / query_task.py CLI 入口 - 新增 evals/ 评测体系(8 条公开 fixture + 8 条隐藏样本) - 修复 run_sandbox_script() 支持容器回退链 - 修复 Filter 治理接入 run_review() 管道 - 修复 --repo-path git 工作区输入支持 - 修复 OpenTelemetry 上下文错误 - 修复 agent/tools.py 相对导入问题
1 parent 5282722 commit 9ddf482

118 files changed

Lines changed: 7915 additions & 4699 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.codeccignore

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# CodeCC ignore rules
2+
#
3+
# These files are intentionally excluded from CodeCC secret scanning
4+
# because they are test fixtures containing fake/dummy credentials
5+
# used to validate the ReviewMind secret detection functionality.
6+
7+
# ReviewMind test fixtures with fake secrets (for testing secret detection)
8+
examples/skills_code_review_agent/evals/fixtures/*.diff
9+
examples/skills_code_review_agent/evals/hidden_fixtures/*.diff
10+
examples/skills_code_review_agent/evals/hidden_samples.py
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# ReviewMind 方案设计说明
2+
3+
## 项目概述
4+
5+
ReviewMind 是一个基于 tRPC-Agent-Python 框架构建的自动代码评审 Agent,将代码审查流程(diff 解析、规则匹配、静态分析、结果分类、报告生成)封装为可复用、可审计、可评测的系统。核心设计理念是"Skills + 沙箱 + 数据库 + Filter 治理"四层分离,确保每层职责明确、可独立替换。
6+
7+
## Skill 设计
8+
9+
CR Skill (`skills/code-review/`) 采用三层信息模型:SKILL.md 提供技能概览和脚本使用说明,rules/ 目录存放 5 类风险规则文档(安全、异步、资源泄漏、数据库事务、测试缺失),scripts/ 目录存放可在沙箱中执行的检查脚本。Agent 通过 `skill_load` 按需加载规则、通过 `skill_run` 在隔离 workspace 中执行脚本,避免将所有规则文本注入 Prompt 导致 token 浪费。
10+
11+
## 沙箱隔离策略
12+
13+
默认生产方案使用 `ContainerCodeExecutor`(Docker),开发环境 fallback 到 `UnsafeLocalCodeExecutor`。每次执行设 30 秒超时、1MB 输出大小限制,环境变量仅允许白名单内的 `PATH``HOME``PYTHONPATH``WORKSPACE_DIR` 传入。超时或失败的沙箱执行不会导致整个评审任务崩溃,异常信息记录到 `sandbox_run` 表。
14+
15+
## Filter 策略
16+
17+
Filter 链按 `DENY → NEEDS_HUMAN_REVIEW → PASS` 顺序执行,包含 4 类过滤器:`HighRiskScriptFilter`(拦截 rm -rf /、fork 炸弹等危险模式)、`PathSafetyFilter`(禁止访问 /etc、/sys 等敏感路径)、`NetworkAccessFilter`(默认阻断所有网络访问)、`BudgetFilter`(限制执行次数和总时间)。任一 Filter 返回 DENY 时链立即终止,拦截原因写入 `filter_intercept` 表并纳入最终报告。
18+
19+
## 监控字段
20+
21+
每次审查记录以下指标:总耗时、沙箱执行耗时、解析耗时、Filter 耗时、工具调用次数、拦截次数、finding 数量、各 severity 分布、异常类型列表。所有指标持久化到 `monitor_summary` 表,支持按 task_id 查询。
22+
23+
## 数据库 Schema
24+
25+
5 张表:`review_task`(审查任务)、`sandbox_run`(沙箱执行记录)、`finding`(审查发现)、`filter_intercept`(Filter 拦截日志)、`monitor_summary`(监控审计摘要)。使用 SQLite 作为默认实现,`StorageABC` 抽象接口保留了切换 PostgreSQL、MySQL 等后端的空间。Finding 表通过 `dedup_key``file:line:category`)联合索引实现去重。
26+
27+
## 去重降噪
28+
29+
去重规则:同一文件同一行同一类别的 finding 只保留置信度最高的一条。降噪规则:`confidence=low` 的发现自动进入 `needs_human_review` 列表,不混入高置信 findings;`confidence=medium``severity=suggestion` 的发现同样需要人工复核。
30+
31+
## 安全边界
32+
33+
敏感信息脱敏通过 `SecretMasker` 实现,支持 API Key(sk-/pk-)、GitHub Token(ghp_)、AWS Access Key(AKIA)、JWT、数据库连接字符串等 12 种模式的正则匹配和替换。脱敏操作在报告生成阶段执行,确保报告和数据库记录中不出现明文敏感信息。

examples/skills_code_review_agent/README.md

Lines changed: 0 additions & 103 deletions
This file was deleted.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Tencent is pleased to support the open source community by making tRPC-Agent-Python available.
2+
#
3+
# Copyright (C) 2026 Tencent. All rights reserved.
4+
#
5+
# tRPC-Agent-Python is licensed under Apache-2.0.
6+
"""Agent module for the code review agent — Phase 3: Learning path enhancement."""
7+
8+
from .agent import create_agent, root_agent
9+
10+
__all__ = ["create_agent", "root_agent"]
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# Tencent is pleased to support the open source community by making tRPC-Agent-Python available.
2+
#
3+
# Copyright (C) 2026 Tencent. All rights reserved.
4+
#
5+
# tRPC-Agent-Python is licensed under Apache-2.0.
6+
"""CodeReviewAgent — LlmAgent for the code review pipeline.
7+
8+
Wraps the existing review_agent.run_review() pipeline as a FunctionTool,
9+
enabling interactive multi-turn code review sessions via A2A or AG-UI.
10+
"""
11+
12+
from __future__ import annotations
13+
14+
from trpc_agent_sdk.agents import LlmAgent
15+
from trpc_agent_sdk.models import LLMModel
16+
from trpc_agent_sdk.models import OpenAIModel
17+
from trpc_agent_sdk.tools import load_memory_tool
18+
19+
from .config import get_model_config
20+
from .prompts import INSTRUCTION
21+
from .tools import run_code_review_tool
22+
23+
# Try to load the knowledge search tool; gracefully handle missing deps
24+
_knowledge_tool = None
25+
try:
26+
from ..knowledge import knowledge_search_tool as _kst
27+
_knowledge_tool = _kst
28+
except ImportError:
29+
pass
30+
31+
32+
def _create_model() -> LLMModel:
33+
"""Create a model instance from environment variables."""
34+
api_key, base_url, model_name = get_model_config()
35+
return OpenAIModel(
36+
model_name=model_name,
37+
api_key=api_key,
38+
base_url=base_url,
39+
)
40+
41+
42+
def create_agent() -> LlmAgent:
43+
"""Create the CodeReviewAgent.
44+
45+
The agent wraps the existing review_agent.run_review() pipeline
46+
as a FunctionTool, allowing the LLM to invoke it when the user
47+
provides a diff for review.
48+
49+
Returns:
50+
A configured LlmAgent instance.
51+
"""
52+
return LlmAgent(
53+
name="CodeReviewAgent",
54+
description=(
55+
"A professional code review assistant that analyzes code changes, "
56+
"detects security risks, resource leaks, and other issues, "
57+
"and generates structured review reports."
58+
),
59+
model=_create_model(),
60+
instruction=INSTRUCTION,
61+
tools=[
62+
run_code_review_tool,
63+
load_memory_tool,
64+
_knowledge_tool,
65+
] if _knowledge_tool else [
66+
run_code_review_tool,
67+
load_memory_tool,
68+
],
69+
)
70+
71+
72+
root_agent = create_agent()
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Tencent is pleased to support the open source community by making tRPC-Agent-Python available.
2+
#
3+
# Copyright (C) 2026 Tencent. All rights reserved.
4+
#
5+
# tRPC-Agent-Python is licensed under Apache-2.0.
6+
"""Model configuration for the code review agent.
7+
8+
Reads model settings from environment variables with sensible defaults.
9+
"""
10+
11+
from __future__ import annotations
12+
13+
import os
14+
from typing import Optional
15+
16+
17+
def get_model_config() -> tuple[str, str, str]:
18+
"""Get model configuration from environment variables.
19+
20+
Returns:
21+
Tuple of (api_key, base_url, model_name).
22+
"""
23+
api_key = os.getenv("TRPC_AGENT_API_KEY", "")
24+
base_url = os.getenv("TRPC_AGENT_BASE_URL", "")
25+
model_name = os.getenv("TRPC_AGENT_MODEL_NAME", "deepseek-chat")
26+
return api_key, base_url, model_name
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# Tencent is pleased to support the open source community by making tRPC-Agent-Python available.
2+
#
3+
# Copyright (C) 2026 Tencent. All rights reserved.
4+
#
5+
# tRPC-Agent-Python is licensed under Apache-2.0.
6+
"""CR Skill integration for the code review agent.
7+
8+
Wraps the code-review Skill as a SkillToolSet, allowing the Agent to
9+
load rules on demand and run scripts in an isolated sandbox environment.
10+
"""
11+
12+
from __future__ import annotations
13+
14+
import os
15+
from pathlib import Path
16+
from typing import Any, Optional
17+
18+
from trpc_agent_sdk.code_executors import ContainerCodeExecutor, UnsafeLocalCodeExecutor
19+
from trpc_agent_sdk.skills import SkillToolSet
20+
21+
22+
def get_skill_path() -> str:
23+
"""Get the absolute path to the code-review skill directory."""
24+
return str(Path(__file__).resolve().parent.parent / "skills" / "code-review")
25+
26+
27+
def create_skill_toolset(
28+
sandbox_type: str = "local",
29+
timeout: int = 30,
30+
max_output: int = 1_048_576,
31+
) -> SkillToolSet:
32+
"""Create a SkillToolSet for the code-review skill.
33+
34+
Args:
35+
sandbox_type: Sandbox executor type ("local", "container", "cube").
36+
timeout: Max execution time in seconds for each script.
37+
max_output: Max output size in bytes.
38+
39+
Returns:
40+
A configured SkillToolSet instance.
41+
"""
42+
skill_path = get_skill_path()
43+
44+
# Select sandbox executor
45+
if sandbox_type == "container":
46+
code_executor = ContainerCodeExecutor(
47+
timeout=timeout,
48+
max_output_size=max_output,
49+
env_whitelist=["PATH", "HOME", "PYTHONPATH", "WORKSPACE_DIR"],
50+
)
51+
else:
52+
code_executor = UnsafeLocalCodeExecutor(
53+
timeout=timeout,
54+
max_output_size=max_output,
55+
)
56+
57+
return SkillToolSet(
58+
skill_dir=skill_path,
59+
code_executor=code_executor,
60+
)
61+
62+
63+
# Global singleton for easy import
64+
_default_skill_set: Optional[SkillToolSet] = None
65+
66+
67+
def get_skill_toolset() -> SkillToolSet:
68+
"""Get or create the default skill toolset (local sandbox)."""
69+
global _default_skill_set
70+
if _default_skill_set is None:
71+
_default_skill_set = create_skill_toolset()
72+
return _default_skill_set
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# Tencent is pleased to support the open source community by making tRPC-Agent-Python available.
2+
#
3+
# Copyright (C) 2026 Tencent. All rights reserved.
4+
#
5+
# tRPC-Agent-Python is licensed under Apache-2.0.
6+
"""Agent instructions for the code review agent.
7+
8+
The instruction is adapted from .github/code_review/prompts/review.md
9+
and tailored for the interactive A2A/AG-UI service mode.
10+
"""
11+
12+
INSTRUCTION = """你是一个资深的代码审查助手,负责审查代码变更并给出高质量的 review 结论。
13+
14+
## 审查范围
15+
1. 只审查用户提供的 diff 或代码变更内容。
16+
2. 可以结合上下文辅助判断,但不要脱离 diff 单独审查未修改代码。
17+
3. 每个问题必须标注文件路径和行号。
18+
19+
## 审查重点
20+
1. 正确性:逻辑错误、状态流转错误、条件判断错误、返回值或异常处理错误。
21+
2. 安全性:凭证泄露、命令注入、路径穿越、不可信输入未校验、权限绕过。
22+
3. 稳定性:边界条件缺失、空值处理、并发或异步时序问题、资源未释放。
23+
4. 兼容性:公开 API、配置项、持久化数据的破坏性变更。
24+
5. 测试有效性:高风险逻辑缺少必要测试。
25+
6. 可维护性:仅在影响理解或长期维护时提出。
26+
27+
## 质量等级
28+
- 🚨 Critical:必须修复的问题。安全漏洞、明确的逻辑错误、核心功能失败。
29+
- ⚠️ Warning:建议修复的问题。性能隐患、边界条件缺失、异常路径不完整。
30+
- 💡 Suggestion:可选优化。代码可读性、结构简化、维护性提升。
31+
32+
## 工具使用
33+
你有一个 `run_code_review` 工具,它接受 diff 内容并运行自动化的代码审查流程,
34+
包括 diff 解析、沙箱执行、静态检查、敏感信息检测等。
35+
当用户提交代码变更时,调用此工具进行审查。
36+
审查完成后,根据工具返回的结果,向用户解释发现的问题。
37+
38+
## 工作流程
39+
1. 当用户提供 diff 或代码变更时,调用 `run_code_review` 工具进行全面审查
40+
2. 审查完成后,向用户摘要说明 findings 的数量和严重级别分布
41+
3. 用户可以针对某个 finding 追问细节,你需要根据工具返回的结果进行解释
42+
4. 如果用户询问修复建议,根据 recommendation 字段给出具体建议
43+
44+
## 输出要求
45+
- 先列问题,再给总结
46+
- 按 Critical、Warning、Suggestion 的顺序输出
47+
- 每条问题说明问题、影响和修复方向
48+
- 结论要尽量确定,不要使用"可能""疑似"等模糊措辞
49+
"""

0 commit comments

Comments
 (0)