All-my-ai-needs midea-recall-diagnose-playwright
用于排查 sit/uat/prod 环境下 `/rag-recall/api/search/keyword` 未召回目标 doc/faq 的问题。支持两种输入:1) 完整请求(headers+body;若 `headers.appId` 缺失但 `body.appId` 存在,可回填);2) requestId+targetId。统一走“回放 -> ELK -> ES -> 代码最小核对”,禁止 broad search 和冲突口径。
install
source · Clone the upstream repo
git clone https://github.com/codingSamss/all-my-ai-needs
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/codingSamss/all-my-ai-needs "$T" && mkdir -p ~/.claude/skills && cp -r "$T/platforms/hermes/skills/software-development/midea-recall-diagnose-playwright" ~/.claude/skills/codingsamss-all-my-ai-needs-midea-recall-diagnose-playwright-a0a980 && rm -rf "$T"
manifest:
platforms/hermes/skills/software-development/midea-recall-diagnose-playwright/SKILL.mdsource content
Recall 排查(索引路由版)
0. 优先级与硬规则(必须遵守)
- 规则优先级:
>SKILL.md
。冲突时只按本文件执行。references/*.md - 接口约束:
回放只能用终端keyword
,禁止浏览器地址栏访问。curl -X POST - 取证范围:本技能只用
,禁止调用ELK + ES
。/rag-recall/api/search/trace/recordInfo - 执行通道约束(强制):除
回放外,ELK/ES 取证一律使用 Playwright 页面操作;禁止keyword
/脚本直连 ELK。curl - 完整请求强制回放:拿到
后,必须先回放并获取 freshheaders + body
,再查 ELK/ES。requestId - 回放后 requestId-first:第一条 ELK 查询必须包含
。requestId + TRACE_TARGET_ES + targetId - 首条 KQL 精确匹配(强制):首条查询中
必须完整精确匹配,禁止requestId/targetId/TRACE_TARGET_ES
通配(如*
)。replay_* - 禁止 broad search:回放成功后,禁止先用
单独扫 3 天日志再逐步收敛。targetId - ELK 门禁(强制):任何 ELK 查询执行前,必须先通过
校验;校验失败禁止继续查 ELK。python3 scripts/elk_guard.py ... --kql '<KQL>' - 时间窗规则:回放后先查
;无结果再扩到回放时间点 ±15 分钟
。now-3d~now - TRACE 触发条件(已核对):
只会在TRACE_TARGET_ES
非空时打印;若原始请求traceTargetIds
,原traceTargetIds=[]
很可能查不到该类日志,必须回放并注入requestId
。targetIds - TRACE 日志格式(已核对):真实生产日志中,
会携带phase=request
,requestDsl=...
会携带phase=response
;isError/tookMs/returnedHitCount/totalHitCount
形如targetUrl
。样例见GET /<index或逗号分隔索引> [cluster=N] (<desc>)
。references/trace-target-es-format.md - 回放头回填规则(已核对):若
缺失但headers.appId
存在,可回填为回放请求头;request.body.appId
同理。除这两个已核对字段外,其他关键鉴权头不得猜。appChannel - 字段规则:优先以 ELK
实际字段为准;字段不明确再查 ESrequestDsl
。_mapping - ES 路由规则(强制):进入 ES 前优先从 ELK
中的targetUrl
直接解析集群;若没有集群标识,再从[cluster=...]
/requestDsl
提取实际索引名做路由;禁止固定地址直查。targetUrl - ES 路由消歧规则(强制):若日志已带
,不得再要求用户补[cluster=...]
;只有在无集群标识且sourceSystem
命中共享索引导致多集群歧义时,才可用requestDsl
辅助消歧;若仍不能唯一定位,必须中止,禁止 fallback。sourceSystem - 阶段顺序来源(强制):优先用运行时
提取真实阶段顺序;拿不到则动态读取关键链路代码(CHAIN_NAME
);都失败才回退默认顺序。SearchLiteFlowService + LiteFlowConstants - 阶段顺序门禁(强制):首次丢失阶段必须按当前链路顺序判定,未验证前序文本召回证据时,禁止直接判定向量阶段丢失。
- 首次丢失校验(强制):输出结论前必须通过
校验。python3 scripts/first_loss_guard.py - 代码后置:默认先完成回放/ELK/ES 定位,输出前再做最小代码核对。
- 最小代码集:只读与“首次丢失阶段”直接相关的
个文件,禁止全量扫代码。2~4 - targetIds 上限:最多 10 个,超出直接拒绝。
- 缺参处理:缺少可复用
(优先appId
,其次headers.appId
)或其他关键鉴权头时,不得猜测,必须要求补齐。body.appId
1. 输入模式
A. 完整请求模式(优先)
- 输入:
env + targetType + targetIds + request.headers + request.body - 行为:必须先回放,再进入 ELK/ES。
B. requestId 模式
- 输入:
env + targetType + targetIds + requestId - 行为:直接 ELK-first;证据不足时要求补全完整请求并执行回放。
2. 30 秒流程卡(固定顺序)
- 规范化输入并校验 JSON。
- 回放请求(fresh
+ 注入requestId
)。traceTargetIds - 先用
生成并校验 KQL,再用scripts/elk_guard.py
查 ELK。requestId + TRACE_TARGET_ES + targetId - 仅当首次丢失在召回阶段时进入 ES 做三步快检。
- 输出前做最小代码核对,给出代码证据。
3. 标准流程(可执行)
3.1 完整请求模式
- 规范化输入:
cat >/tmp/diag_input.json <<'JSON' <input-json> JSON jq -e . /tmp/diag_input.json >/dev/null python3 scripts/prepare_diagnosis.py --input /tmp/diag_input.json
- 回放前处理:
- 将
替换为 fresh 值(body.requestId
或原ID_replay_<ts>
)。uuidgen - 将
合并到targetIds
。body.traceTargetIds - 若
缺失但headers.appId
存在,可用body.appId
回填请求头;body.appId
同理。appChannel
- 执行回放:
curl -X POST '<base_url>/rag-recall/api/search/keyword' \ -H 'Content-Type: application/json' \ -H 'appId: <appId>' \ -H 'appChannel: <appChannel>' \ -d '<body-with-fresh-requestId-and-traceTargetIds>'
- 回放成功判定:
- 响应中拿到 replay
。requestId - 记录最小摘要:
、总命中数、错误信息。requestId
- ELK 阶段定位:
- 查询必须包含:
(可加requestId + targetId + TRACE_TARGET_ES
)。link_id=requestId - 查询前必须执行门禁:
# 生成推荐 KQL python3 scripts/elk_guard.py \ --request-id '<replayRequestId>' \ --target-id '<targetId>' \ --mode first \ --emit-template # 校验你将要执行的 KQL;失败则停止,不得继续 python3 scripts/elk_guard.py \ --request-id '<replayRequestId>' \ --target-id '<targetId>' \ --mode first \ --kql '<your-kql>'
- 首条 KQL 必须直接采用
输出,不允许“因为太长”而删减到 requestId-only / targetId-only。--emit-template - 时间窗先用 15 分钟,再扩 3 天。
- 执行方式:只允许 Playwright(如
);禁止browser_navigate/browser_type/browser_press_key
ELK API。curl - 先从 ELK 提取该次请求的
阶段顺序,再按顺序找首个CHAIN_NAME
的phase=response hit=false
。cmpId - 首次丢失结论前必须跑阶段门禁(示例):
python3 scripts/first_loss_guard.py \ --target-type DOC \ --chain-line 'CHAIN_NAME[_FULL_RANGE_SEARCH_WITH_LLM_] full_range_meta_filter[...]==>full_range_docTxtRecall[...]==>doc_item_vector_retrieval_batch_es[...]==>full_range_rerank[...]' \ --events '[{"cmpId":"full_range_docTxtRecall","phase":"response","hit":true},{"cmpId":"doc_item_vector_retrieval_batch_es","phase":"response","hit":false}]' \ --assert-first-loss doc_item_vector_retrieval_batch_es
- 若没有
,直接让脚本从代码提取链路顺序:CHAIN_NAME
python3 scripts/first_loss_guard.py \ --target-type DOC \ --repo-root '<rag-recall-root>' \ --chain-id '_FULL_RANGE_SEARCH_WITH_LLM_' \ --events '<events-json>'
仅用于调试覆盖,不作为常规输入。--chain-order- 若
返回first_loss_guard.py
,禁止输出“向量阶段首次丢失”。BLOCKED/FAIL
- ES 验证(仅召回阶段进入):
- 先解析 ES 控制台路由(示例):
python3 scripts/prepare_diagnosis.py \ --input /tmp/diag_input.json \ --config references/env-config.local.yaml \ --request-dsl '<requestDsl-or-raw-elk-line>' \ --source-system '<sourceSystem-if-needed>' | jq '.esConsoleRoute'
- 若脚本报
:先检查是否命中了共享 FAQ 索引;必要时补一个requestDsl index route is ambiguous
做消歧。sourceSystem - 若脚本报
或unable to resolve ES console route
:立即中止并补齐有效的sourceSystem ... has no ES cluster mapping
证据。requestDsl/sourceSystem
原始Q1
复跑。requestDsl
目标存在性(DOC 用Q2
;FAQ 用doc_id
)。knowledge_base_id
保留 filter + 去掉 text must(仅文本阶段需要)。Q3- 执行方式:只允许 Playwright 控制台页面操作;禁止
直连 ES。curl
3.2 requestId 模式
- 直接按
查 ELK。requestId + targetId + TRACE_TARGET_ES - 若 15 分钟无结果,扩到
。now-3d~now - 若原始请求
或扩窗后仍无有效证据,判定“未完成带 trace 的复现”,要求补全完整请求并回放。traceTargetIds=[] - 首次丢失在召回阶段时,再进入 ES 三步快检。
4. 代码核对(按需触发,输出前必须)
触发条件(任一满足):
- 已定位首次丢失阶段,准备输出根因。
- ELK/ES 证据冲突或无法解释。
- 用户明确要求查看实现细节。
最小必读文件(按场景选 2~4 个):
- 入口与参数约束:
api/src/main/java/com/midea/jr/robot/rag/recall/api/web/controller/SearchController.java
- TRACE 语义:
infrastructure/src/main/java/com/midea/jr/robot/rag/recall/infrastructure/aspect/EsQueryTraceAspect.javacommon/src/main/java/com/midea/jr/robot/rag/recall/common/utils/TraceTargetScanUtils.java
- cmpId 映射:
common/src/main/java/com/midea/jr/robot/rag/recall/common/constant/LiteFlowConstants.java
- 召回实现:
- DOC:
domain/src/main/java/com/midea/jr/robot/rag/recall/domain/search/cmp/fullrange/FullRangeDocTxtRecallCmp.java - DOC 向量:
domain/src/main/java/com/midea/jr/robot/rag/recall/domain/search/cmp/fullrange/RecallDocItemVectorBatchEsCmp.java - FAQ:
domain/src/main/java/com/midea/jr/robot/rag/recall/domain/search/cmp/fullrange/FullRangeFaqTxtRecallCmp.java
- DOC:
5. 根因判定最小集
:该阶段未命中目标的最高优先级证据。phase=response hit=false
:索引缺数据/发布未生效/索引路由不覆盖。目标存在性=0
:文本匹配或过滤条件问题。目标存在性>0 且 原DSL=0
:排序/阈值/TopN 问题。原DSL>0 但最终未返回- 若已确认丢在
或之后:停止 ES 深挖,按 rerank/准出问题交付。full_range_rerank
6. 输出模板(固定)
- 目标首次丢失阶段(
)cmpId - 简要原因
- ELK 关键证据
- 阶段审计(文本/向量/重排各阶段
)response hit=true|false|unknown - 代码证据(至少 2 条,
)文件:行号 - 若在召回阶段:ES 证据(
)total/returned/rank/score - 下一步动作(仅当前阶段相关)
7. 违规恢复协议(必须)
- 若出现任一违规(如
、targetId-only
、缺requestId-only
、先 broad search),必须立即中止当前路径。TRACE_TARGET_ES - 若出现
通配/截断(如requestId
)或首条 KQL 被降级,按违规处理并立即中止。replay_* - 若出现
查询 ELK/ES(非curl
回放),按违规处理并立即中止。keyword - 若出现“未验证文本阶段就判向量阶段”的情况,按违规处理。
- 先输出一行:
。BLOCKED_BY_GUARD: <违规原因> - 然后从“ELK 阶段定位”重跑:先
校验通过,再继续。elk_guard.py
8. 资源
scripts/prepare_diagnosis.pyscripts/elk_guard.pyscripts/first_loss_guard.pyreferences/quick-runbook.mdreferences/trace-target-es-format.mdreferences/env-config.example.yamlreferences/env-config.local.yaml