基于LangChain的简易智能旅游助手Agent

简介: 本文分享基于LangChain开发的智能旅游助手Agent,支持“查天气+荐景点”双功能,对比ReAct与FunctionCall两种实现模式,并详解工具封装、记忆管理、执行框架等LangChain核心优势。代码开源,含FastAPI后端与原生HTML/JS前端。

一、项目背景与功能实现

本文分享基于 LangChain 框架开发的智能旅游助手 Agent,核心功能是「查询城市天气 + 根据天气推荐景点」,并对比 ReAct 与 FunctionCall 两种 Agent 实现模式的差异,同时总结 LangChain 框架的使用优势。

核心功能拆解

  1. 天气查询工具:调用 wttr.in 开源天气接口,获取指定城市实时天气(天气描述+温度),仅支持实时查询,忽略日期参数;
  2. 景点推荐工具:基于 Tavily 搜索引擎,构造「城市+天气+适合景点」查询词,获取精准的景点推荐结果;
  3. Agent 逻辑控制:限制每个城市的工具调用次数(天气/景点各1次),获取有效景点结果后直接返回最终回答,避免重复调用;
  4. 前端交互:基于原生 HTML/JS 实现简洁的对话界面,支持消息发送、加载状态、对话重置。

核心文件技术细节

1. lc_react.py:ReAct 模式

ReAct 模式的核心是「思考-行动-观察」循环,通过提示词约束 LLM 输出固定格式的文本(Thought/Action/Action Input),再解析文本执行工具。

关键函数

_json_objects_in_text:从 LLM 输出的杂乱文本中提取 JSON 对象(解决 LLM 易拼接无关文本的问题);

_weather_params_from_input/_attraction_params_from_input:解析工具入参,分别适配天气/景点工具的参数结构;

工具装饰器 @tool:定义工具描述与入参格式,ReAct 模式下工具入参为 JSON 字符串,需手动解析;

Prompt 模板:严格定义 ReAct 格式(Thought/Action/Action Input/Final Answer),并加入「防重复调用」规则约束。

Agent 初始化

agent = create_react_agent(
    llm=llm,
    prompt=prompt_template,
    tools=[get_weather, get_attraction],
)

agent_executor = AgentExecutor(
    agent=agent,
    memory=memory,
    tools=[get_weather, get_attraction],
    verbose=True,
    handle_parsing_errors="返回到上一步并重新尝试,确保Action Input是有效的JSON格式",
    max_iterations=8,
    early_stopping_method="generate",
    stream_runnable=False,
)

2. lc_functioncall.py:FunctionCall 模式

FunctionCall 模式利用 LLM 的工具调用能力,让模型输出结构化的工具调用指令,无需手动解析文本。

  • 关键优化

    • 基于 Pydantic 定义工具入参 Schema(WeatherInput/AttractionInput),替代 ReAct 模式的 JSON 字符串解析;
    • 工具函数直接接收结构化参数(city: str, weather: str),无需手动提取;
    • Prompt 模板简化:使用 MessagesPlaceholder 管理对话历史与 Agent 思考过程,无需手动定义 ReAct 格式。
  • Agent 初始化

    agent = create_tool_calling_agent(
        llm=llm,
        prompt=prompt_template,
        tools=[get_weather, get_attraction],
    )
    

3. main.py:FastAPI 服务封装

  • 动态加载 Agent 模式:根据 .env 中的 AGENT_MODE 加载 ReAct 或 FunctionCall 版本的 Agent;

  • 接口设计:

    • /api/chat:接收用户消息,调用 Agent 并返回结果;
    • /api/chat/reset:清空对话记忆;
  • 静态资源挂载:将 index.html 作为静态页面挂载,实现前后端一体化部署。

4. index.html:前端交互

  • 原生 JS 实现核心逻辑:消息发送 / 接收、加载状态、自适应文本框、对话重置;
  • 样式设计:响应式布局(移动端隐藏侧边栏)、气泡式消息展示、加载动画;
  • 接口交互:通过 fetch 调用后端接口,处理网络错误与服务端异常。

二、开发过程中遇到的问题与解决办法

问题 1:ReAct 模式下 LLM 输出格式不规范

现象

LLM 输出的 Action Input 常拼接无关文本(如 Observation 内容),导致 JSON 解析失败,报错「无法解析 LLM 的输出」。

解决办法

  1. 编写解析函数:_json_objects_in_text 从杂乱文本中精准提取 JSON 对象,忽略无关拼接内容;
  2. 参数提取优化:_weather_params_from_input/_attraction_params_from_input 针对天气 / 景点工具的参数结构,分别处理 JSON 解析逻辑;
  3. 切换模式:改用 FunctionCall 模式,利用 LLM 原生的工具调用能力,输出结构化参数,从根源避免格式问题。

