ADR-005: 营业时间 LLM 解析与 Agent 架构决策

修改记录

日期

变更

2026-07-18

ADR-005++ 表格化,Planner Agent / 调整端点修正为 🚧,修正回退策略描述

ADR-005++

状态

说明

验证

节假日/季节优化

holidays 库查询法定节假日,注入 prompt

tools.py:17-36

MCP 迁移预留

已迁移至 ADR-006,当前维持手写 FC

tool_call 两阶段

🚧

Planner Agent 扩展

add_poi / remove_poi / adjust_days 函数已实现,未接入前端

planner.py:48-152

🚧

方案调整端点

backend adjust_plan + schema 就绪,HTTP 路由已移除

pipeline.py:264-373

跨午夜营业时间截断

22:00-02:00 截断,仅 LLM prompt 约束

parse_biz_hours:195

状态

✅ 已采纳

背景

高德 POI API 返回的 opentime2 字段格式极其复杂,现有 _parse_opentime_to_tw() 纯函数规则解析难以覆盖全部变体:

格式变体

示例

规则解析难度

季节分段

04/01-10/31 08:30-17:00;11/01-03/31 08:30-16:30

节假日特例

春节,劳动节 08:30-17:00

极高(节假日不固定)

闭馆日

周一 全天不开放

停止入园

08:30-17:00,17:00停止入园

24小时

00:00-24:00

跨天

20:00-02:00

空/无意义

暂无营业时间 / ""

规则引擎每覆盖一种变体都需要新增正则分支,且无法泛化未知格式。

三方案对比

方案

优点

缺点

结论

A: 纯 LLM 解析

覆盖无限格式变体,成本极低(~0.0003元/次),失败回退零风险

依赖 API 可用性,增加毫秒级延迟

✅ 采纳

B: 规则增强

无外部依赖,零延迟

格式变体无限,维护成本持续增长,总有未覆盖的边界 case

❌ 放弃

C: 规则+LLM 混合

常见格式走规则,兜底走 LLM

两套逻辑增加维护复杂度,规则覆盖的边际效益递减

❌ 不推荐

LLM 成本测算:每次解析约 50-100 token,按 DeepSeek 价格 ~0.5元/百万 token,单次约 0.000025-0.00005 元,即使每日万次调用也仅 ~0.5 元。

决策

决策 1:纯 LLM 解析(方案 A)

采用 LLM 直接解析营业时间,放弃规则增强方案。

原因:

  • 格式变体无限,规则引擎永远追不上

  • LLM 成本极低,失败返回 None 无风险

  • 回退策略:后端 parse_biz_hours 返回 None,前端 usePoiSearch.ts:55?? 运算符兜底默认值

决策 2:日期/节假日前置计算

datetime + holidays 库在调用 LLM 前计算出当前日期、星期、是否为法定节假日,注入 prompt 以减小 LLM 的理解负担:

今天:2026-07-06(星期一),法定节假日:否
营业时间原始字符串:周一至周日 09:00-22:00

决策 3:MVP 不上 MCP

手写 Function Calling。当前工具数仅 1 个(parse_biz_hours),MCP 协议带来额外复杂度而无收益。等工具数增长到 3-5 个时再增量迁移(已迁移至 ADR-006)。

数据流

详见 docs/structure/backend.md 数据流图 — 营业时间 LLM 解析已内嵌至 GET /api/poi-lookup 流程中。

影响范围

文件

变更

说明

backend/agent/tools.py

新增 parse_biz_hours()

LLM 调用封装,含 prompt + 回退逻辑

backend/api/schemas.py

POILookupItem 新增 tw_start/tw_end 字段

返回前端展示

backend/data/amap_loader.py

get_poi_details 调用 parse_biz_hours()

LLM 解析,旧 _parse_opentime_to_tw 代码残留但已不被调用

frontend/src/pages/HomePage.vue

confirmPoi() 不再硬编码 (480, 1020)

使用后端返回的营业时间