
本文是对上一版 RepoWise 介绍稿的重写。原稿信息密度很高,但停留在"这是什么"的百科式罗列;这一版尝试回答"为什么会是这样"——从 AI Coding 的演化路径讲起,落到 RepoWise 的源码架构、算法选择、工程权衡,最后用可复现的官方基准数据验证它的核心主张。
全景图:一张图看完 RepoWise
在拆解细节之前,先给一张能概括全文分析框架的图——如果只记住一张图,记住这张:
#mermaid-svg-UzFQhOICPW7XjMXa{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-UzFQhOICPW7XjMXa .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-UzFQhOICPW7XjMXa .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-UzFQhOICPW7XjMXa .error-icon{fill:#552222;}#mermaid-svg-UzFQhOICPW7XjMXa .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-UzFQhOICPW7XjMXa .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-UzFQhOICPW7XjMXa .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-UzFQhOICPW7XjMXa .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-UzFQhOICPW7XjMXa .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-UzFQhOICPW7XjMXa .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-UzFQhOICPW7XjMXa .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-UzFQhOICPW7XjMXa .marker{fill:#333333;stroke:#333333;}#mermaid-svg-UzFQhOICPW7XjMXa .marker.cross{stroke:#333333;}#mermaid-svg-UzFQhOICPW7XjMXa svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-UzFQhOICPW7XjMXa p{margin:0;}#mermaid-svg-UzFQhOICPW7XjMXa .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-UzFQhOICPW7XjMXa .cluster-label text{fill:#333;}#mermaid-svg-UzFQhOICPW7XjMXa .cluster-label span{color:#333;}#mermaid-svg-UzFQhOICPW7XjMXa .cluster-label span p{background-color:transparent;}#mermaid-svg-UzFQhOICPW7XjMXa .label text,#mermaid-svg-UzFQhOICPW7XjMXa span{fill:#333;color:#333;}#mermaid-svg-UzFQhOICPW7XjMXa .node rect,#mermaid-svg-UzFQhOICPW7XjMXa .node circle,#mermaid-svg-UzFQhOICPW7XjMXa .node ellipse,#mermaid-svg-UzFQhOICPW7XjMXa .node polygon,#mermaid-svg-UzFQhOICPW7XjMXa .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-UzFQhOICPW7XjMXa .rough-node .label text,#mermaid-svg-UzFQhOICPW7XjMXa .node .label text,#mermaid-svg-UzFQhOICPW7XjMXa .image-shape .label,#mermaid-svg-UzFQhOICPW7XjMXa .icon-shape .label{text-anchor:middle;}#mermaid-svg-UzFQhOICPW7XjMXa .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-UzFQhOICPW7XjMXa .rough-node .label,#mermaid-svg-UzFQhOICPW7XjMXa .node .label,#mermaid-svg-UzFQhOICPW7XjMXa .image-shape .label,#mermaid-svg-UzFQhOICPW7XjMXa .icon-shape .label{text-align:center;}#mermaid-svg-UzFQhOICPW7XjMXa .node.clickable{cursor:pointer;}#mermaid-svg-UzFQhOICPW7XjMXa .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-UzFQhOICPW7XjMXa .arrowheadPath{fill:#333333;}#mermaid-svg-UzFQhOICPW7XjMXa .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-UzFQhOICPW7XjMXa .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-UzFQhOICPW7XjMXa .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-UzFQhOICPW7XjMXa .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-UzFQhOICPW7XjMXa .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-UzFQhOICPW7XjMXa .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-UzFQhOICPW7XjMXa .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-UzFQhOICPW7XjMXa .cluster text{fill:#333;}#mermaid-svg-UzFQhOICPW7XjMXa .cluster span{color:#333;}#mermaid-svg-UzFQhOICPW7XjMXa div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-UzFQhOICPW7XjMXa .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-UzFQhOICPW7XjMXa rect.text{fill:none;stroke-width:0;}#mermaid-svg-UzFQhOICPW7XjMXa .icon-shape,#mermaid-svg-UzFQhOICPW7XjMXa .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-UzFQhOICPW7XjMXa .icon-shape p,#mermaid-svg-UzFQhOICPW7XjMXa .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-UzFQhOICPW7XjMXa .icon-shape .label rect,#mermaid-svg-UzFQhOICPW7XjMXa .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-UzFQhOICPW7XjMXa .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-UzFQhOICPW7XjMXa .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-UzFQhOICPW7XjMXa :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
Repository 原始代码 + git 历史
Tree-sitter AST · 15 语言
Dependency Graph(NetworkX DiGraph)
Git Analyzerchurn / ownership / co-change
Knowledge Graph+ 自动 Wiki
Decision Graph8 来源 + 证据等级
Risk / Health Graph25 marker → 3 信号
9 个 MCP 工具
Coding AgentClaude Code / Cursor / Codex
一句话概括这张图:Repository Intelligence 本质上是 Graph Computing——所有能力都是同一张依赖图叠加不同数据源之后的投影,最终统一通过 MCP 交给 Agent。后面每一节,其实都是在展开这张图里的某一条边。
一、AI Coding 正在走向"仓库理解"这一层(笔者的归纳,非行业定论)
Claude Code 已经能一次改几十个文件、自主跑测试、自己修 bug。但你有没有注意到一个细节:它每开一个新会话,又要重新 grep 一遍整个仓库。同一个"这个函数为什么这么写"的问题,上周问过一次,这周换个会话,它还是要重新翻commit、重新读注释、重新猜一遍。
它不是没有记忆容量,它根本没有"仓库大脑"。每一轮探索都是这样一个循环:
#mermaid-svg-0KeEbyovQgwfADuz{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-0KeEbyovQgwfADuz .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-0KeEbyovQgwfADuz .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-0KeEbyovQgwfADuz .error-icon{fill:#552222;}#mermaid-svg-0KeEbyovQgwfADuz .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-0KeEbyovQgwfADuz .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-0KeEbyovQgwfADuz .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-0KeEbyovQgwfADuz .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-0KeEbyovQgwfADuz .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-0KeEbyovQgwfADuz .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-0KeEbyovQgwfADuz .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-0KeEbyovQgwfADuz .marker{fill:#333333;stroke:#333333;}#mermaid-svg-0KeEbyovQgwfADuz .marker.cross{stroke:#333333;}#mermaid-svg-0KeEbyovQgwfADuz svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-0KeEbyovQgwfADuz p{margin:0;}#mermaid-svg-0KeEbyovQgwfADuz .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-0KeEbyovQgwfADuz .cluster-label text{fill:#333;}#mermaid-svg-0KeEbyovQgwfADuz .cluster-label span{color:#333;}#mermaid-svg-0KeEbyovQgwfADuz .cluster-label span p{background-color:transparent;}#mermaid-svg-0KeEbyovQgwfADuz .label text,#mermaid-svg-0KeEbyovQgwfADuz span{fill:#333;color:#333;}#mermaid-svg-0KeEbyovQgwfADuz .node rect,#mermaid-svg-0KeEbyovQgwfADuz .node circle,#mermaid-svg-0KeEbyovQgwfADuz .node ellipse,#mermaid-svg-0KeEbyovQgwfADuz .node polygon,#mermaid-svg-0KeEbyovQgwfADuz .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-0KeEbyovQgwfADuz .rough-node .label text,#mermaid-svg-0KeEbyovQgwfADuz .node .label text,#mermaid-svg-0KeEbyovQgwfADuz .image-shape .label,#mermaid-svg-0KeEbyovQgwfADuz .icon-shape .label{text-anchor:middle;}#mermaid-svg-0KeEbyovQgwfADuz .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-0KeEbyovQgwfADuz .rough-node .label,#mermaid-svg-0KeEbyovQgwfADuz .node .label,#mermaid-svg-0KeEbyovQgwfADuz .image-shape .label,#mermaid-svg-0KeEbyovQgwfADuz .icon-shape .label{text-align:center;}#mermaid-svg-0KeEbyovQgwfADuz .node.clickable{cursor:pointer;}#mermaid-svg-0KeEbyovQgwfADuz .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-0KeEbyovQgwfADuz .arrowheadPath{fill:#333333;}#mermaid-svg-0KeEbyovQgwfADuz .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-0KeEbyovQgwfADuz .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-0KeEbyovQgwfADuz .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-0KeEbyovQgwfADuz .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-0KeEbyovQgwfADuz .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-0KeEbyovQgwfADuz .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-0KeEbyovQgwfADuz .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-0KeEbyovQgwfADuz .cluster text{fill:#333;}#mermaid-svg-0KeEbyovQgwfADuz .cluster span{color:#333;}#mermaid-svg-0KeEbyovQgwfADuz div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-0KeEbyovQgwfADuz .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-0KeEbyovQgwfADuz rect.text{fill:none;stroke-width:0;}#mermaid-svg-0KeEbyovQgwfADuz .icon-shape,#mermaid-svg-0KeEbyovQgwfADuz .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-0KeEbyovQgwfADuz .icon-shape p,#mermaid-svg-0KeEbyovQgwfADuz .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-0KeEbyovQgwfADuz .icon-shape .label rect,#mermaid-svg-0KeEbyovQgwfADuz .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-0KeEbyovQgwfADuz .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-0KeEbyovQgwfADuz .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-0KeEbyovQgwfADuz :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
不够
勉强够
下一次会话
收到任务
grep 关键词
读候选文件
够理解了吗?
再 grep 一次
猜测架构 / 猜测意图
修改代码
这个循环每次都要从零跑一遍,token 暴涨、幻觉频发、代码健康越改越差——不是模型不够聪明,而是上下文获取方式本身有问题。
把这几年 AI 编码工具的演化摆在一起看,可以整理出这样一条升级线——这是笔者自己的归纳框架,不是行业公认的分期,标出来是为了让下面的论证有个坐标,而不是暗示"业界已经公认进入第四阶段":
#mermaid-svg-hT1ZtrJhQW8geSa9{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-hT1ZtrJhQW8geSa9 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-hT1ZtrJhQW8geSa9 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-hT1ZtrJhQW8geSa9 .error-icon{fill:#552222;}#mermaid-svg-hT1ZtrJhQW8geSa9 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-hT1ZtrJhQW8geSa9 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-hT1ZtrJhQW8geSa9 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-hT1ZtrJhQW8geSa9 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-hT1ZtrJhQW8geSa9 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-hT1ZtrJhQW8geSa9 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-hT1ZtrJhQW8geSa9 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-hT1ZtrJhQW8geSa9 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-hT1ZtrJhQW8geSa9 .marker.cross{stroke:#333333;}#mermaid-svg-hT1ZtrJhQW8geSa9 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-hT1ZtrJhQW8geSa9 p{margin:0;}#mermaid-svg-hT1ZtrJhQW8geSa9 .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-hT1ZtrJhQW8geSa9 .cluster-label text{fill:#333;}#mermaid-svg-hT1ZtrJhQW8geSa9 .cluster-label span{color:#333;}#mermaid-svg-hT1ZtrJhQW8geSa9 .cluster-label span p{background-color:transparent;}#mermaid-svg-hT1ZtrJhQW8geSa9 .label text,#mermaid-svg-hT1ZtrJhQW8geSa9 span{fill:#333;color:#333;}#mermaid-svg-hT1ZtrJhQW8geSa9 .node rect,#mermaid-svg-hT1ZtrJhQW8geSa9 .node circle,#mermaid-svg-hT1ZtrJhQW8geSa9 .node ellipse,#mermaid-svg-hT1ZtrJhQW8geSa9 .node polygon,#mermaid-svg-hT1ZtrJhQW8geSa9 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-hT1ZtrJhQW8geSa9 .rough-node .label text,#mermaid-svg-hT1ZtrJhQW8geSa9 .node .label text,#mermaid-svg-hT1ZtrJhQW8geSa9 .image-shape .label,#mermaid-svg-hT1ZtrJhQW8geSa9 .icon-shape .label{text-anchor:middle;}#mermaid-svg-hT1ZtrJhQW8geSa9 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-hT1ZtrJhQW8geSa9 .rough-node .label,#mermaid-svg-hT1ZtrJhQW8geSa9 .node .label,#mermaid-svg-hT1ZtrJhQW8geSa9 .image-shape .label,#mermaid-svg-hT1ZtrJhQW8geSa9 .icon-shape .label{text-align:center;}#mermaid-svg-hT1ZtrJhQW8geSa9 .node.clickable{cursor:pointer;}#mermaid-svg-hT1ZtrJhQW8geSa9 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-hT1ZtrJhQW8geSa9 .arrowheadPath{fill:#333333;}#mermaid-svg-hT1ZtrJhQW8geSa9 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-hT1ZtrJhQW8geSa9 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-hT1ZtrJhQW8geSa9 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-hT1ZtrJhQW8geSa9 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-hT1ZtrJhQW8geSa9 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-hT1ZtrJhQW8geSa9 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-hT1ZtrJhQW8geSa9 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-hT1ZtrJhQW8geSa9 .cluster text{fill:#333;}#mermaid-svg-hT1ZtrJhQW8geSa9 .cluster span{color:#333;}#mermaid-svg-hT1ZtrJhQW8geSa9 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-hT1ZtrJhQW8geSa9 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-hT1ZtrJhQW8geSa9 rect.text{fill:none;stroke-width:0;}#mermaid-svg-hT1ZtrJhQW8geSa9 .icon-shape,#mermaid-svg-hT1ZtrJhQW8geSa9 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-hT1ZtrJhQW8geSa9 .icon-shape p,#mermaid-svg-hT1ZtrJhQW8geSa9 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-hT1ZtrJhQW8geSa9 .icon-shape .label rect,#mermaid-svg-hT1ZtrJhQW8geSa9 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-hT1ZtrJhQW8geSa9 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-hT1ZtrJhQW8geSa9 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-hT1ZtrJhQW8geSa9 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
第一阶段 · Copilot补全一行代码
第二阶段 · Cursor编辑一个文件/一个功能
第三阶段 · Claude Code自主完成任务,跨多个文件
第四阶段 · Repository IntelligenceAgent 开始拥有仓库记忆
前三个阶段解决的都是"生成"问题:模型能不能写出正确的代码。但当 Agent 真正开始在大型仓库里长期、多轮、跨会话地工作时,一个新问题浮现出来——Agent 没有记忆。这正是 RepoWise(GitHub: repowise-dev/repowise,AGPL-3.0)想要解决的缺口——它不做代码生成,而是把上面那个"grep → read → guess"的循环,替换成一次性建好、随后可反复查询的仓库记忆层。
这也回答了"为什么 2026 年才出现这类工具":只有当 Agent 真正开始自主、多轮、跨文件地工作(第三阶段成熟之后),"重复探索"的成本才会大到值得专门建一层基础设施去解决。这不是一个孤立的工具,而是 AI Coding Stack 补齐的必然一环。
AI 最大的幻觉,往往不是不会写代码,而是不知道这段代码为什么存在。
二、RepoWise 在 AI Coding Stack 中的位置
#mermaid-svg-NuSab21LhGUgpJyL{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-NuSab21LhGUgpJyL .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-NuSab21LhGUgpJyL .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-NuSab21LhGUgpJyL .error-icon{fill:#552222;}#mermaid-svg-NuSab21LhGUgpJyL .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-NuSab21LhGUgpJyL .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-NuSab21LhGUgpJyL .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-NuSab21LhGUgpJyL .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-NuSab21LhGUgpJyL .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-NuSab21LhGUgpJyL .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-NuSab21LhGUgpJyL .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-NuSab21LhGUgpJyL .marker{fill:#333333;stroke:#333333;}#mermaid-svg-NuSab21LhGUgpJyL .marker.cross{stroke:#333333;}#mermaid-svg-NuSab21LhGUgpJyL svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-NuSab21LhGUgpJyL p{margin:0;}#mermaid-svg-NuSab21LhGUgpJyL .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-NuSab21LhGUgpJyL .cluster-label text{fill:#333;}#mermaid-svg-NuSab21LhGUgpJyL .cluster-label span{color:#333;}#mermaid-svg-NuSab21LhGUgpJyL .cluster-label span p{background-color:transparent;}#mermaid-svg-NuSab21LhGUgpJyL .label text,#mermaid-svg-NuSab21LhGUgpJyL span{fill:#333;color:#333;}#mermaid-svg-NuSab21LhGUgpJyL .node rect,#mermaid-svg-NuSab21LhGUgpJyL .node circle,#mermaid-svg-NuSab21LhGUgpJyL .node ellipse,#mermaid-svg-NuSab21LhGUgpJyL .node polygon,#mermaid-svg-NuSab21LhGUgpJyL .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-NuSab21LhGUgpJyL .rough-node .label text,#mermaid-svg-NuSab21LhGUgpJyL .node .label text,#mermaid-svg-NuSab21LhGUgpJyL .image-shape .label,#mermaid-svg-NuSab21LhGUgpJyL .icon-shape .label{text-anchor:middle;}#mermaid-svg-NuSab21LhGUgpJyL .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-NuSab21LhGUgpJyL .rough-node .label,#mermaid-svg-NuSab21LhGUgpJyL .node .label,#mermaid-svg-NuSab21LhGUgpJyL .image-shape .label,#mermaid-svg-NuSab21LhGUgpJyL .icon-shape .label{text-align:center;}#mermaid-svg-NuSab21LhGUgpJyL .node.clickable{cursor:pointer;}#mermaid-svg-NuSab21LhGUgpJyL .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-NuSab21LhGUgpJyL .arrowheadPath{fill:#333333;}#mermaid-svg-NuSab21LhGUgpJyL .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-NuSab21LhGUgpJyL .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-NuSab21LhGUgpJyL .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-NuSab21LhGUgpJyL .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-NuSab21LhGUgpJyL .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-NuSab21LhGUgpJyL .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-NuSab21LhGUgpJyL .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-NuSab21LhGUgpJyL .cluster text{fill:#333;}#mermaid-svg-NuSab21LhGUgpJyL .cluster span{color:#333;}#mermaid-svg-NuSab21LhGUgpJyL div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-NuSab21LhGUgpJyL .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-NuSab21LhGUgpJyL rect.text{fill:none;stroke-width:0;}#mermaid-svg-NuSab21LhGUgpJyL .icon-shape,#mermaid-svg-NuSab21LhGUgpJyL .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-NuSab21LhGUgpJyL .icon-shape p,#mermaid-svg-NuSab21LhGUgpJyL .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-NuSab21LhGUgpJyL .icon-shape .label rect,#mermaid-svg-NuSab21LhGUgpJyL .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-NuSab21LhGUgpJyL .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-NuSab21LhGUgpJyL .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-NuSab21LhGUgpJyL :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
LLM · 推理能力
Agent · 任务执行 / 工具调用
Repository Intelligence · 仓库记忆层← RepoWise 在这里
Repository · 原始代码 + git 历史
它和几个常被拿来对比的项目并不是同一件事,但边界也没有绝对清晰——这几年这些项目也在互相靠近:
- Sourcegraph:核心优势仍然是代码索引与搜索,但其 Cody/Agentic 相关能力这几年也在往 embeddings、context engine、agent 集成方向扩展,"Sourcegraph 只做搜索"这个刻板印象已经不完全准确;相对而言,RepoWise 更聚焦在代码演化历史、缺陷校准的健康分析和架构决策记录这几块。💡
- DeepWiki:偏"文档生成",把代码变成可读的 Wiki,MCP 工具数量较少(3 个),没有决策层、没有缺陷校准的健康分。✅
- CodeScene:在"代码健康"这条线上路径最接近,两者都做 hotspot、代码健康、技术债分析。但不是简单的"谁功能更多"——CodeScene 在行为式代码分析(behavioral code analysis)这条线上积累更久,RepoWise 的差异化更多在 Agent 原生的 MCP 集成、架构决策挖掘和自动 Wiki 这几块 README 里明确对比过的能力上(详见第八节的对比表)。💡
RepoWise 的定位准确说是:Git 行为智能 + 缺陷校准的代码健康分(带具体修复方案)+ 自动生成文档 + Agent 原生 MCP 接口 + 架构决策记录 + 多仓库协同,这六者叠加在同一份索引上,自托管、开源。✅(这一定位表述与项目 README 的自我定位一致)
三、源码 Walkthrough:五层是怎么变成一条索引管道的
上一版这一节还是"我推测这条链路应该是这样"。这次我实际克隆了 repowise-dev/repowise 仓库读了源码(packages/core/src/repowise/core/),可以给出真实的模块路径和调用关系,而不是根据文档反推。
真实目录结构(节选,对应 commit eb133ce4🔍):
packages/core/src/repowise/core/
├── ingestion/graph/builder.py # class GraphBuilder(…):真正的图构建器
├── pipeline/orchestrator.py # async def run_pipeline(…):唯一的管道入口
├── pipeline/phases/
│ ├── ingestion.py # Phase 1:遍历 + 解析 + 建图
│ ├── git.py # Phase 1:git log + co-change(并行跑)
│ └── analysis.py # Phase 2:dead_code / health / decision
├── analysis/health/scoring.py # 25 个 marker 的权重表 + 打分内核
├── analysis/health/refactoring/ # Extract Class / Move Method / Break Cycle 等
├── analysis/decisions/ # 决策挖掘
└── registry/mcp_tool_registry.py
真实的执行顺序,比原稿画的"一条直线"要更聪明一点——多处是并发跑的,源码注释里写得很清楚:
#mermaid-svg-inVrZfc3gUcnkHZV{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-inVrZfc3gUcnkHZV .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-inVrZfc3gUcnkHZV .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-inVrZfc3gUcnkHZV .error-icon{fill:#552222;}#mermaid-svg-inVrZfc3gUcnkHZV .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-inVrZfc3gUcnkHZV .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-inVrZfc3gUcnkHZV .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-inVrZfc3gUcnkHZV .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-inVrZfc3gUcnkHZV .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-inVrZfc3gUcnkHZV .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-inVrZfc3gUcnkHZV .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-inVrZfc3gUcnkHZV .marker{fill:#333333;stroke:#333333;}#mermaid-svg-inVrZfc3gUcnkHZV .marker.cross{stroke:#333333;}#mermaid-svg-inVrZfc3gUcnkHZV svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-inVrZfc3gUcnkHZV p{margin:0;}#mermaid-svg-inVrZfc3gUcnkHZV .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-inVrZfc3gUcnkHZV .cluster-label text{fill:#333;}#mermaid-svg-inVrZfc3gUcnkHZV .cluster-label span{color:#333;}#mermaid-svg-inVrZfc3gUcnkHZV .cluster-label span p{background-color:transparent;}#mermaid-svg-inVrZfc3gUcnkHZV .label text,#mermaid-svg-inVrZfc3gUcnkHZV span{fill:#333;color:#333;}#mermaid-svg-inVrZfc3gUcnkHZV .node rect,#mermaid-svg-inVrZfc3gUcnkHZV .node circle,#mermaid-svg-inVrZfc3gUcnkHZV .node ellipse,#mermaid-svg-inVrZfc3gUcnkHZV .node polygon,#mermaid-svg-inVrZfc3gUcnkHZV .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-inVrZfc3gUcnkHZV .rough-node .label text,#mermaid-svg-inVrZfc3gUcnkHZV .node .label text,#mermaid-svg-inVrZfc3gUcnkHZV .image-shape .label,#mermaid-svg-inVrZfc3gUcnkHZV .icon-shape .label{text-anchor:middle;}#mermaid-svg-inVrZfc3gUcnkHZV .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-inVrZfc3gUcnkHZV .rough-node .label,#mermaid-svg-inVrZfc3gUcnkHZV .node .label,#mermaid-svg-inVrZfc3gUcnkHZV .image-shape .label,#mermaid-svg-inVrZfc3gUcnkHZV .icon-shape .label{text-align:center;}#mermaid-svg-inVrZfc3gUcnkHZV .node.clickable{cursor:pointer;}#mermaid-svg-inVrZfc3gUcnkHZV .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-inVrZfc3gUcnkHZV .arrowheadPath{fill:#333333;}#mermaid-svg-inVrZfc3gUcnkHZV .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-inVrZfc3gUcnkHZV .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-inVrZfc3gUcnkHZV .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-inVrZfc3gUcnkHZV .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-inVrZfc3gUcnkHZV .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-inVrZfc3gUcnkHZV .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-inVrZfc3gUcnkHZV .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-inVrZfc3gUcnkHZV .cluster text{fill:#333;}#mermaid-svg-inVrZfc3gUcnkHZV .cluster span{color:#333;}#mermaid-svg-inVrZfc3gUcnkHZV div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-inVrZfc3gUcnkHZV .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-inVrZfc3gUcnkHZV rect.text{fill:none;stroke-width:0;}#mermaid-svg-inVrZfc3gUcnkHZV .icon-shape,#mermaid-svg-inVrZfc3gUcnkHZV .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-inVrZfc3gUcnkHZV .icon-shape p,#mermaid-svg-inVrZfc3gUcnkHZV .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-inVrZfc3gUcnkHZV .icon-shape .label rect,#mermaid-svg-inVrZfc3gUcnkHZV .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-inVrZfc3gUcnkHZV .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-inVrZfc3gUcnkHZV .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-inVrZfc3gUcnkHZV :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
repowise init
Phase 1: Ingestion
_run_ingestion遍历 → 解析(进程池) → 建图 → 动态提示
_run_git_indexinggit log → co-change 累积
Phase 2: Analysis
dead_code 分析
health 分析
decision 抽取
Knowledge Graph 骨架(零 LLM,确定性)
Phase 3: Generation(可选)LLM 生成 Wiki 页面
持久化 SQLite + LanceDB
源码里的原话(orchestrator.py 注释)解释了为什么这么设计:Git 索引是 I/O 密集型,和"解析+建图"没有数据依赖,所以两者一开始就并发跑;而 dead_code、health、decision 三个分析共享同一份只读输入(图 + git 元数据 + 解析结果),彼此之间也没有数据依赖,用 asyncio.gather 一起跑——decision 抽取要调 LLM、耗时更长,但它的等待时间被 dead_code 和 health 这两个 CPU 密集型任务的计算时间"藏"起来了。🔍 这是一处原稿完全没提到、但确实体现工程功力的细节:不是简单串行地"先建图、再查 git、再查健康",而是刻意把无依赖的任务并发掉,把慢的 I/O/LLM 调用藏在快的 CPU 计算背后。
图构建器本身的设计也值得一提:GraphBuilder 是这样声明的——
class GraphBuilder(MetricsMixin, ResolveMixin, EdgesMixin, SerializeMixin, RehydrateMixin):
...
🔍 它把"指标计算(PageRank/betweenness)"“符号解析”“建边”“序列化”“从磁盘恢复"拆成五个独立的 Mixin,组合成一个类,而不是一个几千行的巨石类。这个设计本身其实是 RepoWise 自己"反对"的那种大类的反面——某种程度上算是"以身作则”。💡 底层图对象是标准的 networkx.DiGraph,PageRank 和 betweenness 都做了结果缓存(_pagerank_cache),避免重复计算。🔍
数据从一个源文件到最终一个 MCP 响应,实际流经的路径是这样的:
#mermaid-svg-72dCRlZV4AT6KgTF{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-72dCRlZV4AT6KgTF .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-72dCRlZV4AT6KgTF .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-72dCRlZV4AT6KgTF .error-icon{fill:#552222;}#mermaid-svg-72dCRlZV4AT6KgTF .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-72dCRlZV4AT6KgTF .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-72dCRlZV4AT6KgTF .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-72dCRlZV4AT6KgTF .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-72dCRlZV4AT6KgTF .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-72dCRlZV4AT6KgTF .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-72dCRlZV4AT6KgTF .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-72dCRlZV4AT6KgTF .marker{fill:#333333;stroke:#333333;}#mermaid-svg-72dCRlZV4AT6KgTF .marker.cross{stroke:#333333;}#mermaid-svg-72dCRlZV4AT6KgTF svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-72dCRlZV4AT6KgTF p{margin:0;}#mermaid-svg-72dCRlZV4AT6KgTF .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-72dCRlZV4AT6KgTF .cluster-label text{fill:#333;}#mermaid-svg-72dCRlZV4AT6KgTF .cluster-label span{color:#333;}#mermaid-svg-72dCRlZV4AT6KgTF .cluster-label span p{background-color:transparent;}#mermaid-svg-72dCRlZV4AT6KgTF .label text,#mermaid-svg-72dCRlZV4AT6KgTF span{fill:#333;color:#333;}#mermaid-svg-72dCRlZV4AT6KgTF .node rect,#mermaid-svg-72dCRlZV4AT6KgTF .node circle,#mermaid-svg-72dCRlZV4AT6KgTF .node ellipse,#mermaid-svg-72dCRlZV4AT6KgTF .node polygon,#mermaid-svg-72dCRlZV4AT6KgTF .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-72dCRlZV4AT6KgTF .rough-node .label text,#mermaid-svg-72dCRlZV4AT6KgTF .node .label text,#mermaid-svg-72dCRlZV4AT6KgTF .image-shape .label,#mermaid-svg-72dCRlZV4AT6KgTF .icon-shape .label{text-anchor:middle;}#mermaid-svg-72dCRlZV4AT6KgTF .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-72dCRlZV4AT6KgTF .rough-node .label,#mermaid-svg-72dCRlZV4AT6KgTF .node .label,#mermaid-svg-72dCRlZV4AT6KgTF .image-shape .label,#mermaid-svg-72dCRlZV4AT6KgTF .icon-shape .label{text-align:center;}#mermaid-svg-72dCRlZV4AT6KgTF .node.clickable{cursor:pointer;}#mermaid-svg-72dCRlZV4AT6KgTF .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-72dCRlZV4AT6KgTF .arrowheadPath{fill:#333333;}#mermaid-svg-72dCRlZV4AT6KgTF .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-72dCRlZV4AT6KgTF .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-72dCRlZV4AT6KgTF .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-72dCRlZV4AT6KgTF .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-72dCRlZV4AT6KgTF .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-72dCRlZV4AT6KgTF .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-72dCRlZV4AT6KgTF .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-72dCRlZV4AT6KgTF .cluster text{fill:#333;}#mermaid-svg-72dCRlZV4AT6KgTF .cluster span{color:#333;}#mermaid-svg-72dCRlZV4AT6KgTF div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-72dCRlZV4AT6KgTF .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-72dCRlZV4AT6KgTF rect.text{fill:none;stroke-width:0;}#mermaid-svg-72dCRlZV4AT6KgTF .icon-shape,#mermaid-svg-72dCRlZV4AT6KgTF .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-72dCRlZV4AT6KgTF .icon-shape p,#mermaid-svg-72dCRlZV4AT6KgTF .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-72dCRlZV4AT6KgTF .icon-shape .label rect,#mermaid-svg-72dCRlZV4AT6KgTF .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-72dCRlZV4AT6KgTF .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-72dCRlZV4AT6KgTF .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-72dCRlZV4AT6KgTF :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
源文件 .py/.ts/…
Tree-sitter Parser
ParsedFile(AST + 符号列表)
Graph Builder.add_file()写入 File/Symbol 节点
Edge 解析import/call 边
networkx.DiGraph
scoring.py25 个 marker 命中检测
按 _BIOMARKER_WEIGHT_MULTIPLIER加权 + 分类 cap
每文件 1-10 分三信号:defect/maintainability/perf
SQLite
get_health() 等9 个 MCP 工具
这条链路里,scoring.py 里的权重表是实打实校准出来的,不是拍脑袋定的——源码注释写着:这批权重是 2026-05-29 在一个 13 个仓库、5 种语言(Python/TS/JS/Rust/Go)、830 个文件(其中 216 个有过 bug 修复)的语料上,用带 NLOC(代码行数)控制变量的 L2 正则逻辑回归拟合出来的,跨项目留一交叉验证的 AUC 约 0.70。🔍 排名前几的校准后权重是:co_change_scatter(1.8)、change_entropy(1.51)、ownership_risk(1.38)、nested_complexity(1.34)——这和第七节里跑分用的"21 仓库、9 语言、ROC AUC 0.74"是两个不同的语料集:一个用来拟合权重(13 仓库),一个用来做独立验证(21 仓库)。🔍 这个"训练集/验证集分离"的做法本身,是这条数据可信的原因之一——如果拿同一批仓库既调参又验证,AUC 数字会好看得多,但没有意义。💡
为什么增量更新这么快? 因为图是"可切片"的——一次 commit 通常只影响 3-10 个节点,repowise update 只需要重建这些节点及其依赖闭包,而不是重新跑一遍全量索引:
#mermaid-svg-xnewOYeWR1IH9h7H{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-xnewOYeWR1IH9h7H .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-xnewOYeWR1IH9h7H .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-xnewOYeWR1IH9h7H .error-icon{fill:#552222;}#mermaid-svg-xnewOYeWR1IH9h7H .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-xnewOYeWR1IH9h7H .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-xnewOYeWR1IH9h7H .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-xnewOYeWR1IH9h7H .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-xnewOYeWR1IH9h7H .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-xnewOYeWR1IH9h7H .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-xnewOYeWR1IH9h7H .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-xnewOYeWR1IH9h7H .marker{fill:#333333;stroke:#333333;}#mermaid-svg-xnewOYeWR1IH9h7H .marker.cross{stroke:#333333;}#mermaid-svg-xnewOYeWR1IH9h7H svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-xnewOYeWR1IH9h7H p{margin:0;}#mermaid-svg-xnewOYeWR1IH9h7H defs #statediagram-barbEnd{fill:#333333;stroke:#333333;}#mermaid-svg-xnewOYeWR1IH9h7H g.stateGroup text{fill:#9370DB;stroke:none;font-size:10px;}#mermaid-svg-xnewOYeWR1IH9h7H g.stateGroup text{fill:#333;stroke:none;font-size:10px;}#mermaid-svg-xnewOYeWR1IH9h7H g.stateGroup .state-title{font-weight:bolder;fill:#131300;}#mermaid-svg-xnewOYeWR1IH9h7H g.stateGroup rect{fill:#ECECFF;stroke:#9370DB;}#mermaid-svg-xnewOYeWR1IH9h7H g.stateGroup line{stroke:#333333;stroke-width:1;}#mermaid-svg-xnewOYeWR1IH9h7H .transition{stroke:#333333;stroke-width:1;fill:none;}#mermaid-svg-xnewOYeWR1IH9h7H .stateGroup .composit{fill:white;border-bottom:1px;}#mermaid-svg-xnewOYeWR1IH9h7H .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px;}#mermaid-svg-xnewOYeWR1IH9h7H .state-note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-xnewOYeWR1IH9h7H .state-note text{fill:black;stroke:none;font-size:10px;}#mermaid-svg-xnewOYeWR1IH9h7H .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5;}#mermaid-svg-xnewOYeWR1IH9h7H .edgeLabel .label rect{fill:#ECECFF;opacity:0.5;}#mermaid-svg-xnewOYeWR1IH9h7H .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-xnewOYeWR1IH9h7H .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-xnewOYeWR1IH9h7H .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-xnewOYeWR1IH9h7H .edgeLabel .label text{fill:#333;}#mermaid-svg-xnewOYeWR1IH9h7H .label div .edgeLabel{color:#333;}#mermaid-svg-xnewOYeWR1IH9h7H .stateLabel text{fill:#131300;font-size:10px;font-weight:bold;}#mermaid-svg-xnewOYeWR1IH9h7H .node circle.state-start{fill:#333333;stroke:#333333;}#mermaid-svg-xnewOYeWR1IH9h7H .node .fork-join{fill:#333333;stroke:#333333;}#mermaid-svg-xnewOYeWR1IH9h7H .node circle.state-end{fill:#9370DB;stroke:white;stroke-width:1.5;}#mermaid-svg-xnewOYeWR1IH9h7H .end-state-inner{fill:white;stroke-width:1.5;}#mermaid-svg-xnewOYeWR1IH9h7H .node rect{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-xnewOYeWR1IH9h7H .node polygon{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-xnewOYeWR1IH9h7H #statediagram-barbEnd{fill:#333333;}#mermaid-svg-xnewOYeWR1IH9h7H .statediagram-cluster rect{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-xnewOYeWR1IH9h7H .cluster-label,#mermaid-svg-xnewOYeWR1IH9h7H .nodeLabel{color:#131300;}#mermaid-svg-xnewOYeWR1IH9h7H .statediagram-cluster rect.outer{rx:5px;ry:5px;}#mermaid-svg-xnewOYeWR1IH9h7H .statediagram-state .divider{stroke:#9370DB;}#mermaid-svg-xnewOYeWR1IH9h7H .statediagram-state .title-state{rx:5px;ry:5px;}#mermaid-svg-xnewOYeWR1IH9h7H .statediagram-cluster.statediagram-cluster .inner{fill:white;}#mermaid-svg-xnewOYeWR1IH9h7H .statediagram-cluster.statediagram-cluster-alt .inner{fill:#f0f0f0;}#mermaid-svg-xnewOYeWR1IH9h7H .statediagram-cluster .inner{rx:0;ry:0;}#mermaid-svg-xnewOYeWR1IH9h7H .statediagram-state rect.basic{rx:5px;ry:5px;}#mermaid-svg-xnewOYeWR1IH9h7H .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#f0f0f0;}#mermaid-svg-xnewOYeWR1IH9h7H .note-edge{stroke-dasharray:5;}#mermaid-svg-xnewOYeWR1IH9h7H .statediagram-note rect{fill:#fff5ad;stroke:#aaaa33;stroke-width:1px;rx:0;ry:0;}#mermaid-svg-xnewOYeWR1IH9h7H .statediagram-note rect{fill:#fff5ad;stroke:#aaaa33;stroke-width:1px;rx:0;ry:0;}#mermaid-svg-xnewOYeWR1IH9h7H .statediagram-note text{fill:black;}#mermaid-svg-xnewOYeWR1IH9h7H .statediagram-note .nodeLabel{color:black;}#mermaid-svg-xnewOYeWR1IH9h7H .statediagram .edgeLabel{color:red;}#mermaid-svg-xnewOYeWR1IH9h7H #dependencyStart,#mermaid-svg-xnewOYeWR1IH9h7H #dependencyEnd{fill:#333333;stroke:#333333;stroke-width:1;}#mermaid-svg-xnewOYeWR1IH9h7H .statediagramTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-xnewOYeWR1IH9h7H :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
git commit
diff 出受影响文件
图上取 3-10 个受影响节点
沿可达边级联到 Wiki/Health
写回 SQLite + LanceDB
<30 秒完成
检测变更
定位切片
重建切片
级联更新
持久化
官方 README 标注这一过程可以在 3000 文件的仓库上 30 秒内完成。✅
四、算法:一条统一链路,加三个真正值得展开的
原稿只是罗列了 PageRank、Leiden、MFAS、LCOM4、Rabin-Karp 这些名词。上一版逐个解释了理由,但连续五六个术语堆在一起,读起来容易疲劳。这次换个组织方式:先看统一链路,再挑三个最值得展开的算法细讲,剩下的放进"延伸阅读"。
#mermaid-svg-xOzZlIPryJO9w6aM{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-xOzZlIPryJO9w6aM .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-xOzZlIPryJO9w6aM .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-xOzZlIPryJO9w6aM .error-icon{fill:#552222;}#mermaid-svg-xOzZlIPryJO9w6aM .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-xOzZlIPryJO9w6aM .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-xOzZlIPryJO9w6aM .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-xOzZlIPryJO9w6aM .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-xOzZlIPryJO9w6aM .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-xOzZlIPryJO9w6aM .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-xOzZlIPryJO9w6aM .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-xOzZlIPryJO9w6aM .marker{fill:#333333;stroke:#333333;}#mermaid-svg-xOzZlIPryJO9w6aM .marker.cross{stroke:#333333;}#mermaid-svg-xOzZlIPryJO9w6aM svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-xOzZlIPryJO9w6aM p{margin:0;}#mermaid-svg-xOzZlIPryJO9w6aM .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-xOzZlIPryJO9w6aM .cluster-label text{fill:#333;}#mermaid-svg-xOzZlIPryJO9w6aM .cluster-label span{color:#333;}#mermaid-svg-xOzZlIPryJO9w6aM .cluster-label span p{background-color:transparent;}#mermaid-svg-xOzZlIPryJO9w6aM .label text,#mermaid-svg-xOzZlIPryJO9w6aM span{fill:#333;color:#333;}#mermaid-svg-xOzZlIPryJO9w6aM .node rect,#mermaid-svg-xOzZlIPryJO9w6aM .node circle,#mermaid-svg-xOzZlIPryJO9w6aM .node ellipse,#mermaid-svg-xOzZlIPryJO9w6aM .node polygon,#mermaid-svg-xOzZlIPryJO9w6aM .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-xOzZlIPryJO9w6aM .rough-node .label text,#mermaid-svg-xOzZlIPryJO9w6aM .node .label text,#mermaid-svg-xOzZlIPryJO9w6aM .image-shape .label,#mermaid-svg-xOzZlIPryJO9w6aM .icon-shape .label{text-anchor:middle;}#mermaid-svg-xOzZlIPryJO9w6aM .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-xOzZlIPryJO9w6aM .rough-node .label,#mermaid-svg-xOzZlIPryJO9w6aM .node .label,#mermaid-svg-xOzZlIPryJO9w6aM .image-shape .label,#mermaid-svg-xOzZlIPryJO9w6aM .icon-shape .label{text-align:center;}#mermaid-svg-xOzZlIPryJO9w6aM .node.clickable{cursor:pointer;}#mermaid-svg-xOzZlIPryJO9w6aM .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-xOzZlIPryJO9w6aM .arrowheadPath{fill:#333333;}#mermaid-svg-xOzZlIPryJO9w6aM .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-xOzZlIPryJO9w6aM .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-xOzZlIPryJO9w6aM .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-xOzZlIPryJO9w6aM .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-xOzZlIPryJO9w6aM .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-xOzZlIPryJO9w6aM .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-xOzZlIPryJO9w6aM .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-xOzZlIPryJO9w6aM .cluster text{fill:#333;}#mermaid-svg-xOzZlIPryJO9w6aM .cluster span{color:#333;}#mermaid-svg-xOzZlIPryJO9w6aM div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-xOzZlIPryJO9w6aM .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-xOzZlIPryJO9w6aM rect.text{fill:none;stroke-width:0;}#mermaid-svg-xOzZlIPryJO9w6aM .icon-shape,#mermaid-svg-xOzZlIPryJO9w6aM .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-xOzZlIPryJO9w6aM .icon-shape p,#mermaid-svg-xOzZlIPryJO9w6aM .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-xOzZlIPryJO9w6aM .icon-shape .label rect,#mermaid-svg-xOzZlIPryJO9w6aM .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-xOzZlIPryJO9w6aM .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-xOzZlIPryJO9w6aM .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-xOzZlIPryJO9w6aM :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
Dependency Graph
Leiden模块划分
MFAS打破循环依赖
JaccardMove Method 判断
Refactoring Plan
Code Health Score
为什么用 Leiden 而不是更常见的 Louvain 做社区检测? Louvain 有一个已知缺陷——可能产生"内部不连通"的社区(一个社区里的节点在图上其实并不相连),这在依赖图场景下是致命的:如果一个"逻辑模块"被判定出来,但里面的文件互相根本没有调用关系,这个模块划分就没有实际意义。Leiden 算法保证了社区内部连通性,同时收敛更快、结果更稳定,这正是"把调用图划分成有意义的逻辑模块"这个任务需要的性质。💡
为什么用 MFAS 处理循环依赖? MFAS(Minimum Feedback Arc Set,最小反馈边集)解决的是"删除最少的边使图无环"这个组合优化问题。放在依赖图场景下,它给出的是"打破这个循环依赖,最少需要移除哪几条 import 边"——这比人工去看循环依赖列表、猜测该切哪条边要精确得多,这也是 Break Cycle 重构建议的算法基础。💡
为什么用 Jaccard 相似度做 Move Method 判断(feature envy 检测)? Jaccard 系数衡量的是两个集合的重叠程度。用在这里,是比较"一个方法实际调用的字段/方法集合"与"它所在类 vs 目标类的字段/方法集合"的重叠度——如果一个方法对另一个类的重叠度显著高于对自己类的重叠度,就是经典的 feature envy(依恋情结),应该被移动过去。这是一个可以量化、可以排序的判断,而不是"看起来应该搬过去"的直觉。💡
这三个算法选择背后有一条共同逻辑:都是确定性的、可复现的、不依赖 LLM 的。这也解释了为什么 Code Health 这一层能做到"零 LLM 调用、30 秒内跑完 3000 个文件"——本质上是传统静态分析算法的组合应用,权重通过在真实缺陷语料上做 L2 正则逻辑回归拟合出来(见上一节源码里的具体数字),而不是像大多数 linter 那样靠经验手调阈值。🔍
延伸阅读(其余算法,简要备注,感兴趣可自行查证):LCOM4(衡量类内聚度,相比早期 LCOM1-3 能正确处理"通过共享字段间接连通"的方法组,是 Extract Class 建议的基础);Rabin-Karp(滚动哈希做重复代码检测,天然抗变量重命名,用于全仓库克隆扫描);PageRank / Betweenness(衡量节点在依赖图中的全局重要性,决定重构建议的排序优先级)。💡
五、Decision Intelligence:AI 幻觉的另一个根源
在往下讲工程细节之前,值得单独展开 Decision Intelligence 这一层——它在原稿里只占了几行,但可能是整个项目里最容易被低估的部分。Agent 出现幻觉,很多时候不是编不出代码,而是不知道"这里为什么要这样写",于是它按自己的假设重新发明了一遍,和已有决策冲突。RepoWise 把这件事变成了一张可追溯的证据图:
#mermaid-svg-6kZ1TiorWH7K0bVl{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-6kZ1TiorWH7K0bVl .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-6kZ1TiorWH7K0bVl .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-6kZ1TiorWH7K0bVl .error-icon{fill:#552222;}#mermaid-svg-6kZ1TiorWH7K0bVl .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-6kZ1TiorWH7K0bVl .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-6kZ1TiorWH7K0bVl .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-6kZ1TiorWH7K0bVl .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-6kZ1TiorWH7K0bVl .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-6kZ1TiorWH7K0bVl .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-6kZ1TiorWH7K0bVl .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-6kZ1TiorWH7K0bVl .marker{fill:#333333;stroke:#333333;}#mermaid-svg-6kZ1TiorWH7K0bVl .marker.cross{stroke:#333333;}#mermaid-svg-6kZ1TiorWH7K0bVl svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-6kZ1TiorWH7K0bVl p{margin:0;}#mermaid-svg-6kZ1TiorWH7K0bVl .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-6kZ1TiorWH7K0bVl .cluster-label text{fill:#333;}#mermaid-svg-6kZ1TiorWH7K0bVl .cluster-label span{color:#333;}#mermaid-svg-6kZ1TiorWH7K0bVl .cluster-label span p{background-color:transparent;}#mermaid-svg-6kZ1TiorWH7K0bVl .label text,#mermaid-svg-6kZ1TiorWH7K0bVl span{fill:#333;color:#333;}#mermaid-svg-6kZ1TiorWH7K0bVl .node rect,#mermaid-svg-6kZ1TiorWH7K0bVl .node circle,#mermaid-svg-6kZ1TiorWH7K0bVl .node ellipse,#mermaid-svg-6kZ1TiorWH7K0bVl .node polygon,#mermaid-svg-6kZ1TiorWH7K0bVl .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-6kZ1TiorWH7K0bVl .rough-node .label text,#mermaid-svg-6kZ1TiorWH7K0bVl .node .label text,#mermaid-svg-6kZ1TiorWH7K0bVl .image-shape .label,#mermaid-svg-6kZ1TiorWH7K0bVl .icon-shape .label{text-anchor:middle;}#mermaid-svg-6kZ1TiorWH7K0bVl .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-6kZ1TiorWH7K0bVl .rough-node .label,#mermaid-svg-6kZ1TiorWH7K0bVl .node .label,#mermaid-svg-6kZ1TiorWH7K0bVl .image-shape .label,#mermaid-svg-6kZ1TiorWH7K0bVl .icon-shape .label{text-align:center;}#mermaid-svg-6kZ1TiorWH7K0bVl .node.clickable{cursor:pointer;}#mermaid-svg-6kZ1TiorWH7K0bVl .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-6kZ1TiorWH7K0bVl .arrowheadPath{fill:#333333;}#mermaid-svg-6kZ1TiorWH7K0bVl .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-6kZ1TiorWH7K0bVl .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-6kZ1TiorWH7K0bVl .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-6kZ1TiorWH7K0bVl .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-6kZ1TiorWH7K0bVl .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-6kZ1TiorWH7K0bVl .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-6kZ1TiorWH7K0bVl .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-6kZ1TiorWH7K0bVl .cluster text{fill:#333;}#mermaid-svg-6kZ1TiorWH7K0bVl .cluster span{color:#333;}#mermaid-svg-6kZ1TiorWH7K0bVl div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-6kZ1TiorWH7K0bVl .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-6kZ1TiorWH7K0bVl rect.text{fill:none;stroke-width:0;}#mermaid-svg-6kZ1TiorWH7K0bVl .icon-shape,#mermaid-svg-6kZ1TiorWH7K0bVl .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-6kZ1TiorWH7K0bVl .icon-shape p,#mermaid-svg-6kZ1TiorWH7K0bVl .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-6kZ1TiorWH7K0bVl .icon-shape .label rect,#mermaid-svg-6kZ1TiorWH7K0bVl .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-6kZ1TiorWH7K0bVl .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-6kZ1TiorWH7K0bVl .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-6kZ1TiorWH7K0bVl :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
CLI 手动录入
Decision Graph
源码内联标记# WHY: / # DECISION:
Git 考古学
ADRNygard/MADR
CHANGELOG
PR body
README
Claude 会话 transcript确定性过滤
证据等级
verified
fuzzy
unverified
状态
proposed
active
deprecated
superseded
八个来源汇聚成一张带证据等级、带状态流转的图,get_why 工具就是在这张图上做检索。Repository Intelligence 不是让 Agent 写得更快,而是让 Agent 拥有一份可查证的长期记忆——这句话放在决策层上体现得最直接。
六、工程权衡:为什么是 SQLite + LanceDB,而不是 Neo4j + Milvus
这是原稿完全没有触及的一块。一个"图数据库 + 向量数据库"的组合,理论上更自然的选择是 Neo4j(图)+ Milvus/Pinecone(向量)这类专用系统。RepoWise 选了 SQLite(结构化元数据)+ NetworkX(内存图计算)+ LanceDB(本地向量存储)✅,这是一个明显偏"轻量本地化"的选择,代价和收益都很清楚:
| 部署 | 需要独立服务、运维成本 | 单文件、零部署 |
| 增量更新 | 依赖数据库自身的事务/索引机制 | 内存图直接切片重建,更灵活但受限于单机内存 |
| 隐私 | 数据可能经过网络传输给云服务 | 100% 本地,源码不出机器 |
| 规模上限 | 支撑千万级节点无压力 | 官方标注约 3 万+节点级别 ✅ |
| 多仓库 | 天然支持分布式 | 通过 workspace 模式在单机内做跨仓库联邦查询 |
这个权衡本质上是"给个人开发者/中小团队自托管"这个定位决定的——如果目标用户是要在自己笔记本上 pip install 之后立刻能跑,那专用图数据库的部署成本就是不可接受的。反过来说,这个架构决定了它目前不太适合动辄百万文件的超大型 monorepo(官方也建议这种情况先用 –mode fast 索引再升级)。⚠️("3 万+节点"上限及超大型 monorepo 建议属于官方文档措辞,具体数字建议作者发布前用最新文档核对一次)
七、验证:官方数据是否经得起推敲
原稿直接照抄了官网的几个数字(token 减少 96%、文件读取减少 89%、工具调用减少 70%、缺陷捕获提升 2.3 倍),没有做任何验证。这次我去查了 RepoWise 专门用来自证的基准仓库 repowise-bench,结论是:这几个数字不是纯营销话术,方法论是公开、可复现的,但有一个前提必须先说清楚——这些数字全部来自项目自己发布的基准报告,是自我报告(self-reported),不是第三方独立复现或同行评审的结果。可复现≠已被复现,读者如果拿它做重大技术选型依据,建议自己跑一遍 repowise-bench 里的脚本验证。
Agent 效率benchmark:这是在 pallets/flask 和 scikit-learn/scikit-learn 两个真实开源仓库上,用同一个模型(claude-sonnet-4-6)、同一套 SWE-QA 任务集,对比"带 RepoWise MCP 工具"和"不带"两种配置跑出来的成对实验(paired benchmark)。✅ 官方给出的具体数字是:单次 get_context 调用加载上下文从 64,039 token 降到 2,391 token(约 27 倍),跨两个基准仓库文件读取减少 69%-89%,工具调用减少 49%-70%,且回答质量基本持平(at parity)——这个"质量持平"的限定词原稿完全没提,但它其实是这组数据能否成立的关键前提:如果省了 token 但答案变差了,这个优化就没有意义。✅
代码健康分是否真的预测缺陷:这是原稿吹得最响、但也最该被质疑的一条。官方基准是在 21 个开源仓库、覆盖 9 种"Full 语言层级"语言、共 2,770 个文件上,与 CodeScene(这个赛道公认的商业标杆)做的头对头对比,且明确控制了"无数据泄漏"(健康分在历史某个 commit 计算,缺陷修复统计的是之后 6 个月内的真实修复记录)。✅ 实测结果:
| Recall@20%行数预算 | 0.173 | 0.074 |
| 效力感知排序(Popt) | 0.607 | 0.462 |
| 缺陷密度(按规模归一化) | 2.18× | 0.56× |
| ROC AUC(判别力) | 0.731 | 0.705 |
跨项目平均 ROC AUC 为 0.74(95% CI 0.68–0.79),个别仓库最高到 0.90;控制文件规模后依然显著(偏 Spearman ρ = −0.16,说明不是简单"标记大文件");在从未见过的外部数据集(PROMISE/jEdit)上 AUC 仍有 0.76–0.78。✅
这组数据比原稿引用的营销页数字更有说服力,因为它是头对头、控制了数据泄漏、跑在真实开源仓库上的对比,而不是自说自话。当然,ROC AUC 0.74 严格来说属于"中等偏上"的判别力,不是"精准预测",官方自己的表述也是"预测性的,不是绝对的"——这个自谦的限定词值得保留,避免读者误以为这是一个"零误报"的工具。✅
比起 ROC AUC 这种统计学术语,其实有一个更直觉的视角:Reviewer 每天只能看那么多文件。真正决定健康分有没有用的,不是它在理论上多"精准",而是——
#mermaid-svg-RXW0DAxmnG7zr8Bb{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-RXW0DAxmnG7zr8Bb .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-RXW0DAxmnG7zr8Bb .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-RXW0DAxmnG7zr8Bb .error-icon{fill:#552222;}#mermaid-svg-RXW0DAxmnG7zr8Bb .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-RXW0DAxmnG7zr8Bb .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-RXW0DAxmnG7zr8Bb .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-RXW0DAxmnG7zr8Bb .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-RXW0DAxmnG7zr8Bb .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-RXW0DAxmnG7zr8Bb .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-RXW0DAxmnG7zr8Bb .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-RXW0DAxmnG7zr8Bb .marker{fill:#333333;stroke:#333333;}#mermaid-svg-RXW0DAxmnG7zr8Bb .marker.cross{stroke:#333333;}#mermaid-svg-RXW0DAxmnG7zr8Bb svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-RXW0DAxmnG7zr8Bb p{margin:0;}#mermaid-svg-RXW0DAxmnG7zr8Bb .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-RXW0DAxmnG7zr8Bb .cluster-label text{fill:#333;}#mermaid-svg-RXW0DAxmnG7zr8Bb .cluster-label span{color:#333;}#mermaid-svg-RXW0DAxmnG7zr8Bb .cluster-label span p{background-color:transparent;}#mermaid-svg-RXW0DAxmnG7zr8Bb .label text,#mermaid-svg-RXW0DAxmnG7zr8Bb span{fill:#333;color:#333;}#mermaid-svg-RXW0DAxmnG7zr8Bb .node rect,#mermaid-svg-RXW0DAxmnG7zr8Bb .node circle,#mermaid-svg-RXW0DAxmnG7zr8Bb .node ellipse,#mermaid-svg-RXW0DAxmnG7zr8Bb .node polygon,#mermaid-svg-RXW0DAxmnG7zr8Bb .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-RXW0DAxmnG7zr8Bb .rough-node .label text,#mermaid-svg-RXW0DAxmnG7zr8Bb .node .label text,#mermaid-svg-RXW0DAxmnG7zr8Bb .image-shape .label,#mermaid-svg-RXW0DAxmnG7zr8Bb .icon-shape .label{text-anchor:middle;}#mermaid-svg-RXW0DAxmnG7zr8Bb .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-RXW0DAxmnG7zr8Bb .rough-node .label,#mermaid-svg-RXW0DAxmnG7zr8Bb .node .label,#mermaid-svg-RXW0DAxmnG7zr8Bb .image-shape .label,#mermaid-svg-RXW0DAxmnG7zr8Bb .icon-shape .label{text-align:center;}#mermaid-svg-RXW0DAxmnG7zr8Bb .node.clickable{cursor:pointer;}#mermaid-svg-RXW0DAxmnG7zr8Bb .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-RXW0DAxmnG7zr8Bb .arrowheadPath{fill:#333333;}#mermaid-svg-RXW0DAxmnG7zr8Bb .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-RXW0DAxmnG7zr8Bb .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-RXW0DAxmnG7zr8Bb .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-RXW0DAxmnG7zr8Bb .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-RXW0DAxmnG7zr8Bb .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-RXW0DAxmnG7zr8Bb .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-RXW0DAxmnG7zr8Bb .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-RXW0DAxmnG7zr8Bb .cluster text{fill:#333;}#mermaid-svg-RXW0DAxmnG7zr8Bb .cluster span{color:#333;}#mermaid-svg-RXW0DAxmnG7zr8Bb div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-RXW0DAxmnG7zr8Bb .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-RXW0DAxmnG7zr8Bb rect.text{fill:none;stroke-width:0;}#mermaid-svg-RXW0DAxmnG7zr8Bb .icon-shape,#mermaid-svg-RXW0DAxmnG7zr8Bb .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-RXW0DAxmnG7zr8Bb .icon-shape p,#mermaid-svg-RXW0DAxmnG7zr8Bb .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-RXW0DAxmnG7zr8Bb .icon-shape .label rect,#mermaid-svg-RXW0DAxmnG7zr8Bb .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-RXW0DAxmnG7zr8Bb .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-RXW0DAxmnG7zr8Bb .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-RXW0DAxmnG7zr8Bb :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
随机/按修改时间
按 RepoWise 健康分排序
有限的 Review 预算比如每天只看 20 个文件
按什么排序?
baseline命中率 ~24%
Recall@20%0.173 vs CodeScene 0.074
在同样只能看 20 个文件的预算约束下,按健康分排序找到的真实 bug 数量是 CodeScene 的 2.3 倍——这才是"Recall@20%行数预算"这个指标真正想说明的事情:不是分数打得准不准,而是有限的人力精力该往哪投。✅
Distill(命令输出压缩):pytest -q(11 个失败用例)从 3,374 token 压到 1,317(省 61%,且 11 条失败信息全部保留);git log -50 省 89%;git diff(30 次提交)省 86%。✅ 这条原稿完全没提,但其实是日常使用中体感最强的一个功能——它解决的是"Agent 读命令行输出时被噪音淹没"这个很具体的痛点。
八、正面对比:RepoWise 到底比谁强、强在哪
原稿只是说了句"对标 CodeScene / DeepWiki / Sourcegraph",没有真正列出差异。下面这张表是根据官方文档整理、并标注了我认为需要读者自行判断的地方:
| 自托管开源 | ✅ AGPL-3.0 | ❌ 云端 | ✅(Docker) | ❌(企业版才有) |
| MCP 原生接口 | ✅ 9 个工具 | ✅ 3 个工具 | ✅ | ✅ |
| 代码健康分 | ✅ 25 marker,缺陷校准 | ❌ | ✅ 25-30 marker | ❌ |
| 跨文件重构方案(带 blast radius) | ✅ | ❌ | ⚠️ 仅限单函数内 | ❌ |
| 架构决策挖掘 | ✅ 8 个来源 | ❌ | ❌ | ❌ |
| 自动生成 Wiki | ✅ | ✅ | ❌ | ✅(PR2Doc) |
| 从使用历史学习(会话挖掘决策、按需求分配 Wiki 生成预算) | ✅ | ❌ | ❌ | ❌ |
| 多仓库协同 | ✅ 跨仓库 co-change + 联邦 MCP | ❌ | ❌ | ❌ |
(数据来源:RepoWise 官方 README 的对比表,已核实与其自身基准报告一致 ✅;作为项目自己给出的对比表,天然会突出自身优势,建议读者结合第七节的第三方可复现基准一起看待,而不是只信这张表)
RepoWise 真正的差异化不是"五层都有"(DeepWiki、CodeScene 也各有一部分),而是决策层(Decision Intelligence)和"缺陷校准的健康分 + 具体修复方案"这个组合——前者是把"为什么这么设计"当作可追溯资产系统化对待的较早尝试之一,后者是"不仅告诉你哪里有问题,还告诉你具体该怎么改、影响半径多大"。据笔者目前查到的信息,这两块的组合方式还没有直接对标物,但笔者没有做穷尽式的同类项目调研,这个判断有被推翻的可能。💡
九、RepoWise 做不到什么
国外技术博客写清楚一个工具的局限,往往比吹嘘功能更能建立信任。这几点是读完源码和文档后我认为需要如实说明的边界:
- Graph 不理解业务语义。 它知道 A 调用了 B,不知道"B 是核心结算逻辑,改动需要走双人复核"这种业务规则——这类知识仍然要靠 Decision Intelligence 由人工/AI 会话逐步喂入,图本身不会凭空理解重要性。💡
- Decision Intelligence 依赖历史留痕。 如果一个项目从来没写过 commit message、没留注释、没开过 PR 讨论,8 个来源里能挖到的证据会很稀薄,unverified 的比例会偏高——这层的价值和团队既有的文档习惯强相关,不是无中生有。💡
- Health Score 是预测,不是证明。 ROC AUC 0.74 意味着"倾向性更高",不意味着"这个文件一定有 bug";把它当成排优先级的工具是合理的,当成"零误报的质检机器"就会误用。✅(官方自己的措辞也是"predictive, not absolute")
- 本地图数据库架构有规模上限。 第六节讨论过,SQLite + 内存图这套组合官方标注约 3 万+节点级别体验最好,动辄百万文件的超大型 monorepo 建议先用 –mode fast 索引。⚠️(具体数字请以最新文档为准)
- LLM 仍然不可替代。 Graph/Git/Health 三层可以零 LLM 跑,但 Wiki 生成、语义问答(get_answer)、决策抽取里"这段话是不是在陈述一个架构决定"这类语义判断,依然需要 LLM 参与——RepoWise 解决的是"减少 Agent 探索成本",不是"消灭对 LLM 的依赖"。💡
十、源码设计点评:三个我喜欢的地方,三个我觉得还能改进的地方
我最喜欢的三个设计:
我认为还能改进的地方:
十一、快速上手(保留精华,供实操)
# 零 API Key 也能跑:Graph + Git + Health + 死代码检测
pip install repowise
cd your-repo
repowise init –index-only -y
# 需要自动 Wiki + 语义搜索时补上 provider
export ANTHROPIC_API_KEY=sk-ant-...
repowise init –provider anthropic
# 日常
repowise serve # MCP + 本地 Dashboard
repowise update # 增量同步,<30s
repowise health –refactoring-targets
repowise risk main..HEAD
repowise distill pytest -q
Claude Code 接入:
/plugin marketplace add repowise-dev/repowise
/plugin install repowise@repowise
# 或直接注册 MCP:
claude mcp add repowise — repowise mcp
托管版(repowise.dev)面向团队,提供托管部署、免安装的 hosted MCP 端点、免费的 PR Bot(零 LLM 调用的确定性评论)。⚠️ 具体价格档位我没有找到可验证来源,原稿写的"$15/mo 起"建议发布前自行到官网核实,避免定价过期。
十二、我的判断:RepoWise 真正在构建的是什么
如果只能用一句话概括 RepoWise 的价值,我不会说"它是一个自动生成 Wiki 的工具",也不会说"它是一个健康分工具"。
我认为它真正的价值点是:把"为什么这么设计"这件事,从散落在 commit、PR、注释里的隐性知识,变成了一份可查询、可追溯、带证据等级(verified/fuzzy/unverified)的结构化资产——这不代表它是唯一或最早这么做的项目,但确实是目前笔者见过的、把这件事做得最系统化的开源实现之一。这恰好是 AI 编码时代很大的一块知识缺口——代码越来越多是 AI 写的,人类 ownership 和决策记忆却在同步流失,而这个决策层正是在补这个洞。
再往远处看,"仓库"这个概念本身也在被重新定义:
#mermaid-svg-41DmfQREYsuU4MNt{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-41DmfQREYsuU4MNt .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-41DmfQREYsuU4MNt .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-41DmfQREYsuU4MNt .error-icon{fill:#552222;}#mermaid-svg-41DmfQREYsuU4MNt .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-41DmfQREYsuU4MNt .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-41DmfQREYsuU4MNt .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-41DmfQREYsuU4MNt .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-41DmfQREYsuU4MNt .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-41DmfQREYsuU4MNt .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-41DmfQREYsuU4MNt .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-41DmfQREYsuU4MNt .marker{fill:#333333;stroke:#333333;}#mermaid-svg-41DmfQREYsuU4MNt .marker.cross{stroke:#333333;}#mermaid-svg-41DmfQREYsuU4MNt svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-41DmfQREYsuU4MNt p{margin:0;}#mermaid-svg-41DmfQREYsuU4MNt .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-41DmfQREYsuU4MNt .cluster-label text{fill:#333;}#mermaid-svg-41DmfQREYsuU4MNt .cluster-label span{color:#333;}#mermaid-svg-41DmfQREYsuU4MNt .cluster-label span p{background-color:transparent;}#mermaid-svg-41DmfQREYsuU4MNt .label text,#mermaid-svg-41DmfQREYsuU4MNt span{fill:#333;color:#333;}#mermaid-svg-41DmfQREYsuU4MNt .node rect,#mermaid-svg-41DmfQREYsuU4MNt .node circle,#mermaid-svg-41DmfQREYsuU4MNt .node ellipse,#mermaid-svg-41DmfQREYsuU4MNt .node polygon,#mermaid-svg-41DmfQREYsuU4MNt .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-41DmfQREYsuU4MNt .rough-node .label text,#mermaid-svg-41DmfQREYsuU4MNt .node .label text,#mermaid-svg-41DmfQREYsuU4MNt .image-shape .label,#mermaid-svg-41DmfQREYsuU4MNt .icon-shape .label{text-anchor:middle;}#mermaid-svg-41DmfQREYsuU4MNt .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-41DmfQREYsuU4MNt .rough-node .label,#mermaid-svg-41DmfQREYsuU4MNt .node .label,#mermaid-svg-41DmfQREYsuU4MNt .image-shape .label,#mermaid-svg-41DmfQREYsuU4MNt .icon-shape .label{text-align:center;}#mermaid-svg-41DmfQREYsuU4MNt .node.clickable{cursor:pointer;}#mermaid-svg-41DmfQREYsuU4MNt .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-41DmfQREYsuU4MNt .arrowheadPath{fill:#333333;}#mermaid-svg-41DmfQREYsuU4MNt .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-41DmfQREYsuU4MNt .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-41DmfQREYsuU4MNt .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-41DmfQREYsuU4MNt .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-41DmfQREYsuU4MNt .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-41DmfQREYsuU4MNt .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-41DmfQREYsuU4MNt .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-41DmfQREYsuU4MNt .cluster text{fill:#333;}#mermaid-svg-41DmfQREYsuU4MNt .cluster span{color:#333;}#mermaid-svg-41DmfQREYsuU4MNt div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-41DmfQREYsuU4MNt .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-41DmfQREYsuU4MNt rect.text{fill:none;stroke-width:0;}#mermaid-svg-41DmfQREYsuU4MNt .icon-shape,#mermaid-svg-41DmfQREYsuU4MNt .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-41DmfQREYsuU4MNt .icon-shape p,#mermaid-svg-41DmfQREYsuU4MNt .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-41DmfQREYsuU4MNt .icon-shape .label rect,#mermaid-svg-41DmfQREYsuU4MNt .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-41DmfQREYsuU4MNt .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-41DmfQREYsuU4MNt .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-41DmfQREYsuU4MNt :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
尚未发生,仅为推演
过去Repository = Git 版本历史
现在Repository = Graph+Git+Docs+Decisions+Health的复合索引
未来Repository = 持续自我更新的World Model
Planning推演变更影响
Simulation模拟修改后果
Self-Evolution自主治理代码库
(虚线部分是笔者的推演,不是 RepoWise 现有能力,标出来是为了说明方向,而不是暗示它已经做到)💡
代码文件只是这个 World Model 的"观测值"(observation),真正有价值的是从这些观测值里提炼出的架构关系、知识归属、决策依据、风险分布和演化轨迹。这里想强调的重点,其实不是"RepoWise 已经代表了未来",而是Repository Intelligence 这一层为什么大概率会成为 AI Coding 基础设施的标配——Agent 的探索成本是真实存在且会持续增长的问题,谁来解决、用什么架构解决还有很大变数,但"要解决"这件事本身不太可能是伪需求。RepoWise 现在做的,是把这个方向的雏形跑通、跑到能自证有效(用真实缺陷数据验证)的程度,是当前笔者看到的、最接近这一方向的开源探索之一,而不是终局答案。这不代表它已经完美——AUC 0.74 不是万能药,本地图数据库架构也有规模上限,前面几节提到的局限也都是真实存在的边界。
如果再往外推一层,"仓库智能"本身也只是一个更大范围的中间站:
#mermaid-svg-MvjmiHb1bKku9DxQ{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-MvjmiHb1bKku9DxQ .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-MvjmiHb1bKku9DxQ .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-MvjmiHb1bKku9DxQ .error-icon{fill:#552222;}#mermaid-svg-MvjmiHb1bKku9DxQ .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-MvjmiHb1bKku9DxQ .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-MvjmiHb1bKku9DxQ .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-MvjmiHb1bKku9DxQ .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-MvjmiHb1bKku9DxQ .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-MvjmiHb1bKku9DxQ .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-MvjmiHb1bKku9DxQ .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-MvjmiHb1bKku9DxQ .marker{fill:#333333;stroke:#333333;}#mermaid-svg-MvjmiHb1bKku9DxQ .marker.cross{stroke:#333333;}#mermaid-svg-MvjmiHb1bKku9DxQ svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-MvjmiHb1bKku9DxQ p{margin:0;}#mermaid-svg-MvjmiHb1bKku9DxQ .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-MvjmiHb1bKku9DxQ .cluster-label text{fill:#333;}#mermaid-svg-MvjmiHb1bKku9DxQ .cluster-label span{color:#333;}#mermaid-svg-MvjmiHb1bKku9DxQ .cluster-label span p{background-color:transparent;}#mermaid-svg-MvjmiHb1bKku9DxQ .label text,#mermaid-svg-MvjmiHb1bKku9DxQ span{fill:#333;color:#333;}#mermaid-svg-MvjmiHb1bKku9DxQ .node rect,#mermaid-svg-MvjmiHb1bKku9DxQ .node circle,#mermaid-svg-MvjmiHb1bKku9DxQ .node ellipse,#mermaid-svg-MvjmiHb1bKku9DxQ .node polygon,#mermaid-svg-MvjmiHb1bKku9DxQ .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-MvjmiHb1bKku9DxQ .rough-node .label text,#mermaid-svg-MvjmiHb1bKku9DxQ .node .label text,#mermaid-svg-MvjmiHb1bKku9DxQ .image-shape .label,#mermaid-svg-MvjmiHb1bKku9DxQ .icon-shape .label{text-anchor:middle;}#mermaid-svg-MvjmiHb1bKku9DxQ .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-MvjmiHb1bKku9DxQ .rough-node .label,#mermaid-svg-MvjmiHb1bKku9DxQ .node .label,#mermaid-svg-MvjmiHb1bKku9DxQ .image-shape .label,#mermaid-svg-MvjmiHb1bKku9DxQ .icon-shape .label{text-align:center;}#mermaid-svg-MvjmiHb1bKku9DxQ .node.clickable{cursor:pointer;}#mermaid-svg-MvjmiHb1bKku9DxQ .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-MvjmiHb1bKku9DxQ .arrowheadPath{fill:#333333;}#mermaid-svg-MvjmiHb1bKku9DxQ .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-MvjmiHb1bKku9DxQ .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-MvjmiHb1bKku9DxQ .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-MvjmiHb1bKku9DxQ .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-MvjmiHb1bKku9DxQ .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-MvjmiHb1bKku9DxQ .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-MvjmiHb1bKku9DxQ .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-MvjmiHb1bKku9DxQ .cluster text{fill:#333;}#mermaid-svg-MvjmiHb1bKku9DxQ .cluster span{color:#333;}#mermaid-svg-MvjmiHb1bKku9DxQ div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-MvjmiHb1bKku9DxQ .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-MvjmiHb1bKku9DxQ rect.text{fill:none;stroke-width:0;}#mermaid-svg-MvjmiHb1bKku9DxQ .icon-shape,#mermaid-svg-MvjmiHb1bKku9DxQ .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-MvjmiHb1bKku9DxQ .icon-shape p,#mermaid-svg-MvjmiHb1bKku9DxQ .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-MvjmiHb1bKku9DxQ .icon-shape .label rect,#mermaid-svg-MvjmiHb1bKku9DxQ .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-MvjmiHb1bKku9DxQ .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-MvjmiHb1bKku9DxQ .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-MvjmiHb1bKku9DxQ :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
尚未发生,仅为推演
Repository单仓库的代码结构
Repository IntelligenceRepoWise 现在做的
Engineering Intelligence跨仓库、跨工具链的工程全景
Organization Intelligence团队、知识、效能、风险的组织画像
RepoWise 现在的 Workspace 模式已经在做"跨仓库 co-change、契约检测"这一步,某种程度上是 Engineering Intelligence 的雏形;但"知道团队知识分布在哪些人身上、知道研发效能瓶颈在哪个环节、知道组织性风险(而不只是代码风险)",是明显更远的一步,目前没有证据表明 RepoWise 已经在做这件事——这条虚线纯属笔者推演,标出来是希望读者看清"现在做到了什么"和"未来可能往哪走"之间的边界,而不是把预测当成既成事实。💡
未来的代码仓库,或许不再是一组文件,而是一个可以被追问、被推演的世界模型。



