yek:用 Git 历史给文件排优先级,把仓库压成一份 LLM 可读的文本
A fast Rust based tool to serialize text-based files in a repository or directory for LLM consumption
秒懂
- 它是什么?
- yek 是一个 Rust 写的命令行工具,把目录或仓库里的文本文件序列化成单个文件。它的取舍很清楚:默认按 .gitignore 过滤、按 Git 提交历史推断文件重要性,并让重要文件排在输出末尾。本文梳理它的机制、配置、边界,以及什么时候不该用它。
- 适合谁用?
- yek 适合需要把本地代码库快速变成一段上下文的工程师,尤其是已经用 .gitignore 管理仓库、并且希望重要文件落在上下文尾部的人。如果你的仓库几乎没有提交历史,或者你依赖的是跨仓库的语义检索而不是单次快照,yek 的排序逻辑帮不上忙。
- 能商用吗?
- 可以。MIT 是宽松许可证:你可以使用、修改并销售基于它的软件,只需保留版权和许可证声明。
- 还在维护吗?
- 在维护。仓库最近一次提交在 78 天前。
- 用什么语言写的?
- 主要是 Rust(依据 GitHub 的语言统计)。
以上回答依据项目的 GitHub 数据(最近同步于 2026年9月15日)和我们的分析,不构成法律意见。
开源项目深度解析
它要解决的是「把哪些文件塞进上下文」这个问题
把代码库交给模型时,真正的困难不是读取文件,而是决定读哪些。一个中等规模的仓库动辄上千个文件,其中大量是锁文件、构建产物、二进制资源和测试夹具。手工挑选既慢又容易漏。yek 的定位就是替你做这个筛选:它在仓库或目录里跑一遍,把文本文件按某种顺序拼成一个文件输出。README 把它描述为「a fast Rust based tool to serialize text-based files in a repository or directory for LLM consumption」。目标读者是那些需要反复把代码库喂给模型的人,比如用命令行配合剪贴板做代码问答,或者把仓库快照作为提示词的一部分。它不调用任何模型接口,也不做嵌入或检索,输出就是纯文本,后续怎么用完全由你决定。
默认行为:三个过滤层加一个排序规则
yek 不做任何配置直接运行时,会依次套用几层规则。第一层是 .gitignore,README 明确写着默认「Uses `.gitignore` rules to skip unwanted files」。第二层是内置的忽略模式,覆盖二进制文件和过大的文件,README 称之为「Infers additional ignore patterns (binary, large, etc.)」。第三层才是你通过 --ignore-patterns 追加的规则。排序逻辑是这里最值得注意的部分:yek 用 Git 历史推断哪些文件更重要,并且把重要文件放在输出末尾。README 给的理由是「LLMs tend to pay more attention to content that appears later in the context」。这是个有意的设计选择,把模型对上下文首尾位置敏感这一常见观察直接编码进了输出格式。README 里的示例输出顺序是 README.md、tests/test.rs、src/utils.rs、src/main.rs,可以看到入口文件排在最后。
输出格式由 --output-template 控制,默认值是 ">>>> FILE_PATH\nFILE_CONTENT",也就是每个文件前面加一行 >>>> 加路径。管道场景下行为会变:README 说明它会「Automatically detects if output is being piped and streams content instead of writing to files」。也就是说 yek 直接跑会把结果写进临时目录并打印路径,而 yek src/ | pbcopy 这种写法会走流式输出。
令牌上限模式与截断策略
--tokens 是 yek 与按字节截断的工具拉开差距的地方。传入 --max-size 时按字节计算,传入 --tokens 128k 时切换到令牌计数模式。README 对截断行为的说明是「yek will remove any files that won't fit in the capped context size. It will try to fit in more important files」。这句话包含两个信息:超出上限的文件会被整体丢弃,而不是被截成半截;丢弃顺序依据的仍然是那套重要性排序。
这个策略的代价需要说清楚。文件是整体进出的,所以一个 200KB 的核心模块可能在只剩 150KB 预算时被整个扔掉,而几个小文件却被保留。排序本身来自 Git 提交历史,在一个刚初始化、只有一两次提交的仓库里,这个信号接近于噪声。文档没有给出重要性分数的具体计算方式,也没有说明历史深度如何影响结果,所以这部分只能当作启发式来用,不能当作可复现的优先级保证。
安装与第一次运行
Unix 系统上 README 给出的安装方式是 curl -fsSL https://azimi.me/yek.sh | bash,Windows 用 irm https://azimi.me/yek.ps1 | iex。这两个脚本来自项目自己的域名,执行前值得先看一眼内容。从源码构建则是 git clone https://github.com/mohsen1/yek,进入目录后 cargo install --path .。
跑起来的最小命令就是 yek,它会处理当前目录并把结果写进临时文件,然后把路径打印出来。几个常用变体:yek src/ tests/ 处理多个目录,yek "src/**/*.ts" 用 glob 匹配,README 特别提醒 glob 要加引号防止 shell 提前展开。yek --max-size 100KB --output-dir /tmp/yek src/ 指定输出位置。yek -t 会在内容前面加目录树,yek --tree-only 只输出目录树不带内容,这两个选项都与 --json 不兼容。--line-numbers 会在输出里带上行号。
yek.yaml 能改什么,不能改什么
在项目根目录放一个 yek.yaml,或者用 --config-file 指定路径,就可以把大部分命令行选项固化下来。文档列出的可配置项分成两组。文件处理组包括 max_size、tokens、ignore_patterns、unignore_patterns。输出组包括 json、debug,以及输出目录、输出文件名和输出模板。README 还提到配置可以定义文件优先级规则、追加二进制扩展名到内置列表、以及配置基于 Git 的优先级加权。
--no-config 可以完全跳过配置文件加载,这在排查「为什么某个文件被排除了」时很有用。--unignore-patterns 用来覆盖内置忽略规则,README 的措辞是「Yek has some built-in ignore patterns, but you can override them here」。如果你需要把某个被内置规则挡掉的二进制格式纳入输出,这是唯一的入口。需要注意的是,可配置项覆盖的是过滤和输出层面,Git 历史推断出的排序本身没有暴露成可调参数,你只能通过优先级规则去影响它。
什么时候它不合适
最明显的不适用场景是仓库缺少有意义的提交历史。yek 的排序依赖 Git 历史,README 把这一点写成了默认行为的一部分。在一个从模板生成、只有一次初始提交的项目里,这个信号基本失效,输出的顺序会退化成某种未经说明的次序。
第二个场景是输出体积接近或超过上下文上限。截断策略是整体丢弃文件,这意味着你拿到的可能是一份缺少关键模块的上下文,而工具不会在输出里标出「这里少了一个 200KB 的文件」。要发现这一点,得自己比对 yek --tree-only 的结果和实际输出里的文件列表。
第三,yek 生成的是一次性快照。它不做增量、不做索引、也不保留跨次运行的差异。如果你的工作流需要的是「在代码库里按语义检索相关片段」,那么每次重新序列化整个仓库再交给模型,成本会随着仓库增长而线性上升,而检索方案的成本曲线不是这样。
与 repomix 这类打包工具的差别
同一类需求下更常见的工具是 repomix(前身 repomix,早期叫 repomix 之前的 repopack)。两者都做「把仓库打包成单个文件给 LLM 用」这件事,差别在于默认策略。repomix 更强调输出格式的多样性,支持 XML、Markdown、JSON 等结构,并且会生成一份带文件摘要的头部信息,方便模型先建立整体印象。yek 的输出默认是纯文本加一个 >>>> 分隔符,结构信息要靠 -t 加目录树来补。
排序逻辑上的分歧更关键。yek 把 Git 提交历史当作重要性信号,并刻意把重要文件放在末尾。repomix 按文件路径组织,顺序稳定且可预测。如果你需要的是可复现的输出,路径排序更容易做 diff;如果你相信模型对尾部内容更敏感,yek 的排列是有针对性的。这是两种假设,不是优劣。另外 yek 是 Rust 实现,README 把「fast」放在第一句,但文档里没有给出任何具体的性能数字,所以速度只能作为设计取向来看待,不能当作可引用的结论。
维护成本与许可
项目采用 MIT 许可,这是最宽松的一类,允许商用、修改和再分发,只需保留版权声明和许可文本。这里不构成法律意见,如果你的组织对依赖许可有内部审查流程,按流程走即可。
从发布节奏看,v0.25.5 发布于 2026-06-29,v0.25.4 在 2026-06-06,v0.25.3 在 2026-06-02。版本号仍停在 0.x,意味着接口和行为都还可能变动,yek.yaml 里的键名、命令行选项的语义在升级时需要重新核对。升级成本主要落在两处:一是配置文件的字段,二是默认忽略规则。后者尤其需要注意,因为内置的二进制和大文件判断如果收紧,你原本能拿到的文件会静默消失。稳妥的做法是升级后先跑一次 yek --tree-only,把文件清单和升级前对比,再决定是否要用 --unignore-patterns 补回来。
编辑结论
yek 适合需要把本地代码库快速变成一段上下文的工程师,尤其是已经用 .gitignore 管理仓库、并且希望重要文件落在上下文尾部的人。如果你的仓库几乎没有提交历史,或者你依赖的是跨仓库的语义检索而不是单次快照,yek 的排序逻辑帮不上忙。上手前先确认三件事:在目标仓库里跑一次 yek --tree-only 看被纳入的文件范围是否符合预期,用 yek --tokens 128k 观察截断后剩下哪些文件,再检查 yek.yaml 里的 ignore_patterns 是否需要补充。
社区笔记