Composer 给了答案,你点开顶上的”context” 面板,发现它根本没读你明知该参考的 utils/parseInvoice.ts。Cursor 的上下文面板就是它真正交给模型的文件清单——不在里面就是没看着做的。这通常不是 bug,而是嵌入检索的几个典型失败模式:分数算低了、被 .cursorignore 排除了、文件刚改过没来得及重新索引、或上下文窗口被噪声占满。
修法可以一键(手动 @File),也可以系统性地改善信号。
常见原因
1. 嵌入检索打分不够高
Cursor 用文件内容嵌入做相似度检索。utils.ts 里如果有 500 行各种工具函数,针对 “parse invoice” 这个 query 的相似度会被稀释;同一个文件叫 parseInvoice.ts 反而命中文件名信号一下子排到前面。
如何判断:把目标文件 rename 试一下 git mv utils.ts parseInvoiceHelpers.ts,重新索引后再看面板。
2. 被 .cursorignore 或 .gitignore 排除
Cursor 默认尊重 .gitignore,再加 .cursorignore 二次过滤。常见误伤:dist/、build/、generated/,里面其实有 schema/types 是模型该参考的。
如何判断:
cat .cursorignore
git check-ignore -v path/to/missing-file.ts
第二条会告诉你被哪条规则排除。
3. 文件刚改名或刚新增,索引没更新
Cursor 索引是增量的,但改名后旧名条目可能滞留 5-30 秒;新增文件需要文件保存事件触发。期间检索会用旧索引。
如何判断:在 Settings → Features → Codebase Indexing 看 “Files indexed” 数字和你 git ls-files | wc -l 对比。
4. 上下文窗口满了,关键文件被挤出
模型的 context window 是有限的。Composer 自动加进来的”近期编辑过的文件”、“打开的 tab”、“被 import 的文件”如果太多,留给目标文件的预算就没了。
如何判断:context 面板里如果有十几二十个不相关 tab 或最近编辑文件,就是这种。
5. 文件名通用,导致语义相似度被分摊
index.ts、helpers.ts、types.ts、utils.ts 这种通用名在 monorepo 里有几十个,retrieval 选了别处的同名兄弟。
如何判断:context 面板里出现了同名但路径不对的文件。
6. 文件是二进制 / 大文件 / 不支持的扩展名
.parquet、.bin、.gz、超过 1MB 的纯文本 Cursor 默认不索引。
如何判断:ls -lh path/to/file 看大小;如果是常规扩展名但 > 1MB 也会被跳过。
动手前先确认
- 确认问题是在 Composer / Cmd+K / chat 哪个入口;Cmd+K 完全不走全仓检索。
- 复现前先 commit 一次,避免改名 / 删 ignore 把别人配置弄乱。
- 记下 Cursor 版本和当前模型;不同版本检索 ranking 算法有调整。
需要收集的信息
- Cursor 版本、操作系统、仓库总文件数。
.cursorignore全文、.gitignore关键条目。- Settings → Features → Codebase Indexing 截图(“Last indexed” 时间 + “Files indexed” 数量)。
- Composer context 面板截图(你看到的实际加载文件列表)。
- 目标缺失文件的路径、大小、扩展名。
最短修复路径
按”立刻可救 → 系统改善”排序。
Step 1:手动 @File
最快的救场。在 Composer 输入框输 @parseInvoice 让自动补全把它带进上下文,再发 prompt。这一步永远成功,5 秒搞定。
Step 2:审计 .cursorignore
cat .cursorignore
git check-ignore -v src/utils/parseInvoice.ts
如果被命中:
- 临时:注释掉那条规则、重启 Cursor、再试。
- 长期:用更精确的 glob,例如
dist/**/*.js而不是dist/,至少保留 types。
Step 3:强制重建索引
Cmd+Shift+P → “Cursor: Rebuild Codebase Index”,等 5-30 分钟跑完。如果项目刚做过大改名 / 大量新增,这一步必跑。
Step 4:给重要文件起有语义的名字
utils.ts 拆成 parseInvoice.ts / formatCurrency.ts / validateEmail.ts。检索打分 = 文件名信号 + 内容信号,文件名一改命中率立刻上去。
Step 5:在 .cursorrules 里固定指认 canonical 文件
# .cursorrules
When working on invoice logic, always read:
- src/utils/parseInvoice.ts
- src/types/invoice.ts
- src/api/invoices.ts
These define the canonical model and parser.
Cursor 把 rules 内容直接喂给模型,相当于给它一份显式索引。
Step 6:清掉上下文里的噪声
Composer context 面板每个文件旁边有 × 删除按钮,把无关的 tab / 历史文件删掉,给目标文件腾窗口。也可以 Composer Settings → “Auto-include open tabs” 关掉。
怎么确认已经修好
- 重启 Cursor 后再触发一次原 prompt,确认面板里目标文件在。
- 让 Composer 答完后追问 “List every file you read”,验证它真正读了目标文件。
- 切到另一台机器同步同一仓库重做,确认不是只有你本地索引被修好。
如果还是没修好
- 把 prompt 缩到最小:单一关键词 + 显式 @File。
- 回滚最近一次
.cursorignore改动或 Cursor 升级。 - 在 forum.cursor.com 搜 “context panel missing”;附 Cursor 版本 + 仓库结构 + 缺失文件路径。
- 抓 View → Output → Cursor 的索引日志贴 Bug Reports。
预防建议
- 重要参考文件用语义文件名,别用
utils.ts/helpers.ts这种万能名。 .cursorignore只放真正的构建产物,types / schemas / 配置都要留下。- 把核心工作流的 canonical files 列在
.cursorrules或CONTEXT.md里。 - 大改名 / 大量新增后立即 Cmd+Shift+P → Rebuild Codebase Index,不要等。
- 重要 prompt 永远手动 @File 关键参考,不要赌自动检索。