打造AI智能旅行规划器:基于LLM和Crew AI的Agent实践

引言

今天来学习大佬开发的一个AI驱动的旅行规划应用程序,它能够自动处理旅行规划的复杂性——寻jni找航班、预订酒店以及优化行程。传统上,这个过程需要手动搜索多个平台,常常导致决策效率低下。

通过利用**代理型人工智能(Agentic AI)**的力量,这个应用程序展示了AI代理是如何协作以简化规划过程的——检索实时旅行数据、分析选项,并使用大型语言模型(LLM)生成AI驱动的建议。

什么是代理型人工智能(Agentic AI)?

代理型人工智能(Agentic AI)指的是能够主动运行、独立做决策,并且无需持续人工干预即可执行复杂任务的自主人工智能系统。

关键特性:

  1. 自主决策 — 通过允许AI自主思考、推理并采取行动,减少人工劳动。
  2. 多代理协作 — 让不同的AI代理专注于特定任务,提高准确性和效率。
  3. 可扩展性与效率 — AI代理并行执行任务,与传统工作流程相比减少了处理时间。
  4. 增强用户体验 — 为复杂任务提供更快、更智能、更个性化的解决方案。

与需要逐步指令的传统AI模型不同,代理型人工智能(Agentic AI)能够动态工作,实时做决策,与其他代理协作,并根据上下文数据优化工作流程。

这个代理型人工智能(Agentic AI)系统的关键特性

以下是使这个AI旅行规划器强大的最重要的特性的分解:
在这里插入图片描述

1. 航班搜索自动化
  • 通过SerpAPI从Google Flights检索实时航班数据
  • 根据价格、转机次数和旅行时间筛选航班。
  • AI根据性价比和便利性推荐最佳航班。
2. 酒店推荐
  • 从Google Hotels搜索实时酒店可用性
  • 根据位置、预算、设施和用户评分进行筛选。
  • AI通过分析与关键地点的接近程度等因素,建议最佳酒店。
3. AI驱动的分析与建议
  • 使用Gemini LLM的AI代理评估旅行选项。
  • 使用Crew AI协调多个AI代理以做出更好的决策。
  • AI解释其对航班和酒店的推荐,提供见解。
4. 动态行程生成
  • AI根据航班和酒店预订构建结构化的旅行计划。
  • 生成按天划分的行程,包含必游景点、餐厅推荐以及当地交通选项。
5. 易于使用的API集成
  • API端点允许用户搜索航班、酒店并请求AI驱动的建议。
  • 启用与前端UI(Streamlit)的无缝集成。

实现指南

让我们一步步了解构建这个AI驱动的旅行规划系统的步骤:

先决条件

在开始编码之前,请确保在本地计算机上满足以下先决条件:

  1. 安装Python 3.8+
  2. 拥有用于获取实时航班和酒店数据的 SerpAPI 密钥
  3. 拥有用于AI建议的 Google Gemini API 密钥
  4. 使用 CrewAI 来协调AI驱动的代理

安装所需的库:

pip install fastapi uvicorn pydantic serpapi crewai streamlit

步骤1:设置环境并加载API密钥

首先,让我们设置环境并配置必要的API密钥:

import os
import uvicorn
import asyncio
import logging
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import List, Optional
from serpapi import GoogleSearch
from crewai import Agent, Task, Crew, Process, LLM
from datetime import datetime
from functools import lru_cache# 加载API密钥
GEMINI_API_KEY = os.getenv("GOOGLE_API_KEY", "gemini_api_key_here")
SERP_API_KEY = os.getenv("SERPER_API_KEY", "serpapi_key_here")# 初始化日志记录器
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
logger = logging.getLogger(__name__)

步骤2:初始化Google Gemini AI(LLM)

我们将使用CrewAI的LLM,为简单起见,实现LRU缓存以仅初始化一次:

@lru_cache(maxsize=1)
def initialize_llm():"""初始化并缓存LLM实例,避免重复初始化。"""return LLM(model="gemini/gemini-2.0-flash",provider="google",api_key=GEMINI_API_KEY)

步骤3:定义Pydantic模型

我们将使用Pydantic模型来强制执行请求和响应的严格数据验证:

class FlightRequest(BaseModel):origin: strdestination: stroutbound_date: strreturn_date: strclass HotelRequest(BaseModel):location: strcheck_in_date: strcheck_out_date: strclass ItineraryRequest(BaseModel):destination: strcheck_in_date: strcheck_out_date: strflights: strhotels: strclass FlightInfo(BaseModel):airline: strprice: strduration: strstops: strdeparture: strarrival: strtravel_class: strreturn_date: strairline_logo: strclass HotelInfo(BaseModel):name: strprice: strrating: floatlocation: strlink: strclass AIResponse(BaseModel):flights: List[FlightInfo] = []hotels: List[HotelInfo] = []ai_flight_recommendation: str = ""ai_hotel_recommendation: str = ""itinerary: str = ""

