ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

快速读懂 jevgrep 源码级解析:retrieve 到 selection 的声明单元与调用上下文挑选算法

快速读懂 jevgrep 源码级解析:retrieve 到 selection 的声明单元与调用上下文挑选算法 快速读懂 jevgrep 源码级解析retrieve 到 selection 的声明单元与调用上下文挑选算法【免费下载链接】jevgrepFind code by asking what it does. A CLI for coding agents that uses Jev to discover relevant files and source context.项目地址: https://gitcode.com/gh_mirrors/je/jevgrep面对一个陌生代码库编码代理coding agent最大的时间开销往往是找代码。jevgrep 解决的就是这个问题你用一句自然语言提问jg命令就会返回相关文件、值得追读的函数、以及逐字的源码摘录。 下面我们从 retrieve 到 selection 完整走一遍这条挑选管线看看声明单元和调用上下文究竟是怎么被挑出来的。一句话看懂全流程从提问到源码摘录整条检索管线由一个入口函数串起来retrieve()。它依次完成四件事阶段做什么关键模块① 发现广度优先遍历目录树用 Jev 模型给目录/文件打分retrieve.ts② 解析把入选文件切成一个个声明单元函数、方法、类…source.ts③ 挑选对每个单元做三组布尔判定按阈值取舍selection.ts④ 补全渲染窗口扩展 注释吸附 Python 调用上下文call-context.ts设计上有两个贯穿始终的原则见 docs/architecture.md没有固定 top-N通过相关性门槛0.5的文件全部保留不强行截断成前两名。失败不擦除任何一次判定失败都不能抹掉之前已经拿到的证据。发现阶段用预览和阈值剪枝目录树retrieve()以根目录为种子做逐层遍历L297-L395资源限额单次搜索最多查看 10 万个目录条目单文件超过 1 MB 不再参与源码级检查。批量评分评分请求按不超过 128 项且序列化后不超过 38 KB自动分批一批失败时自动二分重发score()。目录阈值Jev 给出的相关性概率 0.5才继续深入否则该目录被剪枝。文件切块大文件会先用 splitSource() 按 12 KB 切成连续片段分别打分——定位精度因此从整文件提升到文件区段。还有一个精巧的一次机会的二次召回L472-L483若某个高分文件里出现.context单元即类头jevgrep 会以它为关系锚点让之前被剪枝的目录带着内容样本重新参与一轮评分——判断的是这个目录里的代码是否真的声明、继承或直接使用了那个类而不是话题相似。每次评分前还会用内容哈希复核源文件没变unchanged()文件一旦在中途被修改该文件的所有选择结果都会被安全作废而不是基于旧字节给出行号。声明单元inspect() 如何把文件切成可判定的小块声明单元SourceUnit是整个挑选算法的基本货币它长这样source.ts#L6-L14export type SourceUnit { id: string; name: string; // 如 MyClass.handle_request range: Range; // startLine / endLine 行号 sourceByteStart: number; // 字节坐标保证与快照逐字对应 sourceByteEnd: number; partial?: boolean; ownerHeaders?: Range[]; // 所属类的类头位置 };inspect() 按语言分三路处理Python通过内置的 Pyodide CPython 解释器解析 AST拿到方法/函数范围TypeScript/JavaScript直接用 TypeScript 编译器 API 遍历顶层语句与类成员类头会被记为独立的.context单元其他语言降级为按 24 KB 定长切分的纯文本片段fallback: unsupported。两个工程细节值得注意行 ↔ 字节双坐标sourceText() 先算出每一行的字节偏移表之后所有行号都能无损换算成字节区间摘录永远是逐字原文。超大单元再切分单个单元超过sourceUnitBytes 24 KBselection.ts#L15时会按16 行为步长切成标记为partial的小块若切分点落在 UTF-8 多字节字符中间会回退到字符边界textUnits()。selection三重布尔判定与 0.5 / 0.25 / 0.7 三道阈值文件入选后selectFile() 把声明单元分组每组 ≤ 8 个、跨度 ≤ 14 KB连同文件开头 20 行 单元前后各 8 行的上下文发给 Jev对每个单元问三组问题requests.ts#L4-L53q相关性这段代码是否直接实现或控制被调查的行为——注意指令明确写了包含 bug 的当前实现也算因为我们要找的是待调查的代码不是已经正确的代码scope作用域它是否属于查询所指向的那个具体 API / 组件功能相似的另一个 API 不算ref引用关系仅上下文轮它定义的符号是否被其他已选证据直接引用判定结果取三者的最大值随后分三档处理selection.ts#L232-L245阈值含义去向 0.7高置信进入展示层优先渲染到 stdout 0.5相关选为证据跨度selected 0.25值得看一眼记为阅读线索reading leads只给路径和行号选取还有一个可撤销机制上下文二次轮selectEvidence()会把第一轮选出的摘录当作证据回传给第二轮评分此时若某单元的判定 ≤ 0.5系统会把它占用的跨度从已选集合中精确扣除L220-L231。但注意边界只有成功的否定判定才能撤销请求失败的组会原样保留旧选择。调用上下文self.method() 的继承链追踪选出方法体之后Python 文件还会走一次结构化补全它不依赖模型纯 AST 计算类内邻域neighborhood.py为每个被选中的方法补充所在类的类头最多 40 行以及前、后两个兄弟方法——方法不会凭空出现兄弟方法常常解释了共享的状态。继承调用线索calls.py由 localCallContext() 调用扫描被选中方法体内形如self.x()的调用如果x当前类里没有实现就沿MRO 继承链C3 线性化向上找找到后把调用点 父类方法 父类类头都补进展示区间。calls.py的输出里有个诚实的字段unknownEarlierBases——当继承链上的某个祖先类不在本仓库内时追踪结果只是线索而非运行时分派证明jevgrep 会把它标注出来而不是假装确定。这也呼应了架构文档里的定位取回的是证据解释与判断留给调用它的代理。渲染3 行窗口、注释吸附与 0.7 展示层证据跨度要变成你看到的摘录还要过几道工序excerptsFor()每个选定区间向上下各扩3 行留出调用点上下文若扩窗后紧邻注释中间会自动把整条注释吸附进来绝不截断注释展示层只渲染得分 0.7 的决策跨度并自动并入ownerHeaders——所以你看到的每个方法前面通常带着它的类声明。一张表看懂关键常量常量值含义stageWorkers32阶段内并发上限retrieve.ts#L20导航批次≤ 128 项 / 38 KB超限自动分批失败自动二分相关阈值0.5 / 0.25 / 0.7选证据 / 留线索 / 进展示层sourceUnitBytes24 KB声明单元上限超限切 16 行块预览窗口文件头 20 行 单元前后 8 行每次判定附带的上下文渲染扩展±3 行 注释吸附摘录的可读性保证资源限额10 万条目 / 1 MB 文件单次搜索的保险丝小结挑选算法的三个设计取舍读完 retrieve、selection、source 与 call-context可以提炼出三条取舍判定与呈现分离发给 Jev 的证据面0.5比展示面0.7宽——展示可以更严格但证据不能缩水只增不删失败请求不擦除已有证据剪枝目录有机会被锚点二次召回展示层永远可以加结构类头、兄弟方法诚实的不确定行号永远基于不可变快照的哈希仓库外继承基类、被截断的预览都会在输出里被标注而不是静默省略。想进一步看设计动机可以继续读 docs/architecture.md 与 实现记录想看一条真实命令的完整输出样例见 stdout-example.txt。【免费下载链接】jevgrepFind code by asking what it does. A CLI for coding agents that uses Jev to discover relevant files and source context.项目地址: https://gitcode.com/gh_mirrors/je/jevgrep创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表