问题 2:重复调用工具

现象

LLM 可能因「确认天气」「翻译推荐结果」等原因重复调用同一城市的天气 / 景点工具。

解决办法

  • 在 Prompt 中加入严格规则:每个城市的 get_weather/get_attraction 最多调用 1 次;
  • 景点推荐结果有效时,强制返回 Final Answer,禁止后续工具调用。

三、ReAct 与 FunctionCall 模式对比

维度 ReAct 模式 FunctionCall 模式
核心原理 基于「思考 - 行动 - 观察」文本循环,手动定义格式并解析 利用 LLM 原生工具调用能力,输出结构化指令
参数处理 需手动解析 JSON 字符串,易受格式污染 基于 Pydantic 自动校验入参,结构化参数直接使用
提示词复杂度 高:需严格定义 ReAct 格式(Thought/Action 等) 低:仅需描述工具用途,格式由框架自动处理
灵活性 高:可自定义任意格式的思考过程 中:受 LLM 工具调用格式约束
稳定性 低:易因 LLM 输出格式偏差导致解析失败 高:结构化输出,解析成功率高
适用场景 复杂推理场景(需显式思考过程) 简单工具调用场景(参数明确、逻辑固定)

四、LangChain 对比原生手写 Agent 的优势

1. 工具封装与管理

  • LangChain 提供 @tool 装饰器,可快速定义工具描述、入参 Schema,原生手写需手动设计工具注册 / 调用逻辑;
  • 内置工具调用解析器,无需手动处理 LLM 输出的格式校验、参数提取。

2. 记忆能力

  • LangChain 提供 ConversationBufferMemory 等记忆组件,一键集成对话上下文管理,原生手写需手动维护会话状态;
  • 记忆组件与 Agent 解耦,可灵活切换记忆策略(如有限窗口记忆、摘要记忆)。

3. Agent 执行框架

  • AgentExecutor 封装了「思考 - 调用工具 - 处理结果」的循环逻辑,原生手写需手动实现循环控制、最大迭代次数、错误处理;
  • 内置错误处理机制(如 handle_parsing_errors),可快速适配 LLM 输出异常场景。

4. 多模式适配

  • 支持 ReAct、FunctionCall、OpenAI Functions 等多种 Agent 模式,切换成本低;
  • 原生手写需为每种模式重新设计解析逻辑与执行流程。

5. 生态集成

  • 无缝集成 OpenAI/Tavily 等第三方服务,无需手动封装 API 调用;
  • 提供 Prompt 模板、输出解析器等组件,降低提示词工程成本。

五、总结

本次项目通过 LangChain 实现了两种模式的旅游助手 Agent,实践发现:

  1. ReAct 模式适合需要显式推理过程的复杂场景,但需投入大量精力处理格式解析问题;
  2. FunctionCall 模式更适合简单工具调用场景,稳定性高,开发效率高;
  3. LangChain 框架大幅降低了 Agent 开发成本,尤其是工具管理、记忆、执行循环等核心模块,相比原生手写可节省 70% 以上的代码量;
  4. 实际开发中,建议优先使用 FunctionCall 模式(稳定性高),复杂推理场景结合 ReAct 模式的显式思考过程。

后续可优化方向:

  • 增加多轮对话的上下文理解能力(如识别「昨天问的上海天气」等指代);
  • 接入更多工具(如景点门票、交通信息);
  • 优化景点推荐结果,增加本地化 / 个性化策略。
  • 添加RAG?虽然暂时没想好怎么个做法,但为了学习是肯定会融入RAG的。

Github连接:https://github.com/KevinJosephDavis/TravelAgent.git

