201 lines
9.4 KiB
Markdown
201 lines
9.4 KiB
Markdown
---
|
||
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` preset;filter 里有 `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。
|