Agent 层

修改记录

日期

变更

2026-07-18

从 backend.md 拆分独立

一、架构总览

Agent 层位于 HTTP 路由层和求解引擎层之间,负责 LLM 对话与工具调用。

路由层 (routes.py)
    ↓ POST /api/chat
Agent 层
    ├── chat.py        对话流调度
    ├── tools/          工具注册与执行
    ├── commentator.py  评语生成
    └── planner.py      规划调整
    ↓
引擎层 (engine/)     ← 工具函数(poi_lookup 等)

二、目录结构

backend/agent/
├── chat.py           对话流:build_chat_messages / chat_stream / stream_chat
├── commentator.py    评语生成器:generate_commentary
├── planner.py        三指令规划器:add_poi / remove_poi / adjust_days
└── tools/
    ├── __init__.py   工具注册表 TOOL_REGISTRY
    ├── prompts.py    所有 LLM prompt 模板集中管理
    ├── poi.py        POI 查询工具:poi_lookup / parse_biz_hours
    └── rag.py        BM25 检索引擎:search_rag() / RagEngine

三、对话流

详见 backend.md §四 路由层

SSE 协议格式

后端通过 text/event-stream 推送结构化事件:

type

触发时机

前端行为

tool_status

LLM 返回 tool_call 时

显示"正在查询..."

tool_result

工具执行完成后

渲染 POI 卡片至左侧待选栏

content

LLM 流式生成文字时

打字机效果追加

error

对话生成异常时

显示错误提示

done

全部输出完毕

结束 loading 状态

消息构建

build_chat_messages()prompts.py 读取 CHAT_SYSTEM,附加规划上下文后组装为 OpenAI 格式。

RAG 上下文注入

每次调用 build_chat_messages() 时自动触发 BM25 全文检索(rag.py):

  1. search_rag(query) 对用户消息分词后检索 docs/*.md + README.md

  2. 取 top-3 相关片段,格式化为 相关知识:\n- [来源] 标题:片段...

  3. system 角色注入消息列表(位于 CHAT_SYSTEM 之后,user 消息之前)

匹配策略:中文拆单字、英文空白分词,无需 jieba 等外部库。

调试模式

MOCK_MODE=True 时走 mock_stream_chat() 固定回复,无需 API Key。 正式部署应保持 MOCK_MODE=False

四、工具系统

注册表

TOOL_REGISTRY 字典集中管理所有可调用工具(tools/__init__.py):

TOOL_REGISTRY: dict[str, Callable] = {
    "poi_lookup": poi_lookup,
}

新增工具只需在 tools/ 下新建文件、实现函数、注册到 TOOL_REGISTRY

主流程

用户消息 → build_chat_messages() + TOOL_DEFINITIONS
  → LLM 非流式首调
    ├─ tool_calls → 执行工具 → tool_result 追加 messages → LLM 二次调用 → SSE 流式回复
    └─ text       → SSE 直接流式输出

poi_lookup 工具

详见 tools/poi.py

通过高德 API 查询 POI 坐标、地址和营业时间。自动识别酒店与景点:

  • 酒店:poi_type="hotel",时间窗 0-1440(全天)

  • 景点:poi_type="spot",时间窗由 LLM 解析 opentime2

详见 data.md §POILookupItem

五、提示词管理

所有 LLM prompt 集中在 tools/prompts.py

常量

用途

CHAT_SYSTEM

对话系统 prompt

PARSE_PROMPT

营业时间 LLM 解析模板

POI_TOOL_DEF

poi_lookup 工具定义(JSON schema)

TOOL_DEFINITIONS

全部工具定义列表

六、评语与规划调整

commentator.py

generate_commentary(plan_result) → 自然语言评语。规则模板 + LLM 润色混合模式。 详见 docs/产品路线图.md 第一阶段。

planner.py

三指令规划器,当前函数已就绪但未接入 Function Calling

函数

功能

add_poi_to_plan()

加景点后调用 cluster_and_solve 重算

remove_poi_from_plan()

去景点后重映射索引重算

adjust_plan_days()

调天数后重分配行程

目标:后续注册到 TOOL_REGISTRY 后,用户可通过对话调整方案。

七、数据流

Function Calling 流程

用户: "查一下广州的白云山"
  → POST /api/chat { message: "查一下广州的白云山" }
  → build_chat_messages() → [system, user]
  → OpenAI tools=TOOL_DEFINITIONS
  → LLM: tool_call → poi_lookup(city="广州", name="白云山")
  → 高德 API → 坐标/地址/营业时间
  → SSE: tool_result
  → pendingPois[] 追加 ← 前端左侧待选栏
  → messages 追加 tool result → LLM 二次调用
  → SSE: content → "找到了!白云山..."
  → SSE: done

RAG 检索流程

用户: "这个项目是做什么的"
  → POST /api/chat { message: "这个项目是做什么的" }
  → build_chat_messages()
      ├─ search_rag("这个项目是做什么的") → BM25 检索 docs/ 相关片段
      └─ 注入 system message(知识段位于 user 之前)
  → OpenAI 无 tools 调用 → SSE 直接流式输出
  → SSE: content → "这是一个基于 VNS+ 引擎的..."
  → SSE: done