步骤4:Fast API初始化用于后端处理

现在,我们将创建一个REST API来处理旅行规划请求:

from fastapi import FastAPI, HTTPExceptionapp = FastAPI(title="Travel Planning API", version="1.0.1")

步骤5:使用SerpAPI实时检索航班和酒店数据

让我们实现辅助函数,使用SerpAPI检索航班和酒店数据:

None

async def run_search(params):"""通用函数,异步运行SerpAPI搜索。"""try:return await asyncio.to_thread(lambda: GoogleSearch(params).get_dict())except Exception as e:logger.exception(f"SerpAPI搜索错误:{str(e)}")raise HTTPException(status_code=500, detail=f"搜索API错误:{str(e)}")async def search_flights(flight_request: FlightRequest):"""使用SerpAPI从Google Flights获取实时航班详情。"""logger.info(f"搜索航班:从{flight_request.origin}{flight_request.destination}")params = {"api_key": SERP_API_KEY,"engine": "google_flights","hl": "en","gl": "us","departure_id": flight_request.origin.strip().upper(),"arrival_id": flight_request.destination.strip().upper(),"outbound_date": flight_request.outbound_date,"return_date": flight_request.return_date,"currency": "USD"}search_results = await run_search(params)flights = search_results.get("flights")return flights
async def search_hotels(hotel_request: HotelRequest):"""从SerpAPI获取酒店信息。"""logger.info(f"搜索酒店:{hotel_request.location}")params = {"api_key": SERP_API_KEY,"engine": "google_hotels","q": hotel_request.location,"hl": "en","gl": "us","check_in_date": hotel_request.check_in_date,"check_out_date": hotel_request.check_out_date,"currency": "USD","sort_by": 3,"rating": 8}search_results = await run_search(params)hotels = search_results.get("properties")return hotels

步骤6:定义多代理任务、团队和流程

现在让我们使用CrewAI设置我们的多代理系统:

代理1:航班分析

  • 航班分析师代理接收航班选项
  • Gemini LLM分析价格、时长、转机次数和便利性
  • AI推荐最佳航班并提供详细理由

代理2:酒店分析

  • 酒店分析师代理接收住宿选项
  • Gemini LLM比较价格、评分、位置和设施
  • AI推荐最佳酒店并提供详细理由

代理3:行程生成

  • 行程代理使用航班和酒店推荐
  • 创建按天划分的计划,包含景点、餐厅和交通安排
  • 根据地理位置优化日程安排
  • 包含时间估算和实用旅行提示

None

async def get_ai_recommendation(data_type, formatted_data):logger.info(f"从AI获取{data_type}分析")llm_model = initialize_llm()# 根据数据类型配置代理if data_type == "flights":role = "AI航班分析师"goal = "分析航班选项并推荐最佳选择,考虑价格、时长、转机次数和整体便利性。"backstory = f"AI专家,提供基于多个因素的航班选项深入分析。"description = """根据以下详细信息,推荐最佳航班:**推荐理由**:- **价格**:详细说明为什么此航班与其他航班相比最具性价比。- **时长**:解释为什么此航班与其他航班相比具有最佳时长。- **转机次数**:讨论为什么此航班的转机次数最少或最合理。- **旅行舱位**:描述为什么此航班提供最佳舒适度和设施。使用提供的航班数据作为推荐依据。确保在回答中明确说明每个属性的选择理由,不要重复航班详细信息。"""elif data_type == "hotels":role = "AI酒店分析师"goal = "分析酒店选项并推荐最佳选择,考虑价格、评分、位置和设施。"backstory = f"AI专家,提供基于多个因素的酒店选项深入分析。"description = """根据以下分析,生成最佳酒店的详细推荐。回答应基于价格、评分、位置和设施等因素提供清晰的理由。**AI酒店推荐**推荐最佳酒店,基于以下分析:**推荐理由**:- **价格**:与其他选项相比,推荐的酒店在价格上最具性价比,提供的设施和服务物有所值。解释为什么这是最佳选择。- **评分**:与替代选项相比,评分更高,确保更好的整体客户体验。解释为什么这使其成为最佳选择。- **位置**:酒店位于优越位置,靠近重要景点,方便旅行者出行。- **设施**:酒店提供如Wi-Fi、游泳池、健身中心、免费早餐等设施。讨论这些设施如何提升体验,使其适合不同类型的旅行者。**理由要求**:- 确保每个部分清晰解释为什么此酒店是基于价格、评分、位置和设施等因素的最佳选择。- 与其他选项进行比较,解释为什么此选项脱颖而出。- 提供简洁、结构良好的理由,使推荐对旅行者清晰明了。- 推荐应帮助旅行者基于多个因素做出明智的决策,而不仅仅是单一因素。"""else:raise ValueError("无效的AI推荐数据类型")# 创建代理和任务analyze_agent = Agent(role=role,goal=goal,backstory=backstory,llm=llm_model,verbose=False)analyze_task = Task(description=f"{description}\n\n要分析的数据:\n{formatted_data}",agent=analyze_agent,expected_output=f"基于对所提供详细信息的分析,解释最佳{data_type}选择的结构化推荐。")# 定义CrewAI工作流程analyst_crew = Crew(agents=[analyze_agent],tasks=[analyze_task],process=Process.sequential,verbose=False)# 执行CrewAI流程crew_results = await asyncio.to_thread(analyst_crew.kickoff)return str(crew_results)
  • 现在,让我们实现行程规划代理:
