上周我帮朋友规划泰国游,光是对比曼谷酒店价格、查实时天气、换算美元到泰铢就开了6个网页,最后预算还算错了——相信不少人都有过这种“旅行计划比上班还累”的经历。但现在不一样了:用Streamlit+LangChain搭一个AI旅行代理,输入“5天泰国游,预算800美元”,3秒就能拿到带天气、酒店、行程和视频的完整方案,甚至连每天的饭钱都给你算明白。

这篇文章不是干巴巴的API文档,而是一份“从0到部署”的实战指南——不管你是想解决自己的旅行规划难题,还是想练手AI应用开发,跟着做就能出成果。

序章:旅行计划的“旧痛”与AI的“新解”

做旅行计划时,我们总在重复三件麻烦事:打开天气APP查目的地温度,切换到酒店平台比价,再用计算器手动算总花费,最后还得去B站找旅行视频——信息散在各处,预算经常超支,花两小时做的计划可能还漏了关键景点。

而这个AI旅行代理恰好把这些事打包解决了:它用OpenWeatherMap查天气,靠Google Serper搜实时酒店价格,借LangChain的工具链自动算预算,最后用Streamlit把结果做成清爽的网页。核心技术栈其实很亲民:LangChain负责“让AI知道该调用什么工具”,Streamlit负责“把AI的结果变成人能看懂的界面”,OpenAI GPT-4则负责理解你的需求(比如“预算800美元转成印度卢比”)。

对普通人来说,这是个能直接用的旅行工具;对开发者来说,这是个绝佳的“AI+垂直场景”练手项目——毕竟不是所有AI项目都需要复杂的模型训练,把现成工具组合好,就能解决实际问题。

直觉:这个AI代理到底能帮你做什么?

先别着急写代码,我们先看看它的“硬实力”。假设你输入:“3天曼谷游,预算500美元,转成印度卢比,要查天气、找 budget 酒店、看旅行视频”,它会返回这些内容:

  1. 实时天气:曼谷当前气温、湿度,甚至会提醒你“今日有雷阵雨,建议带伞”(数据来自OpenWeatherMap,和手机天气APP一样准);
  2. 酒店推荐:3家每晚30-40美元的酒店,附地址和评分,还会算好3天总费用(比如35美元/晚×3天=105美元,折合成印度卢比约8750);
  3. 行程表:每天的安排都带价格——第一天大皇宫(门票10美元)+ 湄南河游船(15美元),第二天暹罗广场购物(无门票)+ 街头小吃(5美元/餐);
  4. 旅行视频:3个YouTube链接,标题都是“2025曼谷旅行攻略”“曼谷街头美食指南”这类精准内容;
  5. 预算 breakdown:总花费380美元(含酒店、餐饮、景点),还剩120美元可灵活支配。

和某猪、某程这类传统旅行APP比,它的核心优势是“动态计算”——不是给你一堆酒店列表让你自己挑,而是根据你的预算主动筛选,甚至会帮你避开“价格看起来低但位置偏远”的坑(靠搜索工具爬取用户评分)。

实战:从0搭建开发环境(3步搞定)

接下来进入实操环节,不管你用Windows还是Mac,跟着做就能跑通。首先要准备三个东西:GitHub账号(用来存代码)、三个API密钥(OpenAI、Google Serper、OpenWeatherMap),以及电脑上的Python环境(3.8+就行)。

第一步:克隆代码仓库并进入目录

先打开终端(Windows用PowerShell,Mac用终端),执行这行命令克隆项目:

git clone https://github.com/yourusername/ai-travel-agent.git
cd ai-travel-agent

这里把“yourusername”换成你的GitHub用户名——如果还没建仓库,先在GitHub上新建一个空仓库,再把本地代码推上去(后面部署会用到)。

第二步:创建虚拟环境并安装依赖

为了避免依赖冲突,我们先建一个虚拟环境。执行以下命令:

# 创建虚拟环境
python -m venv venv

# 激活环境(Mac/Linux)
source venv/bin/activate

# 激活环境(Windows)
venv\Scripts\activate

激活后,终端前面会出现“(venv)”,说明环境没问题。接下来安装依赖:

pip install -r requirements.txt

requirements.txt里已经包含了Streamlit、LangChain、OpenAI等所有需要的库——这里要注意,如果你用的是Python 3.12+,可能会遇到“python-dotenv”安装警告,忽略就行,不影响使用。

第三步:配置API密钥(关键步骤,别踩坑)

项目需要三个API密钥才能工作,分别是:

  • OpenAI API:用来让AI理解你的需求(获取链接);
  • Google Serper API:用来搜酒店、汇率、景点价格(获取链接);
  • OpenWeatherMap API:用来查天气(获取链接)。

拿到密钥后,在项目根目录新建一个.env文件(注意文件名前面有个点),里面写:

