Imported from IBRANCE/NavAgent (
AGENTS.md). Install upstream withnpx skills add IBRANCE/NavAgent. Copyright stays with the author.
AGENTS.md — 出行 Agent (NavAgent) 改动入口
新会话从这里出发,无需先行探索即可定位改动点、明确改后要跑的校验。 本文件只做「导航」;领域术语的权威定义在 CONTEXT.md,此处不重复。
一句话领域语言
以出行规划(去哪/玩几天/每天去哪些点,产出行程 Itinerary)为主脑, 调用导航规划(两点间怎么走,产出路线 Route)与城际交通(跨城班次,产出 跨城段 TransitLeg)为工具,最终交付「带路线的行程」。术语的精确定义与禁用词见 CONTEXT.md#Language。
关键命令
| 命令 | 作用 |
|---|---|
make dev |
前台启动开发服务器(端口 9099) |
make check |
改动后必跑:类型检查 (tsc --noEmit) + 单测 (vitest run) + 全量 ESLint (next lint) |
make test / make typecheck |
单独跑单测 / 单独跑类型检查 |
make lint / make lint-staged |
全量 ESLint / 只 lint 已暂存的 .ts/.tsx(快速反馈) |
make test-file FILE=… / make test-changed |
只跑单个测试文件 / 只跑受未提交改动影响的用例 |
make help |
列出全部 target |
任何代码改动后,以 make check 作为默认校验门槛。改动范围小时,可先用
make lint-staged + make test-file(或 make test-changed)拿到最小校验反馈,make check 语义不变。
质量门禁(强制运行)
门禁在提交前与合并前两处强制执行,失败即阻断。ESLint 已纳入门禁:
提交前只 lint 暂存文件(lint-staged,快速反馈),合并前跑全量 lint(make check)。
| 层 | 位置 | 触发时机 | 执行内容 |
|---|---|---|---|
| 提交前 | hooks/pre-commit(唯一真相源,版本化) | 本地 git commit |
类型检查 + 单测 + 暂存文件 lint(lint-staged) |
| 合并前 | .github/workflows/check.yml | push / Pull Request | make check(类型检查 + 单测 + 全量 lint) |
| 0019 | Langfuse 可观测性:OTel SDK v5 + agent/generation/tool 三层埋点 + PII 掩码与开关(LANGFUSE_* 环境变量)+ 系统提示词版本镜像(navagent-system-prompt)与 generation 链接 | 改 lib/observability/、lib/agent/model.ts 的 streamFn、追踪属性/埋点策略时 |
未使用变量/参数由 TypeScript 承担(tsconfig 的
noUnusedLocals/noUnusedParameters), 故 ESLint 保持no-unused-vars: off;两层门禁均会跑tsc,检测不会遗漏。
新克隆运行 make setup 即自动安装本地 hook(幂等:已存在则跳过;不改 git 配置、不引入额外工具)。
也可手动安装:
ln -sf ../../hooks/pre-commit .git/hooks/pre-commit
紧急情况下可用 git commit --no-verify 跳过本地 hook;合并门禁(CI)不可跳过。
目录职责图
app/
api/chat/route.ts [高风险] SSE Route Handler:agent 事件 → 前端事件
api/a2a/ A2A 对外门面:route.ts(JSON-RPC + SSE)与 agent-card/(发现文档,ADR-0018)
components/ 前端 ChatPanel / MapView(高德 JS SDK 地图)
lib/chat-client.ts 前端 SSE 客户端
lib/
agent/ [高风险] Agent 主脑
agent.ts 组装单一 agent loop、汇总工具集 tools
model.ts / prompt.ts LLM 模型接入 / 系统提示词
tools/ ← Agent 工具面(见下)
a2a/ [高风险] A2A server 端协议翻译层:executor 桥接 + PII 拦截/脱敏 + 出口闸 + 鉴权(ADR-0018)
amap/ [高风险] 高德客户端:POI 搜索、路线规划、距离/天气(地理骨架)
ctrip/ 城际火车降级源:searchTrains(12306 实时 + Mock,仅途牛调用失败时兜底,空结果不降级,ADR-0016)
tuniu/ [高风险] 途牛结构化数据与下单客户端:tuniu-cli 双层解包(门票/酒店/机票/火车查询 + 门票/火车真实下单,PII 日志脱敏)
luckin/ 瑞幸官方 MCP 客户端:JSON-RPC over HTTP + 归一化(门店/商品/下单,未支付剥离取餐码,ADR-0014)
session/ SessionStore(进程内会话状态)+ TravelerStore(出行人 PII 暂存,不落盘,ADR-0012)
observability/ [高风险] Langfuse 可观测层(OTel SDK v5,ADR-0019):otel.ts 启动/掩码/flush,trace.ts 根 observation 与工具 span 生命周期,prompt.ts 系统提示词版本镜像与链接
shared/ itinerary.ts:前后端共享的行程/事件 TS 类型(强契约)
validate-itinerary.ts:[高风险] 确定性护栏层(pre 硬错误/post 软警告,ADR-0010)
tool-status.ts:工具状态文案 TOOL_STATUS(chat SSE 与 A2A 两面共用)
docs/adr/ 架构决策记录(见下方索引)
tests/ vitest 单测
Agent 工具面(改工具从这里入手)
工具集在 lib/agent/agent.ts 的 tools 汇总,可插拔(见 ADR-0002)。
用户可读的状态文案映射在 lib/shared/tool-status.ts 的 TOOL_STATUS(chat 与 A2A 两面共用)。
| 工具文件 | 提供的工具 |
|---|---|
| tools/amap-tools.ts | search_places get_place_detail plan_route compare_routes distance_matrix get_weather |
| tools/alert-tools.ts | get_weather_alerts get_typhoons get_earthquakes(极端天气预警与台风路径:中央气象台 NMC;近期震情:USGS。均免 key,失败诚实降级为「暂不可用」;台风路径经 SSE typhoon 事件绘制到前端地图) |
| tools/tuniu-tools.ts | search_attraction_tickets search_hotels search_flights search_trains(途牛结构化数据;服务端排序/时段过滤,火车 sortBy 默认耗时升序、机票无偏好时早/午/晚三片并行合并,见 ADR-0016;火车途牛主源,仅调用失败降级 12306,空结果诚实返回,见 ADR-0009/0016) |
| tools/tuniu-order-tools.ts | request_traveler_info get_ticket_book_form create_ticket_order query_train_detail book_train cancel_train_order query_flight_cabins create_flight_order cancel_flight_order query_hotel_detail create_hotel_order(门票/火车/机票/酒店真实下单,订单态 ordered 回写行程真相源,见 ADR-0011/0015;工厂 createTuniuOrderTools(sessionId) 按会话绑定,出行人 PII 经表单旁路注入见 ADR-0012,机票/酒店 opaque 令牌经闭包 draft 旁路见 ADR-0015) |
| tools/luckin-tools.ts | search_luckin_shops search_luckin_products get_luckin_product_detail switch_luckin_product create_luckin_order query_luckin_order cancel_luckin_order(瑞幸官方 MCP 咖啡自取下单,preview→create 确定性内聚,订单回写行程真相源 coffee/ordered,见 ADR-0014) |
| tools/present-itinerary.ts | present_itinerary(收尾工具,唯一结构化真相源,见 ADR-0003;内嵌确定性护栏层 pre/post 校验,见 ADR-0010) |
高风险区(改动需格外谨慎,改后必跑 make check)
- lib/agent/ — Agent loop 与工具集主干;改工具优先「增删工具」而非改 loop(ADR-0002)。
- lib/amap/ — 与高德坐标系(GCJ-02)/API 强绑定(ADR-0001),路线 polyline 是行程真相源的一部分。
- lib/observability/ 与 lib/agent/model.ts 的 streamFn — Langfuse 追踪埋点(ADR-0019):streamFn 包装层必须保持「不抛出、失败编码进 stream」契约;PII 掩码/开关变更会影响数据外发边界。
- app/api/chat/route.ts — agent 事件到 SSE 事件的翻译层;
present_itinerary结果在此落库并推前端。 - lib/a2a/ — A2A 协议翻译层(ADR-0018):真实下单对外暴露 + PII 拦截旁路/task history 脱敏 + 行程出口闸;改 Itinerary 契约、下单工具面、取消/忙时语义时必须同步此处。
ADR 索引(各自适用范围)
| ADR | 主题 | 适用范围 |
|---|---|---|
| 0001 | 高德作为地图与路线服务商 | 改 lib/amap/、坐标系/POI/市内路线、地图组件时 |
| 0002 | 首期单城市 + 工具可插拔 | 新增/删除 Agent 能力、评估功能范围时 |
| 0003 | present_itinerary 为唯一真相源 | 改行程 schema、present_itinerary 入参、前后端契约时 |
| 0004 | Next.js 全栈单仓 + pi-agent-core + SSE | 改 Route Handler、SSE 事件、会话状态、共享类型时 |
| 0005 | 跨城 TransitLeg + 携程 + 三个独立工具(火车降级链保留,降级触发条件被 ADR-0016 收窄;航班/火车数据源被 ADR-0008/0009 取代,大巴已下线见 ADR-0013) | 改城际交通(lib/ctrip/ 火车降级、TransitLeg 模型)时 |
| 0006 | 购票导流闭环 + 内嵌 Booking + 诚实三态 + 共享深链(三态已被 ADR-0011 扩为四态;餐厅配票与 dpurl 透传已被 ADR-0013 移除) | 改预订项、深链、总价、buildDeepLink、预订前端时 |
| 0007 | 机票/大巴维持 Mock + Provider 接缝 + 火车式降级(已被 ADR-0008 取代:mock 工具已删除) | 追溯机票/大巴 mock 历史决策时 |
| 0008 | 美团=内容/商业真相源、高德=地理骨架、LLM=桥接(门票/酒店/机票/火车被 ADR-0009 取代,剩余大巴/餐厅范围已被 ADR-0013 取代:美团 CLI 已移除) | 追溯美团数据源历史决策时 |
| 0009 | 途牛=门票/酒店/机票/火车结构化真相源、火车途牛主源+12306 降级(「本项目不下单」前提已被 ADR-0011 取代;「美团=大巴/餐厅兜底」分工已被 ADR-0013 修订;降级触发条件被 ADR-0016 收窄为空≠失败) | 改 lib/tuniu/、途牛工具、结构化字段直填 present_itinerary、途牛深链兜底时 |
| 0010 | 确定性护栏层:pre 硬错误阻断 + post 软警告体检 + 单人预算约束 | 改 lib/shared/validate-itinerary.ts、校验规则/阈值、warnings/budgetCents 契约、骨架预算行时 |
| 0011 | 真实下单闭环:门票/火车对话内下单 + 诚实四态 ordered + PII 最小化(修订 ADR-0006 三态、取代 ADR-0009「不下单」前提;「对话内收集 PII」环节已被 ADR-0012 修订为表单旁路) | 改下单工具、订单态透传、支付链接展示时 |
| 0012 | 出行人 PII 表单旁路(表单提交即确认、PII 不进 LLM 上下文)+ 分享快照脱敏(消息打码 + 剥离 paymentUrl)(旁路通道被 ADR-0018 扩展至 A2A 面的 DataPart 往返) | 改出行人表单/travelerStore//api/traveler、下单工具 PII 注入、分享脱敏时 |
| 0013 | 移除美团 CLI:大巴下线、餐厅退化为高德纯推荐节点、删 bookingDeepLink/bookingProvider 透传(取代 ADR-0008 剩余范围,修订 ADR-0006/0009) | 改餐厅推荐、城际交通品类、booking 透传字段时 |
| 0014 | 瑞幸官方 MCP 咖啡下单:服务端单账号 token、仅自取、preview→create 确定性内聚、订单入行程真相源 coffee/ordered(修订 ADR-0006/0011 品类枚举) | 改 lib/luckin/、瑞幸工具、咖啡 booking 组装时 |
| 0015 | 机票/酒店对话内真实下单 + opaque 令牌会话闭包旁路(cabinPriceId/preBookParam 不进 LLM)+ PII 字段映射(修订 ADR-0011「其余品类维持导流」范围) | 改机票/酒店下单工具、舱位/房型 draft、途牛下单 wrapper 时 |
| 0016 | 途牛搜索取数策略:服务端排序/时段过滤 + 火车 sortBy + 机票 TIME 三片并行 + 空≠失败降级语义(修订 ADR-0005/0009 火车降级触发条件) | 改途牛搜索入参/排序/时段映射、火车降级判定、机票分片合并时 |
| 0017 | 提示词契约断言:关键编排行为句级固化进 agent-factory 单测 + 提示词变更验收方式约定(删/削弱规则须先修订 ADR;对模型透明的降级链禁入提示词) | 改 lib/agent/prompt.ts 关键编排短语、增删编排规则、改提示词契约测试时 |
| 0018 | A2A server 对外暴露:全能力面(含真实下单)+ a2a:<contextId> 隔离复用 Agent loop + input-required 下单挂起 + PII DataPart 旁路/脱敏 + 行程 Artifact 出口闸 schemaVersion + API Key 总开关(修订 ADR-0012 旁路载体) |
改 lib/a2a/、app/api/a2a/、Agent Card skills、A2A 任务/取消/忙时语义、出口契约测试时 |