async def generate_itinerary(destination, flights_text, hotels_text, check_in_date, check_out_date):"""根据航班和酒店信息生成详细的旅行行程。"""try:# 将字符串日期转换为datetime对象check_in = datetime.strptime(check_in_date, "%Y-%m-%d")check_out = datetime.strptime(check_out_date, "%Y-%m-%d")# 计算天数days = (check_out - check_in).daysllm_model = initialize_llm()analyze_agent = Agent(role="AI旅行规划师",goal="根据航班和酒店信息为用户创建详细的行程",backstory="AI旅行专家,生成包含航班详情、酒店住宿和目的地必游景点的按天划分的行程。",llm=llm_model,verbose=False)analyze_task = Task(description=f"""根据以下详细信息,为用户创建一个{days}天的行程:**航班详情**:{flights_text}**酒店详情**:{hotels_text}**目的地**:{destination}**旅行日期**:{check_in_date}{check_out_date}{days}天)行程应包括:- 航班到达和出发信息- 酒店入住和退房详情- 按天划分的活动- 必游景点及预计参观时间- 餐厅推荐,用于用餐- 当地交通提示**格式要求**:- 使用markdown格式,使用清晰的标题(#用于主标题,##用于天数,###用于部分)- 使用emoji表示不同类型的活动(地标用,餐厅用🍽️等)- 使用项目符号列出活动- 包括每个活动的预计时间- 格式化行程,使其视觉上美观且易于阅读""",agent=analyze_agent,expected_output="一个结构良好、视觉上美观的markdown格式行程,包括航班、酒店和按天划分的活动,带有emoji、标题和项目符号。")
itinerary_planner_crew = Crew(agents=[analyze_agent],tasks=[analyze_task],process=Process.sequential,verbose=False)crew_results = await asyncio.to_thread(itinerary_planner_crew.kickoff)
return str(crew_results)

步骤7:航班和酒店搜索的API端点

现在让我们实现我们的API端点:

  1. 获取航班推荐
@app.post ("/search_flights/", response_model=AIResponse)
async def get_flight_recommendations(flight_request: FlightRequest):flights = await search_flights(flight_request)flights_text = format_travel_data("flights", flights)ai_recommendation = await get_ai_recommendation("flights", flights_text)return AIResponse(flights=flights, ai_flight_recommendation=ai_recommendation);

2. 获取酒店推荐

@app.post ("/search_hotels/", response_model=AIResponse)
async def get_hotel_recommendations(hotel_request: HotelRequest):hotels = await search_hotels(hotel_request)hotels_text = format_travel_data("hotels", hotels)ai_recommendation = await get_ai_recommendation("hotels", hotels_text)return AIResponse(hotels=hotels, ai_hotel_recommendation=ai_recommendation);

步骤8:生成AI处理的行程

让我们实现我们的行程生成端点:

@app.post("/generate_itinerary/", response_model=AIResponse)
async def get_itinerary(itinerary_request: ItineraryRequest):itinerary = await generate_itinerary(itinerary_request.destination,itinerary_request.flights,itinerary_request.hotels,itinerary_request.check_in_date,itinerary_request.check_out_date)return AIResponse(itinerary=itinerary)

最后,让我们添加服务器启动代码:


