传统的旅游预订平台往往只是一个信息展示和交易撮合系统,用户需要自己筛选航班、对比酒店、规划每日行程,耗时且容易因为信息不对称导致体验不佳。借助大语言模型的推理能力和工具调用机制,我们可以构建一个旅游行程规划与预订Agent。这个Agent能够接收用户的自然语言需求,自主拆解任务,调用后端的航班查询、酒店预订、景点推荐等API接口,最终为用户生成一份可直接执行的行程方案。

旅游Agent的系统架构与核心组件
构建一个旅游Agent,首先需要明确其核心架构。与简单的聊天机器人不同,Agent系统通常包含感知层、大脑层和行动层。感知层负责接收用户的自然语言输入,大脑层由大语言模型担任,负责意图理解、任务拆解和决策规划,行动层则是一系列可调用的外部工具或API接口。
在旅游场景中,大脑层需要处理复杂的用户需求。例如用户说想带老人去三亚玩五天,预算一万元,希望住海景房。大模型需要从中提取出目的地、出行天数、预算金额、特殊住宿偏好等关键信息,并判断当前需要调用哪些工具。是先查机票还是先查酒店?如果预算紧张,是否需要调整住宿标准?这些决策都需要在架构设计时予以考虑。
行动层的设计直接决定了Agent的能力边界。一个完整的旅游Agent通常需要集成航班搜索、酒店预订、景点门票购买、天气查询、地图导航等多个工具。每个工具都需要定义清晰的输入输出规范,以便大模型能够正确调用并解析返回结果。下面是一个工具定义的代码示例:
import json
# 定义旅游Agent可用的工具列表
travel_tools = [
{
"type": "function",
"function": {
"name": "search_flights",
"description": "根据出发地、目的地和日期搜索可用航班",
"parameters": {
"type": "object",
"properties": {
"origin": {
"type": "string",
"description": "出发城市,例如北京"
},
"destination": {
"type": "string",
"description": "目的城市,例如三亚"
},
"date": {
"type": "string",
"description": "出发日期,格式为YYYY-MM-DD"
}
},
"required": ["origin", "destination", "date"]
}
}
},
{
"type": "function",
"function": {
"name": "book_hotel",
"description": "根据酒店名称和入住日期预订酒店",
"parameters": {
"type": "object",
"properties": {
"hotel_name": {
"type": "string",
"description": "酒店名称"
},
"check_in": {
"type": "string",
"description": "入住日期"
},
"check_out": {
"type": "string",
"description": "退房日期"
},
"room_type": {
"type": "string",
"description": "房型,如海景房、标准间"
}
},
"required": ["hotel_name", "check_in", "check_out"]
}
}
}
]
上述代码定义了航班搜索和酒店预订两个核心工具。每个工具的描述信息至关重要,大模型依赖description字段来判断何时应该调用该工具。参数的描述同样需要精确,例如日期格式必须明确说明,否则大模型生成的参数可能无法被后端API正确解析。
基于Function Calling的工具调用机制实现
Function Calling是大模型实现Agent能力的关键技术。当用户输入一条消息后,大模型不仅生成文本回复,还可以输出一个结构化的函数调用请求。这个请求包含函数名和参数,Agent的执行引擎接收到该请求后,调用对应的后端API,将API返回结果再次传给大模型,大模型基于结果生成最终回复或发起新的函数调用。
在旅游场景中,一次完整的对话往往涉及多次函数调用。比如用户要求规划三亚五日游,Agent可能先调用天气查询工具获取目的地天气情况,再调用航班搜索工具查找机票,然后调用酒店搜索工具筛选住宿,最后综合所有信息生成行程单。这个多步骤的调度过程,就是通过Function Calling的循环机制实现的。
下面展示一个Agent主循环的简化实现,帮助理解整个调用流程:
import openai
def run_travel_agent(user_message, conversation_history):
# 将用户消息加入对话历史
conversation_history.append({"role": "user", "content": user_message})
while True:
# 调用大模型,传入工具定义
response = openai.chat.completions.create(
model="gpt-4-turbo",
messages=conversation_history,
tools=travel_tools,
tool_choice="auto"
)
message = response.choices[0].message
# 如果大模型决定调用工具
if message.tool_calls:
conversation_history.append(message)
for tool_call in message.tool_calls:
function_name = tool_call.function.name
function_args = json.loads(tool_call.function.arguments)
# 根据函数名分发到对应的处理函数
if function_name == "search_flights":
result = search_flights(**function_args)
elif function_name == "book_hotel":
result = book_hotel(**function_args)
else:
result = {"error": "未知的工具"}
# 将工具执行结果加入对话历史
conversation_history.append({
"role": "tool",
"tool_call_id": tool_call.id,
"content": json.dumps(result, ensure_ascii=False)
})
else:
# 大模型不再调用工具,返回最终回复
final_reply = message.content
conversation_history.append(message)
return final_reply
这段代码的核心在于while True循环。每次循环中,大模型都会根据当前对话历史和工具执行结果,决定是继续调用工具还是给出最终回复。当message.tool_calls为空时,说明大模型已经收集到足够的信息,可以生成最终的行程规划方案了。这种设计使得Agent能够自主完成多步骤的复杂任务,而不需要人工干预每一步的流程。
需要注意的是,工具调用的错误处理非常关键。后端API可能因为网络问题或参数错误返回异常,Agent需要将这些异常信息以友好的方式反馈给大模型,让大模型决定是重试、更换参数还是直接告知用户。一个健壮的Agent系统应该对每个工具调用包裹异常捕获逻辑,避免因为单个工具的故障导致整个对话崩溃。
多轮对话中的上下文记忆与状态管理
旅游规划是一个典型的多轮对话场景。用户很少在一句话中给出所有需求,往往是在交互过程中不断补充和修改。用户可能先说想去三亚,接着补充预算是五千,然后又问能不能改成去厦门。Agent需要维护一个完整的对话状态,记住用户的所有偏好和约束条件,并在需求变更时及时更新。
对话状态的管理可以分为短期记忆和长期记忆。短期记忆指的是当前对话会话中的上下文信息,通常通过将对话历史完整传给大模型来实现。但是当对话轮次过多时,完整的对话历史会超出大模型的上下文窗口,导致信息丢失或调用成本激增。这时需要对历史对话进行压缩和摘要。
长期记忆则涉及跨会话的用户偏好存储。例如用户上次预订过海景房,下次规划行程时Agent可以主动推荐类似房型。这通常需要借助向量数据库,将用户的历史偏好和行程记录向量化存储,在新的对话开始时通过相似度检索召回相关信息。下面是一个简单的状态管理结构示例:
from dataclasses import dataclass, field
from typing import List, Optional
@dataclass
class TravelState:
"""旅游Agent的对话状态管理类"""
destination: Optional[str] = None
origin: Optional[str] = None
start_date: Optional[str] = None
duration_days: Optional[int] = None
budget: Optional[float] = None
preferences: List[str] = field(default_factory=list)
booked_flights: List[dict] = field(default_factory=list)
booked_hotels: List[dict] = field(default_factory=list)
def update_from_message(self, user_message):
"""从用户消息中提取并更新状态"""
# 这里可以结合大模型的意图识别来更新字段
# 简化示例:基于关键词匹配
if "三亚" in user_message:
self.destination = "三亚"
if "北京出发" in user_message:
self.origin = "北京"
if "海景房" in user_message:
if "海景房" not in self.preferences:
self.preferences.append("海景房")
def generate_context_prompt(self):
"""生成当前状态的摘要提示词"""
prompt = "当前已知的用户需求信息如下:\n"
if self.destination:
prompt += f"目的地:{self.destination}\n"
if self.origin:
prompt += f"出发地:{self.origin}\n"
if self.budget:
prompt += f"预算:{self.budget}元\n"
if self.preferences:
prompt += f"偏好:{', '.join(self.preferences)}\n"
return prompt
通过TravelState类,Agent可以在每轮对话中维护一个结构化的状态对象。当用户修改需求时,直接更新对应字段即可。在调用大模型之前,通过generate_context_prompt方法将当前状态转化为自然语言提示词,拼接到对话历史中,确保大模型始终掌握最新的用户需求。这种方式比单纯依赖对话历史更加可靠,也更容易控制。
除了状态管理,多轮对话中的意图切换也是一个难点。用户可能在规划行程的过程中突然询问签证办理流程,或者要求取消之前的预订。Agent需要具备意图识别能力,判断当前消息属于行程规划的延续还是全新的任务。对于复杂的多意图场景,可以考虑引入子Agent机制,将不同类型的任务分发给专门的子Agent处理,主Agent负责协调和汇总结果。
构建一个旅游行程规划与预订Agent是一项涉及自然语言理解、工具调用编排和状态管理的系统工程。从架构设计到Function Calling实现,再到对话状态管理,每个环节都需要精心打磨。随着大模型推理能力的不断提升和工具生态的日益丰富,这类垂直领域的Agent将在更多实际场景中落地,为用户提供真正智能化的端到端服务体验。
旅游Agent行程规划Function Calling修改时间:2026-08-21 00:15:02