OPENAI_API_KEY=你的OpenAI密钥
SERPER_API_KEY=你的Google Serper密钥
OPENWEATHERMAP_API_KEY=你的OpenWeatherMap密钥

这里有个坑要提醒:密钥后面别加空格!我之前多打了个空格,结果启动时一直报“API密钥无效”,查了半小时才发现问题。另外,千万别把.env文件提交到GitHub——项目里的.gitignore已经帮你排除了这个文件,放心用。

项目结构快速解读

此时你的项目文件夹里应该有这些文件:

ai-travel-agent/
├── app.py          # 核心:Streamlit界面和逻辑
├── Assignment.ipynb # 原始Jupyter笔记本(可备用)
├── requirements.txt # 依赖列表
├── .env            # 你的API密钥(本地用)
└── .streamlit/     # Streamlit配置(后面自定义主题用)
    └── config.toml

重点关注app.py——所有的界面显示、AI调用逻辑都在这里;.streamlit/config.toml则是用来改界面主题的,比如把背景色改成浅蓝色,后面会讲。

实战:跑起第一个AI旅行代理(5分钟看到效果)

环境搭好后,我们马上启动应用,看看它到底能不能用。

启动命令的三种玩法

在终端执行最基础的启动命令:

streamlit run app.py

执行后,终端会显示“您的应用正在运行”,并自动打开浏览器,地址是http://localhost:8501——这是Streamlit的默认端口。

如果遇到“端口8501已被占用”的错误(比如你之前开了其他Streamlit应用),可以换个端口:

# 用8502端口启动
streamlit run app.py --server.port 8502

如果想边改代码边看效果(开发模式),可以加--server.runOnSave true,这样改完app.py保存后,应用会自动刷新:

streamlit run app.py --server.runOnSave true

首次运行的常见问题排查

如果启动后浏览器显示“API密钥错误”,先检查这两点:

  1. .env文件里的密钥是否正确(复制粘贴时别漏字符);
  2. 终端是否激活了虚拟环境(有没有“(venv)”标识)——如果没激活,Python找不到python-dotenv库,就无法读取.env文件。

如果显示“无法连接到OpenAI”,可能是网络问题——可以试试切换网络,或者检查OpenAI API的配额(免费用户有5美元额度,足够测试)。

最小可运行示例:查一次曼谷行程

在浏览器的输入框里,粘贴这段查询(和之前的例子一样):

3天曼谷游,预算500美元,转成印度卢比。查当前天气,找每晚低于40美元的酒店,算总花费,给旅行视频链接。

点击“提交”后,界面会显示“AI正在处理”的加载动画——这个过程大概3-5秒(取决于网络速度和API响应时间)。

预期结果应该是这样的

  • 顶部显示曼谷当前天气:比如“28℃,多云,湿度65%”;
  • 酒店部分:3家酒店,每家电价35-40美元,总费用105-120美元,折合成印度卢比约8750-10000;
  • 行程表:每天的景点、餐饮、费用,比如“第一天:大皇宫(10美元)+ 泰式午餐(5美元)”;
  • 视频部分:3个YouTube链接,标题包含“曼谷旅行攻略2025”;
  • 预算总结:总花费约320美元,剩余180美元。

如果能看到这些内容,说明你的AI旅行代理已经跑通了——接下来就可以玩更多功能,比如查东京、巴黎的行程,或者调整预算。

实战:核心功能拆解(知道它为什么能工作)

光会用还不够,我们简单拆解一下核心功能,让你知道背后的逻辑——以后想加新功能(比如机票查询),也知道从哪下手。

1. 天气查询:怎么做到实时准确?

当你输入“查曼谷天气”时,app.py里的get_weather(city)函数会被调用——它会把“曼谷”作为参数,传给OpenWeatherMap API,拿到返回的JSON数据后,提取出气温、湿度、天气状况,再用Streamlit显示出来。

你可以在app.py里找到这段逻辑(简化版):

def get_weather(city):
    api_key = os.getenv("OPENWEATHERMAP_API_KEY")
    url = f"https://api.openweathermap.org/data/2.5/weather?q={city}&appid={api_key}&units=metric"
    response = requests.get(url)
    data = response.json()
    return f"{city}当前气温:{data['main']['temp']}℃,天气:{data['weather'][0]['description']}"

这里的units=metric表示用摄氏度(默认是华氏度),如果想改回华氏度,把metric换成imperial就行。

2. 预算计算:实时汇率从哪来?

当你需要“把美元转成印度卢比”时,AI会调用search_google工具,搜索“2025年X月X日美元兑印度卢比汇率”——数据来自Google搜索结果,和你在Google上查的汇率一致。

比如当前汇率是1美元=83印度卢比,AI会自动计算:35美元/晚×3天=105美元×83=8715印度卢比——这个计算过程用的是LangChain里的addition/multiply工具,不用你写复杂的数学逻辑。

