3.1 从零设计“旅小智”:一个生产级的 AI 旅行规划智能体系统架构

2 阅读1分钟

导语:欢迎开启课程第三周的挑战!在经历了第一周的“单兵作战”和第二周的“团队协同”之后,我们将在本周完成一次“集团军”级别的综合项目实战。我们的目标是构建一个名为 “旅小智”(TripGenius) 的 AI 旅行规划智能体。这不仅仅是一个后台运行的脚本,而是一个完整的、拥有前端用户界面、后端 API 服务、以及复杂多智能体内核的全栈应用。本章作为本周的开篇,我们将扮演“首席架构师”的角色,从零开始,设计“旅小智”的宏观系统架构。我们将定义它的愿景、角色、技术栈,并绘制出系统各组件之间交互的蓝图。一份清晰、健壮的架构设计,是项目成功的一半。

目录

  1. 项目愿景:人人都能拥有的“私人旅行定制师”
    • 痛点分析:传统旅行规划的繁琐与信息过载
    • “旅小智”的核心价值:提供个性化、端到端的旅行规划与预订服务
  2. 技术栈选型:构建一个现代化的 AI 应用
    • 前端(Frontend): Streamlit - 快速构建数据驱动的 Web UI
    • 后端(Backend): FastAPI - 高性能的 Python API 框架
    • 智能体内核(Agent Core): LangGraph - 编排我们的多智能体团队
    • 容器化(Containerization): Docker - 实现标准化的打包与部署
  3. 系统宏观架构:前后端分离与智能内核
    • 三层架构:用户界面层、业务逻辑层、智能体核心层
    • Mermaid 图:可视化“旅小智”的系统架构
    • 数据流:一次完整的用户请求是如何在三层之间流动的?
  4. 智能体团队设计:定义“旅小智”的多角色 Agent
    • 团队角色
      • TravelPlanner (旅行规划师 - 主管): 团队的核心大脑,负责与用户沟通、分解任务、调度其他专家。
      • CityExpert (城市攻略专家): 负责搜索和推荐目的地城市的景点、美食、文化活动。
      • HotelExpert (酒店预订专家): 负责根据预算和偏好搜索和筛选酒店。
      • FlightExpert (机票预订专家): 负责搜索和比较机票信息。
      • ItineraryGenerator (行程生成器): 负责将所有信息整合成一份详细的、每日的行程单。
    • 协作模式:一个以 TravelPlanner 为中心的、动态的、层级化的协作网络。
  5. LangGraph 图设计:为 AI 团队绘制“组织架构图”
    • 状态定义(TripState: 我们需要追踪用户的需求、目的地、预算、规划草案、预订信息等。
    • 核心节点planner, city_expert_node, hotel_expert_node, flight_expert_node, itinerary_generator_node
    • 路由逻辑planner 将扮演一个极其智能的中央路由器,根据对话的进展和当前任务,动态地将工作流分发给不同的专家节点。
  6. API 接口设计(API Contract)
    • 定义前后端之间的通信契约。
    • POST /trip/invoke: 发起一个新的对话回合,流式返回 Agent 的思考过程和最终结果。
    • GET /trip/state: 获取指定会话的当前状态,用于前端恢复和展示。
  7. 用户交互流程(User Flow)
    • 描绘用户从打开网页到获得最终行程单的完整交互路径。
  8. 总结:蓝图在手,天下我有

1. 项目愿景:人人都能拥有的“私人旅行定制师”

痛点分析

规划一次完美的旅行是一件既令人兴奋又极其耗时费力的事:

  • 信息过载:面对网络上无穷无尽的攻略、点评、榜单,我们常常无所适从。
  • 需求繁杂:需要同时考虑机票、酒店、景点、餐饮、交通、预算等多个维度,并在它们之间做出权衡。
  • 个性化缺失:大多数在线旅游平台(OTA)提供的是标准化的产品,难以满足“我想在一个安静的海边小镇住三天,其中一天下午想去学冲浪”这类高度个性化的需求。
  • 流程割裂:搜索攻略、预订机票、预订酒店通常需要在不同的平台上来回切换。

“旅小智”的核心价值

“旅小智”旨在解决这些痛点。它不仅仅是一个聊天机器人,而是一个对话式的、端到端的私人旅行定制师

  • 个性化理解:通过自然语言对话,深入理解用户的模糊需求、预算和个人偏好。
  • 专家级建议:利用背后由多个专家 Agent 组成的团队,提供专业、可靠的目的地、住宿和交通建议。
  • 动态规划:能够与用户进行多轮“讨价还价”,实时调整和优化行程计划。
  • 一站式服务:在未来,可以集成真实的预订 API,实现从规划到预订的无缝体验(本次项目将使用模拟工具)。

2. 技术栈选型:构建一个现代化的 AI 应用

  • 前端: Streamlit
    • 为什么选它? Streamlit 是一个纯 Python 的前端框架,能让我们以惊人的速度将数据脚本转换为可交互的 Web 应用。对于以 Python 为主的 AI 开发者来说,无需学习复杂的前端技术(如 React, Vue),就能快速构建出漂亮、实用的用户界面。非常适合原型验证和内部工具。
  • 后端: FastAPI
    • 为什么选它? FastAPI 以其高性能、易用性、以及与 Pydantic 的无缝集成而闻名。它能自动生成交互式的 API 文档(基于 OpenAPI 和 JSON Schema),非常适合作为 AI 应用的后端,为前端提供稳定、标准的 API 服务。
  • 智能体内核: LangGraph
    • 为什么选它? 旅行规划是一个典型的、需要多专家协作的复杂任务。LangGraph 提供了构建这种复杂、有状态、有循环的多智能体系统的完美工具,其灵活性和可控性远超传统的 AgentExecutor
  • 容器化: Docker
    • 为什么选它? Docker 是实现开发、测试、生产环境一致性的行业标准。它能将我们的全栈应用(包括 Python 环境、前后端代码、Agent 模型)打包成一个标准化的容器,实现“一次构建,到处运行”。

3. 系统宏观架构:前后端分离与智能内核

我们将采用经典的前后端分离架构。

  • 用户界面层 (UI Layer):由 Streamlit 构建。它是一个独立运行的服务,负责渲染用户界面、接收用户输入、并通过 HTTP 请求与后端通信。
  • 业务逻辑层 (Business Logic Layer):由 FastAPI 构建。它也是一个独立的服务,负责处理前端的请求、管理用户会话、并作为“翻译官”与智能体内核进行交互。
  • 智能体核心层 (Agent Core Layer):由 LangGraph 构建的 AI 团队。它被业务逻辑层调用,负责执行真正的“智能”任务。

Mermaid 图:可视化“旅小智”的系统架构

graph TD
    subgraph User's Browser
        U[用户]
    end
    
    subgraph Frontend Server (Streamlit)
        S[Streamlit UI]
    end

    subgraph Backend Server (FastAPI + LangGraph)
        F[FastAPI Endpoints]
        L[LangGraph Core]
    end

    subgraph External Services
        DB[(Memory DB\nSqlite)]
        T[Tool APIs\n(Search, Weather, etc.)]
    end

    U -- "1. 交互" --> S;
    S -- "2. 发起 HTTP API 调用 (e.g., /invoke)" --> F;
    F -- "3. 调用 LangGraph App" --> L;
    L -- "4. 读/写状态" --> DB;
    L -- "5. 调用外部工具" --> T;
    T -- "6. 返回工具结果" --> L;
    L -- "7. 返回执行结果" --> F;
    F -- "8. 流式返回 HTTP 响应" --> S;
    S -- "9. 更新 UI 展示" --> U;

数据流解读

  1. 用户在 Streamlit 界面上输入“我想去云南玩一周,预算 5000”。
  2. Streamlit 将这个请求打包,通过 HTTP POST 发送给 FastAPI 的 /invoke 端点。
  3. FastAPI 接收到请求,为该用户会话找到或创建一个 thread_id,然后调用 LangGraph appstreaminvoke 方法,并将 thread_id 和用户输入传入。
  4. LangGraph 内核开始运转。TravelPlanner 主管 Agent 介入,它从 Sqlite 数据库中加载该 thread_id 的历史状态。
  5. TravelPlanner 决定需要了解云南的景点,于是将任务分配给 CityExpert
  6. CityExpert Agent 节点被执行,它调用外部的 Tavily Search API。
  7. 搜索结果返回给 CityExpert,它进行整理后更新 TripState
  8. TravelPlanner 看到 CityExpert 的结果后,决定下一步需要咨询 HotelExpert... 这个过程不断循环。
  9. 在整个过程中,FastAPI 可以通过 LangGraph 的 stream 方法,将每一步的中间结果(如“正在为您搜索景点...”、“正在为您筛选酒店...”)流式地返回给 Streamlit 前端。
  10. Streamlit 接收到这些流式数据,实时地更新 UI,向用户展示 Agent 的“思考过程”,极大地提升了用户体验。

4. 智能体团队设计:定义“旅小智”的多角色 Agent

我们的 AI 团队将由以下核心角色组成:

角色职责使用工具 (示例)
TravelPlanner (主管)核心协调者。与用户直接对话,理解需求,分解任务,调用其他专家,并最终确认计划。(不直接使用外部工具,而是“调用”其他 Agent 节点)
CityExpert (专家)提供关于特定城市或地区的详细信息,如必游景点、特色美食、当地文化、最佳旅行时间等。TavilySearch, Wikipedia
HotelExpert (专家)根据用户的预算、位置偏好、住宿类型(酒店、民宿)等,搜索和筛选酒店。AmadeusHotelSearch (模拟), Booking.com (模拟)
FlightExpert (专家)根据用户的出发地、目的地和日期,搜索和比较机票。SkyscannerAPI (模拟), GoogleFlights (模拟)
ItineraryGenerator (专家)一个特殊的、非交互式的 Agent。它接收所有已确认的信息(城市、酒店、航班、活动),并生成一份格式化的、每日的行程单。(无外部工具,纯粹的 LLM 生成能力)

5. LangGraph 图设计

状态定义(TripState

class TripState(TypedDict):
    # 用户的原始需求
    user_request: str
    
    # 由 Planner 生成的旅行计划草案
    draft_plan: Dict[str, Any]
    
    # 专家 Agent 的研究结果
    expert_outputs: Dict[str, Any]
    
    # 最终确认的行程单
    final_itinerary: Optional[str]

    # 对话历史
    messages: Annotated[List[BaseMessage], operator.add]
    
    # 下一个要执行的节点
    next_node: str

路由逻辑

TravelPlanner 将是这个图的核心路由器。在每个循环的开始,它都会被调用。它会审视整个 TripState,特别是最新的用户消息和 expert_outputs,然后做出决策,更新 next_node 字段。

  • 初始状态 -> 用户输入 -> TravelPlanner 决策 -> next_node = city_expert
  • city_expert 完成 -> TravelPlanner 决策 -> next_node = hotel_expert
  • ...
  • 所有信息收集完毕 -> TravelPlanner 决策 -> next_node = itinerary_generator
  • 行程单生成 -> TravelPlanner 决策 -> next_node = END

6. API 接口设计(API Contract)

FastAPI 将提供以下核心接口:

  • POST /trip/invoke:
    • Request Body: {"input": "用户输入", "thread_id": "可选的会话ID"}
    • Response Body (流式): Server-Sent Events (SSE) stream. 每个事件都是一个 JSON 对象,可能包含:
      • {"event": "on_agent_start", "agent": "CityExpert"}
      • {"event": "on_tool_end", "output": "搜索结果..."}
      • {"event": "on_llm_end", "output": "AI 思考的中间文本..."}
      • {"event": "final_result", "itinerary": "{...}"}
    • 作用: 驱动 Agent 进行一轮或多轮工作,并实时反馈进度。
  • GET /trip/state/{thread_id}:
    • Response Body: {"state": TripState}
    • 作用: 获取某个会话的完整历史状态,用于调试或在用户刷新页面后恢复前端 UI。

7. 用户交互流程(User Flow)

  1. 用户打开 Streamlit 应用,看到一个欢迎界面和聊天输入框。
  2. 用户输入第一个请求:“下个月我想带家人去海边玩,有什么推荐吗?”
  3. Streamlit 将请求发送到 FastAPI 后端。
  4. 后端 TravelPlanner Agent 开始工作,它可能会反问:“很棒的想法!为了更好地为您推荐,能告诉我您的预算、出行人数和偏好的旅行风格(比如悠闲度假还是紧凑观光)吗?”
  5. 这个反问通过流式响应实时显示在前端 UI 上。
  6. 用户回复:“我们两个人,预算 8000,喜欢悠闲一点的。”
  7. TravelPlanner 接收到新信息,决定调用 CityExpert。前端显示:“正在为您寻找合适的海滨城市...”
  8. CityExpert 返回了几个城市选项(如三亚、厦门、青岛)及各自的优缺点。
  9. TravelPlanner 将这些选项呈现给用户。
  10. 用户选择了“厦门”。
  11. TravelPlanner 接着调用 HotelExpertFlightExpert...
  12. 经过几轮这样的交互,所有信息确认完毕。
  13. TravelPlanner 调用 ItineraryGenerator,生成最终的 PDF 或 Markdown 行程单。
  14. 前端显示“您的专属行程已生成!”,并提供下载链接。

8. 总结:蓝图在手,天下我有

通过本章的设计,我们为“旅小智”项目绘制了一份清晰、完整、可执行的架构蓝图。我们明确了项目的目标、技术栈、系统分层、数据流、AI 团队的角色与协作方式,以及前后端的交互契约。

这份蓝图将是我们接下来几章编码工作的“北极星”,指引我们高效、有序地将一个宏大的构想,一步步变为现实。