# 运行FastAPI服务器
if __name__ == "__main__":logger.info("启动旅行规划API服务器")uvicorn.run(app, host="0.0.0.0", port=8000)

步骤9:构建Streamlit前端界面

现在让我们使用Streamlit创建一个用户友好的界面:

import streamlit as st
import requests
from datetime import datetime, timedelta# API URL
API_BASE_URL = "http://localhost:8000"
API_URL_FLIGHTS = f"{API_BASE_URL}/search_flights/"
API_URL_HOTELS = f"{API_BASE_URL}/search_hotels/"
API_URL_COMPLETE = f"{API_BASE_URL}/complete_search/"
API_URL_ITINERARY = f"{API_BASE_URL}/generate_itinerary/"
...

步骤10:运行应用程序

启动FastAPI后端服务器:

 python gemini2_travel_backend.py

这将启动运行在http://localhost:8000的后端服务器。

None

在新的终端窗口中,启动Streamlit前端:

Streamlit UI将自动在默认的网络浏览器中打开,地址为http://localhost:8501

None

步骤11:最终演示(多代理AI + Gemini LLM)

让我们通过一个完整的用户旅程来看看多代理系统在实践中是如何工作的:

None

None

AI生成的旅行行程

这个示例展示了多代理系统如何通过协同工作的专门AI代理创建连贯的个性化旅行计划,每个代理都由Google的Gemini 2.0 LLM的智能驱动。

总结

上述文章展示了多代理AI、Google Gemini LLM以及结构化的AI任务提示工程如何帮助实现智能自动化。通过利用实时数据、并行AI执行和LLM驱动的建议,我们可以在金融、医疗保健、物流和客户支持等各个领域高效地自动化复杂的决策任务。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/diannao/84703.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

21. 自动化测试框架开发之Excel配置文件的测试用例改造

21. 自动化测试框架开发之Excel配置文件的测试用例改造 一、测试框架核心架构 1.1 组件依赖关系 # 核心库依赖 import unittest # 单元测试框架 import paramunittest # 参数化测试扩展 from chap3.po import * # 页面对象模型 from file_reader import E…

如何在电力系统中配置和管理SNTP时间同步?

在电力系统中配置和管理 SNTP 时间同步需结合行业标准(如《DL/T 1100.1-2019》)和分层架构特点,确保安全性、可靠性和精度适配。以下是具体操作指南,涵盖架构设计、设备配置、安全管理、运维监控四大核心环节,并附典型…

MTK-关于HW WCN的知识讲解

前言: 最近做项目过程中和硬件打交道比较多,现在关于整理下硬件的HW wcn的知识点 一 MTK常见的MT6631 Wi-Fi 2.4GHz 匹配调谐指南 ‌拓扑结构选择‌ 推荐采用并联电容拓扑(‌shunt cap topology‌)代替并联电感拓扑(‌shunt inductor topology‌),以减少潜在电路设计…

(1)课堂 1--5,这五节主要讲解 mysql 的概念,定义,下载安装与卸载

(1)谢谢老师: (2)安装 mysql : (3)镜像下载 ,这个网址很好 : (4) 另一个虚拟机的是 zhang 123456 : 接着配置…

U-Boot ARMv8 平台异常处理机制解析

入口点:arch/arm/cpu/armv8/start.S 1. 判断是否定义了钩子,如有则执行,否则往下走。执行save_boot_params,本质就是保存一些寄存器的值。 2. 对齐修复位置无关码的偏移 假设U-Boot链接时基址为0x10000,但实际加载到0…

mysql安装教程--笔记

一、Windows 系统安装 方法1:使用 MySQL Installer(推荐) 1. 下载安装包 访问 MySQL 官网下载页面,选择 MySQL Installer for Windows。 2. 运行安装程序 双击下载的 .msi 文件,选择安装类型: ◦ Developer…

投资策略规划最优决策分析

目录 一、投资策略规划问题详细 二、存在最优投资策略:每年都将所有钱投入到单一投资产品中 (一)状态转移方程 (二)初始条件与最优策略 (三)证明最优策略总是将所有钱投入到单一投资产品中…

NGINX HTTP/3 实验指南安装、配置与调优

一、HTTP/3 简介 基于 QUIC:在 UDP 之上实现的多路复用传输,内置拥塞控制与前向纠错,无需三次握手即可恢复连接。零 RTT 重连:借助 TLS 1.3,实现连接恢复时的 0-RTT 数据发送(视底层库支持)。多…

编程日志5.28

string赋值操作 算法: #include<iostream> using namespace std; int main() { //1.字符串常量的赋值 string s1; s1 = "英雄哪里出来"; cout << s1 << endl; //2.字符串变量的赋值 string s2; s2 = s1; cout <…

