
1. 项目概述一个基于Claude的智能PR代码审查机器人最近在团队内部搞了个小项目把代码审查这个事儿给自动化了。起因很简单每次有新同事提交PR或者项目赶进度的时候代码审查的反馈周期就会被拉长有时候一个简单的PR要等上大半天才能收到第一轮反馈。对于开发者来说等待反馈的时间是最难熬的尤其是当你已经切换到下一个任务又被拉回来改代码的时候。这个项目的核心思路就是用AI来充当第一轮代码审查员。它会在PR创建或者更新时自动触发调用Claude模型通过Anthropic官方API或者OpenRouter对代码变更进行深度分析然后在GitHub上直接发布行内评论。这些评论不是泛泛而谈而是会按照正确性、安全性、性能、错误处理、设计、可维护性、测试、API契约这八个维度来归类并且给出具体的、可操作的修改建议。更贴心的是它还会通过Slack给PR作者发私信通知他审查结果已经就绪。我把它命名为OpenClaw PR Reviewer。这个名字里的“OpenClaw”其实是一个可选的增强模式后面会详细讲。这个工具特别适合中小型团队或者开源项目维护者能显著提升代码入库前的质量门槛把一些常见的低级错误和代码坏味道在合并前就拦截下来。2. 核心设计思路与架构拆解2.1 为什么选择Claude作为审查引擎市面上可用的LLM很多比如GPT系列、DeepSeek、Gemini等等。最初选型时我们重点对比了GPT-4和Claude Sonnet。最终选择Claude主要是基于它在代码理解和长上下文处理上的稳定表现。GPT-4的创造力很强但在代码审查这种需要严谨、一致性的任务上有时会“过度发挥”给出一些天马行空但不切实际的建议。Claude的输出则更加稳健、结构化特别是在我们定义的八个审查维度上它能很好地遵循指令给出针对性强的反馈。另一个关键因素是成本与性能的平衡。Claude Sonnet模型在保证高质量输出的同时API成本相对可控尤其适合高频触发的自动化场景。当然项目并没有锁死在一家供应商上。通过集成OpenRouter作为备选渠道你实际上可以间接使用包括Claude、GPT在内的多种模型这提供了灵活性。在配置里你可以通过LLM_PROVIDER环境变量轻松切换。2.2 整体工作流与组件职责整个机器人的工作流是一个清晰的管道处理模式核心是响应GitHub的Webhook事件。GitHub Webhook (PR opened/pushed/reopened) │ ▼ PR Review Bot (FastAPI后端) ├── 1. 验证Webhook签名 (HMAC-SHA256) - 确保请求来源可信 ├── 2. 过滤无效PR - 跳过草稿PR、机器人自己提交的PR ├── 3. 获取PR差异 - 调用GitHub API拉取完整的diff ├── 4. 过滤非审查文件 - 忽略lock文件、构建目录、二进制文件等 ├── 5. 发送至LLM审查 - 将处理后的diff和项目上下文发送给Claude ├── 6. 发布GitHub评论 - 将LLM的反馈解析为行内评论review comment └── 7. 发送Slack通知 - 私信通知作者可选广播到团队频道每个环节都由一个独立的模块负责github_client.py: 封装所有与GitHub API的交互包括获取PR详情、diff、提交评论等。这里要注意权限管理使用的PATPersonal Access Token需要repo权限。diff_utils.py: 这是预处理的核心。它不仅要解析diff格式还要负责“分块”。对于超过2000行变更的大型PR直接扔给LLM可能会超出上下文长度或导致分析质量下降。这个模块会自动将大diff按文件切割成多个可管理的块分别发送审查。review_engine.py: LLM交互的中枢。它负责构建一个结构化的提示词Prompt将diff、审查规则、项目上下文CONTEXT.md整合在一起发送给Claude并解析其返回的结构化JSON结果。slack_notifier.py: 通知模块。它的难点在于如何准确地将GitHub用户名映射到Slack用户ID。我们实现了三级查找策略优先使用静态配置文件user_mapping.yml其次尝试通过GitHub公开邮箱匹配Slack账号最后在Slack工作区内搜索同名用户。openclaw_client.py: 可选的高级模式。OpenClaw是一个开源AI智能体框架。启用后审查请求会路由给一个持久的OpenClaw智能体。这个智能体具有“会话记忆”能力可以记住对这个PR之前轮次的讨论使得审查建议更具连贯性和上下文感知能力适合非常复杂或迭代多次的PR。实操心得Webhook事件去抖在实际使用中我们发现当开发者连续向PR推送多个提交时会瞬间触发多次Webhook。如果每次都立即执行完整的审查流程会造成API资源的浪费和重复评论。因此我们在Webhook处理入口实现了一个30秒的去抖debounce逻辑。即收到push事件后等待30秒如果期间没有新的push事件才触发审查。这确保了在开发者快速连续推送时只对最终状态进行一次审查体验更佳。3. 详细配置与部署指南3.1 环境准备与基础配置机器人的运行依赖于几个关键的外部服务凭证缺一不可。下面是一步步的配置清单。1. 获取API密钥与令牌Anthropic API Key: 前往 Anthropic Console 注册并创建API密钥。如果你选择使用OpenRouter则可以跳过这一步。OpenRouter API Key (可选): 前往 OpenRouter 注册并创建密钥。这为你提供了模型选择的灵活性。GitHub Personal Access Token: 在你的GitHub账号设置 - Developer settings - Personal access tokens - Tokens (classic) 中生成。权限务必勾选repo完全控制仓库这样机器人才能读写PR和评论。Slack Bot Token: 按照项目文档创建Slack应用并添加chat:write,users:read,users:read.email权限安装到工作区后即可获得xoxb-开头的Bot Token。2. 本地开发环境搭建# 克隆仓库 git clone https://github.com/rshivam973/openclaw-pr-reviewer.git cd openclaw-pr-reviewer # 创建并激活虚拟环境强烈推荐避免污染系统Python python -m venv venv # Windows: venv\Scripts\activate # Linux/Mac: source venv/bin/activate # 安装依赖 pip install -r requirements.txt核心依赖包括fastapi(Web框架),httpx(HTTP客户端),pydantic(数据验证),pyyaml(规则解析) 等。3. 配置文件与环境变量项目根目录下有一个.env.example文件复制它并填写你的密钥。cp .env.example .env然后编辑.env文件它看起来像这样# 必须项至少配置一个LLM密钥 ANTHROPIC_API_KEYsk-ant-xxx # 或者使用 OpenRouter # OPENROUTER_API_KEYsk-or-xxx # LLM_PROVIDERopenrouter # 显式指定提供商不指定则自动检测 # GitHub 配置 GITHUB_PATghp_xxx WEBHOOK_SECRETyour_very_strong_secret_here # 用于验证GitHub Webhook # Slack 配置 SLACK_BOT_TOKENxoxb-xxx SLACK_PR_REVIEWS_CHANNELC12345678 # 可选团队审查频道ID SLACK_FALLBACK_CHANNELC87654321 # 可选用户映射失败时的通知频道 # 机器人自身标识避免自己审查自己 BOT_GITHUB_USERNAMEpr-review-bot # 高级功能OpenClaw 模式 (默认关闭) OPENCLAW_ENABLEDfalse OPENCLAW_BASE_URLhttp://127.0.0.1:18789 OPENCLAW_WEBHOOK_TOKENoptional_auth_token重要安全提示Webhook SecretWEBHOOK_SECRET是保障安全的关键。GitHub会在发送Webhook请求时使用这个密钥对请求体生成一个HMAC SHA256签名放在请求头的X-Hub-Signature-256里。我们的服务端会用同样的密钥重新计算签名并比对只有一致才处理请求。千万不要使用默认值或弱密码建议用openssl rand -hex 32命令生成一个强随机字符串。3.2 审查规则深度定制 (review_rules/default.yml)默认的审查规则可能不适合所有项目你可以通过修改review_rules/default.yml文件来定制机器人的行为。这个文件是机器人“思考”的准则。# review_rules/default.yml checklist: - has_tests # 检查新增代码是否包含测试 - no_secrets # 检查是否意外提交了密钥或密码 - pr_description_complete # 检查PR描述是否详细 - no_console_logs # 检查是否遗留了调试用的console.log/print语句 severity_threshold: suggestion # 只报告“建议”及以上级别的问题可选info, suggestion, warning, error skip_files: - *.lock # 忽略包锁文件如 package-lock.json, yarn.lock - *.min.js # 忽略压缩后的JS - *.min.css # 忽略压缩后的CSS - dist/** # 忽略构建输出目录 - build/** - node_modules/** - *.pyc # 忽略Python字节码 - __pycache__/** skip_options: draft_prs: true # 是否跳过草稿PR # bot_users: [] # 可以配置一个列表来跳过其他机器人的PR规则解析与扩展checklist: 这是一个“强制检查项”列表。LLM在审查时会被明确要求关注这些点。例如no_secrets会让AI特别留意像API_KEY,password, 或JWT密钥等模式的字符串。你可以根据团队规范添加更多项如follows_naming_convention遵循命名规范。severity_threshold: 这是一个过滤器。如果设为warning那么所有被标记为info或suggestion的轻微问题都不会被发布到GitHub上只会在内部日志中记录。这可以避免在PR上产生“信息噪声”。skip_files: 使用 glob 模式匹配。对于前端项目你可能还想加入*.snap(Jest快照文件) 或*.md(仅文档变更)。这里的匹配逻辑是“或”关系命中任意一条即跳过整个文件。3.3 项目上下文注入 (CONTEXT.md)这是让AI审查从“通用”变为“专精”的秘诀。在仓库根目录创建一个CONTEXT.md文件机器人会自动获取并将其内容作为系统提示词的一部分发送给LLM。# My Awesome Project 开发上下文 ## 技术栈与版本 - 后端Python 3.11 FastAPI框架 SQLAlchemy 2.0 ORM PostgreSQL 15 - 前端React 18 with TypeScript 5.0 Vite构建 Tailwind CSS - 测试Pytest (后端) Jest React Testing Library (前端) ## 架构与目录约定 - 本项目采用前后端分离的monorepo结构。 - /backend所有后端代码遵循“功能模块”分包。 - /frontend所有前端代码使用Feature-based目录结构。 - API设计遵循RESTful规范响应格式统一为 {“code”: number, “data”: any, “msg”: string}。 - 错误处理使用自定义的 AppException 异常类在全局异常处理器中转换为标准错误响应。 ## 代码风格与特定要求 - **Python**: 使用 black 和 isort 格式化。类型提示Type Hints必须完整。 - **TypeScript**: 使用严格的 tsconfig 设置。禁止使用 any 类型必须使用 interface 或 type 明确定义。 - **数据库**: 所有查询必须通过SQLAlchemy ORM进行禁止手写原生SQL字符串拼接以防SQL注入。 - **日志**: 使用结构化的JSON日志通过 structlog 库输出。禁止直接使用 print。 - **环境变量**: 必须通过 pydantic-settings 管理并在 settings.py 中声明。 ## 本PR需要特别关注的领域 - 本次改动涉及用户认证模块请重点检查JWT令牌的生成、验证逻辑以及敏感信息如密码的哈希存储。 - 新增了 /api/v1/users/me 端点请确保其权限检查Authentication Authorization完备。当AI在审查一个修改了backend/auth/router.py的PR时它就会知道这个项目用FastAPI、需要检查SQL注入、并且当前模块是安全关键模块。这样提出的建议会精准得多比如它会提醒你“这里直接拼接了用户输入到SQL查询中建议改用SQLAlchemy的参数化查询”或者“JWT的secret应该从配置中读取而不是硬编码”。4. 核心功能实现与实操解析4.1 GitHub Webhook的接收与验证机器人是一个标准的FastAPI应用核心入口是/webhook/github这个POST端点。安全性是这里的第一道关卡。FastAPI 应用初始化与路由# app/main.py 核心片段 from fastapi import FastAPI, Request, HTTPException, BackgroundTasks import hmac import hashlib app FastAPI(titlePR Review Bot) app.post(/webhook/github) async def handle_github_webhook(request: Request, background_tasks: BackgroundTasks): # 1. 验证签名 body_bytes await request.body() signature request.headers.get(X-Hub-Signature-256) if not signature or not verify_signature(body_bytes, signature): raise HTTPException(status_code403, detailInvalid signature) # 2. 解析事件 event request.headers.get(X-GitHub-Event) payload await request.json() # 3. 只处理PR相关事件 if event pull_request: action payload.get(action) # 仅在PR被打开、同步新推送、或重新打开时触发审查 if action in [opened, synchronize, reopened]: # 将耗时的审查任务放入后台立即响应GitHub避免超时 background_tasks.add_task(process_pull_request, payload) return {status: review started} return {status: ignored} def verify_signature(body: bytes, signature_header: str) - bool: 使用HMAC SHA256验证Webhook签名 secret settings.WEBHOOK_SECRET.encode() expected_signature sha256 hmac.new(secret, body, hashlib.sha256).hexdigest() return hmac.compare_digest(expected_signature, signature_header)关键点解析使用BackgroundTasks: 代码审查调用LLM API可能耗时几秒到几十秒而GitHub Webhook期望在短时间内通常10秒内收到响应否则会认为失败并重试。因此我们必须将核心的process_pull_request逻辑放入后台任务让接口立刻返回202 Accepted。事件过滤: 我们只关注pull_request事件并且只在特定的action下触发。这避免了在PR被标记为“已读”、被评论等无关事件时浪费资源。签名验证:hmac.compare_digest是Python中用于对比密码学哈希的安全函数可以防止时序攻击。4.2 Diff获取、解析与智能分块这是预处理阶段最复杂的部分直接决定了送给AI的“食材”质量。步骤1获取原始Diff通过GitHub API的GET /repos/{owner}/{repo}/pulls/{pull_number}接口并设置accept头为application/vnd.github.v3.diff可以直接获取到纯文本格式的diff。这种格式比处理JSON格式的文件变更列表更简单也更容易被LLM理解。步骤2文件过滤拿到diff后首先按文件拆分。然后根据review_rules/default.yml中的skip_files模式进行过滤。我们使用fnmatch库进行glob模式匹配。被匹配到的文件其所有变更行都会被直接忽略不会进入后续流程。步骤3大Diff分块策略LLM有上下文长度限制例如Claude Sonnet 3.5 是200K tokens。一个巨大的、包含几十个文件的PR其diff文本可能轻易超过这个限制。我们的策略是不过滤的单个文件如果diff行数超过一个阈值比如500行则将其单独作为一个“块”。剩余的中小文件按语言或目录进行粗略分组确保每个块的总行数在一个合理的范围内例如目标块大小在800-1500行之间。每个块会附带一个块标识如[Chunk 1/3]和简单的上下文说明如“此块包含前端组件修改”然后分别发送给LLM进行审查。# app/diff_utils.py 分块逻辑简化示意 def chunk_diff(diff_text: str, max_lines_per_chunk: int 1500) - List[DiffChunk]: files split_diff_by_file(diff_text) filtered_files [f for f in files if not should_skip_file(f.filename)] chunks [] current_chunk DiffChunk() for file in filtered_files: if file.line_count 500: # 大文件独立成块 if current_chunk.files: chunks.append(current_chunk) current_chunk DiffChunk() chunks.append(DiffChunk(files[file])) else: if current_chunk.total_lines file.line_count max_lines_per_chunk: chunks.append(current_chunk) current_chunk DiffChunk() current_chunk.add_file(file) if current_chunk.files: chunks.append(current_chunk) return chunks实操心得分块的艺术分块大小需要权衡。块太小如300行会导致API调用次数激增增加成本和延迟且AI可能缺乏足够的上下文来理解跨文件的改动关联。块太大如2500行可能超出模型上下文导致审查不完整或质量下降。经过多次测试将目标块大小设置在1000-1500行大文件500行独立成块是一个比较理想的平衡点。同时尽量将相关的文件如修改了同一个API的控制器、服务和模型文件放在同一个块里有助于AI进行连贯分析。4.3 构建LLM提示词与解析响应这是AI审查的“大脑”。提示词的质量直接决定了审查输出的质量。核心提示词结构我们采用系统提示词System Prompt加用户消息User Message的结构。系统提示词定义了AI的角色、审查的维度和输出格式。# app/review_engine.py 提示词构建简化版 SYSTEM_PROMPT_TEMPLATE 你是一个资深的、严谨的代码审查助手。你的任务是对GitHub Pull Request的代码变更进行审查。 请从以下8个维度进行分析并为每个发现的问题生成一个结构化的评论 1. **正确性**: 代码逻辑是否正确是否存在边界条件错误、死循环、资源未释放 2. **安全性**: 是否存在安全漏洞如SQL注入、XSS、CSRF、硬编码密钥、不安全的权限检查 3. **性能**: 是否存在性能瓶颈如N1查询、未使用索引、低效的算法、重复计算 4. **错误处理**: 是否妥善处理了异常和错误是否有未捕获的异常、不清晰的错误信息 5. **设计**: 代码结构是否清晰是否符合设计模式如单一职责模块耦合度是否过高 6. **可维护性**: 代码是否易于理解和修改命名是否清晰函数是否过长注释是否恰当 7. **测试**: 变更是否包含测试测试用例是否覆盖了主要场景和边界条件 8. **API契约**: 如适用API的请求/响应格式、状态码、错误处理是否符合约定 **项目特定上下文** {project_context} **团队审查规则** {review_rules} **输出格式要求** 你必须以纯JSON数组格式回复每个对象对应一个审查发现。格式如下 json [ { file: src/utils/helper.py, line: 42, severity: suggestion, // 可选: info, suggestion, warning, error category: performance, title: 循环内重复计算, body: 在for循环内部重复调用了 calculate_heavy_operation()建议将其移到循环外部计算一次。 } ]请确保file和line号准确对应diff中的位置。body部分应提供具体的、可操作的修改建议。 **用户消息** 则包含了具体的、经过分块的diff内容Diff to Review (Chunk 1/2)以下是对文件src/api/users.py的修改 -10,7 10,15 def get_user(user_id: int): - user db.query(User).filter(User.id user_id).first() - return user try: user db.query(User).filter(User.id user_id).first() if not user: raise HTTPException(status_code404, detailUser not found) return user except SQLAlchemyError as e: logger.error(fDatabase error fetching user {user_id}: {e}) raise HTTPException(status_code500, detailInternal server error)... (更多diff)**LLM响应解析与后处理** 收到AI的JSON响应后我们需要进行验证和清理 1. **JSON解析与校验**使用Pydantic模型验证每个评论对象的字段是否完整、类型是否正确。 2. **严重性过滤**根据配置的 severity_threshold过滤掉低于阈值的评论例如只保留 warning 和 error。 3. **去重**有时AI会对同一处代码从不同角度提出多个相似评论。我们会根据 file, line, title 进行简单的去重避免评论刷屏。 4. **转换为GitHub Review Comment**GitHub的行内评论API需要特定的格式包括提交SHA、路径、行号和评论内容。我们需要将解析后的数据映射过去。 ### 4.4 Slack通知与用户映射 审查完成后通知要及时、准确地送达。这里最大的挑战是 **GitHub用户到Slack用户的映射**。 **三级映射策略** 1. **静态映射 (user_mapping.yml)**最可靠、最快的方式。在配置文件中预先写好对应关系。 yaml # user_mapping.yml github_username_a: U12345678 github_username_b: U87654321 2. **邮箱匹配**通过GitHub API获取PR作者的公开邮箱地址然后使用Slack API的 users.lookupByEmail 方法进行查找。这要求用户在Slack和GitHub上使用了相同的邮箱并且该邮箱在Slack工作区内是公开的。 3. **工作区搜索**作为最后的手段使用Slack API的 users.list 获取所有用户然后根据GitHub用户名进行模糊匹配比如全名或显示名的部分匹配。这个方法最慢且可能匹配错误。 **通知消息设计** 发送到Slack的消息需要信息明确、行动指引清晰。我们采用Slack的Block Kit来构建富文本消息。 python # app/slack_notifier.py 消息构建示例 def build_pr_review_message(pr_url, repo_name, pr_title, findings_count, comment_url): blocks [ { type: section, text: { type: mrkdwn, text: f 你好你的PR *{pr_url}|{repo_name}#123: {pr_title}* 已经完成了AI初步审查。 } }, { type: section, fields: [ {type: mrkdwn, text: f*审查发现数:*\n{findings_count}}, {type: mrkdwn, text: f*严重问题:*\n{count_severe(findings)}}, ] }, { type: actions, elements: [ { type: button, text: {type: plain_text, text: 查看详细评论}, url: comment_url, style: primary } ] }, { type: context, elements: [{type: mrkdwn, text: 这是一个自动生成的审查请结合人工审查进行判断。}] } ] return blocks消息会通过chat.postMessageAPI发送到用户的Slack私信DM。如果配置了SLACK_PR_REVIEWS_CHANNEL同样的消息也会被广播到团队频道让其他成员知晓审查动态。5. 生产环境部署与运维5.1 使用Docker容器化部署为了确保环境一致性和易于部署强烈推荐使用Docker。Dockerfile解析# 使用官方Python精简镜像作为基础 FROM python:3.11-slim-bookworm # 设置工作目录 WORKDIR /app # 安装系统依赖如有需要例如用于构建某些Python包 RUN apt-get update apt-get install -y --no-install-recommends \ gcc \ rm -rf /var/lib/apt/lists/* # 复制依赖声明文件并安装 COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt # 复制应用代码 COPY app/ ./app/ COPY review_rules/ ./review_rules/ # 创建一个非root用户运行应用增强安全性 RUN useradd -m -u 1000 botuser USER botuser # 暴露端口 EXPOSE 8000 # 启动命令 CMD [uvicorn, app.main:app, --host, 0.0.0.0, --port, 8000]使用Docker Compose一键部署创建一个docker-compose.yml文件可以方便地管理服务。version: 3.8 services: pr-review-bot: build: . container_name: pr-review-bot ports: - 8000:8000 # 将宿主机的8000端口映射到容器的8000端口 env_file: - .env # 从当前目录的.env文件读取环境变量 volumes: # 挂载本地配置目录方便更新规则和用户映射而不重建镜像 - ./review_rules:/app/review_rules:ro - ./user_mapping.yml:/app/user_mapping.yml:ro restart: unless-stopped # 容器意外退出时自动重启 healthcheck: # 健康检查确保服务可用 test: [CMD, curl, -f, http://localhost:8000/health] interval: 30s timeout: 10s retries: 3运行命令非常简单docker-compose up -d。你的机器人就在后台运行起来了。5.2 服务器、网络与Webhook配置机器人需要在一个能被GitHub访问到的公网地址上运行。方案一云服务器推荐在AWS EC2、Google Cloud Compute Engine、阿里云ECS等云服务商上购买一台最低配置的虚拟机如1核1GB内存。成本每月大约5-10美元。安装Docker和Docker Compose。将项目代码或至少docker-compose.yml和.env文件上传到服务器。运行docker-compose up -d。在云服务器控制台的安全组/防火墙规则中开放8000端口或你自定义的端口的入站流量。方案二使用Ngrok进行内网穿透适合开发测试如果你只在本地开发测试或者没有公网服务器Ngrok是一个完美的工具。# 1. 在本地运行机器人 uvicorn app.main:app --host 0.0.0.0 --port 8000 # 2. 在另一个终端启动ngrok将本地8000端口暴露到公网 ngrok http 8000Ngrok会生成一个随机的https://xxxx.ngrok-free.app地址。将这个地址配置为GitHub Webhook的Payload URL即可。注意免费版Ngrok的地址每次重启都会变化且可能有速率限制不适合生产环境。GitHub Webhook配置详解进入你的GitHub仓库 - Settings - Webhooks - Add webhook。Payload URL: 填写你的服务器公网地址例如https://your-server.com:8000/webhook/github。确保是HTTPS。Content type: 选择application/json。Secret: 填写你在.env文件中设置的WEBHOOK_SECRET。两边必须完全一致。Which events would you like to trigger this webhook?: 选择Let me select individual events然后只勾选Pull requests。这确保只有PR事件会触发机器人。点击Add webhook。GitHub会立即发送一个ping事件进行测试你可以在服务器的日志中查看是否接收成功。5.3 监控、日志与故障排查一个稳定的服务离不开监控。日志配置建议使用Python的structlog或loguru库来替代标准logging它们能输出结构化的JSON日志便于后续用ELK或Loki等工具收集分析。# 在app/main.py中配置loguru示例 import loguru from loguru import logger logger.add(logs/pr_review_bot.log, rotation100 MB, retention10 days, levelINFO) logger.add(sys.stderr, levelDEBUG) # 开发时输出到控制台关键的操作点都要打日志Webhook接收、PR信息、Diff分块情况、LLM API调用开始与结束、评论发布结果、Slack通知结果。健康检查端点项目自带的/health端点应该被你的监控系统如Prometheus, UptimeRobot定期调用。它可以返回服务的状态、运行时间、当前使用的LLM提供商和模型等信息。常见故障排查清单问题现象可能原因排查步骤GitHub Webhook显示“未送达”1. 服务器网络不通。2. Webhook Secret不匹配。3. 服务进程崩溃。1. 在服务器上curl -X POST https://your-server.com:8000/health测试服务是否存活。2. 检查服务器日志查看Webhook接收时是否有403错误。3. 检查Docker容器状态docker ps。PR有更新但未触发审查1. Webhook事件未勾选“Pull requests”下的“Pushes”。2. 后台任务处理异常。3. PR是草稿状态。1. 在GitHub Webhook配置页面查看Recent Deliveries确认push事件是否送达。2. 检查应用日志看process_pull_request任务是否被触发和执行。3. 确认PR不是Draft状态。AI审查成功但无Slack通知1. Slack Token无效或权限不足。2. 用户映射失败。3. 网络问题导致Slack API调用失败。1. 检查日志中Slack API的响应。2. 确认user_mapping.yml文件格式正确且已挂载到容器。3. 尝试在容器内手动运行一个简单的Slack消息发送测试脚本。LLM返回空评论或格式错误1. 提示词被修改导致AI不按格式输出。2. 上下文过长AI输出被截断。3. API密钥额度用尽或模型不可用。1. 查看发送给LLM的完整提示词和响应日志。2. 检查Diff大小考虑降低分块行数阈值。3. 检查Anthropic/OpenRouter控制台确认API状态和额度。6. 高级功能OpenClaw智能体模式解析OpenClaw模式是这个项目的“增强版”。在基础模式中每次审查都是独立的、无状态的。而OpenClaw智能体可以维持一个“会话”记住之前在这个PR上讨论过什么。工作原理当OPENCLAW_ENABLEDtrue时review_engine.py不会直接调用Claude API而是将审查请求转发给一个运行在OPENCLAW_BASE_URL的OpenClaw网关。这个网关背后连接着一个配置了特定“工具”和“记忆”能力的AI智能体。会话记忆智能体为每个PR通过repository和pull_number标识创建一个独立的会话。当同一个PR有新的推送时智能体能回顾之前几轮审查的对话历史从而提出更具连贯性的建议。例如它可能会说“在上一轮中我指出了这里的SQL注入风险你已修复。本次新增的代码中又出现了类似的字符串拼接模式建议一并修改。”工具调用OpenClaw智能体可以被赋予调用外部工具的能力。例如它可以调用一个本地的代码分析工具如semgrep进行安全扫描或者调用一个测试覆盖率检查工具然后将这些工具的结果整合到它的审查意见中使得审查更加深入和全面。降级策略在openclaw_client.py中我们实现了完善的错误处理。如果OpenClaw服务不可达、响应超时或返回错误客户端会自动降级到直接调用标准的Claude API保证审查流程不会因为高级功能故障而中断。部署OpenClaw这需要额外的步骤来部署OpenClaw服务本身。通常你需要在一个单独的容器或进程中运行OpenClaw网关和智能体定义。项目的openclaw-agent/目录下提供了一个可移植的智能体包你可以参考其README进行部署。这增加了系统的复杂性但对于追求极致审查质量的团队来说可能是值得的。7. 效果评估、调优与团队协作7.1 如何评估机器人的审查质量上线初期不要完全依赖AI审查。建议采用“AI初审 人工复核”的模式。并行审查在团队中挑选几个典型的PR让AI和资深工程师同时进行审查。对比两者提出的问题看AI的“命中率”抓住了多少真正的问题和“误报率”提出了多少无效或错误的建议。校准审查规则根据对比结果调整review_rules/default.yml。如果AI总是对某些无害的代码模式提出“警告”可以将这些模式添加到skip_patterns或降低其严重性。如果AI漏掉了一些你们团队特别关注的问题比如特定的日志格式要求可以在checklist中强化提示。优化提示词AI的表现很大程度上取决于提示词。如果你发现AI在某个维度如“设计”上的建议比较空泛可以尝试在系统提示词中为该维度提供更具体的例子或检查清单。7.2 与团队工作流整合为了让机器人更好地融入团队可以考虑以下几点设定预期在团队内明确AI审查是辅助工具不能替代人工审查。它的主要价值是捕捉低级错误、确保基础规范并为初级开发者提供学习机会。Slack频道集成将SLACK_PR_REVIEWS_CHANNEL配置为团队的工程频道。这样所有AI审查结果都会公开其他成员可以围观、学习甚至在AI漏报时补充评论。处理误报鼓励开发者在收到不准确的AI评论时直接在GitHub上回复并说明原因例如“这是为了兼容旧API的临时写法”。这本身也是一个很好的技术交流过程。定期回顾可以每周或每双周快速回顾一下AI审查的统计情况通过日志分析看看哪些类型的问题最常见这能反哺团队的代码规范和技术债清理工作。经过几周的磨合你会发现团队提交的代码质量基线有了明显的提升一些常见的“坑”在合并前就被填平了。更重要的是它把开发者从重复性的基础审查中解放出来让他们能更专注于架构设计和核心逻辑的讨论。这个机器人最终成为了我们团队开发流程中一个无声但高效的伙伴。