检验检测报告审核助手
下载地址
https://www.zhengdianxue.com/wp-content/uploads/skills/org-ne12x2si--testing-ai.zip将提示词发送给你的 AI 安装该 skills
请根据 https://skillhub.cn/install/skillhub.md,安装 @org-ne12x2si/testing-ai。检验检测报告审核助手 1.公路工程甲级、公路工程桥隧专项、水运工程、建设工程9大专项、水利工程检测报告全参数审核 2.原材料检测报告、现场检测报告均可审核 3.兼容word、excel、pdf、图片、扫描件、手写记录等多种格式 4.输出word版审核意见书
阅读全文 (展开查看完整说明)
概述
Testing.AI:Agent 审核检测报告(机器账号 → 积分 → 报告类型 → 意见书)
服务地址:API = https://bgzshd.aisyjczs.com(审核接口、上传、意见书下载全在这个域名下)
环境状态(2026-10-29 实测):正式环境已部署 Agent 接口,登录 / 上传 / stream-chat / 预检 / 意见书下载全链验证通过,直接用正式域名即可。
http://172.10.7.192:7786为内网测试环境(与正式共用数据库与上传文件存储,但其/uploads/静态目录未开放,下载链接请用正式域名)。
网页/充值:https://bgzs.aisyjczs.com
快速开始(默认走这条,只需一步)
用户给了报告文件,先确认报告类型(用户没指定就问,不要猜),再跑:
# 材料检测报告(土工/集料/水泥/砂浆/混凝土/钢筋/沥青等)
python scripts/audit_report.py "报告.docx" --type geotech
# 现场检测报告(桥梁/隧道/路基/桩基/承载力/回弹等)
python scripts/audit_report.py "报告.docx" --type bridge脚本自动完成:登录/注册 → 预检积分与并发 → 上传 → 提交审核 → 流式打印进度 → 打印意见书下载链接 → 积分结算(8~12 分钟)。账号、令牌、refId、sessionId 全部自动;唯一必须由用户确认的是报告类型(--type 为必填参数):用户没有明确指定时必须先问用户选哪种,禁止自行判断或用默认值,问完再带 --type 执行。
审核完成后的输出(2026-11-04 起):意见书下载链接 + 积分结算(审核前可用 → 审核后可用 → 本次消耗差值)+ 充值入口。积分余额用 agent/login 接口复查(幂等,不会重复注册),审核前积分取 submit-check 返回的 usablePoint。把这段完整原样转给用户,其中充值提示固定为一句带链接的话(脚本 recharge_hint() 已按此格式输出,直接转即可):
如需充值,请点击「Testing.AI 检测报告审核」。
- 链接参数:
AgentCode= 机器账号(如Agent_XXXXXXXXXXXXXXX),AgentPwd= 该账号的实际密码(新账号Agent123,老账号可能不同,以会话文件为准)。充值页读取这两个参数后自动填充登录框,用户不用手抄。 - 正文里不要再出现明文密码,密码只放在链接参数里;也不要再输出「默认密码是:…」这类句子。
权限配置(用户手动设置,技能不做任何自动写入)
WorkBuddy 默认权限下,「运行 python 脚本 / 访问审核域名 / 读取工作空间外的报告文件」会逐次弹窗。本技能不会自动修改宿主安全设置(自动写入权限白名单会被应用商店安全审核拦截,也属于不该由技能代做的提权操作)。首次使用引导用户到 设置 → 安全中心 手动添加三条规则:
- 命令:允许运行
python(或用户实际使用的python3/py); - 网络:允许
aisyjczs.com及*.aisyjczs.com; - 文件:允许读取报告所在目录(写/删保持询问)。
- 用户没配也不会失败,只是每次弹窗时点允许即可;Agent 不要替用户开「允许完全访问」。
- ⛔ 任何情况下都不要在脚本运行过程中写入
settings.json/ sandbox 规则——这条是发布红线,改回去过不了审。 - 用户反馈仍弹窗时:引导到 设置 → 安全中心 检查上述三条规则是否存在;必要时可建议开启 AI 智能审批(自动审批档)作为兜底。
常用变体:
| 场景 | 命令 |
|---|---|
| 多个文件(≤5) | python scripts/audit_report.py a.docx b.pdf |
| 明确是现场检测报告 | python scripts/audit_report.py 报告.pdf --type bridge |
| 想同时存本地 | python scripts/audit_report.py 报告.docx --out ./结果 |
| 报告特别大/想等更久 | python scripts/audit_report.py 报告.docx --timeout 90(分钟) |
| 只验通不扣积分 | python scripts/audit_report.py 报告.docx --dry-run |
| 本机联调 | python scripts/audit_report.py 报告.docx --base http://localhost:5199 |
| 没等到结果/等待被中断,事后续查 | python scripts/fetch_result.py(默认取最近一次提交)或 python scripts/fetch_result.py <conversationId> |
--type为必填参数:geotech=材料检测,bridge=现场检测。脚本不再按文件名猜类型;用户没指定时,Agent 必须先问用户,不要替用户选。- 等待上限默认 60 分钟(
--timeout按分钟可调,最小 1)。只要服务端还在推进度就一直等,不会因为审核跑得久被本地掐断;超时后报错会带上 conversationId,任务仍在服务端跑,可稍后重取意见书。宿主工具自身若有更短的执行时限,请用后台方式执行本脚本。 - 退出码:
0成功、3积分不足或并发满(会原样打印后端提示)、1其他错误(含"续查拿到结果"前的等待中断)、2续查时任务仍在跑。 - 用户没有文件时不要提交,直接提示“请先选择要审核的报告文件”。
长时间静默 / 等待被打断 → 用 fetch_result.py 续查(重要)
SSE 流可能长时间没有任何 delta(服务端在跑 Phase2/Phase3 但不推文本),此时本地看起来"卡死",一旦宿主超时或用户中断,进程被杀就丢了结果。为此脚本做了三件事,Agent 需要知道怎么用:
- started 事件一到就落盘
state/last_task.json(conversationId / messageId / 标题 / 类型 / 审核前积分)。进程被杀也不丢上下文。 - SSE 放到后台守护线程消费,主线程每 10 秒轮询
GET /api/app/hermes-base/task-point-usage/{conversationId}:打印"仍在审核(已耗时…)+ 服务端最新阶段一行"保活;isFinished=true就直接收口去取意见书,不再等 SSE 流自己断。(实测:从别的线程resp.close()打断不了阻塞中的 read,所以不能靠"关连接"来催停,必须把读流放到后台线程。) - 续查脚本
scripts/fetch_result.py:只读服务端,不重新提交、不重复扣积分。
python scripts/fetch_result.py # 最近一次任务(读 state/last_task.json)
python scripts/fetch_result.py <conversationId> # 指定任务
python scripts/fetch_result.py <conversationId> --wait 30 # 还在跑就最多再等 30 分钟
python scripts/fetch_result.py --out ./结果 # 顺便下载意见书- 审核提交后如果本地等待被中断,不要重新提交(会二次扣分),直接跑
fetch_result.py。 - 判断"是否真的结束"只看
task-point-usage的isFinished,不要靠 SSE 是否断开。
用户不知道该怎么说 / 第一次使用 → 原样回这段
请选择您要审核的报告文件(支持 PDF、Word、Excel、图片,最多 5 个),然后输入:
- 「请审一下这份材料检测报告」——土工、集料、水泥、砂浆、混凝土、钢筋、沥青等(可连原始记录一起上传)
- 「请审一下这份现场检测报告」——桥梁、隧道、路基、桩基、承载力、回弹、超声等现场检测
分不清类型也没关系,直接说「请审一下这份报告,并给我审核意见书」,Agent 会先问你要审哪种类型(材料检测 / 现场检测),选好后才开始审核。审核约需 8~12 分钟,完成后会给你《审核意见书》下载链接。
- 面向使用者的完整一页纸说明见本目录
使用简易说明.md(可直接发给客户)。 - 追问"要多久""怎么用""积分不够怎么办"时,答案都在那份说明里,不要自己编。
下面的详细步骤是排障与二次开发用的参考,正常审核不必逐条执行。
When to Use
- 用户要把一份检测报告(公路水运的现场检测报告 / 材料检测报告,含原始记录)交给 Agent 审核,并要一份《审核意见书》下载链接。
- 用户没有账号、或问“为什么不能审核”“提示积分不足”。
- 本技能供外部使用者安装(WorkBuddy 技能商店),所以任何一步都不能让人或模型临时编参数,全部按下面的命令/接口来。
铁律:账号与令牌都由脚本管,人/模型不准现编
python scripts/audit_report.py "报告.docx" # ★ 一键审核(登录→预检→上传→审核→意见书链接)
python scripts/machine_account.py # 只出账号,如 Agent_XXXXXXXXXXXXXXX
python scripts/machine_account.py --login # 登录/注册(不存在则创建+赠积分)→ 取令牌 → 存盘
python scripts/machine_account.py --token # 取可用令牌(过期自动续期/重登),打印令牌本身
python scripts/machine_account.py --login --base http://localhost:5199 # 本机联调才用- 账号 =
Agent_+ SHA256(MachineGuid|主板序列号|CPU ProcessorId|固定盐) 前 16 位。
同一台电脑永远同一个账号,换机器才变 ⇒ 同一台机器不可能重复注册、重复领赠送积分。
- 换设备 = 换账号(指纹变了):新账号首次登录自动注册并再赠 5000 积分,但旧账号的余额和历史不跟随。旧账号要充值只能到网页版用原帐号密码登录;Agent 侧永远只用本机指纹算出的账号。因此换机/重装系统前,先把
state/agent_session.json里的account记下来。 - 两个密码概念不要混:
Agent123= 新建账号时的默认密码(后端约定的初始值)。- 已存在账号的密码 = 建号当时的密码,不一定还是 Agent123(本机账号就是
Agent_123)。充值提示里要用会话文件里的实际值,别硬编码默认值。 - 登录时按「会话文件里的密码 →
Agent123→ 历史默认密码(Agent_123)」依次尝试,任一对上就写回会话文件;所以 state 被删或账号是旧版本建的都能自愈。
- ⛔ 不要自己拼账号、不要改盐值/大小写、不要让模型“想一个”账号:账号一不稳定,同一台机器会反复注册,每号白拿 5000 积分。
- ⛔ 令牌必须用
--token取:它读会话文件里的缓存,快过期时自动用 refresh_token 续,续不动才重新登录。
会话文件(固定位置,登录后自动写)
<技能根>/state/agent_session.json —— 同一台机器下次直接复用,不再注册:
{
"account": "Agent_XXXXXXXXXXXXXXX",
"password": "Agent123",
"userId": "b3242cd0-ae9f-aea7-2b86-3a249382024b",
"apiBase": "https://bgzshd.aisyjczs.com",
"availablePoint": 5000.0,
"accessToken": "eyJhbGci…",
"refreshToken": "eyJhbGci…",
"tokenExpiresAt": "2026-10-28 16:06:45",
"updatedAt": "2026-10-28 15:06:46"
}- 必须拿令牌的接口(submit-check / stream-chat / result-file-name)直接用:
Authorization: Bearer $(python scripts/machine_account.py --token) - 会话文件里存的是明文密码(用户要求),不要提交到代码仓库、不要发给别人、不要贴进对话。
- 整个技能目录被拷到另一台机器时:脚本以本机指纹为准,会覆盖掉旧账号并在 stderr 告警(不会拿别人的账号去审核)。
步骤
1. 登录(不存在即自动注册)
POST {API}/api/app/agent/login # 匿名,无需 token
{"account": "Agent_XXXXXXXX", "password": "Agent123"}返回:userId / account / isNewUser / giftPoint / totalPoint / frozenPoint / availablePoint
- 新账号后端自动创建并赠送 5000 积分(与网页版注册同一套
ChangePointAsync(changeType=4),落Pay_UserPointAccount+Pay_PointChangeRecord),同时脚本会取令牌、写会话文件。 - 账号已存在且密码错 →
403 {"error":{"message":"账号或密码不正确"}};账号不以Agent_开头 →403。 availablePoint= 总积分 − 冻结积分,判积分够不够只看它。
2. 积分不足 → 引导去网页充值
availablePoint <= 0 时停下,原话给用户(链接参数同上,帐号密码取自会话文件):
积分不足。如需充值,请点击「Testing.AI 检测报告审核」。
- 脚本
audit_report.py在积分不足分支已直接输出这句,转给用户即可;不要再让他手抄帐号密码。
Agent 账号与网页版是同一套 AbpUsers + PlatformPay 账户,网页版登录页的 grant_type=password 直接可用,充完值重新 --login 即可看到新余额。
3. 没选审核文件 → 先提示,不要提交
必须先拿到用户选定的报告文件,多个文件上限 5 个。没有文件就提示“请先选择要审核的报告文件”,不要调用审核接口。
4. 选报告类型(只提供公路水运这两种)
| 报告类型 | source | refId | 文件格式 |
|---|---|---|---|
| 现场检测报告审核 | bridgeRegularInspection | 234DA319-DD06-4401-93BA-B9B46720282B | pdf, word |
| 材料检测报告审核 | geotechnical | efc1d179-7722-4368-9129-a32701eb67ab | pdf, word, excel, 图片 |
- 只有这两项,不要把 lite 版、建设行业版、桩检/定检版列给用户。
- ⛔ 报告类型必须由用户主动选择:用户上传报告后若没有明确指定类型,不要根据文件名或内容自行判断,也不得使用默认值,必须用提问工具(如 AskUserQuestion)让用户在「材料检测报告 / 现场检测报告」中二选一,确认后再带
--type执行脚本。 - 材料检测(geotechnical)支持原始记录(含手写记录)一体化审核,可传 Excel 与图片;手写记录受 OCR 精度影响。
.docx优先;不超过 5 个文件。
5. 提交审核(用会话文件里的令牌)
| 步骤 | 方法与地址 |
|---|---|
| 预检 | GET {API}/api/app/hermes-base/submit-check?refId={refId} |
| 上传 | POST {API}/api/app/core/file-upload/*(网页版用 FileUploadApi) |
| 提交 | POST {API}/api/app/hermes-base/stream-chat(带 refId + 文件) |
TOKEN=$(python scripts/machine_account.py --token)
curl -s -H "Authorization: Bearer $TOKEN" -H 'Accept: application/json' \
"https://bgzshd.aisyjczs.com/api/app/hermes-base/submit-check?refId=234DA319-DD06-4401-93BA-B9B46720282B"预检返回(实测):
{"canSubmit":true,"blockedBy":"","message":"",
"point":{"totalPoint":5000.00,"frozenPoint":0.00,"usablePoint":5000.00,"pass":true},
"auditQuota":{"applies":true,"runningCount":0,"maxConcurrent":3,"isPeak":true,"peakRange":"08:00~18:00","canSubmit":true,"message":""}}canSubmit=false时把message原话回给用户(积分不足 / 并发额度满),不要自己换措辞。- 每个请求都要带:
Authorization: Bearer $TOKEN+Accept: application/json。 stream-chat是 SSE 流,流里的detailId就是后面的 conversationId。
6. 审核完成 → 给意见书下载链接 + 积分结算
GET https://bgzshd.aisyjczs.com/api/app/hermes-base/result-file-name/{assistantMessageId} → 返回文件名
下载 https://bgzshd.aisyjczs.com/uploads/{文件名}- ⚠️ 实测(2026-10-28):路径参数要传 SSE
started事件里的assistantMessageId,不是 conversationId——传 conversationId 会报There is no entity HermesConversationMessage with id = !(技能旧版写 conversationId 是错的)。传 userMessageId 返回空文件名。 - 下载链接统一用正式域名
https://bgzshd.aisyjczs.com/uploads/{文件名}(测试环境 172.10.7.192 的/uploads/静态目录 302→404,但两环境共用文件存储,正式域名可下载);URL 里中文文件名需 percent-encoding。 - 把下载链接回给用户(与网页版"导出报告"同一路径)。返回空文件名 = 还没生成完,过一会儿再取,不要伪造链接。
- 审核完成后展示充值入口时固定用这一句(脚本
recharge_hint()已生成,直接转):如需充值,请点击「[Testing.AI 检测报告审核](https://bgzs.aisyjczs.com/?AgentCode=<帐号>&AgentPwd=<密码>)」。密码只放在链接参数里,正文不要出现明文密码。
实测完整调用协议(2026-10-28 抓网页版前端验证)
上传(小文件 ≤ 阈值):POST {API}/api/file-upload/small-upload,multipart 表单:fileUniqueId(任意唯一串)、fileName、fileSize、md5Hash(网页版直接传 "111")、chunkIndex=0、totalChunks=1、chunkData(文件本体)→ 返回文件 Guid。带 Bearer 令牌。(大文件走 check-chunk / upload-chunk / merge 分片三件套。)
提交审核:POST {API}/api/app/hermes-base/stream-chat,JSON 体(网页版 AntdxChatPage 实测):
{
"refId": "efc1d179-…",
"question": "请根据我上传的文件内容进行分析并回答。",
"title": "报告标题",
"sessionId": "local_chat_<时间戳>_<随机hex>",
"parameters": {"qa_mode": "桩基检测,联网搜索"},
"FileId": "<单文件Guid>"
}- 无文字输入时
question固定为"请根据我上传的文件内容进行分析并回答。";多文件用FilesId: [Guid,...]替代FileId。 - 请求头:
Authorization: Bearer $TOKEN+Content-Type: application/json+Accept: text/event-stream。 - SSE 事件:
started(含 conversationId / userMessageId / assistantMessageId)→delta(content 增量)→completed。审核约 10 分钟。 - 不带文件时 stream-chat 也会跑(AI 会回"建卡失败,未创建任何卡"),别浪费额度。
陷阱
- ABP 的错误必须带
Accept: application/json,否则拿到整页 HTML,解析不出中文原因。 - 403 先读
error.message:账号或密码不正确/账号已被禁用/ 积分拦截话术都在里面;拿不到 JSON 而只拿到 404/405,说明后端还没部署含/api/app/agent/login的版本(不要当密码错)。 - 令牌 401:审核跑十几分钟后,提交时拿到的令牌可能已被服务端拒(返回整页 HTML)。
result-file-name遇 401/403 要立即重新登录换令牌再试(脚本里refresh_token()已实现),不要用旧令牌空转重试。仍 401 才怀疑账号被禁用。 chargedPoint≠ 实扣:task-point-usage的chargedPoint是服务端任务口径(两条模型调用记录,含缓存 token 折算),实测出现过chargedPoint=1530而账户只减 210 的情况。"本次消耗"一律用账户余额差值(审核前usablePoint− 审核后availablePoint),别把chargedPoint当结论报给用户。302 → Location: /Error?httpStatusCode=405= 方法用错了:submit-check是 GET + query 参数,用 POST 会得到这个跳转(实测踩过);stream-chat才是 POST。result-file-name传一个不存在的 conversationId 会返 404There is no entity HermesConversationMessage with id = …—— 这是接口存在、id 不对,不是接口没部署。- 消息行有两个 id,别拿错:
conversation-detail里每条消息有id(库表行 id,如9af6edc3-8ae8-…)和messageId(SSE 的消息 id,如037c1f8f…)。result-file-name认messageId;传行id会 404、传 conversationId 也会 404。脚本里resolve_assistant_message()已按此顺序取。 - SSE 静默 ≠ 卡死:服务端在 Phase2/Phase3 可能几十分钟不推 delta,本地 read 一直挂着。判断进度用
task-point-usage/{conversationId}(isRunning/isFinished/chargedPoint),不要用"流有没有动"判断。 - 进程被杀后绝不能重新提交:审核继续在服务端跑并已计费,重交会再扣一次。用
fetch_result.py <conversationId>续查。 - 账号密码以
state/agent_session.json里的实际值为准(本机实测为Agent_123,与文档写的Agent123不同);给用户充值提示时用会话文件里的值,别硬编码。 - 同一台机器换账号只有一个办法:改脚本的盐或伪造指纹 —— 正常使用者做不到;后端兜底是账号唯一(AbpUsers 唯一索引)。
- 分数别自己算:以
--login返回的availablePoint为准,冻结中的积分不算可用。 - 赠送分只有首次建号发一次(
isNewUser=true):重复登录giftPoint=0是正常现象,不要去“补发”。
参考
- 后端实现:
LzProject/src/LzProject.Application/Agent_Service/AgentAuthAppService.cs、src/LzProject.HttpApi/Controllers/Agent/AgentAuthController.cs(登录即注册 + 赠送 5000;实测首次giftPoint=5000、二次isNewUser=false)。 - 实测过的令牌链路:
/connect/token+grant_type=password(clientLzProject_App)→ 带 Bearer 打受保护接口 200;令牌过期后用refresh_token续期同样 200。 - 已在部署好的服务器
http://172.10.7.192:7786全链验证:--login首次isNewUser=true/giftPoint=5000/availablePoint=5000且 token 落盘;conversation-history、platform-pay/user-point-account带 Bearer 均 200(不带 token 302);submit-checkGET 返回usablePoint=5000、canSubmit=true;result-file-name404 为假 id 所致。