3. 视频推荐:怎么找到精准的YouTube视频?

视频推荐靠的是youtube_search函数,它会把你的查询(比如“曼谷旅行攻略”)作为关键词,调用YouTube的搜索API,返回最新的3-5个视频链接。

你可以在app.py里调整视频数量——找到youtube_search函数,把max_results=3改成max_results=5,就能多要两个视频链接。

进阶:把代理部署到云端(让朋友也能用上)

本地跑通后,我们把它部署到云端,这样不管在哪,打开链接就能用——推荐用Streamlit Cloud,免费、简单,不用懂服务器。

Streamlit Cloud部署(推荐,10分钟搞定)

  1. 把代码推到GitHub:先在GitHub上新建一个仓库(比如叫ai-travel-agent),然后在本地终端执行:

    # 初始化Git(如果没初始化过)
    git init
    # 添加文件
    git add .
    # 提交
    git commit -m "初始提交:AI旅行代理"
    # 关联远程仓库(换成你的仓库地址)
    git remote add origin https://github.com/yourusername/ai-travel-agent.git
    # 推到GitHub
    git push -u origin main
    

    这里要注意:.env文件不会被推上去(因为.gitignore里排除了),所以云端需要重新配置密钥。

  2. 连接Streamlit Cloud:打开Streamlit Cloud官网,用GitHub账号登录,点击“New app”,然后:

    • Repository:选择你刚推的yourusername/ai-travel-agent
    • Branch:选main
    • Main file path:填app.py(核心文件);
      点击“Deploy”,等待1-2分钟。
  3. 配置云端密钥:部署后,点击“Manage app”→“Secrets”,在文本框里输入:

    OPENAI_API_KEY = "你的OpenAI密钥"
    SERPER_API_KEY = "你的Google Serper密钥"
    OPENWEATHERMAP_API_KEY = "你的OpenWeatherMap密钥"
    

    点击“Save”,应用会自动重启——此时你的AI旅行代理已经在线了,链接是https://your-app-name.streamlit.app(可以分享给朋友)。

其他部署方案对比

如果Streamlit Cloud满足不了你(比如需要更高的访问量),可以试试这两个方案:

  • Heroku:需要创建Procfilesetup.sh文件(用来配置端口),免费额度有限(550小时/月);
  • Railway:不用写配置文件,连接GitHub后自动部署,但免费额度用完后会收费。

具体的部署步骤可以参考项目文档,这里就不展开了——对大多数人来说,Streamlit Cloud足够用。

进阶:3个技巧让你的代理更好用

跑通和部署只是开始,我们可以做一些优化,让体验更好。

1. 用缓存减少API调用(省 money + 提速)

每次查询都调用API,不仅慢,还会消耗配额(比如OpenAI API是按调用次数收费的)。用Streamlit的@st.cache_data装饰器,可以缓存相同查询的结果——比如你查了“曼谷天气”,10分钟内再查,会直接返回缓存结果,不重复调用API。

app.pyget_weather函数上面加一行代码:

@st.cache_data(ttl=600)  # ttl=600表示缓存10分钟(600秒)
def get_weather(city):
    # 原函数逻辑不变

同理,search_googleyoutube_search函数也可以加这个装饰器——注意,涉及实时数据的函数(比如汇率),ttl别设太长,建议1小时(3600秒)以内。

2. 自定义界面主题(换个“旅行风”皮肤)

默认的Streamlit界面是白色的,我们可以改成浅蓝色(像天空一样,符合旅行主题)。在.streamlit/config.toml里写:

[theme]
primaryColor = "#4A90E2"  # 主色调:浅蓝色
backgroundColor = "#F5F7FA"  # 背景色:浅灰色
secondaryBackgroundColor = "#E8F0FE"  # 次要背景色:更浅的蓝
textColor = "#333333"  # 文字色:深灰色
[server]
runOnSave = true  # 保存即刷新

保存后,重启应用,界面就会变成你设置的颜色——如果想换其他颜色,搜“Streamlit theme color codes”,有很多现成的配色方案。

3. 保存聊天历史(不用重复输入)

默认情况下,每次刷新页面,之前的查询记录会消失。用Streamlit的session_state可以保存聊天历史——在app.py里加一段代码:

# 初始化会话状态(如果没有)
if "messages" not in st.session_state:
    st.session_state.messages = []

# 显示历史消息
for msg in st.session_state.messages:
    st.chat_message(msg["role"]).write(msg["content"])

# 处理新输入
if prompt := st.chat_input("输入你的旅行需求..."):
    # 把新输入加入会话状态
    st.session_state.messages.append({"role": "user", "content": prompt})
    # 调用AI处理(原逻辑不变)
    response = react_graph.invoke(...)
    # 把AI的回复加入会话状态
    st.session_state.messages.append({"role": "assistant", "content": response})

