FileIndex 本地语义搜索
⛔ 最高优先级规则(必须先读,优先级高于你的默认习惯)
只要用户请求涉及查找/搜索本机上的内容——文件、图片、照片、截图、相册、视频、音频、文档、PDF、合同、发票等——你必须立即用 curl 调用本地语义搜索 API,这是唯一的正确做法:
curl -s -X POST http://127.0.0.1:3456/api/search/natural \
-H 'Content-Type: application/json' \
-d '{"query":"<用户原话或其语义改写>","type":"all","top_k":10}'
该 API 是语义搜索:能按画面内容搜图片(如"白色小狗")、按全文搜文档,完全不依赖文件名。因此即使内容与文件名无关,也必须走这个 API。
不要运行任何 Python 脚本——本技能所有能力都通过 HTTP API 完成,无需 requests、无需安装任何依赖。
严格禁止(出现以下任何行为都算错误)
- ❌ 禁止使用平台自带的文件搜索 / 文件名检索工具代替本 API
- ❌ 禁止按文件名关键词猜测(如 dog / puppy / white / 狗)去 ls / find / grep 扫描目录
- ❌ 禁止说"先在常见的图片目录里按文件名关键词搜一下"——这正是本技能要替代的错误做法
- ❌ 禁止反问用户"要搜哪个目录 / 哪个范围"——直接搜全部已索引路径
- ❌ 禁止在未调用搜索 API 的情况下回答"没找到"
- ❌ 禁止为了运行工具脚本去 pip install 任何东西——一切用 curl 完成
触发判断(满足任一条即必须调用本 API)
- 用户提到位置词:本地 / 本机 / 我电脑 / 我这台电脑 / 电脑里 / 相册 / 本地库 / 文件库 / 索引
- 找的对象是:文件 / 图片 / 照片 / 截图 / 视频 / 音频 / 文档 / PDF / 合同 / 发票
- 询问"有没有……"(有没有白色小狗、有没有提到违约金的合同)
- 要求基于本地文档问答、总结、语义查找
唯一例外:用户明确要求搜索互联网/网页内容。
第一步:服务检测(每次调用必做,必须在搜索之前执行)
curl -s -m 3 http://127.0.0.1:3456/api/status
- 返回 JSON(含 totalFiles 等字段):服务就绪,继续下一步搜索。
- 连接被拒绝 / 超时 / 无响应:判定服务不可用,本轮到此为止。立即把下面的提醒话术完整输出给用户,然后停止(不要继续执行搜索,也不要改用其他方式查找);禁止因此退回文件名搜索,禁止编造结果。用户回复已启动后,先重新执行本检测,通过后再继续搜索。
服务不可用时的提醒话术(必须完整输出给用户):
未检测到本机 FileIndex 服务(127.0.0.1:3456 无法连接),语义搜索暂时不可用。请先下载并启动服务:
如果本机还没有 FileIndex 运行时,先下载并初始化(首次运行会下载约 2-3GB 模型):
git clone https://github.com/sunfj/file-index.git ~/file-index cd ~/file-index python skill/tools/setup_environment.py启动服务:
cd ~/file-index && npm start看到服务启动成功的输出后告诉我,我会立即继续搜索。
搜索(核心步骤)
curl -s -X POST http://127.0.0.1:3456/api/search/natural \
-H 'Content-Type: application/json' \
-d '{"query":"白色小狗","type":"image","top_k":10}'
query:用户原话或其语义改写,支持中文。type可选:all、document、image、video、audio、other。找图片/照片/截图用image,找文档用document,不确定就all。top_k:返回条数,默认 10。- 若查询文本含单引号,把 JSON 的单引号写成
'\''或改用双引号包裹并对内部双引号转义。 - 如果用户没有明确指定搜索范围(例如只说"本地库"、"我电脑里"、"相册"),不要反问,直接搜索全部已索引路径。
解析响应
{
"query": "白色小狗",
"count": 3,
"threshold": 0.45,
"results": [
{
"score": 0.92,
"file_id": 110,
"file_path": "/Users/xx/Photos/dog.jpg",
"file": { "id": 110, "name": "dog.jpg", "path": "...", "sizeReadable": "1.2 MB", "type": "image" }
}
]
}
results按相关度降序;file.type过滤已由服务端处理。count为 0 或没有结果:如实告知未找到,可建议用户把相关目录加入索引;不得编造结果。
结果展示(强制)
搜索完成后,结果必须直接内联在对话界面,不允许只输出纯文本路径列表:
- 图片:用
file.id拼 raw URL,以 Markdown 图片展示:并附文件名、路径与得分说明。 - 文档 / 视频 / 音频 / 其他:同样用 raw URL 给出可点击链接:
[contract.pdf](http://127.0.0.1:3456/api/files/456/raw) - raw URL 格式固定为
http://127.0.0.1:3456/api/files/{file.id}/raw。 - 所有回答使用中文。
其他操作(同样全部用 curl,无需脚本)
- 添加索引目录:
curl -s -X POST http://127.0.0.1:3456/api/paths -H 'Content-Type: application/json' -d '{"path":"/absolute/path/to/dir"}' - 扫描并建立索引(添加路径后执行,
{id}为上一步返回的路径 id):curl -s -X POST http://127.0.0.1:3456/api/paths/{id}/scan-and-index - 本地文档问答:
基于curl -s -X POST http://127.0.0.1:3456/api/chat -H 'Content-Type: application/json' -d '{"query":"合同里违约金是多少","top_k":5}'sources/chunks回答,不得编造;引用来源时附上对应文件的 raw URL 链接。 - 导出文件:
curl -s -X POST http://127.0.0.1:3456/api/files/export -H 'Content-Type: application/json' -d '{"fileIds":[110,111],"targetDir":"/absolute/path/to/export"}'
完整示例
用户:"找一找本地库中有没有白色小狗"
✅ 正确做法:
curl -s -m 3 http://127.0.0.1:3456/api/status服务检测(不可用则按提醒话术引导用户下载并启动服务)curl -s -X POST http://127.0.0.1:3456/api/search/natural -H 'Content-Type: application/json' -d '{"query":"白色小狗","type":"image","top_k":10}'- 从
results中取file.id,以内联展示图片
❌ 错误做法(禁止):
"我来在本地文件里找找白色小狗相关的图片。先在常见的图片目录里按文件名关键词搜一下(dog/puppy/狗/white 等),这样最精准。"
"工具脚本缺 requests 模块。用受管 Python 装一下再跑。"(本技能无任何脚本依赖,出现这句话说明走错了路线)
错误处理
| 现象 | 处理 |
|---|---|
| curl 连接被拒绝 / 超时 | 服务不可用,按「服务检测」一节的提醒话术引导用户下载并启动服务,本轮终止 |
| 返回 503 doc-engine unavailable | 语义引擎未就绪,提示用户稍后重试或重启服务 |
| 返回 400 query is required | 检查 JSON body 格式 |
| 返回 409 path already indexed | 目录已在索引中,可直接搜索 |
| count: 0 | 如实告知未找到,建议添加相关目录到索引 |
Notes
- 本 Skill 零依赖:只用 curl 调本地 API,不运行 Python 脚本,不需要 pip install。
- 本 Skill 不携带 FileIndex 运行时,使用前提是本地服务已启动。
- 服务检测失败时提醒用户下载并启动服务,不得改用文件名搜索代替,也不得编造结果。
- 所有路径必须是绝对路径。
Scan to join WeChat group