标书查重技能
字段说明见 @references/api.md。命令模板见 templates/workflow.sh。查重脚本是技能根目录的 main.py。
OpenClaw 使用原则
当用户提到“标书查重、投标文件查重、重复率检测、对比文件查重、查重报告下载”时使用本技能。
执行前先判断用户是否已经给齐必要信息。信息不全时,先用通俗的话反问,不要直接运行脚本。
必须确认的内容:
- 主文件:要被检查的那份投标文件,只能 1 个
- 对比文件:拿来和主文件比较的文件,至少 1 个,最多 20 个
- 查重窗口尺度:默认用
40;用户不懂时不用解释算法,直接推荐默认值 - 忽略文本:可选;用户没有提到时默认不填
主文件的解释必须简单:
> 主文件就是“你想检查重复率的那份标书”。其他文件是“拿来对比的标书”。
面向终端用户的表达(默认)
> 默认不要把命令行写给用户。 与本 skill「通俗反问」一致:用白话确认主文件、对比文件、是否用默认窗口;不要列出 python main.py、--batch-id 等,除非用户明确索要「命令怎么写」。
与「仅输出脚本结果」的关系: 查重进度、报告与下载信息以 stdout 原文为准原样展示。
能力说明
- 支持上传 1 个主标书
.docx与 1~20 个对比.docx - 自动获取 OSS 上传凭证、上传文件、回调后端并启动查重
- 支持按
batchId单次查询、持续轮询、下载报告、查询历史、删除记录。查重报告默认下载到用户桌面,优先展示本地路径;不要引导到网盘 - 支持查重窗口尺度
10~200,默认40 - 支持自定义忽略文本;每行一条,最多 100 条
微信登录认证
- 没有可用 Token 时,运行本技能目录里的
python wx_login.py。几秒内命令结束,浏览器在后台继续等扫码,最长 5 分钟。二维码和这个后台浏览器绑在一起,浏览器一关码就失效。 - 只让用户扫二维码,不要提供浏览器登录链接。有的客户端打不开技能目录里的图片时,按下面顺序给图,不要只发文件路径:
1. 把脚本输出里WECHAT_QR_MARKDOWN:后面的整行原样放进回复。这是内嵌二维码,不依赖用户能不能访问脚本所在磁盘。
2. 本地 PNG 只作为补充。工作目录存在时,脚本还会导出/workspace/微信登录二维码.png。文件卡片如果没有真正预览出来,就不要再靠路径。 - 不要只用读取工具打开这张 PNG。那样只有助手自己看得到,用户看不到。
- 用户用微信扫码后,必须在手机上点「确认登录」。只扫不点等于没登录。用户表示已经扫码后,再执行原来的业务命令。
- Token 写入
~/.taitoubiao/token.json,五个技能共用。5 分钟内不要重复启动登录,否则旧码作废。 - 接口返回登录失效时,会清掉缓存并重新出一张码。自动化请设置
TAITOUBIAO_SKIP_AUTO_LOGIN=1。
向用户提问规则
企业微信接入的文件大小限制
如果用户是通过企业微信接入龙虾,单个上传文件不能超过 10MB。遇到以下情况时,不要继续要求用户直接在企业微信里上传大文件:
- 用户说明文件超过 10MB
- 用户上传失败,原因类似“文件过大”
- 需要上传很多 Word 文件或压缩包,可能超过企业微信限制
此时输出:
企业微信里单个文件上传不能超过 10MB。
建议您把所有查重文件上传到龙虾 Ark 网盘,然后把网盘里的文件夹路径发给我;我会从文件夹里整理 Word 文件,再让您选择主文件。
如果不方便使用网盘,也可以移步钛投标官网免费使用标书查重:
https://taitoubiao.com
用户没有提供文件
输出:
请把需要查重的文件发给我。推荐直接发送一个文件夹,或者把所有 Word 文件打包成 .zip 压缩包发送。
如果您是通过企业微信使用,单个文件不要超过 10MB;超过 10MB 时,请先上传到龙虾 Ark 网盘,然后把网盘文件夹路径发给我。
这样我可以先帮您整理出里面的 Word 文件,再让您选择哪一份是主文件。
我需要您确认两类文件:
- 主文件:您想检查重复率的那份标书,只选 1 个
- 对比文件:拿来和主文件比较的标书,可以选 1 到 20 个
如果用户问“为什么建议文件夹或压缩包”,回复:
因为查重通常需要多份 Word 文件。放在一个文件夹或 .zip 压缩包里,我可以一次性整理出来,再编号让您选主文件,比较不容易漏文件。
用户提供了多个文件,但没说明主文件
必须先让用户选择主文件。不要自行默认第一个文件。
如果用户还没有上传文件,优先建议用户把所有文件放到一个文件夹或 .zip 压缩包中发送。
输出:
我已经收到这些 Word 文件,请选择哪一份是主文件。
主文件就是“您想检查重复率的那份标书”,其他文件会作为对比文件。
请直接回复编号即可,例如:1
如果文件列表较短,应同时列出来:
可选文件:
1. 文件A.docx
2. 文件B.docx
3. 文件C.docx
请回复主文件编号。
用户提供的是文件夹或压缩包
如果用户提供的是文件夹或压缩包,必须先整理出里面的 .docx 文件,再询问用户选择主文件。
执行规则:
- 文件夹:先扫描文件夹里的
.docx .zip/.tar/.tar.gz/.tgz:先解压,再扫描解压后的.docx.rar:先尝试用系统工具unar、unrar或bsdtar解压;如果本地没有可用工具或解压失败,脚本会尝试自动安装unar后重试;仍失败时再提示用户重新打包.zip内中文文件名如果是 Windows/GBK 编码,脚本会自动尝试按gb18030/gbk修复文件名- 找到多个
.docx时,必须让用户选择主文件 - 找到 1 个
.docx时,说明它可以作为主文件,但还需要至少 1 个对比文件 - 未找到
.docx时,让用户重新提供 Word 文件
推荐先执行:
python ./main.py \
--prepare-inputs "/absolute/path/folder-or-archive"
脚本会输出可选 Word 文件列表。然后按以下话术询问:
我已经整理出这些 Word 文件,请选择哪一份是主文件。
主文件就是“您想检查重复率的那份标书”,其他文件会作为对比文件。
可选文件:
1. 文件A.docx
2. 文件B.docx
3. 文件C.docx
请直接回复主文件编号即可,例如:1
如果用户给的是 .rar,先执行 --prepare-inputs,让脚本尝试用系统工具解压;如果缺少工具,脚本会尝试安装 unar 后重试。只有脚本输出 RAR 解压失败时,才说明:
这个 RAR 压缩包我这边没有解压成功。请您先解压成文件夹,或重新打包成 .zip 格式后再发我。
如果用户给的是 .7z 等仍不支持的压缩包,说明:
这个压缩包格式我暂时不能自动解压。请您先解压成文件夹,或重新提供 .zip 格式压缩包。
如果文件名曾经出现 ╣║╓ 这类乱码,不要直接告诉用户“没办法转换编码”。应重新执行 --prepare-inputs,让脚本用 GBK/GB18030 规则重新解压并输出文件列表。
用户只提供了 1 个文件
输出:
这份文件可以作为主文件,但还需要至少 1 个对比文件。
请再提供用于对比的 Word 文件,或告诉我它们的本地路径。
用户提供了主文件和对比文件,但没有给窗口尺度
默认使用 40,不用再问。
如果用户主动问窗口尺度是什么,使用这段解释:
窗口尺度可以理解为“查重时关注多长的一段文字”。
默认值 40 比较通用:太小容易把常见短句也算进去,太大可能漏掉短段重复。没有特殊要求我就用 40。
用户问是否需要忽略文本
输出:
忽略文本是指查重时不参与对比的内容,比如项目名称、项目编号、采购人名称这类每份文件都会出现的固定信息。
如果您没有特别要求,可以先不填。
用户要求导入招标分析结果作为忽略文本
如果用户提供了项目名称、项目编号、采购人、代理机构等内容,可以用 --ignore-texts 传入。没有这些内容时,不要编造。
执行规则
场景 A:新建查重任务
满足以下条件才可以执行上传并启动:
- 已明确 1 个主文件
- 已明确 1~20 个对比文件
- 文件都是本地绝对路径
- 文件后缀都是
.docx
默认执行“上传、启动并等待结果”:不要加 --no-wait。脚本会持续轮询,直到查重完成、失败或超时。
默认模式下,OpenClaw 必须等到脚本返回最终结果后再回复用户。禁止在任务刚启动后回复“正在后台运行、1-5分钟后通知、结果出来会通知你”这类中间话术。
只有拿到报告下载链接,或者脚本明确返回失败/超时,才可以回复用户。
只有用户明确说“先提交就行、不用等、稍后我自己查”时,才使用 --no-wait。
场景 B:用户已有 batchId
如果用户提供 batchId 并询问进度,直接执行:
python ./main.py \
--batch-id "BATCH_ID" \
--once
场景 C:用户要求只提交不等待
如果用户明确说“先提交就行、不用等、稍后我自己查”,才使用 --no-wait:
python ./main.py \
--main-file "/absolute/path/main.docx" \
--reference-files "/absolute/path/ref.docx" \
--chunk-size 40 \
--no-wait
输出规范
面向用户的沟通方式见上文「面向终端用户的表达(默认)」;下列仍针对脚本结果的展示要求。
必须优先展示脚本 stdout 的原始 Markdown 结果,不要自行编造查重进度、重复率、相似段落或报告内容。
默认查重流程中,查重报告未生成前不要回复用户;继续等待脚本轮询。完成后展示脚本返回的下载链接。
只有用户明确要求“只查询一下当前进度”或“先提交不等待”时,才可以展示未完成状态。
严格禁止默认输出:
✅ 查重任务已经启动啦!目前正在后台运行,一般1-5分钟会出结果,结果出来我会马上通知你~
正确做法:继续运行默认等待命令,直到 stdout 出现 # 标书查重报告 和 下载链接。
固定报告返回格式
当脚本输出 # 标书查重报告 时,OpenClaw 必须原样展示,不要改标题、不要删字段、不要改表格结构。
查重完成后的固定格式为:
# 标书查重报告
## 基本信息
| 项目 | 内容 |
|---|---|
| 批次ID | `BATCH_ID` |
| 查重状态 | 查重完成(3) |
| 查重进度 | 100% |
| 主文件 | MAIN_FILE.docx |
| 对比文件数量 | N |
| 结果文件 | bidding-check/.../查重报告_xxx.zip |
## 文件信息
| 文件类型 | 文件名 | 文件大小 |
|---|---|---|
| 主文件 | MAIN_FILE.docx | 36.24 KB |
| 对比文件 | REF_FILE.docx | 38.18 KB |
## 报告下载
- **下载链接**:[点击下载查重报告](REPORT_URL)
- **如链接无法点击,请复制以下地址到浏览器打开**:
REPORT_URL
## 说明
- 查重明细、重复段落和相似内容以下载的报告文件为准。
- 下载链接由系统生成,可能存在有效期;如链接过期,请重新获取报告下载链接。
如果脚本返回的是上面格式,只展示该格式,不再额外总结“重复率是多少”或“哪些段落重复”。
如果脚本返回失败,展示失败原因,并用一句简单的话说明下一步:
这次查重没有成功,建议先检查文件是否都是 .docx,或者稍后重新提交一次。
使用限制
- 主标书必须是本地绝对路径
.docx - 对比文件必须是本地绝对路径
.docx - 单文件最大 500MB
- 对比文件数量为 1~20 个
- OSS 上传使用 Python 标准库实现,无需安装
oss2
调用方式
1. 默认:上传、启动并等待完成
python ./main.py \
--main-file "/absolute/path/main.docx" \
--reference-files "/absolute/path/ref1.docx" "/absolute/path/ref2.docx" \
--chunk-size 40 \
--poll-interval 5 \
--timeout 1800
这是默认推荐调用方式。脚本会上传文件、启动查重并等待最终结果;完成后自动展示查重报告下载链接。
2. 仅提交,不等待完成
仅当用户明确要求“不用等结果”时使用:
python ./main.py \
--main-file "/absolute/path/main.docx" \
--reference-files "/absolute/path/ref1.docx" "/absolute/path/ref2.docx" \
--chunk-size 40 \
--no-wait
成功后脚本会输出 batchId。后续使用该 batchId 查询进度。
OpenClaw 收到 batchId 后,应告诉用户:
查重任务已经提交成功。这个批次号可以用来继续查询进度。
3. 单次查询
python ./main.py \
--batch-id "BATCH_ID" \
--once
当状态为 查重完成 时,脚本会自动调用报告下载接口并展示下载链接。
4. 持续轮询已有任务
python ./main.py \
--batch-id "BATCH_ID" \
--poll-interval 5 \
--timeout 1800
轮询直到状态为完成、失败或超时。
5. 使用忽略文本
直接传入:
python ./main.py \
--main-file "/absolute/path/main.docx" \
--reference-files "/absolute/path/ref.docx" \
--ignore-texts "项目名称" "项目编号" \
--poll-interval 5 \
--timeout 1800
或使用文件:
python ./main.py \
--main-file "/absolute/path/main.docx" \
--reference-files "/absolute/path/ref.docx" \
--ignore-texts-file "/absolute/path/ignore.txt" \
--poll-interval 5 \
--timeout 1800
状态说明
| 状态码 | 含义 |
|---|---|
0 |
上传中断 |
1 |
等待查重 |
2 |
正在查重 |
3 |
查重完成 |
4 |
查重失败 |
轮询规则
- 默认每 5 秒查询一次
- 查重正常耗时约 1~5 分钟,大文件或多文件可能更久
status=3:停止轮询,展示查重报告下载链接status=4或status=0:停止轮询,展示失败信息- 未完成时不要自行总结重复率或相似度
可选操作
查询历史:
python ./main.py --list
下载报告:
python ./main.py \
--batch-id "BATCH_ID" \
--download-report
删除记录:
python ./main.py \
--batch-id "BATCH_ID" \
--delete
参数说明
| 参数 | 说明 |
|---|---|
--main-file |
主标书 .docx 绝对路径 |
--reference-files |
对比文件 .docx 绝对路径列表 |
--batch-id |
查重任务批次 ID |
--chunk-size |
查重窗口尺度,范围 10~200,默认 40 |
--ignore-texts |
直接传入忽略文本,多条用空格分隔 |
--ignore-texts-file |
忽略文本文件,每行一条 |
--once |
单次查询状态 |
--no-wait |
上传并启动后立即返回 |
--download-report |
获取报告下载链接 |
--list |
查询历史任务 |
--delete |
删除指定任务 |
--output-format |
markdown 或 json |
常见对话示例
示例 1:用户只说“帮我查重”
回复:
可以。请把需要查重的文件发给我。
推荐直接发送一个文件夹,或者把所有 Word 文件打包成 .zip 压缩包发送。这样我可以先整理文件,再让您选择哪一份是主文件。
我需要您确认两类文件:
- 主文件:您想检查重复率的那份标书,只选 1 个
- 对比文件:拿来和主文件比较的标书,可以选 1 到 20 个
示例 2:用户发了多个文件
回复:
我已经收到这些 Word 文件,请选择哪一份是主文件。
主文件就是“您想检查重复率的那份标书”,其他文件会作为对比文件。
可选文件:
1. 文件A.docx
2. 文件B.docx
3. 文件C.docx
请直接回复主文件编号即可,例如:1
示例 3:用户说“第一个是主文件”
如果文件列表中第一个文件路径明确,则将第一个作为 --main-file,其余作为 --reference-files,使用默认 --chunk-size 40。
示例 4:用户提供 batchId
直接查询,不再询问文件:
python ./main.py \
--batch-id "BATCH_ID" \
--once