目录
相关文章
|
1天前
|
Web App开发 Rust 前端开发
基于Rust开发的m3u8下载器:支持断点续传、边下边播
M3U8 Quicker是一款轻量(仅2MB)跨平台M3U8下载播放器,基于Tauri+Rust+React开发。支持断点续传、AES解密、边下边播、自动转MP4及Chrome一键抓取地址,让课程保存与媒体管理更高效稳定。
54 4
|
1天前
|
缓存 人工智能 安全
Claude Code 偷偷烧钱?逆向工程揭露 7 个叠加 Bug,Max 20x 一天耗尽 43% 周配额
一位 Claude Max 20x 订阅用户仅一天就烧掉了一周 43% 的 token 配额。他逆向分析 Claude Code 源码,找到了 7 个可以叠加触发的缓存 Bug,最致命的是 Extra Usage 模式会静默将缓存时长从 1 小时降级为 5 分钟,形成"死亡螺旋"。
34 3
|
1天前
|
安全 开发工具 git
Git 奇招:无缝接轨远程分支,解锁未合并PR的新特性!
本文手把手教你如何优雅体验开源项目中尚未合并的PR功能:从克隆原仓库、添加fork远程源、获取分支,到创建安全分支、合并并解决冲突。8步清晰流程+避坑提示,助你零基础快速上手,安全尝鲜最新特性!
35 5
|
1天前
|
弹性计算 人工智能 机器人
阿里云ECS/轻量服务器+本地全平台部署OpenClaw|集成QQ机器人+千问Qwen3.6-Plus+Coding Plan大模型配置保姆级教程
2026年,开源AI自动化框架OpenClaw(曾用名Clawdbot)已成为个人与团队效率提升的核心工具,凭借“行动式AI”能力,可将自然语言指令转化为文件管理、系统控制、数据处理、社交交互等实际任务执行。本文完整覆盖2026年阿里云轻量服务器部署及本地MacOS/Linux/Windows11部署OpenClaw(Clawdbot)步骤流程及阿里云千问Qwen3.6-Plus配置或市场上免费大模型Coding Plan API配置及常见问题解答,同步新增阿里云ECS云服务器专业部署、QQ机器人全流程集成方案,所有操作附可直接复制的代码命令、可视化指引与高频问题排查方案。
64 14
|
4月前
|
监控 安全 Unix
iOS 崩溃排查不再靠猜!这份分层捕获指南请收好
从 Mach 内核异常到 NSException,从堆栈遍历到僵尸对象检测,阿里云 RUM iOS SDK 基于 KSCrash 构建了一套完整、异步安全、生产可用的崩溃捕获体系,让每一个线上崩溃都能被精准定位。
1089 103
|
1天前
|
人工智能 运维 监控
OpenClaw 10大自动化场景实战|阿里云轻量服务器部署+零基础避坑指南
2026年,OpenClaw已成为普通人拥有“AI员工”的最低门槛工具——无需编程基础,通过简单配置即可落地10大自动化场景,让效率提升3倍以上。本文完整覆盖**新手零基础阿里云轻量服务器部署OpenClaw(Clawdbot)简单步骤及避坑指南**,从部署、配置到场景落地,全程提供可直接复制的代码与指引,确保用户快速上手。
61 8
|
1天前
|
人工智能 Linux API
阿里云轻量服务器部署OpenClaw与千问Qwen3.6-Plus全流程实战:从环境搭建到模型接入及避坑指南
OpenClaw(原Clawdbot)作为2026年主流的开源AI智能体框架,凭借轻量化、跨平台、可自托管、多IM集成与大模型灵活对接的特性,成为个人与团队搭建专属AI助手的首选方案。本文聚焦阿里云轻量服务器部署OpenClaw的最简流程,覆盖本地MacOS/Linux/Windows11全平台部署方法,详解阿里云千问Qwen3.6-Plus高性能API配置、飞书即时通讯集成步骤,并整理全场景高频问题与避坑方案,所有命令可直接复制运行,零基础用户可按步骤一次部署成功。
163 17
|
1天前
|
人工智能 安全 数据可视化
不止是聊天!深度解析OpenClaw“养龙虾”:技能扩展与多Agent协作
本文围绕 OpenClaw “养龙虾” 展开,解析其技能扩展与多 Agent 协作机制。作为 LLM 执行中间层,它通过可插拔技能为 AI 拓展工具调用与操作能力,借助多智能体分工协作完成复杂任务。文章揭示 AI 从单纯对话向自主执行、协同工作演进的核心趋势,展现智能体工程化落地的关键路径。
225 8
|
前端开发 Java 测试技术
Spring源码学习之:ClassLoader学习(4)
转载:http://www.codeceo.com/article/java-classloader.html 一:什么是ClassLoader?===>大家都知道,当我们写好一个Java程序之后,不是管是CS还是BS应用,都是由若干个.class文件组织而成的一个完整的Java应用程序,当程序在 运行时,即会调用该程序的一个入口函数来调用系统的相关功能,而这些功能都被封装在不同的class文件当中,所以经常要从这个class文件中要调用另 外一个class文件中的方法,如果另外一个文件不存在的,则会引发系统异常。
1025 0
|
1天前
|
运维 安全 中间件
PHP实战:从零到一构建企业级应用(五)
教程来源:https://htnus.cn/category/tech-trends.html 本文详解PHP企业级用户管理系统实战:含操作日志中间件(自动记录请求、脱敏敏感数据)、Docker容器化部署(Nginx+PHP-FPM+Redis多服务集成)及生产级性能优化(OPcache、Redis会话、安全配置),覆盖开发到运维全链路。