这样不管怎么刷新页面,之前的查询和回复都不会丢——对需要多次调整行程的用户来说,体验提升很多。

结论:不止是旅行工具,更是AI落地的思路

到这里,你已经拥有了一个能查天气、算预算、生行程的AI旅行代理——但这个项目的价值不止于此。

对普通人来说,它解决了“旅行计划耗时”的实际问题;对开发者来说,它展示了“如何把AI工具组合起来解决垂直场景问题”:LangChain负责“工具调用逻辑”(什么时候用天气API,什么时候用搜索API),Streamlit负责“用户交互”(把复杂的AI输出变成简单的界面),两者结合,就能快速做出有用的AI应用。

接下来你可以尝试扩展功能:

  • 加“机票查询”:集成Skyscanner API,输入出发地和日期,就能查机票价格;
  • 加“签证提醒”:调用目的地国家的大使馆API,提醒签证办理时间;
  • 加“多人协作”:用Firebase存储行程,让多个人一起编辑。

AI应用开发不一定要从零开始——把现成的工具用好,解决一个小痛点,就是一个好项目。

常见问题解答(FAQ)

Q:API调用次数多了会花钱吗?
A:会,但新手足够用。OpenAI免费用户有5美元额度(调用GPT-4约0.03美元/次),Google Serper免费版每月100次搜索,OpenWeatherMap免费版每天可查60次天气——测试阶段完全够,后续不够可以升级付费版。

Q:部署后访问速度慢怎么办?
A:有两个优化方向:1. 用@st.cache_data缓存API结果,减少调用次数;2. 把应用部署到离你近的区域(Streamlit Cloud可以选区域,比如亚洲的新加坡节点)。

Q:能不能让AI推荐小众景点,而不是热门景点?
A:可以。在search_google函数的查询关键词里加“小众景点”,比如把“曼谷景点”改成“曼谷小众景点 2025”——AI会根据新的关键词搜索,返回更符合需求的结果。

Q:Windows系统激活虚拟环境时提示“权限不足”怎么办?
A:以管理员身份打开PowerShell,执行Set-ExecutionPolicy RemoteSigned,然后输入“Y”确认——这是Windows默认的执行策略限制,改完就能激活虚拟环境了。

工程化checklist(可复制到GitHub Issue)

  • [ ] 已克隆代码仓库并进入目录
  • [ ] 已创建并激活虚拟环境(venv\Scripts\activatesource venv/bin/activate
  • [ ] 已安装所有依赖(pip install -r requirements.txt
  • [ ] 已创建.env文件并填入3个API密钥(无多余空格)
  • [ ] 本地运行streamlit run app.py成功,能查询行程
  • [ ] 已将代码推到GitHub(.env未提交)
  • [ ] 已部署到Streamlit Cloud并配置Secrets
  • [ ] 已添加缓存装饰器(@st.cache_data)优化性能

思考题与答案

  1. 问题:如何给AI旅行代理增加“机票价格查询”功能?
    答案:
    步骤1:注册Skyscanner API(官网链接),获取API密钥;
    步骤2:在.env文件中添加SKYSCANNER_API_KEY=你的密钥
    步骤3:在app.py中新建get_flights(origin, destination, date)函数,调用Skyscanner API获取机票价格(示例代码):

    def get_flights(origin, destination, date):
        api_key = os.getenv("SKYSCANNER_API_KEY")
        url = f"https://partners.api.skyscanner.net/apiservices/browsequotes/v1.0/CN/CNY/zh-CN/{origin}/{destination}/{date}"
        params = {"apiKey": api_key}
        response = requests.get(url, params=params)
        data = response.json()
        # 提取最低价格
        min_price = data["Quotes"][0]["MinPrice"]
        return f"{origin}{destination}{date})的最低机票价格:{min_price}元"
    

    步骤4:在AI工具链中添加get_flights函数,让AI能识别“查机票”需求并调用该函数;
    步骤5:在Streamlit界面添加“出发地、目的地、日期”输入框,关联机票查询功能。

  2. 问题:为什么部署时必须用“环境变量”存储API密钥,而不是直接写在代码里?
    答案:
    有三个核心原因:
    安全风险:如果把密钥写在代码里,提交到GitHub后会被公开——任何人都能拿去调用API,产生高额费用(曾有人泄露OpenAI密钥,一天被刷走几百美元);
    环境适配:本地开发和云端部署可能用不同的密钥(比如本地用测试密钥,云端用生产密钥),用环境变量可以灵活切换,不用改代码;
    合规要求:大多数API服务商(如OpenAI、Google)都要求密钥不能公开存储,违反会被封禁账号——用环境变量是符合最佳实践的做法。