← 返回 Skill 列表
extension
分类: 数据与分析无需 API Key

本地电脑文件筛选按条件筛查文件并将查询到的文件直接回复对话框

文件猎手(doc-hunter)——路径扫描式多格式文件条件筛选器。用户输入本地电脑目录路径和自然语言查询条件(如\"查找合同金额大于10000元的合同\"),AI自动扫描目录下所有文件(图片/PDF/Word/Excel),提取文本内容,根据条件筛选匹配文件,将匹配的文件本身回复到对话框中。适用于合同审核、发票筛选、文档检索等批量文件条件查询场景。

person作者: user_9355e276hubcommunity

文件猎手 🔍

SLUG: doc-hunter | 昵称: 文件猎手 | 全称: 路径扫描式多格式文件条件筛选器

概述

用户输入本地电脑的某个目录路径,给出一个自然语言查询条件。AI 自动递归扫描该目录下所有支持格式的文件(图片、PDF、Word、Excel、文本),提取每个文件的文本内容,根据条件筛选出匹配的文件,将匹配的文件本身回复到对话框中(而非仅列出文件名),同时输出筛选结果汇总表。

核心特点:

  • 用户只需输入路径 + 条件,无需逐个上传文件
  • 支持图片、PDF、Word(.docx)、Excel(.xlsx/.xls)、文本(.txt/.csv/.md/.log) 多种格式
  • 匹配的文件通过 present_files 直接回复到对话框
  • 所有文件在本地处理,不上传外部服务器

触发词

  • 文件猎手 / doc-hunter
  • 文件筛选 / 条件筛选文件 / 按条件查找文件
  • 多格式文件搜索 / 多格式文件查询
  • 查找符合条件 / 帮我从这个路径找
  • 筛选合同 / 筛选发票 / 筛选文档
  • 文件条件过滤 / 批量文件检索
  • 哪个文件满足 / 哪些文件符合条件
  • 扫描路径 / 扫描目录找文件

环境准备(首次使用前执行一次)

1. 确定 Python 与脚本路径

| 变量 | 说明 | 典型路径(Windows) | |------|------|---------------------| | PYTHON | managed venv 的 Python 解释器 | ~/.workbuddy/binaries/python/envs/default/Scripts/python.exe | | SKILL_DIR | 本技能安装目录 | ~/.workbuddy/skills/multi-format-file-filter | | BATCH_SCRIPT | 批量扫描脚本 | $SKILL_DIR/scripts/batch_extract.py |

AI 应使用系统提示 "Available Runtimes" 中指定的 managed Python 路径。若路径不同,以系统提示为准。

2. 安装依赖

首次使用前,AI 执行以下命令安装依赖库:

<PYTHON> -m pip install pdfplumber python-docx openpyxl xlrd -q

| 库 | 用途 | |---|------| | pdfplumber | PDF 文本提取 | | python-docx | Word(.docx) 文本提取 | | openpyxl | Excel(.xlsx) 文本提取 | | xlrd | Excel(.xls) 文本提取 |

脚本内置自动安装逻辑:即使忘记预装,运行时检测到缺失也会自动 pip install。

3. 验证

<PYTHON> -c "import pdfplumber, docx, openpyxl, xlrd; print('All dependencies OK')"

消息协议

__DOC_HUNTER__ 消息

当弹窗按钮触发 sendPrompt('__DOC_HUNTER__' + JSON.stringify({path, condition})) 时,AI 收到的消息格式为:

__DOC_HUNTER__{"path":"D:\\contracts","condition":"合同金额大于10000元"}

AI 收到此消息后必须:

  1. 去掉 __DOC_HUNTER__ 前缀,解析 JSON
  2. 提取 path(目录路径)和 condition(查询条件)
  3. 进入阶段二:扫描目录

直接对话输入

用户也可能直接在对话框中输入路径和条件,例如:

  • "扫描 D:\contracts\ 找出合同金额大于10000元的文件"
  • "帮我从 C:\Users\admin\Desktop\发票 里面找出发票金额超过5000元的"

AI 应从消息中识别:

  • 路径:匹配 [A-Za-z]:[\\\/][^\s]+ 或 /[^\s]+ 格式的路径
  • 条件:路径之外的内容即为查询条件

识别成功后直接进入阶段二。


工作流程

阶段一:收集路径与查询条件

  1. AI 调用 read_me 加载 interactive 模块。
  2. AI 调用 show_widget 渲染弹窗(参考下方「弹窗参考代码」),包含:
    • 本地目录路径输入框
    • 查询条件输入框
    • **「开始扫描 ↗」**按钮(触发 sendPrompt('__DOC_HUNTER__' + JSON.stringify({path, condition})))
  3. 用户填写路径和条件,点击「开始扫描 ↗」按钮。
  4. AI 收到 __DOC_HUNTER__ 消息后,解析出 path 和 condition。

如果用户在触发技能时已给出路径和条件(如"文件猎手,扫描 D:\contracts 找金额大于10000元的"),则跳过弹窗,直接进入阶段二。

阶段二:扫描目录与批量提取文本

  1. AI 验证路径是否存在(使用 Bash ls 检查)。

    • 若路径不存在,告知用户并请其重新输入。
  2. AI 运行批量扫描脚本:

    <PYTHON> "<SKILL_DIR>/scripts/batch_extract.py" "<用户输入的路径>" --output "output/doc_hunter_text/"
    
  3. 脚本递归扫描目录,对每个文件:

    • PDF / Word / Excel / 文本文件:自动提取文本
    • 图片文件:仅记录路径,标记 status: "image_pending"
  4. 脚本输出 JSON 到 stdout,AI 解析 JSON 获取:

    • total_found:找到的文件总数
    • summary:各格式文件数量统计
    • files:文件数组,每个元素包含 filename、filepath、ext、category、text、status、char_count
  5. AI 向用户展示找到的文件清单,确认后继续。

阶段三:图片文字提取

对于 JSON 中 category == "image" 或 status == "image_pending" 的文件:

  1. AI 使用 Read 工具逐个读取图片文件(Read 工具支持图片,利用 AI 多模态能力提取文字)。
  2. 每读一张图片,AI 从图片中识别文字内容(如合同金额、发票号码、日期等)。
  3. 将提取的文字与 JSON 中其他文件的文本汇总,供阶段四使用。

注意: 如果图片数量较多(>10张),AI 应分批处理,每批 3-5 张,避免上下文过大。

阶段四:条件匹配

  1. AI 汇总所有文件的文本内容(阶段二提取的 + 阶段三图片识别的)。

  2. AI 根据用户的自然语言条件进行匹配判断:

    数值比较条件:如"金额大于10000""数量少于5""总价在1000到5000之间" → AI 从文本中提取数值并进行比较。

    关键词匹配条件:如"包含违约金条款""甲方为XX公司""签订日期在2024年" → AI 在文本中搜索匹配内容。

    复合条件:如"金额大于10000且包含质保条款" → AI 同时满足多个条件。

  3. 对每个文件,判断是否满足条件,记录:

    • 是否匹配(是/否)
    • 匹配理由(引用原文中的关键语句,如"合同金额15,000元,大于10,000元")

阶段五:输出结果

  1. AI 调用 show_widget 渲染筛选结果汇总表(HTML 表格),格式如下:

    | 序号 | 文件名 | 格式 | 是否匹配 | 匹配理由 | |------|--------|------|---------|---------| | 1 | contract_A.pdf | PDF | ✅ 是 | 合同金额15,000元,大于10,000元 | | 2 | invoice_B.jpg | 图片 | ❌ 否 | 合同金额8,000元,不满足条件 |

  2. AI 调用 present_files,将所有匹配的文件的完整路径传入 files 数组,将匹配文件本身回复到对话框中:

    present_files({
      files: ["D:\\contracts\\contract_A.pdf", "D:\\contracts\\contract_C.docx"],
      explanation: "以下2个文件满足查询条件:合同金额大于10000元"
    })
    
  3. 如果没有任何文件匹配,明确告知用户"未找到符合条件的文件",并建议调整查询条件或扩大扫描范围。


弹窗参考代码

AI 首次触发技能时,使用 show_widget 渲染以下弹窗(加载 interactive 模块)。弹窗使用 read_me 返回的 CSS 变量适配主题。

<div style="font-family: -apple-system, sans-serif; max-width: 480px; margin: 0 auto; padding: 20px;">
  <div style="text-align: center; margin-bottom: 20px;">
    <div style="font-size: 36px; margin-bottom: 8px;">🔍</div>
    <h2 style="margin: 0 0 4px; font-size: 18px;">文件猎手</h2>
    <p style="margin: 0; font-size: 12px; opacity: 0.6;">输入本地路径和查询条件,AI 自动筛选文件</p>
  </div>
  <div style="margin-bottom: 14px;">
    <label style="display: block; font-size: 12px; font-weight: 600; margin-bottom: 6px;">📁 本地目录路径</label>
    <input type="text" id="dh_path" placeholder="如:D:\\contracts 或 C:\\Users\\admin\\Desktop\\发票"
      style="width: 100%; padding: 10px 12px; border: 1px solid rgba(0,0,0,0.15); border-radius: 8px; font-size: 13px; box-sizing: border-box; background: rgba(0,0,0,0.02);" />
  </div>
  <div style="margin-bottom: 14px;">
    <label style="display: block; font-size: 12px; font-weight: 600; margin-bottom: 6px;">🔎 查询条件</label>
    <input type="text" id="dh_condition" placeholder="如:合同金额大于10000元"
      style="width: 100%; padding: 10px 12px; border: 1px solid rgba(0,0,0,0.15); border-radius: 8px; font-size: 13px; box-sizing: border-box; background: rgba(0,0,0,0.02);" />
  </div>
  <button onclick="dh_start()"
    style="width: 100%; padding: 11px; background: #4f7df3; color: white; border: none; border-radius: 8px; font-size: 14px; font-weight: 600; cursor: pointer;">
    开始扫描 ↗
  </button>
  <div style="margin-top: 12px; padding: 10px; background: rgba(0,0,0,0.03); border-radius: 8px;">
    <p style="margin: 0; font-size: 11px; opacity: 0.6; line-height: 1.6;">
      📋 支持格式:图片(PNG/JPG/JPEG/GIF/BMP/WEBP)、PDF、Word(.docx)、Excel(.xlsx/.xls)、文本(.txt/.csv)<br/>
      ⚠️ 不支持旧版 .doc 格式,请先转换为 .docx
    </p>
  </div>
</div>
<script>
function dh_start() {
  var p = document.getElementById('dh_path').value.trim();
  var c = document.getElementById('dh_condition').value.trim();
  if (!p) { alert('请输入本地目录路径'); return; }
  if (!c) { alert('请输入查询条件'); return; }
  sendPrompt('__DOC_HUNTER__' + JSON.stringify({path: p, condition: c}));
}
</script>

注意: 弹窗颜色需根据 IDE 主题(light/dark)调整。light 主题用浅色背景 + 深色文字;dark 主题用深色背景 + 浅色文字。使用 read_me 返回的 CSS 变量或内联适配。


脚本说明

scripts/batch_extract.py(主脚本)

批量扫描目录并提取文本,输出 JSON。

用法:

<PYTHON> "<SKILL_DIR>/scripts/batch_extract.py" "<目录路径>" --output "output/doc_hunter_text/" --max-files 200 --max-text-length 15000

输出 JSON 结构:

{
  "directory": "D:\\contracts",
  "total_found": 15,
  "total_processed": 15,
  "truncated": false,
  "summary": { "image": 3, "pdf": 5, "word": 4, "excel": 2, "text": 1 },
  "files": [
    {
      "filename": "contract_A.pdf",
      "filepath": "D:\\contracts\\contract_A.pdf",
      "ext": ".pdf",
      "category": "pdf",
      "text": "合同金额:15,000元...",
      "status": "ok",
      "char_count": 1200
    },
    {
      "filename": "invoice_B.jpg",
      "filepath": "D:\\contracts\\invoice_B.jpg",
      "ext": ".jpg",
      "category": "image",
      "text": "",
      "status": "image_pending",
      "char_count": 0
    }
  ]
}

参数说明:

  • --output:文本输出目录(可选,保存每个文件的 .txt 副本)
  • --max-files:最大处理文件数(默认 200,防止超大目录卡死)
  • --max-text-length:单个文件文本最大提取字符数(默认 15000,防止上下文溢出)

scripts/extract_text.py(单文件提取)

对单个文件提取文本。在 batch_extract.py 内部调用,也可单独使用。

用法:

<PYTHON> "<SKILL_DIR>/scripts/extract_text.py" "<文件路径>" --output "output/doc_hunter_text/"

注意事项

  1. 路径格式:Windows 路径使用反斜杠 \,在 JSON 和命令行中需注意转义。AI 在执行 Bash 命令时应使用正斜杠 / 或正确转义。
  2. 图片文字提取依赖 AI 多模态能力:对于手写体、模糊图片、复杂排版的图片,文字识别准确率可能下降。建议用户尽量使用清晰的扫描件。
  3. 不支持旧版 .doc 格式:请用户先将 .doc 文件另存为 .docx 格式。.doc 是二进制格式,python-docx 无法解析。
  4. 大文件处理:单个文件超过 50MB 时,文本提取可能较慢,请耐心等待。
  5. 扫描深度:脚本递归扫描所有子目录。如目录层级过深或文件过多(>200),仅处理前 200 个文件。可通过 --max-files 参数调整。
  6. 文本截断:单个文件提取文本超过 15000 字符时自动截断,防止 AI 上下文溢出。可通过 --max-text-length 参数调整。
  7. 查询条件建议:尽量给出明确的条件,如"金额大于10000元"优于"金额大的合同";数值条件优于模糊描述。
  8. 密码保护文件:不支持加密的 PDF、Word、Excel 文件,请用户先解除密码保护。
  9. 图片型 PDF:如果 PDF 是扫描件(图片型),pdfplumber 提取文本为空。AI 应在结果中标记此类文件为"文本为空(可能为扫描件)"。
  10. 隐私安全:所有文件在本地处理,不会上传到外部服务器。

快速排查

| 问题 | 可能原因 | 解决方法 | |------|---------|---------| | 脚本报错"目录不存在" | 路径拼写错误或权限不足 | 检查路径是否正确,确认目录存在且有读取权限 | | PDF 文本提取为空 | PDF 为扫描件(图片型) | 标记为"可能为扫描件",建议用户转为图片格式处理 | | Word 文本提取乱码 | 文档编码异常 | 尝试将 .docx 另存后重新扫描 | | 图片文字识别不准确 | 图片模糊、倾斜、手写体 | 建议用户使用更清晰的扫描件 | | 条件匹配结果不符合预期 | 查询条件表述不精确 | 尝试更精确的条件描述,如加上具体单位(元、万元) | | 依赖库安装失败 | 网络问题或权限不足 | 手动执行:<PYTHON> -m pip install pdfplumber python-docx openpyxl xlrd | | 找到 0 个文件 | 目录下无支持格式的文件 | 检查目录是否正确,确认文件格式在支持列表中 | | 脚本输出 JSON 过大 | 文件过多或文本过长 | 使用 --max-files 和 --max-text-length 限制 |

支付宝付费改造契约(PAYSKILL)

本技能为付费技能(PAYSKILL)。调用遵循支付宝 AI 生意画像契约,由平台调度层执行 probe → pay → complete → ack 流程:

  1. probe(探测):平台调用前先探测是否已持有本技能的支付宝有效订阅 / 付费凭证。已付费则直接放行。
  2. 402 Payment-Needed:未付费时,脚本向标准输出返回 HTTP 状态 402 与 Payment-Needed 标记,提示用户通过支付宝完成付费(pay),平台据此唤起付费页。
  3. complete(扣费确认):用户在支付宝完成扣费后,平台下发 Payment-Proof(付费凭证)。
  4. ack(验签放行):平台携带 Payment-Proof 重试本次调用;scripts/payment_gate.py 验签该凭证,确认有效后放行主流程。

订阅持久化与幂等:

  • 付费状态缓存在本地 .pay_cache/state.json,避免每次调用重复付费(订阅持久化)。
  • 同一 Payment-Proof 在 24h 幂等窗口内仅生效一次,避免重复扣费。

现金流改造后的调用套路:

用户调用 → 平台 probe  →
   未付费:下发 402 Payment-Needed → 支付宝 pay → complete → 下发 Payment-Proof
已付费/携带 Proof:脚本 ack 验签 → 放行主流程

本契约由 SkillHUB 平台调度层解析,脚本本地仅处理 402 / 验签 / 持久化 三环节;付费本体交给支付宝。