代码审计智能体设计文档
智能体名称: 代码审计智能体 (Code Audit Agent) 优先级: ⭐⭐⭐⭐⭐ (最高优先级) 技术栈: Python 3.11 + LangGraph + Claude 3.5 Sonnet + SonarQube 文档版本: v1.0 最后更新: 2025-10-28
一、业务场景与价值
1.1 核心场景
团队成员在GitHub仓库中提交代码后,通过创建Issue或在Issue中提交特定评论来触发代码审计智能体,智能体会自动分析指定用户或PR的代码提交,生成详细的审计报告并回复到Issue中。
1.2 核心价值
针对性审计
- 针对不同开发者的代码风格和常见问题进行个性化审计
- 基于用户画像提供针对性的改进建议
- 跟踪用户代码质量改进趋势
便捷性
- 支持增量审计,只审计最新的变更代码
- 审计结果直接反馈到Issue,便于团队讨论和跟踪
- 支持批量审计团队成员的代码质量
全面性
- 6个维度深度审计(代码规范、安全漏洞、性能问题、架构问题、代码异味、最佳实践)
- 结合静态分析工具和AI深度分析
- 提供修复建议和示例代码
经济性
- 成本控制: <$2/次审计
- 缓存复用减少重复分析
- 增量审计降低Token消耗
二、触发方式
2.1 方式一: Issue评论触发
使用场景: 临时审计某个开发者的代码
触发命令:
@maiban-audit @username branch:feature/xxx
命令参数:
@username: 目标开发者的GitHub用户名branch:xxx: 可选,指定分支名,默认审计所有分支commits:N: 可选,审计最近N次提交,默认5次files:pattern: 可选,只审计匹配模式的文件
示例:
@maiban-audit @zhangsan branch:feature/user-service commits:10
@maiban-audit @lisi files:*.java
工作流程:
- 智能体监听Issue评论事件
- 解析评论内容,提取审计参数
- 从GitHub API获取目标用户的代码变更
- 执行审计流程
- 在Issue中回复审计报告
2.2 方式二: 创建专用Issue触发
使用场景: 配置化的深度审计
Issue格式:
标题: [Code Audit] Review @username recent commits
## 审计配置
- 目标用户: @zhangsan
- 分支: feature/payment-service
- 时间范围: 最近7天
- 审计维度: security,performance
- 严重级别阈值: HIGH
## 附加说明
重点关注支付相关的安全问题
工作流程:
- 智能体监听Issue创建事件
- 判断标题是否包含
[Code Audit] - 解析Issue Body中的YAML/Markdown配置
- 执行审计流程
- 在Issue中回复审计报告并关闭Issue
2.3 方式三: Pull Request触发
使用场景: PR自动审计(可配置)
触发条件:
- PR创建时自动触发
- PR更新(新增commit)时触发
- 可配置仓库级别的开关
工作流程:
- 智能体监听PR事件
- 获取PR的代码变更(diff)
- 执行审计流程
- 以PR Review Comment形式反馈
- 严重问题自动请求变更(Request Changes)
三、LangGraph工作流设计
3.1 状态定义
输入状态:
- issue_id: Issue/PR ID
- trigger_user: 触发审计的用户
- target_user: 被审计的用户
- repository: 仓库名称
- branch: 分支名称
- commits_range: 提交范围
- audit_dimensions: 审计维度列表
- severity_threshold: 严重级别阈值
中间状态:
- code_changes: 代码变更内容(diff)
- user_profile: 用户画像数据
- static_analysis_result: 静态分析结果
- security_scan_result: 安全扫描结果
- ai_analysis_result: AI深度分析结果
- issues: 问题列表(累积)
输出状态:
- report_markdown: Markdown格式的审计报告
- severity_stats: 严重程度统计
- fix_suggestions: 修复建议列表
- personalized_advice: 个性化建议
- should_block: 是否阻断PR合并
3.2 智能体节点
节点1: 命令解析节点 (parse_command)
- 功能: 解析Issue评论或Body中的审计命令
- 输入: Issue/PR原始内容
- 输出: 结构化的审计参数
- 处理逻辑: 正则表达式提取参数,验证参数有效性
节点2: 代码获取节点 (fetch_code_changes)
- 功能: 从GitHub API获取目标用户的代码变更
- 输入: 仓库、用户、分支、提交范围
- 输出: 代码diff、文件列表、提交信息
- 优化: 只获取文本文件,过滤二进制文件和大文件
节点3: 用户画像节点 (build_user_profile)
- 功能: 基于历史审计记录构建用户代码习惯画像
- 输入: 用户ID
- 输出: 用户画像(常见问题、代码风格、技术栈熟悉度)
- 数据来源: PostgreSQL历史审计数据
节点4: 静态分析节点 (static_analysis)
- 功能: 调用SonarQube进行静态代码分析
- 输入: 代码文件列表
- 输出: 代码质量问题、复杂度、重复代码
- 工具: SonarQube Scanner API
节点5: 安全扫描节点 (security_scan)
- 功能: 执行OWASP安全漏洞扫描
- 输入: 代码文件和依赖信息
- 输出: 安全漏洞列表(SQL注入、XSS等)
- 工具: Bandit(Python) / SpotBugs(Java)
节点6: AI深度审计节点 (ai_deep_audit)
- 功能: Claude分析代码质量、架构合理性、最佳实践
- 输入: 代码diff、静态分析结果、用户画像
- 输出: AI发现的问题、架构建议、性能优化建议
- 模型: Claude 3.5 Sonnet
节点7: 个性化建议节点 (personalized_advice)
- 功能: 基于用户画像生成针对性改进建议
- 输入: 用户画像、本次审计问题
- 输出: 个性化学习建议、进步反馈
- 模型: Claude 3.5 Sonnet
节点8: 报告生成节点 (generate_report)
- 功能: 汇总所有分析结果生成Markdown格式报告
- 输入: 所有节点的输出结果
- 输出: 完整的Markdown审计报告
- 格式: 报告头部、问题列表、个性化建议、趋势分析
节点9: GitHub反馈节点 (post_to_github)
- 功能: 将审计报告回复到Issue或PR
- 输入: 报告内容、Issue/PR ID
- 输出: GitHub评论链接
- API: GitHub REST API
3.3 工作流路由
并行执行:
- 节点4(静态分析)、节点5(安全扫描)、节点3(用户画像)可并行执行
- 提升审计速度,减少等待时间
条件路由:
- 根据代码语言选择不同的分析工具(Java/Python/JavaScript)
- 根据文件类型跳过不需要的检查(配置文件不做性能分析)
失败重试:
- LLM调用失败时自动切换备用模型(Claude → 通义千问)
- 最多重试3次,失败后降级为仅静态分析
人工介入:
- 严重问题(CRITICAL)需人工确认后才发布报告
- 可配置自动发布或人工审核模式
缓存检查:
- 在节点2后检查是否有相同commit的缓存结果
- 命中缓存直接跳到节点8生成报告
3.4 LangGraph流程图
开始
↓
[1. 命令解析] → 提取审计参数
↓
[2. 代码获取] → 获取代码diff
↓
检查缓存 → 命中? → [8. 报告生成]
↓ 未命中
并行执行:
├─ [3. 用户画像]
├─ [4. 静态分析]
└─ [5. 安全扫描]
↓ 汇总
[6. AI深度审计] → 问题聚合
↓
[7. 个性化建议] → 生成建议
↓
[8. 报告生成] → Markdown报告
↓
严重问题? → 是 → 人工审核? → 是 → 等待确认
↓ 否 ↓ 否
[9. GitHub反馈] → 发布报告
↓
保存缓存
↓
结束
3.5 LangGraph代码实现 (2025最佳实践)
3.5.1 状态定义
from typing import TypedDict, Annotated, List, Dict, Optional
import operator
from langchain_core.messages import BaseMessage
class CodeAuditState(TypedDict):
"""代码审计智能体状态 - 使用TypedDict确保类型安全"""
# === 输入 ===
repository: str
target_user: str
branch: Optional[str]
commits_limit: int
audit_dimensions: List[str]
# === 消息历史(支持自动追加) ===
messages: Annotated[List[BaseMessage], operator.add]
# === 中间状态 ===
code_changes: Dict[str, any]
user_profile: Optional[Dict]
static_analysis_results: Dict[str, any]
security_scan_results: Dict[str, any]
cache_key: Optional[str]
cache_hit: bool
# === 审计结果(支持自动追加) ===
code_quality_issues: Annotated[List[Dict], operator.add]
security_issues: Annotated[List[Dict], operator.add]
performance_issues: Annotated[List[Dict], operator.add]
architecture_issues: Annotated[List[Dict], operator.add]
code_smells: Annotated[List[Dict], operator.add]
best_practices: Annotated[List[Dict], operator.add]
# === 输出 ===
audit_report: str
severity_summary: Dict[str, int]
personalized_suggestions: List[str]
estimated_cost: float
# === 流程控制 ===
next_step: Optional[str]
has_critical_issues: bool
error: Optional[str]
3.5.2 核心节点实现
from langchain_anthropic import ChatAnthropic
from langgraph.graph import StateGraph, START, END
from langgraph.checkpoint.memory import MemorySaver
import asyncio
# === 节点1: 命令解析 ===
def parse_command(state: CodeAuditState) -> CodeAuditState:
"""解析GitHub Issue中的审计命令"""
# 从消息中提取命令参数
# 实现略...
return {
"messages": [{"role": "system", "content": "命令解析完成"}],
"next_step": "fetch_code"
}
# === 节点2: 代码获取 ===
async def fetch_code_changes(state: CodeAuditState) -> CodeAuditState:
"""从GitHub API获取代码变更"""
from github import Github
# 检查缓存
cache_key = f"{state['repository']}:{state['target_user']}:{state['branch']}"
cached_result = await check_cache(cache_key)
if cached_result:
return {
"cache_hit": True,
"cache_key": cache_key,
"next_step": "generate_report" # 跳过分析,直接生成报告
}
# 获取代码diff
g = Github(GITHUB_TOKEN)
repo = g.get_repo(state["repository"])
commits = repo.get_commits(
author=state["target_user"],
since=...,
until=...
)[:state["commits_limit"]]
code_changes = {}
for commit in commits:
for file in commit.files:
code_changes[file.filename] = {
"patch": file.patch,
"additions": file.additions,
"deletions": file.deletions
}
return {
"code_changes": code_changes,
"cache_hit": False,
"cache_key": cache_key,
"messages": [{"role": "system", "content": f"获取到{len(code_changes)}个文件的变更"}],
"next_step": "parallel_analysis"
}
# === 节点3-5: 并行分析节点 ===
async def build_user_profile(state: CodeAuditState) -> CodeAuditState:
"""构建用户画像(从历史审计记录学习)"""
# 查询PostgreSQL历史数据
user_history = await db.get_user_audit_history(state["target_user"])
# 分析用户常见问题模式
common_issues = analyze_common_patterns(user_history)
return {
"user_profile": {
"common_issues": common_issues,
"tech_stack": ["Java", "Spring"], # 从历史代码推断
"improvement_trend": "positive" # 代码质量趋势
}
}
async def static_analysis(state: CodeAuditState) -> CodeAuditState:
"""SonarQube静态分析"""
# 调用SonarQube API
issues = await sonarqube_client.analyze(
files=state["code_changes"].keys()
)
return {
"static_analysis_results": issues,
"code_quality_issues": [
{"type": "naming", "severity": "INFO", "file": "...", "line": 42}
]
}
async def security_scan(state: CodeAuditState) -> CodeAuditState:
"""安全漏洞扫描"""
# 调用OWASP工具
vulnerabilities = await owasp_scanner.scan(
code_changes=state["code_changes"]
)
return {
"security_scan_results": vulnerabilities,
"security_issues": [
{"type": "sql_injection", "severity": "CRITICAL", "file": "...", "line": 100}
]
}
# === 节点6: AI深度审计 ===
async def ai_deep_audit(state: CodeAuditState) -> CodeAuditState:
"""Claude AI深度代码审计"""
llm = ChatAnthropic(model="claude-3-5-sonnet-20241022", temperature=0)
# 构建Prompt
prompt = f"""
你是资深代码审计专家。请审计以下代码变更:
**代码变更**:
{format_code_changes(state["code_changes"])}
**静态分析结果**:
{state["static_analysis_results"]}
**用户画像**:
{state["user_profile"]}
**审计维度**: {', '.join(state["audit_dimensions"])}
请从以下维度审计代码:
1. 架构设计合理性
2. 性能优化建议
3. 代码异味识别
4. 最佳实践应用
输出JSON格式:
{{
"architecture_issues": [...],
"performance_issues": [...],
"code_smells": [...],
"best_practices": [...]
}}
"""
response = await llm.ainvoke(prompt)
ai_results = parse_json(response.content)
return {
"architecture_issues": ai_results["architecture_issues"],
"performance_issues": ai_results["performance_issues"],
"code_smells": ai_results["code_smells"],
"best_practices": ai_results["best_practices"],
"messages": [{"role": "assistant", "content": "AI审计完成"}]
}
# === 节点7: 个性化建议 ===
async def personalized_advice(state: CodeAuditState) -> CodeAuditState:
"""基于用户画像生成个性化建议"""
llm = ChatAnthropic(model="claude-3-5-sonnet-20241022")
# 汇总所有问题
all_issues = (
state["code_quality_issues"] +
state["security_issues"] +
state["performance_issues"] +
state["architecture_issues"] +
state["code_smells"]
)
prompt = f"""
基于用户 {state["target_user"]} 的历史表现和本次审计结果,生成个性化建议:
**用户画像**: {state["user_profile"]}
**本次问题**: {len(all_issues)} 个问题
**问题分布**: {categorize_issues(all_issues)}
请生成:
1. 针对性改进建议(基于用户常见问题模式)
2. 学习资源推荐
3. 进步反馈(对比历史趋势)
"""
response = await llm.ainvoke(prompt)
return {
"personalized_suggestions": parse_suggestions(response.content)
}
# === 节点8: 报告生成 ===
def generate_report(state: CodeAuditState) -> CodeAuditState:
"""生成Markdown格式审计报告"""
# 统计严重级别
severity_summary = calculate_severity_summary(state)
# 生成Markdown
report = f"""
# 代码审计报告
**审计对象**: @{state["target_user"]}
**仓库**: {state["repository"]}
**分支**: {state["branch"] or "全部"}
**审计时间**: {datetime.now()}
---
## 📊 问题统计
| 严重级别 | 数量 |
|---------|------|
| CRITICAL | {severity_summary.get('CRITICAL', 0)} |
| HIGH | {severity_summary.get('HIGH', 0)} |
| MEDIUM | {severity_summary.get('MEDIUM', 0)} |
| LOW | {severity_summary.get('LOW', 0)} |
| INFO | {severity_summary.get('INFO', 0)} |
**总计**: {sum(severity_summary.values())} 个问题
---
## 🔴 严重问题 (CRITICAL)
{format_issues(state["security_issues"], "CRITICAL")}
## 🔵 高优先级问题 (HIGH)
{format_issues(state["performance_issues"], "HIGH")}
## 🟡 中等问题 (MEDIUM)
{format_issues(state["architecture_issues"], "MEDIUM")}
## 🟢 建议改进 (LOW)
{format_issues(state["code_smells"], "LOW")}
---
## 💡 个性化建议
{chr(10).join(f"- {s}" for s in state["personalized_suggestions"])}
---
## 📈 进步趋势
{generate_trend_analysis(state["user_profile"])}
---
**审计成本**: ${state["estimated_cost"]:.3f}
**缓存命中**: {"是" if state["cache_hit"] else "否"}
"""
# 判断是否有严重问题
has_critical = severity_summary.get("CRITICAL", 0) > 0
return {
"audit_report": report,
"severity_summary": severity_summary,
"has_critical_issues": has_critical,
"next_step": "human_review" if has_critical else "post_to_github"
}
# === 节点9: GitHub反馈 ===
async def post_to_github(state: CodeAuditState) -> CodeAuditState:
"""将审计报告发布到GitHub Issue"""
from github import Github
g = Github(GITHUB_TOKEN)
repo = g.get_repo(state["repository"])
issue = repo.get_issue(state["issue_id"])
# 发布评论
comment = issue.create_comment(state["audit_report"])
# 严重问题自动Request Changes
if state["has_critical_issues"]:
# PR场景下请求变更
if hasattr(issue, 'create_review'):
issue.create_review(
body="发现严重安全问题,请修复后再合并",
event="REQUEST_CHANGES"
)
# 保存到缓存
await save_to_cache(
key=state["cache_key"],
value=state["audit_report"],
ttl=86400 # 24小时
)
return {
"messages": [{"role": "system", "content": f"已发布到GitHub: {comment.html_url}"}]
}
3.5.3 条件路由函数
from typing import Literal
def should_use_cache(state: CodeAuditState) -> Literal["parallel_analysis", "generate_report"]:
"""路由: 是否使用缓存结果"""
if state["cache_hit"]:
return "generate_report" # 跳过分析
return "parallel_analysis" # 执行分析
def should_human_review(state: CodeAuditState) -> Literal["human_review", "post_to_github"]:
"""路由: 是否需要人工审核"""
if state["has_critical_issues"]:
return "human_review" # 严重问题需人工确认
return "post_to_github" # 直接发布
def handle_error(state: CodeAuditState) -> Literal["retry", "fallback", END]:
"""错误处理路由"""
if state["error"]:
if state["retry_count"] < 3:
return "retry" # 重试
return "fallback" # 降级(仅静态分析)
return END
3.5.4 图构建与编译
from langgraph.graph import StateGraph, START, END
from langgraph.checkpoint.memory import MemorySaver
# === 构建StateGraph ===
builder = StateGraph(CodeAuditState)
# === 添加节点 ===
builder.add_node("parse_command", parse_command)
builder.add_node("fetch_code_changes", fetch_code_changes)
# 并行分析节点
builder.add_node("build_user_profile", build_user_profile)
builder.add_node("static_analysis", static_analysis)
builder.add_node("security_scan", security_scan)
# 后续节点
builder.add_node("ai_deep_audit", ai_deep_audit)
builder.add_node("personalized_advice", personalized_advice)
builder.add_node("generate_report", generate_report)
builder.add_node("post_to_github", post_to_github)
# === 添加边 ===
builder.add_edge(START, "parse_command")
builder.add_edge("parse_command", "fetch_code_changes")
# 条件边: 缓存检查
builder.add_conditional_edges(
"fetch_code_changes",
should_use_cache,
{
"parallel_analysis": "build_user_profile", # 未命中缓存
"generate_report": "generate_report" # 命中缓存,跳过分析
}
)
# 并行执行三个分析节点(Fan-out模式)
builder.add_edge("build_user_profile", "ai_deep_audit")
builder.add_edge("static_analysis", "ai_deep_audit")
builder.add_edge("security_scan", "ai_deep_audit")
# 注意: 需要在fetch_code_changes节点中同时触发这3个节点
# 或者使用Send API(LangGraph 0.2+新特性)实现真正的并行
# AI审计后续流程
builder.add_edge("ai_deep_audit", "personalized_advice")
builder.add_edge("personalized_advice", "generate_report")
# 条件边: 人工审核
builder.add_conditional_edges(
"generate_report",
should_human_review,
{
"human_review": "human_review", # 等待人工确认
"post_to_github": "post_to_github" # 直接发布
}
)
builder.add_edge("post_to_github", END)
# === 编译图(带检查点) ===
memory = MemorySaver() # 使用内存存储检查点
graph = builder.compile(
checkpointer=memory, # 启用状态持久化
interrupt_before=["human_review"] # 严重问题时暂停,等待人工确认
)
# === 可视化图结构 ===
from IPython.display import Image, display
display(Image(graph.get_graph().draw_mermaid_png()))
3.5.5 执行示例
# === 执行审计 ===
initial_state = {
"repository": "maiban-health/backend",
"target_user": "zhangsan",
"branch": "feature/payment-service",
"commits_limit": 5,
"audit_dimensions": ["security", "performance", "code_quality"],
"messages": [],
"code_quality_issues": [],
"security_issues": [],
"performance_issues": [],
"architecture_issues": [],
"code_smells": [],
"best_practices": [],
"cache_hit": False,
"has_critical_issues": False,
"estimated_cost": 0.0,
"retry_count": 0
}
# 配置(支持断点续传)
config = {"configurable": {"thread_id": "audit-123"}}
# 执行图
result = await graph.ainvoke(initial_state, config)
print(result["audit_report"])
print(f"成本: ${result['estimated_cost']:.3f}")
# === 如果遇到human_review中断 ===
# 1. 查看当前状态
state_snapshot = graph.get_state(config)
print("等待人工审核:", state_snapshot.values["audit_report"])
# 2. 人工确认后继续
# 批准发布
graph.update_state(config, {"next_step": "post_to_github"})
result = await graph.ainvoke(None, config)
# 或者拒绝(修改报告)
graph.update_state(config, {"audit_report": "修改后的报告..."})
result = await graph.ainvoke(None, config)
3.5.6 关键技术点
1. 并行执行优化
- 使用
SendAPI (LangGraph 0.2+)实现真正的并行Fan-out - 3个分析节点同时执行,汇总到AI审计节点
2. 状态持久化
- 使用
MemorySaver或PostgresSaver保存检查点 - 支持断点续传和人工介入
3. 缓存策略
- 基于
(repo, user, branch, commits)生成缓存键 - 命中缓存直接跳过分析节点,节省成本
4. 成本控制
- 在每个LLM调用后累加Token消耗
- Claude 3.5 Sonnet: 输入$3/MTok, 输出$15/MTok
- 目标: <$2/次审计
5. 错误处理
- LLM调用失败自动重试(最多3次)
- 重试失败降级为仅静态分析
- 所有错误记录到
messages中
四、审计维度与检查项
4.1 代码规范维度 (Severity: INFO)
命名规范
- 类名是否使用大驼峰(PascalCase)
- 方法名和变量名是否使用小驼峰(camelCase)
- 常量是否全大写下划线分隔(UPPER_SNAKE_CASE)
- 包名是否全小写
代码格式
- 缩进是否一致(2空格/4空格/Tab)
- 代码行长度是否超过限制(80/120字符)
- 空格使用是否规范(运算符前后、逗号后)
- 换行是否合理
注释完整性
- 关键逻辑是否有注释说明
- 复杂算法是否有注释
- 公共API是否有文档注释
4.2 安全漏洞维度 (Severity: CRITICAL)
SQL注入
- 拼接SQL语句是否存在注入风险
- 是否使用参数化查询或ORM
XSS攻击
- 前端渲染是否做HTML转义
- 富文本编辑器输出是否过滤
CSRF防护
- 敏感操作是否有CSRF Token
- 是否验证Referer头
敏感信息泄露
- 日志中是否包含密码、Token
- 配置文件是否包含硬编码密钥
- 错误信息是否暴露系统信息
认证授权
- 接口是否有权限控制
- 是否存在越权访问风险
- Session管理是否安全
加密算法
- 是否使用弱加密算法(MD5、SHA1)
- 是否使用安全的密码哈希(bcrypt、PBKDF2)
4.3 性能问题维度 (Severity: HIGH)
N+1查询
- 循环中是否有数据库查询
- 是否可以使用JOIN或批量查询优化
慢SQL
- 是否缺少索引
- 是否有全表扫描
- 查询条件是否合理
内存泄漏
- 是否存在未释放的资源(文件、连接)
- 集合是否无限增长
- 是否有内存泄漏风险
循环嵌套
- 时间复杂度是否合理(避免O(n²)以上)
- 是否可以用哈希表优化查找
缓存使用
- 是否合理使用缓存
- 缓存是否有过期策略
- 是否存在缓存击穿/雪崩风险
4.4 架构问题维度 (Severity: MEDIUM)
循环依赖
- 模块间是否存在循环依赖
- 包结构是否合理
层次混乱
- 是否跨层调用(Controller直接调用DAO)
- 是否违反分层架构原则
单一职责
- 类是否职责单一
- 方法是否做了过多的事情
接口隔离
- 接口是否粒度合理
- 是否存在胖接口
4.5 代码异味维度 (Severity: LOW)
重复代码
- 是否存在复制粘贴的代码
- 相似逻辑是否可以抽取
过长方法
- 方法行数是否超过限制(50行)
- 是否可以拆分
过多参数
- 参数是否超过5个
- 是否可以用对象封装
神类
- 类是否过于庞大(>500行)
- 是否可以拆分职责
4.6 最佳实践维度 (Severity: MEDIUM)
异常处理
- 是否正确捕获异常
- 是否吞掉异常
- 是否抛出合适的异常类型
资源释放
- 文件、连接是否正确关闭
- 是否使用try-with-resources
- 是否有finally块释放资源
并发安全
- 是否存在线程安全问题
- 共享变量是否有同步控制
- 是否使用线程安全的数据结构
事务管理
- 事务边界是否合理
- 是否有事务传播配置
- 长事务是否拆分
五、用户画像与个性化审计
5.1 用户画像数据结构
基本信息
- user_id: GitHub用户ID
- username: GitHub用户名
- join_date: 加入时间
- total_audits: 累计审计次数
问题统计
- frequent_issues: 高频问题类型(Top 5)
- issue_trend: 问题数量趋势(最近10次审计)
- improvement_rate: 改进率(问题减少百分比)
代码风格
- naming_style: 命名风格偏好
- comment_habit: 注释习惯(充分/一般/缺少)
- code_complexity: 代码复杂度偏好(简单/适中/复杂)
技术栈熟悉度
- languages: 语言熟悉度(Java:0.9, Python:0.7)
- frameworks: 框架熟悉度(Spring:0.8, Django:0.6)
- weak_areas: 薄弱领域(并发编程、性能优化)
成长轨迹
- quality_score_history: 代码质量分数历史
- milestone_achievements: 成就里程碑
- learning_recommendations: 学习建议
5.2 画像构建方法
数据来源
- 历史审计记录(audit_tasks, audit_issues)
- 代码提交历史(GitHub API)
- 团队反馈(可选)
更新频率
- 每次审计后实时更新问题统计
- 每周重新计算趋势和熟悉度评分
- 每月生成成长报告
冷启动策略
- 新用户前3次审计不做个性化,收集基础数据
- 参考团队平均水平设置初始画像
- 主动询问用户的技术背景和关注点
5.3 个性化建议生成
针对高频问题
🔍 个性化提醒
您在本次审计中又出现了资源未释放的问题(第5次)。
建议:
1. 使用try-with-resources自动管理资源
2. 阅读: [Java资源管理最佳实践]
3. 使用IDE检查工具(IntelliJ Resource Leak检查)
进步反馈
🎉 进步反馈
相比上次审计,您的代码质量提升明显:
- 安全问题: 3个 → 0个 ✅
- 性能问题: 5个 → 2个 📈
- 代码规范: 8个 → 3个 📈
继续保持!建议下一步重点关注性能优化。
学习资源推荐
📚 学习建议
基于您的代码审计历史,推荐以下学习资源:
1. [深入理解Java并发编程] - 您的并发代码问题较多
2. [SQL性能优化实战] - 帮助优化慢查询
3. [代码重构技巧] - 减少代码异味
六、审计报告格式
6.1 报告头部
# 📊 代码审计报告
**审计编号**: #12345
**审计时间**: 2025-10-28 14:30:00
**触发者**: @reviewer
**被审计用户**: @zhangsan
**仓库**: maiban/maiban-backend
**分支**: feature/payment-service
**提交范围**: abc123..def456 (5 commits)
---
## 📈 审计概览
| 维度 | CRITICAL | HIGH | MEDIUM | LOW | 总计 |
|------|----------|------|--------|-----|------|
| 安全漏洞 | 1 | 2 | 0 | 0 | 3 |
| 性能问题 | 0 | 3 | 2 | 0 | 5 |
| 架构问题 | 0 | 0 | 2 | 1 | 3 |
| 代码规范 | 0 | 0 | 1 | 5 | 6 |
| 代码异味 | 0 | 0 | 3 | 2 | 5 |
| 最佳实践 | 0 | 1 | 2 | 0 | 3 |
| **总计** | **1** | **6** | **10** | **8** | **25** |
**审计结果**: ⚠️ 存在严重问题,建议修复后再合并
---
6.2 问题列表
## 🚨 严重问题 (CRITICAL)
### 1. SQL注入风险
**文件**: `src/main/java/com/maiban/service/PaymentService.java:45`
**类型**: 安全漏洞 - SQL注入
**严重级别**: CRITICAL
**问题描述**:
使用字符串拼接构建SQL语句,存在SQL注入风险。
**问题代码**:
\`\`\`java
String sql = "SELECT * FROM payments WHERE user_id = '" + userId + "'";
jdbcTemplate.query(sql, ...);
\`\`\`
**修复建议**:
使用参数化查询防止SQL注入:
\`\`\`java
String sql = "SELECT * FROM payments WHERE user_id = ?";
jdbcTemplate.query(sql, new Object[]{userId}, ...);
\`\`\`
**参考资料**: [OWASP SQL注入防御](https://owasp.org/...)
---
## ⚠️ 高优先级问题 (HIGH)
### 2. N+1查询问题
**文件**: `src/main/java/com/maiban/service/OrderService.java:78`
**类型**: 性能问题 - N+1查询
**严重级别**: HIGH
**问题描述**:
在循环中执行数据库查询,当订单数量较多时会产生大量SQL查询。
**问题代码**:
\`\`\`java
for (Order order : orders) {
User user = userRepository.findById(order.getUserId());
// ...
}
\`\`\`
**修复建议**:
使用JOIN或批量查询优化:
\`\`\`java
List<Long> userIds = orders.stream()
.map(Order::getUserId)
.collect(Collectors.toList());
Map<Long, User> userMap = userRepository.findAllById(userIds)
.stream()
.collect(Collectors.toMap(User::getId, u -> u));
\`\`\`
**性能影响**: 100个订单会产生101次查询,优化后只需2次
---
6.3 个性化建议
## 💡 个性化建议
### 🔍 常见问题提醒
您在本次审计中又出现了以下常见问题:
- **资源未释放** (第6次出现) - 建议使用try-with-resources
- **空指针检查缺失** (第4次出现) - 建议使用Optional或Objects.requireNonNull
### 🎉 进步反馈
相比上次审计(2025-10-21),您的代码质量有明显提升:
- ✅ 安全问题: 3个 → 1个 (减少67%)
- ✅ 性能问题: 8个 → 5个 (减少38%)
- ✅ 代码规范: 12个 → 6个 (减少50%)
继续保持!您在代码规范方面进步最快 🚀
### 📚 学习建议
基于您的代码习惯,推荐以下学习资源:
1. [Java资源管理最佳实践](https://...) - 帮助解决资源释放问题
2. [Effective Java第3版 - 第9条](https://...) - try-with-resources最佳实践
3. [阿里巴巴Java开发手册](https://...) - 代码规范参考
---
6.4 趋势分析
## 📊 质量趋势分析
### 近10次审计趋势
\`\`\`
问题数量趋势:
30 ┤ ╭──
25 ┤ ╭────────╯
20 ┤ ╭────────╯
15 ┤ ╭────╯
10 ┤ ╭───╯
5 ┤───╯
0 ┴────────────────────────────────
10/01 10/08 10/15 10/22 10/28
\`\`\`
### 问题类型分布变化
| 类型 | 上次 | 本次 | 变化 |
|------|------|------|------|
| 安全漏洞 | 3 | 1 | ⬇️ -67% |
| 性能问题 | 8 | 5 | ⬇️ -38% |
| 架构问题 | 2 | 3 | ⬆️ +50% |
| 代码规范 | 12 | 6 | ⬇️ -50% |
### 与团队对比
您的代码质量评分: **7.8/10** (团队平均: 7.2)
- 安全性: **8.5/10** (优于平均)
- 性能: **7.2/10** (接近平均)
- 可维护性: **7.5/10** (优于平均)
---
6.5 报告尾部
## 📝 审计说明
**审计工具**:
- 静态分析: SonarQube 10.3
- 安全扫描: Bandit 1.7.5
- AI分析: Claude 3.5 Sonnet
**审计范围**:
- 文件数量: 12个
- 代码行数: 1,245行
- 审计耗时: 2分35秒
- Token消耗: 15,234 (成本: $0.18)
**下一步行动**:
1. ⚠️ 修复1个严重安全问题
2. 🔧 优化6个高优先级性能问题
3. 📖 阅读推荐的学习资源
4. ✅ 修复完成后再次审计
---
💡 **提示**: 使用 `@maiban-audit recheck` 命令重新审计修复后的代码
🤖 由 [麦瓣AI智能体系统](https://github.com/maiban/ai-agents) 生成
七、数据存储设计
7.1 PostgreSQL表设计
审计任务表 (audit_tasks)
CREATE TABLE audit_tasks (
id BIGSERIAL PRIMARY KEY,
task_id VARCHAR(50) UNIQUE NOT NULL,
repository VARCHAR(200) NOT NULL,
trigger_type VARCHAR(20) NOT NULL, -- issue_comment, issue_create, pull_request
trigger_user VARCHAR(100) NOT NULL,
target_user VARCHAR(100) NOT NULL,
branch VARCHAR(200),
commit_range VARCHAR(100),
audit_dimensions TEXT[], -- 审计维度数组
status VARCHAR(20) NOT NULL, -- pending, running, completed, failed
started_at TIMESTAMP,
completed_at TIMESTAMP,
token_usage INTEGER,
api_calls INTEGER,
cost_usd DECIMAL(10, 4),
github_issue_url TEXT,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_audit_tasks_target_user ON audit_tasks(target_user);
CREATE INDEX idx_audit_tasks_status ON audit_tasks(status);
CREATE INDEX idx_audit_tasks_created_at ON audit_tasks(created_at);
审计问题表 (audit_issues)
CREATE TABLE audit_issues (
id BIGSERIAL PRIMARY KEY,
task_id VARCHAR(50) NOT NULL REFERENCES audit_tasks(task_id),
user_id VARCHAR(100) NOT NULL,
issue_type VARCHAR(50) NOT NULL, -- security, performance, architecture, etc.
severity VARCHAR(20) NOT NULL, -- CRITICAL, HIGH, MEDIUM, LOW
file_path TEXT NOT NULL,
line_number INTEGER,
description TEXT NOT NULL,
fix_suggestion TEXT,
example_code TEXT,
is_fixed BOOLEAN DEFAULT FALSE,
fixed_at TIMESTAMP,
created_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_audit_issues_task_id ON audit_issues(task_id);
CREATE INDEX idx_audit_issues_user_id ON audit_issues(user_id);
CREATE INDEX idx_audit_issues_severity ON audit_issues(severity);
用户画像表 (user_profiles)
CREATE TABLE user_profiles (
id BIGSERIAL PRIMARY KEY,
user_id VARCHAR(100) UNIQUE NOT NULL,
username VARCHAR(100) NOT NULL,
total_audits INTEGER DEFAULT 0,
frequent_issues JSONB, -- {"resource_leak": 8, "null_check": 5}
issue_trend JSONB, -- [25, 22, 18, 15, 12, ...] 最近10次
improvement_rate DECIMAL(5, 2),
code_style JSONB, -- {"naming": "camelCase", "comment": "moderate"}
tech_stack JSONB, -- {"Java": 0.9, "Spring": 0.8}
weak_areas TEXT[],
quality_score_history JSONB,
last_audit_at TIMESTAMP,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_user_profiles_user_id ON user_profiles(user_id);
审计报告表 (audit_reports)
CREATE TABLE audit_reports (
id BIGSERIAL PRIMARY KEY,
task_id VARCHAR(50) UNIQUE NOT NULL REFERENCES audit_tasks(task_id),
user_id VARCHAR(100) NOT NULL,
report_markdown TEXT NOT NULL,
severity_stats JSONB, -- {"CRITICAL": 1, "HIGH": 6, ...}
total_issues INTEGER,
github_comment_url TEXT,
created_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_audit_reports_user_id ON audit_reports(user_id);
7.2 Milvus向量数据库
Collection: code_snippets
- 存储审计过的代码片段和对应问题
- 向量维度: 1536 (OpenAI text-embedding-3)
- 元数据: file_path, language, issue_type, severity
- 用途: 检索相似代码片段,复用审计结果
Collection: issue_patterns
- 存储常见问题模式的向量表示
- 向量维度: 1536
- 元数据: pattern_name, description, fix_template
- 用途: 快速匹配新代码中的相似问题
八、GitHub集成方案
8.1 GitHub App配置
App名称: Maiban AI Code Auditor
Webhook订阅事件:
- issue_comment (Issue评论)
- issues (Issue创建/更新)
- pull_request (PR创建/更新)
- pull_request_review_comment (PR审查评论)
权限设置:
- Repository permissions:
- Contents: Read (读取代码)
- Issues: Read & Write (读写Issue)
- Pull requests: Read & Write (读写PR)
- Metadata: Read (读取仓库元数据)
Webhook URL: https://ai-agents.maiban.com/api/v1/github/webhook
Secret: 用于验证Webhook请求来源
8.2 Webhook事件处理
Issue评论事件:
事件: issue_comment.created
判断: 评论内容包含 @maiban-audit
解析: 提取审计命令和参数
触发: 创建审计任务
Issue创建事件:
事件: issues.opened
判断: 标题包含 [Code Audit]
解析: 解析Issue Body中的YAML配置
触发: 创建审计任务
PR事件:
事件: pull_request.opened 或 pull_request.synchronize
判断: 仓库配置开启了PR自动审计
获取: PR的文件变更
触发: 创建审计任务
8.3 权限控制
触发权限:
- 仓库管理员(Admin)
- 仓库维护者(Maintainer)
- 配置的白名单用户
配置方式:
# .github/maiban-audit.yml
allowed_users:
- admin_user1
- admin_user2
allowed_teams:
- team1
- team2
auto_audit_pr: true
audit_dimensions:
- security
- performance
- architecture
severity_threshold: HIGH
审计次数限制:
- 单用户: 10次/天
- 单仓库: 50次/天
- 超限后需要人工审批或等待
8.4 并发控制
Redis分布式锁:
Key格式: audit:lock:{user_id}:{repository}
TTL: 30分钟(审计超时时间)
逻辑: 同一用户同一仓库同时只能有一个审计任务
任务队列:
队列: celery_audit_tasks
优先级: CRITICAL问题的复审 > 新审计 > 定期审计
并发数: 20个worker
超时: 30分钟
九、成本优化策略
9.1 缓存策略
审计结果缓存:
- Key:
audit:cache:{repository}:{commit_sha} - TTL: 24小时
- 内容: 完整的审计报告
- 命中率目标: >70%
代码片段分析缓存:
- Key:
audit:snippet:{file_hash}:{snippet_hash} - TTL: 7天
- 内容: 该代码片段的审计结果
- 减少: 重复代码的LLM调用
用户画像缓存:
- Key:
audit:profile:{user_id} - TTL: 30天
- 内容: 用户画像JSON
- 更新: 每次审计后更新
9.2 增量审计
Git Diff分析:
- 只审计变更的代码行
- 排除: 空白行、注释行、导入语句
- 上下文: 保留变更前后各5行代码
批次大小控制:
- 单次审计: 最多50个文件
- 单个文件: 最多1000行变更
- 超限: 分批审计或提示用户缩小范围
9.3 模型选择策略
Claude Haiku (便宜: $0.25/1M input tokens)
- 代码格式检查
- 命名规范检查
- 简单的代码异味检测
Claude Sonnet (性价比: $3/1M input tokens)
- 常规代码审计
- 安全漏洞检测
- 性能问题分析
- 最佳实践检查
Claude Opus (贵但准确: $15/1M input tokens)
- 复杂架构分析
- 深度重构建议
- 技术债务评估
自动降级:
成本监控 → 超限 → 降级使用Sonnet → 仍超限 → 仅静态分析
9.4 批量处理
相似问题合并:
场景: 10个文件都有相同的空指针检查问题
优化前: 调用10次LLM生成修复建议
优化后: 调用1次LLM,复用修复建议
节省: 90% Token
文件分组:
场景: 审计20个文件
优化前: 每个文件单独分析
优化后: 按语言和问题类型分组,批量分析
节省: 50% Token
9.5 成本监控
实时监控:
- 每次审计记录Token使用量和成本
- 累计每日、每周、每月成本
- 超限告警(邮件、钉钉)
成本分析:
- 按仓库统计成本
- 按用户统计成本
- 按审计维度统计成本
- 生成成本优化建议
预算控制:
- 每日成本上限: $100
- 单次审计上限: $2
- 超限: 暂停服务或降级
十、测试与监控
10.1 测试策略
单元测试:
- LangGraph节点测试
- Prompt模板测试
- 数据处理逻辑测试
- 覆盖率目标: >80%
集成测试:
- GitHub Webhook集成测试
- LLM API调用测试
- 数据库读写测试
端到端测试:
- 完整审计流程测试
- 各种触发方式测试
- 异常场景测试(API失败、超时等)
10.2 监控指标
业务指标:
- 审计次数(按小时/天统计)
- 平均审计耗时
- 问题发现数量(按严重级别)
- 用户满意度
技术指标:
- LLM API调用成功率
- 平均响应时间
- 缓存命中率
- Token使用量
成本指标:
- 每日成本
- 单次审计平均成本
- Token单价
质量指标:
- 误报率
- 漏报率
- 用户反馈评分
文档维护者: AI团队 技术负责人: 待定 创建日期: 2025-10-28 最后更新: 2025-10-28 下次评审: 2025-11-28
