Files
zk-data-agent/skills/elk-fetch/SKILL.md
T
2026-05-08 10:54:27 +08:00

201 lines
9.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
name: elk-fetch
description: 从小米内网 ELK 按 request id 拉取日志。支持多账号 profile、多 ES 集群、多业务 preset(主 NLP / 拒识表 / 免唤醒后处理日志 / 小米汽车 OneTrack 端侧埋点)、深度 JSON 字段自动解析。绕开 Kibana CAS 登录,直接走 ES HTTP API。触发条件:用户给出 Kibana 链接、提到 requestId / request_id 查日志、想看某次请求的 NLP 日志 / 中控仲裁日志(intent_arbitrator_info / llm_agent_info / hit_rules / score_domains/ 拒识 rejectInfo / KEY_WORD_FREE_RESTRIC / 免唤醒判决(keyword-free-log)/ 小爱端到端可用性 / 小爱全离线日志 / OneTrack 埋点 / micar tip。
when_to_use: 用户给出 Kibana 链接、request_id/requestId,或要求查询 NLP 日志、中控仲裁日志、拒识日志、免唤醒日志、小米汽车 OneTrack 埋点日志时使用。
aliases: elk, elk-query, log-fetch, request-log
allowed_tools: python_exec, python_package, read_file
---
# ELK Fetch Skill
按 request id 查小米内网 ELK。**多个 ES 集群**:`default`/`reject``akaiservice.api.es.srv:80``micar` 走独立的 `c3log.api.es.srv:80`。每个 profile 自带 `host`,脚本会自动选集群。
账号密码(团队共用)已 commit 进仓库的 `profiles.json`,无需配置。需要换账号时用 `ELK_FETCH_PROFILES=/abs/path/to/profiles.json` 指向自己的文件。
## 在本数据 Agent 中使用
本 skill 已安装在项目目录 `skills/elk-fetch/`。在本项目中不要用 `bash` 执行 `python elk_query.py`,也不要用 `pip` 直接安装依赖。
实际查询必须使用 `python_exec`
```json
{
"script_path": "skills/elk-fetch/elk_query.py",
"args": ["<request_id>", "--preset", "main"],
"timeout_seconds": 90,
"max_output_chars": 20000
}
```
如果 `python_exec` 返回缺少 `elasticsearch``urllib3`,先使用 `python_package` 安装:
```json
{
"action": "install",
"packages": ["elasticsearch<8", "urllib3"],
"timeout_seconds": 120
}
```
下面所有 `python elk_query.py ...` 命令模板只表示参数选择;实际执行时都要转换为 `python_exec.script_path = "skills/elk-fetch/elk_query.py"` 和对应的 `args`
## 关键文件
| 文件 | 用途 |
|------|------|
| `elk_query.py` | CLI 入口 |
| `INDEX_CATALOG.md` | **每张表的字段 schema reference**(顶层字段 / JSON 字符串字段内部结构) |
| `business/keyword-free.md` | 免唤醒判决 — 拒识 vs kwfree 两张表三个视角的区分 + 排查 playbook |
| `business/intent-arbitrator.md` | 中控仲裁 — `intention.intent_arbitrator_info` 子字段语义 |
| `business/micar-onetrack.md` | 小米汽车 OneTrack — 23177 端到端可用性 / 23176 全离线日志 / 34496 离线NLP结果 |
## Preset 速查
| preset | profile | 集群 | 索引 pattern | 字段名 | 时间字段 | 内置过滤 |
|--------|---------|------|-------------|--------|---------|---------|
| `main` (默认) | default | akaiservice | `arch-flat-nlp-log-f-*` | `request_id` | `timestamp` | 无 |
| `reject` | reject | akaiservice | `aiservice_duplex_rejection_lcs_log*` | **`requestId`** | **`time`** | 无 |
| `kwfree` | default | akaiservice | `nlp_post_processing_lcs-*` | `requestId` | `timestamp` | `moduleName = keyword-free-log` |
| `micar` | micar | **c3log** | `onetrack_xiaoai_micar*` | `request_id` | `timestamp` | 无(一个 rid 多条 tip |
## 选 preset 的决策表
| 用户想看 | preset | 额外参数 | 业务深入 |
|---------|--------|---------|---------|
| query / domain / func / 设备信息 | `main` | — | — |
| **中控仲裁日志**agent 路由 / score_domains / llm_agent_info / hit_rules | `main` | `--json-path intention.intent_arbitrator_info` | [`business/intent-arbitrator.md`](business/intent-arbitrator.md) |
| **拒识表整体**rejectInfo 全部 / reject_reason / 各子策略) | `reject` | 不加 `--json-path` | [`business/keyword-free.md`](business/keyword-free.md) |
| **拒识里的免唤醒**(后置拒识调到免唤醒那次的出入参) | `reject` | `--json-path rejectInfo.strategy_info.reject.KEY_WORD_FREE_RESTRIC` | [`business/keyword-free.md`](business/keyword-free.md) |
| **后处理的免唤醒**(免唤醒模块被后处理调用时自己记的日志) | `kwfree` | — | [`business/keyword-free.md`](business/keyword-free.md) |
| **小米汽车端侧埋点**(端到端可用性 / 全离线日志 / ASR 状态等 OneTrack tip | `micar` | **`--date YYYYMMDD` 强烈建议** | [`business/micar-onetrack.md`](business/micar-onetrack.md) |
## 从 Kibana 链接提取参数
Kibana URL 形如:
```text
...discover#/?...
filters:(...match_phrase:(moduleName:keyword-free-log))
index:d7ff4d65-... ← Kibana index pattern UUID(非 ES 索引名)
query:(language:kuery,query:'requestId : 67f41dff...')
time:(from:now-1d,to:now)
```
反推方法:
- `requestId : xxx` / `request_id : xxx` → request id
- `filters` 里的 `match_phrase:(moduleName:keyword-free-log)`**`kwfree` preset**
- 主机 `aiservice.ak.kibana.cloud.mioffice.cn``default` profile;主机 `akaiservice.kibana.pt.xiaomi.com``reject` profile;主机 `c3log.kibana.pt.xiaomi.com`**`micar` profile(独立集群)**;主机 `akelk.pt.ai.srv``default` profile + `main` preset(中控仲裁的 Kibana 前端,底层就是主表)
- index 名为 `onetrack_xiaoai_micar` 直接走 `micar` presetfilter 里有 `tip` / `tip_name` 也走 `micar`
- `time:(from:now-1d,...)` → 默认近 48 小时,`from:'2026-04-22...'` 这种具体日期 → 传 `--date YYYYMMDD`
Kibana index UUID 不能直接反查 ES 索引名;如遇未知 UUID 跑一次 preset 试,打不中再 probe。
## 命令模板
> 路径形如 `python "C:\Users\Sivan\.claude\skills\elk-fetch\elk_query.py" ...`,下方为简写。每个场景的字段语义和排查思路见 `business/` 对应文档。
### 主 NLP 日志(默认)
```bash
python elk_query.py <request_id>
```
### 中控仲裁日志(→ [`business/intent-arbitrator.md`](business/intent-arbitrator.md)
```bash
# 整个仲裁对象
python elk_query.py <rid> --json-path intention.intent_arbitrator_info
# 命中的 agent + 召回规则 + 仲裁等级
python elk_query.py <rid> \
--fields request_id,query,domain,intention.intent_arbitrator_info.llm_agent_info,intention.intent_arbitrator_info.hit_rules,intention.intent_arbitrator_info.arbitrator_level
# 各候选 domain 的仲裁打分
python elk_query.py <rid> --json-path intention.intent_arbitrator_info.score_domains
```
⚠️ 真东西在 `intention.intent_arbitrator_info`,**顶层同名字段通常 null**。
### 拒识表 / `KEY_WORD_FREE_RESTRIC`(→ [`business/keyword-free.md`](business/keyword-free.md)
```bash
# 整个拒识 rejectInfo
python elk_query.py <rid> --preset reject
# 拒识里的免唤醒子字段
python elk_query.py <rid> --preset reject \
--json-path rejectInfo.strategy_info.reject.KEY_WORD_FREE_RESTRIC
```
同一 requestId 在此索引常有多条(多轮),按 `time` 倒序返回。
### 后处理免唤醒(→ [`business/keyword-free.md`](business/keyword-free.md)
```bash
# 整个 message
python elk_query.py <rid> --preset kwfree --json-path message
# 是否实际处理 + 跳过原因
python elk_query.py <rid> --preset kwfree \
--fields requestId,message.process,message.skipReason,message.request.keywordFreeType
```
### 小米汽车 OneTrack(→ [`business/micar-onetrack.md`](business/micar-onetrack.md)
⚠️ 必须传 `--date YYYYMMDD`(按日 rolling,单日 ~300GB)。
```bash
# 这个 request 上报了哪些 tip
python elk_query.py <rid> --preset micar --date 20260424 \
--fields request_id,tip,tip_name,tip_module_name,event_name
# 端到端可用性(23177)的性能时序
python elk_query.py <rid> --preset micar --date 20260424 \
--fields request_id,tip,key_value.state_result_type,key_value.state_exec_result,key_value.wakeup_received_event,key_value.asr_final,key_value.nlp_finish_answer
# 全离线日志(23176)的模型 debug 输出
python elk_query.py <rid> --preset micar --date 20260424 \
--json-path response_infos.0.nlp_debug_info
```
⚠️ 23176 schema 与其他 tip 不同:负载在 `request_infos[]` / `response_infos[]`**不在 `key_value`**。`response_infos[0]``instructions` + `nlp_debug_info` 两块,研究模型行为时都要看,别只取 nlp_debug_info。
### 指定日期 / 自定义索引
```bash
# 老请求超出 48h 窗口
python elk_query.py <rid> --date 20260422
# probe 未知索引
python elk_query.py <rid> \
--index "some-other-*" --field requestId --time-field time --profile reject
```
## 输出格式
始终单个 JSON 对象到 stdout
```json
{
"request_id": "...",
"preset": "reject",
"profile": "reject",
"index": "aiservice_duplex_rejection_lcs_log*",
"field": "requestId",
"time_field": "time",
"date": "past-48h",
"total": 2,
"hits": [ { "...": "_source(嵌套 JSON 字符串已自动解开)" } ]
}
```
出错时 JSON 里会有 `error` 键,退出码非零。
## 常见坑
- **请求 id 过期**:默认查近 48h,老请求必须 `--date YYYYMMDD`
- **字段名驼峰 vs 下划线**`main` / `micar``request_id``reject` / `kwfree``requestId`;Kibana 界面显示的字段名不一定等于 ES 存储字段名。
- **返回大量字段刷屏**:用 `--fields``--json-path` 精简。
- **不要用 WebFetch 抓 Kibana URL**:会被 CAS 拦到登录页,永远走这个 skill。