下载地址
https://www.zhengdianxue.com/wp-content/uploads/skills/org-oyrzl05c--landray-doc-compare.zip将提示词发送给你的 AI 安装该 skills
请根据 https://skillhub.cn/install/skillhub.md,安装 @org-oyrzl05c/landray-doc-compare。蓝凌文档比对,调用文档比对系统的对外接口比对两份 Word/PDF 文档(doc/docx/pdf),返回差异统计、逐条差异明细与比对结果页面链接。当用户在对话中上传两份文档并要求做文档比对、版本比对、合同/标书/制度条款核对、找出两版差异、比对前后版本修改点时使用。(使用过程中遇到问题请联系18970986058获取APIkey)
阅读全文 (展开查看完整说明)
概述
蓝凌文档比对
Overview
该 skill 是「文档比对系统」对外接口(/api/external/*)的客户端。用户在对话中上传两份文档(标准文档 + 比对文档)后,本 skill 把两份文件提交给比对服务,并返回:
- 差异统计(修改 / 新增 / 删除的内容块数量、差异图片数量)
- 逐条差异明细(每条含
[-删除]/[+新增]标注的文本与中文差异说明) - 可在浏览器中直接查看的可视化比对结果页面链接(
compareUrl)
对话式使用流程(主代理执行指引)
当用户在对话中上传两份文档(或说「比对这两份文档」「看看这两版有什么差别」)时,主代理按以下步骤执行:
- 定位文件:从用户消息中拿到两个上传文件的本地绝对路径。先确认哪一份是标准文档/基准版本(作为左侧
left),哪一份是待比较文档(右侧right)。用户没有明确说明时,按文件修改时间或用户在消息中的描述判断,并在回复中写明「以 X 为标准、Y 为比对对象」。- 只上传了一份文档、或只给了一个路径时,必须先问清楚另一份文档在哪,不要凭猜测比对。
- 执行脚本:用 Bash 调用本 skill 目录下的
scripts/compare_client.py(即<skill安装目录>/scripts/compare_client.py,skill 安装在哪台机器、哪个路径下就 用哪个路径,不要写死任何本地绝对路径),把两个路径按「左 右」顺序传入:
python "<skill安装目录>/scripts/compare_client.py" "<标准文档绝对路径>" "<比对文档绝对路径>"脚本自动读取 auth/auth.json 获取服务地址与 API Key,无需主代理额外传参。用户明确要求忽略某些差异时追加参数:--compare-whitespace(忽略空白)、--compare-punctuation(忽略标点)、--compare-number-format(忽略数字格式)、--compare-underline(忽略下划线)。中文文件名无需特殊处理,脚本会同时传 leftFileNameBase64 / rightFileNameBase64,避免 multipart 文件名乱码。
- 解读结果:脚本输出 JSON,主代理应用自然语言向用户呈现,而不是直接甩原始 JSON。优先呈现:
- 结论:
is_identical(是否完全一致)与summary_text - 差异统计:
diff_overview(修改 / 新增 / 删除 / 相同 / 差异图片) - 逐条差异:
changed_blocks,每条说明「位置 + 原内容 → 新内容」,[-…]是原内容(被删除/被替换),[+…]是新内容(新增/替换后);details是服务给出的中文差异原因 - 可视化结果链接:
compare_url(直接给出,用户可点开看带高亮的对照页面) - 差异条目超过
--max-blocks(默认 200)时changed_blocks_truncated=true,需提示用户结果已截断,完整数据在full_result_file - 若文档是 PDF 且差异在扫描件上,
other_changed_images/ 图片类差异块会体现为图片差异
- 结论:
- 异常处理:脚本以结构化 JSON 报错(
MISSING_AUTH/CONNECTIVITY_FAILED/AUTH_FAILED),按下方「缺失授权或验证失败时的对话处理」引导用户。
授权配置
授权信息按以下优先级读取(高优先级覆盖低优先级):
- 命令行参数:
--base-url、--api-key、--api-secret - 环境变量:
DOC_COMPARE_BASE_URL、DOC_COMPARE_API_KEY、DOC_COMPARE_API_SECRET - skill 内置配置文件:
auth/auth.json(字段address、api-key、api-secret)
服务地址与 Key 默认内置在 auth/auth.json 中,主代理通常无需传参;用户更换地址/Key 时直接编辑该文件,或用 --save-auth 把本次生效的参数写回该文件。
注意:
require_config要求api-key与api-secret同时存在,两者缺一不可(服务端X-Api-Key+X-Api-Secret双头鉴权)。
脚本执行方式(底层工具说明)
scripts/compare_client.py 仅依赖 Python 标准库,用任意 Python 3 运行:
# 正常比对(默认等待比对完成后输出结果摘要)
python scripts/compare_client.py <标准文档> <比对文档>
# 忽略空白与标点差异
python scripts/compare_client.py A.docx B.docx --compare-whitespace --compare-punctuation
# 连通性与授权自检(用内置样例文档,不消耗用户文件)
python scripts/compare_client.py --check
# 只提交任务不等待;拿到 task_id 与 task_access_token
python scripts/compare_client.py A.pdf B.pdf --no-wait
# 输出服务返回的完整原始结果(体积较大)
python scripts/compare_client.py A.docx B.docx --raw
# 临时覆盖服务地址与密钥,并写回 auth.json
python scripts/compare_client.py A.docx B.docx --base-url http://x.x.x.x:8081 --api-key ak_xxx --api-secret sk_xxx --save-auth关键参数:
| 参数 | 默认 | 说明 |
|---|---|---|
--base-url | auth.json / http://127.0.0.1:8081 | 服务地址 |
--poll-interval | 2 | 轮询间隔秒数 |
--timeout | 600 | 等待比对完成的最长秒数 |
--max-blocks | 200 | 输出差异条目上限 |
--out-dir | 系统临时目录下 landray-doc-compare/ | 完整结果 JSON(docdiff-result-<taskId>.json)保存目录。默认落在临时目录,不会污染当前工作目录;需要留档时显式指定 |
--use-proxy | 关 | 默认绕过系统代理直连;仅在内网需经代理时开启 |
- 脚本输出为 JSON(
ensure_ascii=False,保留中文),成功时退出码为 0。 - 脚本失败时同样输出 JSON,含
error与message字段,便于主代理判断分支。 --check用内置的两版样例采购合同跑一次真实比对,不只是探活:链路正常时会返回
is_identical: false、changed_blocks: 2、added_blocks: 1(第一条金额、第三条质保期各改一处,并新增第四条)。看到这个结果说明连通性、鉴权、比对链路全部正常,无需惊慌,也不用向用户报告"发现差异"。样例文档已用服务端同款 POI 5.2.5 验证可正常解析。
缺失授权或验证失败时的对话处理
脚本以结构化 JSON 报错,主代理按以下规则处理。
处理原则
- 不预置地址选项:不要给“服务在本机 8081 端口”这类固定选项,直接引导用户填写真实地址、API Key 与 API Secret。
- 弹输入框收集:使用
AskUserQuestion工具提问,问题正文明确让用户在“其他补充”输入框中填写服务地址、API Key、API Secret。 - 自动重试:拿到用户输入后,用
--save-auth写回auth/auth.json,并立即用--check重新验证连通性与授权;验证通过后继续比对原始文档。 - 验证失败再试:如果用户输入的信息验证不通过,再次弹出输入框;用户选择取消或始终未通过验证时,提示“授权验证失败,暂无法使用文档比对服务”。
1. 缺少授权信息(退出码 2)
{
"error": "MISSING_AUTH",
"message": "缺少 API Key(X-Api-Key)。请在 auth/auth.json 中配置 address / api-key / api-secret,或通过命令行参数、环境变量提供。",
"auth_file": ".../landray-doc-compare/auth/auth.json"
}主代理行动:调用 AskUserQuestion 弹出一个输入框问题:
{
"questions": [
{
"question": "文档比对服务尚未配置授权信息。请提供服务地址、API Key 与 API Secret,可直接在下方“其他补充”输入框中填写。",
"header": "服务授权",
"options": [
{"label": "填写授权", "description": "在下方输入框填写服务地址、API Key 与 API Secret"},
{"label": "取消", "description": "不填写,结束本次比对"}
]
}
]
}用户回复后:
- 选择“取消”或未提供有效信息:回复“未获取到有效的服务地址与密钥,无法继续比对。”
- 提供了完整信息:解析出地址、API Key、API Secret,用
--save-auth写回auth/auth.json,然后用--check做连通性验证;验证通过后立即重新比对原始文档。
解析用户输入时优先按以下格式提取:
- 地址:以
http://或https://开头的 URL。 - 两个密钥:通常是两个非空 token(形如
ak_.../sk_...),按出现顺序对应 API Key、API Secret;无法判断时向用户确认哪个是 Secret。
2. 连通性验证失败(退出码 3)
{ "error": "CONNECTIVITY_FAILED", "message": "无法连接文档比对服务: ...", "service_url": "http://..." }主代理行动:提示用户当前地址无法连通(服务未启动 / 网络或防火墙 / 地址错误),并再次弹出 AskUserQuestion 让用户重新填写,流程同「缺少授权信息」。若用户确认服务就在本机,可提示其启动文档比对服务(项目根目录下 start-server.cmd,等价于 java -jar target/doc-diff-center-1.0.0-SNAPSHOT.jar,默认监听 8081,启动后约 20-30 秒才可访问)后再试。
3. 鉴权被服务端拒绝(退出码 4)
{ "error": "AUTH_FAILED", "message": "授权验证失败: API Key 无效或已停用", "auth_file": "..." }主代理行动:提示用户密钥被服务端拒绝(错误 / 过期 / 停用),或该 Key 缺少权限(需 api:compare、document:upload、document:compare),并再次弹出 AskUserQuestion 让用户重新填写。
4. 等待任务超时(退出码 5)
{ "error": "TASK_TIMEOUT", "task_id": 1001, "compare_url": "http://.../compare/1001#taskToken=..." }主代理行动:告知用户比对仍在服务端进行(大 PDF 或触发 OCR 时较慢),把 compare_url 给用户让其稍后查看;也可调大 --timeout 后重试。
5. 业务错误(退出码 1)
如 当前仅支持 docx、doc、pdf 文档比对(格式不支持)、文件超过 50MB 上限、解析失败 等,直接把 message 转述给用户,不要重试。
结果解读
is_identical:true表示两份文档在比对规则下完全一致。diff_overview:changed_blocks(修改)、added_blocks(新增)、removed_blocks(删除)、same_blocks(相同)、changed_images(差异图片)。changed_blocks[]:status已中文化为「修改 / 新增 / 删除」,left是标准文档侧内容、right是比对文档侧内容,[-…]/[+…]标注差异词,details是中文差异原因(如「文本内容存在差异」「段落样式变化: Normal -> Heading 1」「新增表格」)。compare_url:带高亮对照的可视化结果页面,直接给用户。full_result_file:完整原始结果的本地 JSON 路径(含 PDF 定位矩形、页图等细节)。
详细的接口契约(端点、字段、状态流转、错误码、HTML 差异标记)见 references/api_docs.md。
常见问题排查
- 退出码 2(MISSING_AUTH):
auth/auth.json缺字段,或需同时提供 Key 与 Secret。 - 退出码 3(CONNECTIVITY_FAILED):服务未启动 / 地址错误 / 被代理拦截;确认地址后仍失败时加
--use-proxy试一次。 - 退出码 4(AUTH_FAILED):Key 或 Secret 被拒(401),或任务令牌失效(403)。
- 退出码 1 且 message 是
Access Denied:Key 有效但权限不足。注意服务端此时返回的是 500 而不是 403(未配置AccessDeniedHandler,被兜底异常处理返回 500),需要给该 Key 补上api:compare、document:upload、document:compare权限。 - 文件名乱码 / 显示为
?:脚本已同时传leftFileName与 UTF-8 的leftFileNameBase64。multipart 头里的中文名在服务端会按 ISO-8859-1 解码成乱码,服务端会用 Base64 字段覆盖它,所以两个字段必须同时传,不能只传一个;如仍乱码,检查是否手工调用了其他上传方式。 leftFileNameBase64传了但结果显示英文文件名:说明服务端用了 multipart 头里的名字,通常是 Base64 字段解码失败(非法 Base64),脚本已做兜底,手工调用时注意不要带换行/空格。- PDF 比对很慢:扫描件会走 OCR(
app.ocr.*),请调大--timeout,并优先把结果链接给用户。 - 结果里
left是「左侧无内容」:说明该侧整体缺失,属于新增块。
资源
scripts/compare_client.py:可直接执行的客户端脚本(提交 + 轮询 + 结果归一化)。auth/auth.json:授权配置文件(address / api-key / api-secret)。assets/sample_left.docx、assets/sample_right.docx:--check自检用的样例文档(少量已知差异)。references/api_docs.md:对外接口完整契约参考。