At File 到底是什么
At File 是 DeepSeek Harness Web 界面上的一个「输入框插件」:你在提示框里输入 @,菜单会搜索当前工作区,你选中的路径会作为引用附加到这条消息上。它是一个路径选择器,不是文件上传器。
这个区别就是它的全部要点,也是最容易被误解的地方。插件自己的 README 写得很明确:它加入的引用只包含「工作区相对路径与类型(kind)」,而且「插件不会打开被引用的文件,也不会列出被引用目录的内容」。它在每一步开始前注入的引用消息长这样:
<workspace-reference path="docs/spec.pdf" kind="file" />
docs/spec.pdf 的内容一个字节都不会跟着走。接下来由 agent 自己决定:用当前会话已有的工具,是否要去读这个路径。所以这个插件省掉的是「复制—粘贴」的来回操作,而不是替模型预加载文件。
还有一件事要在开头就说清楚:README 自己的提示框写着,最新的官方 DeepSeek Harness 版本已经内置了 @file 与 @session 引用功能,并建议新安装优先使用官方实现。本插件的定位是:为已有环境保留,并以「尽力而为(best-effort)」的方式不定期维护。
搜索是怎么工作的、索引了什么
- 范围。 索引是为当前活动工作区建立的。README 从未说过选择器会搜索工作区之外的内容,而 Host 侧明确拒绝非工作区相对路径:「绝对路径以及逃出工作区的路径会被忽略。」
- 索引对象。 常规文件、目录以及符号链接。目录链接按其工作区相对别名被遍历;指回上级祖先的链接保持可见,但不会被重复进入。
- 匹配方式。 普通查询匹配文件名。精确名称、前缀以及紧凑匹配排在更松散的结果之前,README 还特别说明:匹配不会把字母散落到一条很长的目录路径上。含
/的查询按顺序匹配路径段——src/view可以找到src/client/view.ts;以斜杠结尾的src/则表示在该路径内部继续搜索。 - 排序与上限。 查询为空时,浅层路径排在深层条目之前,同一深度下目录排在文件之前。可滚动菜单最多展示 50 个候选,README 说这是有意为之:免得根目录下的文件被层层嵌套的目录挤掉。
- 图标与标签。 每条结果显示完整文件名,父目录在下方;重名文件会在主标签里带上父目录。内置 SVG 图标区分文件夹、源码、文本、PDF、图片、数据与配置文件、压缩包以及其他文件。长文件名会换行,而不是被省略号截断;空间足够时菜单会展开到 537px 的设计宽度。
- 缓存。 选择器索引按会话缓存 30 秒。你修改文件过滤规则时会清掉相关缓存,因此下一次
@搜索就会用上刚保存的规则。
键盘操作与输入框行为
当某个目录被高亮时,按 ArrowRight 进入它:草稿会前进为 @path/(末尾没有空格),候选菜单保持打开,方便你接着选下一个。Enter 与鼠标点选保持原有含义——结束这次目录引用,而不是进入目录。
选中的路径会留在草稿里可见,并可以在引用栏里打开或移除。点击被引用的路径走的是 Harness 的 host.openPath 端点。源码里明确写出的语法限制有两条:@path token 不能包含空白字符,也不能包含第二个 @;引用栏只渲染当前会话已稳定(settled)的索引中存在的 token,其他 @文本 一律保持普通文本。
粘贴文本是需要读两遍的特殊情况。默认情况下,从别的应用复制来的 @path 不会打开选择器、不会出现在引用栏、也不会生成 workspace-reference 标记,因为粘贴内容被当作普通文本处理。README 说你可以关掉 Settings -> File mentions 里的 Ignore @ mentions in pasted text 来恢复旧行为。如果你正纳闷「为什么粘贴进来的提及毫无反应」,答案就在这个开关上。
运行要求与配置
README 没有给出最低 Node 版本、操作系统或账号要求;已发布的 package.json 里也没有 engines 字段,因此从这两份来源里根本引不出任何 Node 版本下限。来源能确定的只有这些:
- Harness 底线。 0.7.0 版「同时支持 0.1.1 与 0.1.2 两种 Harness 客户端包布局」。包的 peer dependencies 全部标为 optional 且以通配符指向 DSH 各包,其中
@deepseek-ai/cordis为^4.0.1-rc.1、react为^18.2.0。唯一的硬运行时依赖是zod(^4.4.3);esbuild、vitest、typescript都在devDependencies里。 - 安装与重启。 安装与更新使用本条目
install字段中记录的那条插件命令;README 要求装完后重启dsh web,「以便 Host 与浏览器客户端加载 0.7.0 版」。这一步之所以必要,是因为本插件同时提供两半:Host 侧的索引遍历与浏览器侧输入框 UI。 - Node / pnpm。 插件直接跑仓库里已提交的
lib/产物:README 说「lib/下的构建产物已提交,因此 profile 安装不需要包构建脚本」。pnpm命令只出现在 Development 章节,不是使用者的前置要求。 - 配置。 只有两个键,都作用于路径选择器索引,都写进所选 profile 的
cordis.patch.yml(README 给出的常用路径是~/.dsh/profiles/web/cordis.patch.yml):maxIndexedFiles设定被索引的工作区条目上限;ignoreDirs则替换内置的目录排除清单(设为[]即索引所有目录)。
过滤规则、忽略项与已知限制
默认忽略。 默认索引会跳过常见的版本控制目录、IDE 元数据、依赖树、缓存与构建输出。README 列出的覆盖面包括 VS Code、Visual Studio、JetBrains 系列 IDE、Fleet、Eclipse、Android 与 Gradle、Xcode、CMake、Flutter、.NET、Unity、Unreal,以及常见的 JavaScript 与 Python 输出目录。操作系统元数据文件 desktop.ini、Thumbs.db、.DS_Store 也默认排除。
你自己的过滤规则。 Settings -> File mentions 里管理规则,分 Global(所有工作区共享)与 Workspace(针对所选工作区路径的额外规则,面板会显示它继承的全局规则)。每条规则有自己的匹配模式与大小写设置:Exact 匹配一个完整 basename,不接受路径分隔符;Regex 把一条 JavaScript 正则跑在完整 basename 上,拿不到父目录或工作区路径;Case-sensitive 可以按规则独立开启,默认关闭。非法正则会在保存前提示,并且 Host 还会再拒一次。Restore defaults 重置全局清单;Clear workspace rules 只删除当前工作区新增的部分。ignoreFiles 与工作区清单里既有的字符串值继续作为「不区分大小写的 Exact 规则」生效。设置通过插件自己的 Host 连接保存在 DSH web profile 中。
来源明确写出的限制:
maxIndexedFiles限制的是选择器结果,但「手动输入的路径只要存在于工作区内,仍然可以被引用」。- 文件格式与文件大小不会改变引用行为:「PDF 与其他工作区文件走完全相同的路径引用流程。」
- 过滤发生在 Host 索引遍历期间,早于条目计入
maxIndexedFiles、也早于到达浏览器。 - 零字节文件、二进制文件以及不可读文件的处理方式,来源均未描述。README 只说了格式与大小不影响引用流程;至于二进制文件事后能不能被「读」,取决于会话里的工具,而不取决于本插件。
- 在超大工作区里,README 只记录了索引上限与 30 秒的按会话缓存。它没有给出任何索引耗时、内存占用或性能基准数字;请不要把这些设计说明读成性能承诺。
0.3.0 之前的行为不同。 README 说这套路径引用机制适用于 0.3.0 及以后的版本,而更早的版本会在提交时读取文件内容,并强制执行文件大小上限。所以「它只附加路径」这句话对当前版本成立,但并不适用于这个插件的全部历史。
来源没有说的事情——请把这一段也算作限制。 以下断言本条目刻意不写,因为两份来源都不支持:
- 没有星数或任何流行度数字。 frontmatter 里的
stars与forks是目录元数据,两份来源都没有提到星数、下载量或用户量。 - 不声称文件内容会被内联。 README 说的是相反的事:只发送路径与类型,插件不打开文件。
- 没有任何基准或性能数字。 索引构建耗时、以字节计的工作区上限、规模扩展性说法,来源里一概没有。
- 没有关于对外网络传输的明确表述——两个方向都没有。 README 说明索引来自工作区遍历、过滤规则保存在 profile 设置里、点击路径调用 Harness 的
host.openPath端点;它从未讨论遥测、分析或对外请求。正因为来源沉默,本条目不写「任何东西都不会发往任何地方」,只写「来源中没有描述这类传输」。有文档依据的数据路径是本地的:Host 遍历工作区、结果送到浏览器客户端、引用标记在你本机被加入提示。 - 没有 Node 版本、操作系统支持或账号要求。
package.json里没有engines字段。 - 除了「格式与大小不改变引用流程」之外,没有关于二进制或零字节文件处理的说明。
- 安装来源并不自洽。 本条目
install字段指向omdsh-dev的归档地址,而repo字段指向FSMargoo/dsh-at-file;两份来源没有解释这个差异,本条目不替它编造理由。
什么时候用它、什么时候不要用
如果你的工作在大型仓库里,反复重敲或粘贴路径很烦;或者你特意想让 agent 拿到一个「指针」,由它自己决定要打开文件的多大一部分,那就用它。后一点在大文件上是实打实的好处:引用本身很便宜,只有当任务真的需要内容时才消耗上下文。
但如果下面任何一条说的是你,就别用:
- 你正在做全新安装。 README 自己建议新环境使用官方内置的
@file与@session功能,并把本插件描述为不定期、尽力而为地维护。请把那条提示当作首要建议,而不是脚注。 - 你期待文件内容被塞进提示。 它附加的是路径。agent 用可用工具读不了的文件——README 点名 PDF 属于「取决于工具」,而 DSH 提供
read处理 UTF-8 文本、read_image处理受支持的图片——只会被引用,不保证能被读取。 - 你期待提及在粘贴后仍然生效。 默认不会。
- 你要引用工作区之外的东西。 绝对路径与逃出工作区的路径会被忽略。
- 你需要一个「数据去了哪里」的保证。 来源没有描述任何遥测、上传步骤或它自己发起的网络请求——但它同样从未声明相反的情况,所以请把「本地数据路径」理解为有文档记载的行为,而不是经过审计的保证(见上文的限制部分)。
FAQ
它会把文件内容内联进提示里吗?
不会。选中路径插入的是一个 <workspace-reference> 标记,里面只有工作区相对路径与类型(file 或目录)。README 明确说插件不会打开被引用的文件,也不会列出被引用目录的内容,因此提及的那一刻并没有读取任何内容。如果你希望内容参与推理,需要由 agent 用自己的工具去读那个路径。
它搜索整块磁盘,还是只搜索工作区?
只搜索当前活动工作区。索引是对工作区的一次遍历,Host 会忽略绝对路径以及逃出工作区的路径。README 没有记录任何可以放宽搜索范围的配置——工作区之外的路径无法通过这种方式被引用。
它能处理的文件数量有上限吗?
有,且有文档的旋钮只有一个:profile 的 cordis.patch.yml 里 maxIndexedFiles 限制被索引的条目数,另外每次查询进入菜单的候选数单独限制为 50 个。请注意 README 的澄清:这个上限只限制选择器结果,手动输入的路径只要存在于工作区内依然可用。来源没有公布其他限制——没有以字节计的大小上限,也没有超大工作区的基准数据。
为什么粘贴进来的 @path 毫无反应?
因为在默认设置下,粘贴内容被当作普通文本:从其他应用复制来的提及不会打开选择器、不会出现在引用栏、也不会生成 reference 标记。这是当前版本的有意行为。在 Settings -> File mentions 里关掉 Ignore @ mentions in pasted text 即可恢复旧行为。相关限制还有:token 不能包含空白字符或第二个 @,引用栏只渲染会话已稳定索引中存在的 token。
那我应该装别的什么吗?
README 自己的提示已经回答了这个问题:最新的官方 DeepSeek Harness 版本已内置 @file 与 @session 引用功能,新安装推荐使用官方实现。At File 仍然是为已有环境保留的选项,以尽力而为的方式不定期维护;本条目所描述的是 0.7.0 这个版本。