Trajectory Calibrator 独立服务化 + Hermes 动态调用方案
日期:2026-07-31
现状代码:jetwave-app-server/trajectory-calibrator(v2.2.2)
对标:trajectory-log-analyzer(TLA)、jetwave-traj-store(ingest API)
1. 目标
| 目标 | 说明 |
|---|---|
| 独立服务 | 与 TLA 并列:只负责「错误汇总字段校准」,不写 analysis、不改 history |
| 动态触发 | Hermes / 业务系统在需要时调用,不依赖固定 cron |
| 可观测 | 任务状态、逐条结果、场景分布可查 |
| 安全 | 原表只读;可疑单位默认 SKIP;review_needed 不进排行 |
2. 现状盘点(已有 vs 缺什么)
已有 ✅
trajectory-calibrator/
├── calibrate_trajectory.py # 核心:history → OSS → calibrated
├── api_server.py # Flask HTTP :8091 POST /run
├── mcp_server.py # MCP SSE :8092(Cursor/Hermes 可接)
├── full_run_review.py # 全量验收
├── docker-compose.yml # MODE=all → API + MCP 常驻
└── surf_motion_trajectory_calibrated # 校准结果表
Hermes 今天就能调用的两种方式:
# ① HTTP(推荐 Hermes gateway 调)
curl -X POST http://calibrator:8091/run \
-H "Authorization: Bearer $API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"mode":"upsert","id":14900,"limit":1,"sync":true}'
# ② MCP(Hermes 若已配 trajectory-calibrator SSE)
# tool: run_calibration(mode=upsert, id=14900, sync=true)
缺口 ❌(要做成「和 TLA 同级」独立服务)
| 缺口 | 影响 |
|---|---|
任务状态只在 内存(api_server._jobs) |
容器重启丢历史;Hermes 难对账 |
| 无 单条 webhook 标准接口 | 上传完 history 不能「立刻校准这一条」 |
| 无 MySQL job 表 | 和 TLA 的 surf_log_analysis_job 不对齐 |
| 文档在 app-server,未进 fly-logs 方案体系 | 和 TLA / traj-store 边界不清 |
| cron 仍是默认运维心智 | 应降级为「兜底」,主路径改为事件驱动 |
3. 推荐架构(三服务并列)
┌─────────────────────────────────────┐
App 上传轨迹 │ surf_motion_trajectory_history │
───────────────► │ (MySQL 源表,业务写) │
└──────────┬────────────────────────────┘
│
┌─────────────────────┼─────────────────────┐
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ TLA │ │ Calibrator │ │ traj-store │
│ 故障/温度/KPI │ │ 航时/里程校准 │ │ 轨迹点时空检索 │
│ analysis 表 │ │ calibrated 表 │ │ PostgreSQL │
└────────┬────────┘ └────────┬────────┘ └────────┬────────┘
│ │ │
└─────────────────────┼─────────────────────┘
▼
┌─────────────────────┐
│ Hermes Agent │
│ · 用户问「校准这条」 │
│ · 上传后自动触发 │
│ · 批量 rerun 升级 │
└─────────────────────┘
职责边界(写进 Hermes 工具说明):
| 服务 | 问什么找它 |
|---|---|
| Calibrator | 航时/里程对不对?要不要进排行榜? |
| TLA | 有没有故障?温度/电流异常? |
| traj-store | 轨迹点在地图上怎么查? |
4. Hermes 动态调用设计(核心)
4.1 触发方式(优先级)
P0 单条即时校准(Hermes / 业务回调)
POST /calibrate/trajectory/{source_id}
或 POST /run { "mode":"upsert", "id": 14900, "sync": true }
P1 小批量增量(Hermes 对话:「校准最近 50 条未校准的」)
POST /run { "mode":"incremental", "limit": 50, "sync": false }
→ 返回 job_id → GET /jobs/{job_id}
P2 版本升级重跑(发版后一次)
POST /run { "mode":"rerun", "limit": 5000 }
P3 cron 兜底(可选,每天凌晨)
只扫 P0/P1 漏掉的 incremental
4.2 Hermes 工具定义(建议注册 4 个 tool)
calibrate_one:
description: 校准单条 history(按 source_id)
params: { source_id: int, dry_run: bool=false }
calls: POST /calibrate/trajectory/{source_id}
calibrate_pending:
description: 校准尚未写入 calibrated 表的记录
params: { limit: int=50 }
calls: POST /run mode=incremental
get_calibration_job:
description: 查询校准任务状态与日志尾部
params: { job_id: string }
get_calibration_stats:
description: 读最新 summary JSON + DB 聚合
calls: MCP get_calibration_stats 或 GET /stats
4.3 业务上传后自动校准(Webhook)
App Server 在 history 入库成功后(可选异步):
POST http://trajectory-calibrator:8091/calibrate/trajectory/{id}
Authorization: Bearer ${CALIBRATOR_API_TOKEN}
Hermes 不必参与每一单;webhook 负责默认路径,Hermes 负责「人工/对话触发的例外校准」。
5. API 演进(对齐 traj-store ingest)
5.1 现有 API(保留)
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /health |
健康检查 |
| POST | /run |
批量模式 dry-run / incremental / upsert / rerun |
| GET | /jobs/{id} |
任务详情(当前仅内存) |
5.2 建议新增(P0)
| 方法 | 路径 | 说明 |
|---|---|---|
| POST | /calibrate/trajectory/{source_id} |
单条同步校准,返回 calibrated 行摘要 |
| GET | /calibrate/trajectory/{source_id} |
查是否已校准 + status + notes 摘要 |
| GET | /stats |
待校准数、今日 updated/review 数 |
| POST | /webhook/history-created |
body: { "source_id": 123 },内部调单条校准 |
5.3 持久化 job 表(P1)
新建 surf_log_calibration_job(对齐 TLA):
CREATE TABLE surf_log_calibration_job (
job_id BIGINT AUTO_INCREMENT PRIMARY KEY,
job_type VARCHAR(32) NOT NULL, -- single|incremental|rerun|dry-run
started_at DATETIME NOT NULL,
finished_at DATETIME NULL,
status VARCHAR(16) NOT NULL, -- running|success|partial|failed
source_id INT NULL, -- 单条校准时填
sessions_scanned INT DEFAULT 0,
sessions_upserted INT DEFAULT 0,
sessions_failed INT DEFAULT 0,
error_summary TEXT NULL
);
api_server.py 写 job 时落库,Hermes 可 SQL 对账。
6. 部署模式(推荐)
# docker-compose.yml
services:
trajectory-calibrator:
image: trajectory-calibrator:2.2.2
environment:
MODE: api # ★ 仅 API 常驻,不要 cron
CALIBRATE_MODE: api
API_PORT: 8091
MCP_PORT: 8092
API_TOKEN: ${CALIBRATOR_API_TOKEN}
ports:
- "8091:8091"
- "8092:8092"
restart: unless-stopped
与 TLA 对比:
| TLA | Calibrator | |
|---|---|---|
| 默认运行 | docker compose run --rm(cron 触发) |
API 常驻 + 按需 POST |
| 状态表 | surf_log_analysis_job |
待建 surf_log_calibration_job |
| 结果表 | surf_motion_trajectory_analysis |
surf_motion_trajectory_calibrated |
7. Hermes 配置示例
HTTP 方式(gateway / workflow)
{
"name": "trajectory-calibrator",
"base_url": "http://trajectory-calibrator:8091",
"headers": { "Authorization": "Bearer ${CALIBRATOR_API_TOKEN}" },
"tools": [
{
"name": "calibrate_trajectory",
"method": "POST",
"path": "/run",
"body_template": {
"mode": "upsert",
"id": "{{source_id}}",
"limit": 1,
"sync": true
}
}
]
}
MCP 方式(已内置)
{
"mcpServers": {
"trajectory-calibrator": {
"url": "http://<host>:8092/sse"
}
}
}
Hermes 若跑在 Docker 同一 hermes-net,用服务名 trajectory-calibrator:8091。
8. 实施路线图
| 阶段 | 内容 | 工期 |
|---|---|---|
| Phase 0 | 部署 MODE=api,Hermes 用现有 POST /run + id + sync |
0.5 天 |
| Phase 1 | 新增 POST /calibrate/trajectory/{id} + GET /stats |
1 天 |
| Phase 2 | surf_log_calibration_job + job 持久化 |
1 天 |
| Phase 3 | App Server webhook 上传后触发 | 1 天 |
| Phase 4 | 文档迁入 fly-logs + Hermes tool 正式注册 | 0.5 天 |
Phase 0 今天就能做,不必等改代码。
9. Phase 0 验证命令(Hermes 联调)
# 1. 健康
curl http://127.0.0.1:8091/health
# 2. 单条 dry-run(不写库)
curl -X POST http://127.0.0.1:8091/run \
-H "Content-Type: application/json" \
-d '{"mode":"dry-run","id":14900,"limit":1,"sync":true}'
# 3. 单条写库
curl -X POST http://127.0.0.1:8091/run \
-H "Content-Type: application/json" \
-d '{"mode":"upsert","id":14900,"limit":1,"sync":true}'
# 4. 查库
SELECT source_id, calibration_status,
raw_cumulative_sailing_time, cumulative_sailing_time,
raw_sum_distance, sum_distance,
calibration_version, calibrated_at
FROM surf_motion_trajectory_calibrated
WHERE source_id = 14900;
10. 和「新电机稳定段分析」的关系
| 能力 | 归属服务 |
|---|---|
| 航时/里程纠正 | Calibrator |
| 稳定 20~30km/h 电流/功率 | TLA 扩展 或独立 analysis 脚本 |
| 故障诊断 | TLA |
不要在 Calibrator 里做稳定段;保持单一职责。
11. 决策建议
- 独立服务形态:保持
trajectory-calibrator仓库/目录,Docker API 常驻,cron 仅兜底。 - Hermes 主路径:
POST /run+id+sync=true(Phase 0);后续加 RESTful 单条接口。 - 下一步开发:Phase 1 单条 API + Phase 2 job 表(如需我可在 calibrator 仓库直接改
api_server.py)。