AE的ai图层导到Ai

AE的ai图层导到ai 解决方法: 1、打开ai软件&#xff0c;不用新建&#xff0c;留在那就行。 2、在AE里选中任意一个ai文件图层&#xff0c;只需同时按住ctrl和英文字母键&#xff0c;图层就会自动全部导入到ai中 英文字母键的详情可以参考&#xff1a;http://www.yayihouse.co…

【Springboot+LangChain4j】Springboot项目集成LangChain4j(下)

前置条件&#xff1a;根据上篇文章完成springboot初步集成LangChain4j 【SpringbootLangChain4j】根据LangChain4j官方文档&#xff0c;三分钟完成Springboot项目集成LangChain4j&#xff08;上&#xff09;-CSDN博客 但是接口方法中&#xff0c;关于大模型的配置都是写死的&a…

好坏质检分类实战(异常数据检测、降维、KNN模型分类、混淆矩阵进行模型评估)

任务 好坏质检分类实战 task: 1、基于 data_class_raw.csv 数据&#xff0c;根据高斯分布概率密度函数&#xff0c;寻找异常点并剔除 2、基于 data_class_processed.csv 数据&#xff0c;进行 PCA 处理&#xff0c;确定重要数据维度及成分 3、完成数据分离&#xff0c;数据分离…

以少学习:通过无标签数据从大型语言模型进行知识蒸馏

Learning with Less: Knowledge Distillation from Large Language Models via Unlabeled Data 发表&#xff1a;NNACL-Findings 2025 机构&#xff1a;密歇根州立大学 Abstract 在实际的自然语言处理&#xff08;NLP&#xff09;应用中&#xff0c;大型语言模型&#xff08…

EasyExcel使用

EasyExcel 简介 EasyExcel 是阿里巴巴开源的一个基于 Java 的简单、省内存的读写 Excel 工具。在处理大量数据时&#xff0c;它能极大地减少内存占用&#xff0c;提高性能。下面从依赖配置、模板使用到代码调用&#xff0c;进行详细介绍。 添加依赖 若要在项目里使用 EasyEx…

文件类型汇总

一、文档类文件 Microsoft Office 文档&#xff1a;.doc、.docx&#xff08;Word 文档&#xff09;、.xls、.xlsx&#xff08;Excel 表格&#xff09;、.ppt、.pptx&#xff08;PowerPoint 演示文稿&#xff09; OpenOffice/LibreOffice 文档&#xff1a;.odt&#xff08;文字…

OpenCV CUDA模块图像处理------颜色空间处理之拜耳模式去马赛克函数demosaicing()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 该函数用于在 GPU 上执行拜耳图像&#xff08;Bayer Pattern&#xff09;的去马赛克操作&#xff08;Demosaicing&#xff09;&#xff0c;将单通…

Linux: 守护进程

Linux&#xff1a; 守护进程 &#xff08;一&#xff09;前台进程和后台进程前台进程后台进程 &#xff08;二&#xff09;会话、进程组、进程的关系&#xff08;三&#xff09;守护进程创建守护进程 &#xff08;一&#xff09;前台进程和后台进程 前台进程 前台进程是指当前…

6.4.5_关键路径

AOE网&#xff1a; 用EEdge表示活动&#xff0c;AOV网是用Vertex顶点表示活动 仅有一个入度0的顶点叫开始顶点(源点)&#xff0c;出度0的顶点叫结束顶点(汇点) 各条边表示活动&#xff0c;边上的权值表示完成该活动的开销&#xff0c;各顶点表示事件&#xff0c;事件是就发生…

Oracle 的 TX、TM、UL 锁对比

Oracle 的 TX、TM、UL 锁对比 Oracle 数据库中的这三种锁机制在并发控制中扮演着不同角色&#xff0c;以下是它们的对比分析&#xff1a; 一、基本特性对比 特性TX (事务锁)TM (DML锁)UL (用户锁)锁类型行级锁表级锁应用级自定义锁作用范围保护数据行变更保护表结构不被修改…

Kruskal-Wallis检验 vs. 多次Wilcoxon检验:多重比较-spss

在补充图6中&#xff0c;对喉镜形态分类、病理类型和病程使用 Wilcoxon秩和检验&#xff08;Mann-Whitney U检验&#xff09; 结合 Bonferroni校正&#xff0c;而非 Kruskal-Wallis检验加Dunn’s检验&#xff0c;原因如下&#xff1a; 1. 方法选择的依据 (1) 变量类型与比较组…