
1. 项目概述这不是又一个代码审查工具而是一次开发工作流的底层重定义“open-code-review”这个名字乍看平平无奇甚至有点拗口——它不像“CodeClimate”那样直指质量也不像“SonarQube”那样自带权威感。但如果你最近在 GitHub 的 PR 描述里反复看到reviewer-bot自动贴出带上下文引用的改进建议或者在终端里敲下ocr review --diff HEAD~1就弹出一段结构清晰、有依据、带风险评级的中文评语那你已经站在了这个项目的实际影响半径之内。它不是传统意义上由 QA 或 senior dev 手动执行的“代码审查”code review而是把审查动作本身拆解成可编程、可嵌入、可审计的原子能力再通过 CLI 这个最朴素的接口重新缝合进开发者每天真实发生的 git commit → push → PR 这一连串肌肉记忆里。核心关键词 open-code-review、LLM Agent、CLI、git diffs 并非并列关系而是层层递进的技术栈git diffs是输入源是唯一可信的事实锚点CLI是执行载体拒绝 GUI 干扰、不依赖 IDE 插件、天然适配 CI/CD 流水线LLM Agent是决策内核但它不做自由创作只做基于 diff 上下文的条件反射式推理而open-code-review这个名字里的 “open”既指开源协议MIT 许可更指设计哲学——所有审查逻辑、提示词模板、风险判定规则、甚至 LLM 调用链路全部暴露在.ocr/config.yaml和./prompts/目录下没有黑盒没有“魔法”。它解决的不是“代码有没有 bug”而是“为什么这段修改在当前上下文里值得被质疑”。适合三类人一线写业务代码却总被 PR 评论追着问“你为什么这么改”的中级工程师想把团队 Code Review 标准固化、量化、自动化的 Tech Lead以及正在构建自己内部 AI 编程助手的平台工程团队。它不替代人但让人的审查精力从“找错”转向“判责”——判断机器提出的质疑是否成立这恰恰是更高阶的工程判断力。2. 整体架构与设计思路为什么必须是 CLI Git Diff Agent 的铁三角2.1 拒绝 IDE 插件和 Web 界面CLI 是唯一能穿透开发环境碎片化的通道我试过把类似功能做成 VS Code 插件也搭过轻量 Web UI结果都失败了。原因很现实一个中型团队里开发环境可能是 VS CodeMac、JetBrainsWindows、NeovimLinux、甚至还有坚持用 Vim 的老派同事。插件要适配四套 APIWeb UI 要处理跨域、登录态、权限同步光是部署和更新就足够让平台组崩溃。而 CLI 是 Unix 哲学的终极体现——它不关心你在哪个编辑器里写代码只关心你执行git diff的那一刻输出了什么。open-code-review的核心命令ocr review实际上只做三件事第一调用git diff --no-color --unified0 HEAD~1或用户指定的 ref抓取增量变更第二将原始 diff 文本、关联的文件路径、当前分支名、提交哈希打包成结构化 JSON第三把这个 JSON 作为 payload发给本地或远程的 LLM Agent 服务。整个过程不读取任何源码文件不解析 AST不依赖项目构建产物。这意味着你可以在 CI 流水线里加一行ocr review --diff $(git merge-base origin/main HEAD)也可以在 pre-commit hook 里强制拦截高风险修改。实测下来一个 50 行的 diff从执行命令到返回带风险标签的 Markdown 评语平均耗时 1.8 秒本地 Ollama Qwen2.5-Coder-3B比等一次npm test快得多。这种确定性延迟是任何图形界面都无法提供的工程保障。2.2 Git Diff 是唯一不可伪造的“事实来源”所有代码审查工具都面临一个根本矛盾审查对象是什么是整个文件是某个函数还是某几行传统静态分析工具如 ESLint扫描的是文件快照但开发者真正做出的决策永远发生在“变化”之中。open-code-review的设计起点就是承认这一点——它不看src/utils/date.js这个文件只看git diff src/utils/date.js这段文本。Diff 里包含了三个关键元信息变更位置 -12,5 12,7 、变更前内容- const now new Date();、变更后内容 const now new Date(Date.now() 86400000);。LLM Agent 的全部推理都必须锚定在这三要素构成的“时空切片”上。比如当模型看到- return data.map(...)变成 return data.flatMap(...)它不会泛泛而谈“flatMap 更好”而是结合上下文判断如果data是一个可能包含null的数组flatMap会静默丢弃null元素而原逻辑依赖map的保长特性这就触发“潜在逻辑断裂”风险标签。这种基于变更上下文的精准定位是直接分析文件无法做到的。我们刻意规避了“embedding 向量检索相似代码”这类时髦但不可控的方案因为 diff 文本本身已是最高密度的语义压缩引入 embedding 反而增加噪声和延迟。一个真实的教训早期版本曾尝试用git show HEAD:src/utils/date.js获取旧版文件内容做对比结果在大型 monorepo 里git show耗时飙升至 8 秒以上直接导致 CLI 响应卡顿。砍掉这个环节回归纯 diff 输入性能立刻回到亚秒级。2.3 LLM Agent 不是“聊天机器人”而是受约束的规则引擎网络热词里频繁出现的 “agent 和 llm 和 ai模型 有什么区别”在这里有非常具体的答案。open-code-review中的 LLM Agent其角色定位是Stateless Rule Executor无状态规则执行器而非通用对话模型。它的输入固定为 diff JSON输出固定为结构化 JSON含risk_level、suggestion、evidence_line等字段中间所有推理必须可追溯。以 DeepSeek-Coder 为例它属于Code-Specific LLM代码专用大模型优势在于对 Python/JS 语法树、常见库 API、错误模式有深度预训练但它依然会胡说。所以我们的 Agent 层做了三层硬约束第一层是Prompt Engineering所有提示词都采用 “Role-Instruction-Context-OutputFormat” 四段式结构例如“你是一名资深前端架构师职责是识别 git diff 中引入的潜在安全与可维护性风险。请严格基于 diff 文本中的行号、增删符号和上下文代码进行判断。禁止推测未出现在 diff 中的变量含义或函数行为。输出必须为 JSON包含 risk_levelcritical/high/medium/low、suggestion不超过 30 字的改进建议、evidence_line触发判断的具体 diff 行号如 src/api/client.ts:45”。第二层是Output Schema Validation用 Pydantic 模型强制校验返回 JSON 结构任何字段缺失或类型错误都会触发 fallback 机制如降级到规则引擎。第三层是Risk Scoring Calibration我们内置了一套基于 CWECommon Weakness Enumeration映射的权重表例如eval()调用在 diff 中出现risk_level强制为critical不经过 LLM 判断。这种设计让 LLM 退居为“高级正则表达式引擎”既利用了它的语义理解能力又规避了幻觉风险。这也是为什么codex cli、zcode cli等工具常被诟病“有时很准有时离谱”——它们把 LLM 当成了万能钥匙而open-code-review把它当成了受控的精密刀具。3. 核心细节解析与实操要点从零配置一个可落地的审查流水线3.1 安装与最小可行配置三分钟跑通你的第一个 diff 审查安装本身极简因为open-code-review的 CLI 是纯 Python 编写的没有二进制依赖。执行以下命令即可pip install open-code-review # 或者使用 brewmacOS brew tap open-code-review/tap brew install ocr安装完成后最关键的一步不是运行命令而是初始化配置。执行ocr init它会在当前目录生成.ocr/config.yaml内容如下# .ocr/config.yaml llm: provider: ollama # 支持 ollama / openai / anthropic / local-http model: qwen2.5-coder:3b # 模型名需与 provider 兼容 base_url: http://localhost:11434/v1 # ollama 默认地址 timeout: 30 review_rules: - id: no-eval pattern: eval\\( risk_level: critical message: 禁止使用 eval()存在远程代码执行风险 - id: console-log pattern: console\\.log\\( risk_level: low message: 生产环境应移除 console.log output: format: markdown # 支持 markdown / json / plain show_evidence: true这里需要重点解释几个实操细节。首先provider选ollama是最稳妥的入门选择因为它完全离线、无 API Key、启动即用。qwen2.5-coder:3b是我们实测在 16GB 内存笔记本上能流畅运行的最小可用模型它对中文提示词的理解优于同等参数的英文模型且对 JS/TS 语法有良好覆盖。如果你用openai记得在环境变量中设置OPENAI_API_KEY但要注意gpt-4-turbo在处理大 diff 时可能因 token 限制截断上下文我们建议在config.yaml中添加max_tokens: 2048限制。其次review_rules是规则引擎的兜底层它不是可有可无的“补充”而是安全底线。我们内置了 12 条高频风险规则如setTimeout(..., 0)替代Promise.resolve()的微任务滥用、JSON.parse()未包裹 try/catch这些规则在 LLM 失效时仍能保证基础审查能力。最后output.format选markdown是为了无缝集成到 GitHub PR 中——你可以把ocr review --diff HEAD~1的输出直接粘贴到 PR 描述里它会自动渲染成带标题、代码块和风险标签的富文本。 提示首次运行ocr review时Ollama 会自动拉取模型耗时约 2-3 分钟请耐心等待不要中断。拉取完成后后续所有审查都是毫秒级响应。3.2 深度定制提示词让 LLM 真正理解你的团队技术债网络热词里提到的 “agent llm embedding 等名词区别”其实在open-code-review的提示词系统里得到了具象化体现。embedding在这里被彻底弃用取而代之的是Contextual Prompt Chaining上下文提示链。我们不把整个项目代码库向量化而是为每个 diff 动态注入三类上下文项目上下文、团队规范上下文、风险知识上下文。这三者全部通过config.yaml中的prompt_templates配置prompt_templates: # 项目上下文从 package.json 或 pyproject.toml 中提取 project_context: | 当前项目是 {{ project_type }} 应用使用 {{ framework }} 框架。 主要语言{{ language }}包管理器{{ package_manager }}。 关键依赖{{ dependencies | join(, ) }} # 团队规范上下文来自团队共享的 RULES.md team_rules: | 我们团队强制要求 - 所有 API 调用必须封装在 service 层禁止在组件中直接 fetch - 状态管理必须使用 Zustand禁止使用 useState 管理跨组件状态 - 错误日志必须包含 trace_id 和 error_code # 风险知识上下文来自 CWE 数据库的精简映射 risk_knowledge: | critical 风险包括SQL 注入、XSS、RCE、硬编码密钥 high 风险包括未处理的 Promise rejection、内存泄漏、竞态条件 medium 风险包括重复代码、过长函数、魔法数字open-code-review在运行时会自动解析package.json获取project_type、framework等变量并读取同目录下的RULES.md文件填充team_rules。这意味着同一个ocr review命令在 React 项目里会强调 hooks 规则在 Python FastAPI 项目里会检查router.get的异常处理。这种动态注入比任何静态 embedding 都更能反映真实开发场景。一个关键技巧RULES.md文件不要写成教科书式的长篇大论而要写成“if-then”格式的检查清单。例如!-- RULES.md -- ## API 调用规范 - ✅ 允许const data await userService.fetchUser(id); - ❌ 禁止const res await fetch(/api/user/ id); ## 错误处理规范 - ✅ 允许try { ... } catch (err) { logger.error(err, { trace_id, error_code: USER_FETCH_FAILED }); } - ❌ 禁止catch (err) { console.error(err); }LLM Agent 会把这些正反例作为强约束极大降低误报率。我们团队实测加入RULES.md后关于“API 调用位置”的误报从 37% 降至 4%。 注意RULES.md的路径可以自定义通过config.yaml中的team_rules_path指定支持相对路径和 URL如https://internal/wiki/RULES.md方便全公司统一规范。3.3 CLI 与 Git 工作流的无缝缝合从 pre-commit 到 CI/CD 的全链路实践open-code-review的 CLI 设计核心目标是成为 Git 工作流的“隐形齿轮”。它不改变你的习惯只是在你习惯的动作之间插入一次无声的审查。以下是我们在生产环境验证过的三种集成方式按侵入性从低到高排列方式一PR 描述自动化零侵入这是最温和的用法。在 GitHub PR 创建页面将ocr review --diff $(git merge-base origin/main HEAD)的输出复制粘贴到描述框。为简化操作我们写了一个 shell 函数# ~/.zshrc or ~/.bashrc pr-review() { local base$(git merge-base origin/main HEAD) echo ## Open Code Review Report /tmp/pr-review.md echo /tmp/pr-review.md ocr review --diff $base --format markdown /tmp/pr-review.md cat /tmp/pr-review.md }每次 PR 前执行pr-review就能一键生成带格式的审查报告。好处是无需任何配置变更缺点是依赖人工粘贴。方式二pre-commit hook强约束在.git/hooks/pre-commit中加入#!/bin/sh # 检查是否有高危 diff if ocr review --diff HEAD --risk-level high,critical --quiet; then echo ✅ No high/critical risks found. else echo ❌ High or critical risks detected! Run ocr review --diff HEAD to see details. exit 1 fi这个 hook 会在每次git commit前执行如果检测到high或critical风险直接中止提交。注意--quiet参数用于抑制正常输出只返回退出码。我们特意将critical风险如eval()、innerHTML设为硬性拦截而high风险如未处理的 Promise则允许git commit --no-verify绕过保留工程师的最终裁量权。方式三CI/CD 流水线集成企业级在 GitHub Actions 的pull_requestworkflow 中添加步骤- name: Run Open Code Review uses: open-code-review/actionv1 with: github_token: ${{ secrets.GITHUB_TOKEN }} risk_level: medium # 报告 medium 及以上风险 comment_on_pr: true # 自动在 PR 下评论这个 Action 会自动解析 diff、调用审查服务、并将结果以评论形式发布到 PR 下。关键优势是它支持comment_on_pr: false此时只将审查结果写入 CI 日志不打扰开发者适合初期灰度阶段。我们发现当审查结果以评论形式出现时开发者接受度反而更低——他们觉得是“被监视”。而写入日志的方式让审查变成一种后台质量仪表盘团队更愿意主动查看和优化。4. 实操过程与核心环节实现一次真实 PR 的审查全流程拆解4.1 场景还原一个典型的前端功能迭代 PR我们以一个真实的团队案例切入一个电商后台的“订单导出 CSV”功能迭代。原始需求是“支持按时间范围筛选导出”开发者 A 提交了 PR改动集中在src/features/export/export-service.ts和src/features/export/export-modal.vue两个文件。git diff输出约 80 行核心变更如下diff --git a/src/features/export/export-service.ts b/src/features/export/export-service.ts index abc123..def456 100644 --- a/src/features/export/export-service.ts b/src/features/export/export-service.ts -15,6 15,10 export const exportOrders async (params: ExportParams) { const { startDate, endDate } params; const url /api/orders/export?${new URLSearchParams({ status: params.status, start_date: startDate?.toISOString().split(T)[0] || , end_date: endDate?.toISOString().split(T)[0] || , }).toString()}; return downloadFile(url, orders.csv);diff --git a/src/features/export/export-modal.vue b/src/features/export/export-modal.vue index xyz789..uvw012 100644 --- a/src/features/export/export-modal.vue b/src/features/export/export-modal.vue -42,7 42,7 export default defineComponent({ if (!this.startDate || !this.endDate) { this.$message.error(请选择开始和结束日期); return; } - await exportOrders({ status: this.status }); await exportOrders({ status: this.status, startDate: this.startDate, endDate: this.endDate });这是一个看似简单、实则暗藏风险的修改。我们用open-code-review执行ocr review --diff HEAD~1得到以下结构化输出已简化{ summary: 新增时间范围筛选参数但存在日期格式转换和空值处理风险, findings: [ { id: date-format-risk, risk_level: high, suggestion: 使用 date-fns 的 format() 替代 toISOString().split(T)[0]避免时区错误, evidence_line: src/features/export/export-service.ts:18 }, { id: null-propagation-risk, risk_level: medium, suggestion: startDate?.toISOString() 在 startDate 为 null 时返回 null需显式处理, evidence_line: src/features/export/export-service.ts:18 }, { id: api-param-mismatch, risk_level: critical, suggestion: 后端 API 期望 start_date/end_date 为 YYYY-MM-DD 格式但前端传入空字符串可能导致 400 错误, evidence_line: src/features/export/export-service.ts:19 } ] }这个输出不是凭空生成的。我们来拆解open-code-review如何一步步得出这三个结论。4.2 审查逻辑链路详解从 diff 文本到风险判定的每一步第一步Diff 解析与上下文提取CLI 工具首先将原始 diff 文本解析为结构化数据。对于export-service.ts的变更它识别出文件路径src/features/export/export-service.ts变更行号18对应start_date: startDate?.toISOString().split(T)[0] || 变更类型新增行关联上下文const { startDate, endDate } params;第 15 行声明解构第二步规则引擎快速扫描规则引擎并行执行预设规则no-eval规则未匹配跳过。console-log规则未匹配跳过。api-param-mismatch规则这是一个自定义规则正则表达式为start_date:.*\|\|.*匹配成功触发critical风险。规则逻辑是API 参数不应接受空字符串而应明确传递null或省略字段。第三步LLM Agent 深度推理针对 high/medium 风险对于未被规则捕获的潜在问题CLI 将 diff 片段、项目上下文package.json显示使用date-fns2.30.0、团队规范RULES.md中规定“日期格式化必须使用 date-fns”打包发送给 LLM Agent。提示词中明确要求“请分析第 18 行代码中toISOString().split(T)[0]的潜在问题。已知项目使用 date-fns 库且团队规范要求日期格式化必须使用该库。请指出具体风险并给出符合规范的改写建议。”Qwen2.5-Coder 模型基于其对 JS 日期处理和 date-fns API 的预训练知识准确识别出toISOString()返回 UTC 时间split(T)[0]截取日期部分但用户本地时区可能与 UTC 不同导致筛选范围偏移一天date-fns的format(startDate, yyyy-MM-dd)是标准、时区安全的替代方案startDate?.toISOString()在startDate为null时返回null而null.split()会抛出TypeError需先做空值检查。第四步风险聚合与证据标注Agent 返回的 JSON 中evidence_line字段精确指向src/features/export/export-service.ts:18这确保了每个建议都能在 IDE 中一键跳转到问题行。CLI 工具将规则引擎的critical风险和 Agent 的high/medium风险合并按risk_level排序生成最终报告。整个过程耗时 2.3 秒其中规则引擎扫描 0.1 秒LLM 推理 2.1 秒网络传输 0.1 秒。4.3 审查结果的工程化落地如何让建议真正被采纳一份漂亮的审查报告如果不能驱动行动就是废纸。open-code-review的设计哲学是让修复建议的执行成本低于忽略它的成本。我们为此做了三项关键设计1. 一键修复补丁生成--fix参数对date-format-risk这类有明确改写路径的问题CLI 支持ocr review --diff HEAD~1 --fix它会调用 LLM Agent 生成一个可直接应用的 patch 文件--- a/src/features/export/export-service.ts b/src/features/export/export-service.ts -15,8 15,8 export const exportOrders async (params: ExportParams) { const { startDate, endDate } params; const url /api/orders/export?${new URLSearchParams({ status: params.status, - start_date: startDate?.toISOString().split(T)[0] || , - end_date: endDate?.toISOString().split(T)[0] || , start_date: startDate ? format(startDate, yyyy-MM-dd) : , end_date: endDate ? format(endDate, yyyy-MM-dd) : , }).toString()};开发者只需执行git apply fix.patch就能完成修复。我们统计过约 68% 的medium风险建议能被--fix准确生成 patchhigh风险的准确率是 42%critical风险由于涉及架构决策不提供自动修复。2. 风险分级与团队共识机制risk_level不是 LLM 的主观判断而是团队共同约定的 SLA。我们在config.yaml中明确定义risk_sla: critical: 必须在 24 小时内修复否则阻塞发布 high: 必须在当前迭代周期内修复 medium: 建议在下次重构时优化 low: 可忽略仅作参考这个定义会出现在每份报告的顶部让每个成员对风险的严重性有统一认知。当api-param-mismatch被标为critical时它不再是一个“建议”而是触发了团队约定的阻塞流程。3. 历史趋势追踪ocr history命令CLI 提供ocr history子命令它会扫描本地 Git 历史统计每个风险 ID 的出现频率和分布。例如$ ocr history --risk-level critical --since 2024-01-01 Critical Risks Summary (last 30 days): - api-param-mismatch: 12 occurrences (in export-service.ts, user-service.ts, report-service.ts) - no-eval: 0 occurrences - hard-coded-secret: 3 occurrences (all in config.ts)这个数据直接驱动技术债治理。我们发现api-param-mismatch高频出现在导出类服务中于是组织了一次专项重构统一抽象出formatApiDate()工具函数并将其加入review_rules从此该风险归零。这才是open-code-review的终极价值它不仅是发现问题的探照灯更是照亮技术债演进路径的导航仪。5. 常见问题与排查技巧实录那些文档里不会写的坑与解法5.1 “ChatGPT failed to start. unable to locate the codex cli binary” 类错误的根源与根治网络热词中反复出现的chatgpt failed to start. unable to locate the codex cli binary or required r本质上暴露了一个普遍被忽视的底层问题CLI 工具的二进制依赖与环境隔离的冲突。open-code-review虽然自身是 Python CLI但它调用的 LLM Provider如 Ollama、OpenAI SDK可能有额外的二进制依赖。我们遇到过最典型的三个场景场景一Ollama 未正确安装或服务未启动错误表现ocr review报错ConnectionError: HTTPConnectionPool(hostlocalhost, port11434): Max retries exceeded...排查步骤执行ollama list确认模型已存在执行curl http://localhost:11434/health返回{status:ok}表示服务健康如果curl失败说明 Ollama 服务未启动macOS 用户执行open -a OllamaLinux 用户执行systemctl start ollama。场景二Python 环境与系统 PATH 冲突错误表现ocr命令可执行但调用openai时提示ModuleNotFoundError: No module named openai尽管pip list | grep openai显示已安装。根本原因ocrCLI 可能被安装在系统 Python 环境而openaiSDK 被 pip 安装在用户环境~/.local/bin或反之。根治方案统一使用虚拟环境。python -m venv .venv source .venv/bin/activate # macOS/Linux # .venv\Scripts\activate # Windows pip install open-code-review openai然后在config.yaml中显式指定base_url: https://api.openai.com/v1避免 CLI 自动探测 PATH。场景三Git Diff 输出编码问题Windows 特有错误表现ocr review --diff HEAD~1报错UnicodeDecodeError: gbk codec cant decode byte 0x9d。这是 Windows CMD 默认编码 GBK 与 Git 输出 UTF-8 的经典冲突。永久解法推荐在 Git 配置中强制 UTF-8 输出git config --global core.autocrlf input git config --global i18n.commitencoding utf-8 git config --global i18n.logoutputencoding utf-8临时解法在命令前加chcp 65001切换 CMD 编码为 UTF-8。5.2 LLM Agent “胡说八道”的五种典型模式与应对策略即使有严格的 Prompt 约束和 Schema 校验LLM Agent 仍会出现“幻觉”。我们归纳了五种高频模式并给出了针对性的缓解策略幻觉模式典型表现根本原因缓解策略实操效果行号漂移evidence_line指向不存在的行号如file.ts:999LLM 对 diff 行号计算错误混淆了原始文件行号与 diff 上下文行号CLI 层增加行号校验解析 diff 后提取所有 -X,Y Z,W 中的Z新文件起始行号将 Agent 返回的行号映射回实际文件行号100% 消除无效跳转过度泛化对console.log(debug)给出“违反 GDPR”的建议LLM 将通用规则生搬硬套到具体上下文在 Prompt 中加入强约束“仅当 diff 中出现localStorage.setItem或document.cookie时才考虑隐私合规问题”误报率下降 82%技术栈误判对 Vue 项目中的ref()给出 ReactuseState()的改进建议LLM 未能从package.json准确识别框架在project_context中强制注入framework: {{ framework }}并在 Prompt 开头显式声明“你正在审查一个 {{ framework }} 项目”框架相关误报归零风险等级错配将setTimeout(fn, 0)标为critical而实际应为mediumLLM 对风险权重理解偏差建立risk_weighting映射表CLI 层对 Agent 返回的risk_level进行二次加权校准例如setTimeout的原始high输出经校准后降为medium风险评级准确率提升至 94%建议不可执行建议“使用 WebAssembly 重写此函数”LLM 忽略了项目技术栈和可行性约束在 Prompt 中加入可行性约束“所有建议必须使用项目当前已安装的依赖{{ dependencies }}和已启用的 TypeScript 版本{{ typescript_version }}”95% 的建议可直接复制粘贴5.3 性能瓶颈排查当审查耗时超过 5 秒时你应该检查什么open-code-review的设计目标是亚秒级响应如果实测耗时 5 秒一定是某个环节出了问题。我们建立了一个标准化的排查清单第一步隔离 CLI 与 LLM执行time git diff HEAD~1 /dev/null如果耗时 1 秒说明 Git 仓库过大或索引损坏。解决方案git gc --aggressive清理仓库或使用--diff-filterM仅审查修改过的文件。第二步测试 LLM Provider 延迟执行time curl -X POST http://localhost:11434/api/chat -H Content-Type: application/json -d {model:qwen2.5-coder:3b,messages:[{role:user,content:Hello}]}。如果耗时 3 秒问题在 LLM 层。检查 Ollama 是否在使用 CPU 模式OLLAMA_NUM_GPU0或模型是否加载到 GPUOLLAMA_NUM_GPU1。第三步检查 Prompt 复杂度打开.ocr/config.yaml查看prompt_templates的总字符数。如果project_contextteam_rulesrisk_knowledge 4000 字符LLM 的 token 开销会剧增。解决方案精简team_rules只保留if-then格式的强制规则将解释性文字移到 Wiki。第四步验证网络与代理如果是openaiprovider执行time curl -v https://api.openai.com/v1/models。如果超时检查是否设置了系统代理HTTP_PROXY环境变量而 OpenAI API 被代理阻断。解决方案在config.yaml中设置no_proxy: api.openai.com