当前位置: 首页 > article >正文

Helloagents-13travel agent学习笔记

承接上文Helloagents-13.智能旅行助手学习笔记 _helloagents旅游项目-CSDN博客1.全链路架构梳理1. 订单接入用户输入 - 后端接收前端 (Vue)用户在网页上填好目的地如“悉尼”、天数、出发日期等点击“生成”。数据打包成一个 HTTP POST 请求发给后端。后端的看门大爷 (Pydantic)FastAPI 接收到请求后第一时间交给Pydantic。它会检查数据格式对不对比如天数必须是整数目的地不能为空。如果不符合直接打回符合则放行进入核心车间。2. 原材料采购绕过 LLMPython 强行“截胡”调 API这是我改的原本的开源设计是让大模型自己去看工具说明书Function Calling调高德地图。但因为 MCP 工具链传参丢失空字典{}问题大模型不会用工具了。重构了架构Python 后端直接接管了“采购权”。修改amap_service用硬编码直接去请求高德 API稳定地拿到了最真实的目的地天气、POI兴趣点和路线原生 JSON 数据。3.图片素材补充Serper 搜图引擎有了高德的文字数据还不够由于 Unsplash 对中文景点支持极差改用serper替代unsplash搜图。新建了serper_service.py根据高德给出的景点名称通过 Serper API 精准抓取真实的景点图片 URL。4.翻译官与排版员调度大模型 LLMPython 后端把从高德拿到的真实地理数据、从 Serper 拿到的景点图片链接以及用户的输入打包塞进设定好的 Prompt 里。大模型根据这些原材料生成一份标准的长 JSON。里面包含了每日的行程安排、交通推荐和基础的费用估算。5. 结构质检JSON 解析与响应组装后端用 Pydantic 校验大模型吐出的中文行程 JSON。检查它是否严格包含前端所需的字段如days,attractions,location等。如果解析成功就把这串标准的 JSON 响应发送给前端。6. 页面渲染前端展示Vue 页面接单前端拿到数据后进行解析。地图联动提取出 JSON 里的经纬度或地点信息传给高德地图前端组件Map.vue在右侧渲染出真实的交互式地图路线。图文排版在左侧将每日行程、Serper 抓取到的真实景点图片、以及基础的预算信息渲染成网页列表。2.Bug总结1.MCP 工具链瘫痪bug:在让大模型生成旅行计划时系统直接报错大模型回复“抱歉工具不可用”。深层根本原因是LLM的依赖性:底层的amap-mcp-server存在 Bug在向大模型注册工具时传递的参数说明书是个空字典{}。大模型虽然聪明但它没有参数说明它根本不知道怎么构造高德地图的 API 请求导致 Function Calling 整个流程直接断裂。解决方案放弃了让 LLM 自主调度工具。用 Python 代码做拦截直接硬编码去调用高德 API 获取真实的 JSON 气象和地理数据然后将这些数据作为“上下文知识”拼接在 Prompt 里喂给大模型。大模型从“手握方向盘的司机”降级成了“专业的翻译官和排版员”从架构上消除了工具调度的不稳定性。2.Unsplash 的“语言隔离”与翻译拦截bug:在前端页面上行程列表渲染出来了高德地图也显示了但是像“夫子庙”、“玄武湖”这样的景点配图要么完全空白要么显示默认的错误图片。深层根本原因是API 语境偏差:系统原本调用的是国外的 Unsplash 免费图库。这个图库的检索引擎是纯英文语境的。当系统傻乎乎地把高德地图返回的中文景点名如“夫子庙”直接当作参数塞给 Unsplash API 时对方根本无法解析直接返回空结果0 hits。解决方案在poi.py调用图片 API 之前强行插入了一个翻译层数据预处理。先调用大模型或翻译工具将中文 POI 翻译成准确的英文地名然后再去请求 Unsplash。这体现了在对接第三方跨国 API 时必须做的数据标准化处理。3.图库“幻觉”与 Serper 引擎的彻底替换bug翻译层加上之后图片确实出来了。但是当搜索南京“水游城”时前端显示了一张北京“水立方”的照片搜索某些小众景点时出来的全是风马牛不相及的风景图。深层根本原因是数据源覆盖率缺陷这是第三方数据源先天不足。Unsplash 作为一个海外的无版权图库它对中国本土化垂直场景尤其是具体的地理 POI的覆盖率极低。当它找不到精确匹配时它的底层搜索算法会进行“宽泛匹配”比如看到“水”就推水立方导致前端出现幻觉。解决方案改用了Serper。新建了serper_service.py并在config.py中重构了环境变量。在poi.py中切断了旧图库的引用实现了业务代码的无缝切换。3.核心代码-伪代码总结逻辑1.Prompt 的动态编排层backend/app/agents/trip_planner_agent.py拦截llm硬编码调用高德api# 提取自 _search_attractions 等工具调用函数 # 我们不再把工具丢给 agent.run而是直接用 self.amap_tool.run 传死参数 result self.amap_tool.run({ action: call_tool, tool_name: maps_text_search, arguments: { keywords: keywords, city: request.city, citylimit: true } })prompt拼装# 提取自 _generate_plan_with_llm # Python 用 f-string 把真实的高德 JSON 强行嵌入到了用户的上下文中 query f请根据以下真实数据生成{request.city}的{request.travel_days}天旅行计划: ... **景点数据 (JSON):** {json.dumps(attraction_data, ensure_asciiFalse, indent2)} **天气数据 (JSON):** {json.dumps(weather_data, ensure_asciiFalse, indent2)} ... # 最后直接 invoke 裸调大模型没有 agent 调度只有最纯粹的对话 messages [ {role: system, content: PLANNER_PROMPT}, {role: user, content: query} ] response self.llm.invoke(messages)planner_prompt1少样本提示代码体现 直接给了大模型一个完整的带缩进的 JSON 结构模板如 location: {longitude: 116.397128, latitude: 39.916527}。架构意义 相比于用自然语言说“请输出包含经纬度的地点信息”直接给一个模板能让大模型的 JSON 输出准确率提升 90% 以上。2防御性边界指令代码体现 温度必须是纯数字(不要带°C等单位)架构意义 因为后端的 Pydantic Schema 里温度的类型大概率定义成了 int。如果大模型输出 25°C后端就会直接报格式验证错误。这句 Prompt 从源头上掐断了解析崩溃的风险。3密集的显式约束代码体现 每天安排2-3个景点、每天必须包含早中晚三餐架构意义 防止大模型“偷懒”或“产生幻觉”。大模型经常会省略输出通过明确的数量限制逼迫大模型进行充分的上下文推理保证行程内容的饱满度。trip_planner_agent.py的架构trip_planner_agent.py (多智能体旅行规划器核心逻辑) │ ├── 顶层常量与配置 │ └── PLANNER_PROMPT (全局常量定义系统级人设与极严谨的 JSON 模板约束) │ ├── class MultiAgentTripPlanner (核心业务类) │ │ │ ├── 1. 初始化层 │ │ └── __init__ (加载大模型 llm并注册绑定 amap_mcp_server) │ │ │ ├── 2. 核心调度主流程 (Facade 模式) │ │ └── plan_trip (对外唯一公开的方法像指挥官一样调度下面的私有方法) │ │ ├── 调用 _search_attractions (抓取景点) │ │ ├── 调用 _get_weather (抓取天气) │ │ ├── 调用 _search_hotels (抓取酒店) │ │ ├── 调用 _generate_plan_with_llm (丢给大模型翻译) │ │ └── 调用 _parse_response (解析返回结果) │ │ │ ├── 3. 工具拦截调用层 (硬编码拿数据) │ │ ├── _search_attractions (调高德地点搜索) │ │ ├── _get_weather (调高德天气 API) │ │ └── _search_hotels (调高德搜酒店) │ │ │ ├── 4. 数据预处理层 │ │ └── _parse_mcp_result (剥离工具返回的无效字符只提取 JSON) │ │ │ ├── 5. 核心推理层 │ │ └── _generate_plan_with_llm (组装 System 模板 User 真实数据调 LLM) │ │ │ └── 6. 兜底与容错层 │ ├── _parse_response (正则剥离大模型返回的 json 等脏数据) │ └── _create_fallback_plan (如果大模型罢工强行用 Python 写死一个兜底行程) │ └── 全局单例实例化 ├── _multi_agent_planner (全局缓存变量) └── get_trip_planner_agent() (单例模式入口确保全局只初始化一次高德工具)2.外部API的调度与清洗层backend/app/services/amap_service.py清洗烂字符串修复 Pydantic 报错在服务层做了一层正则拦截。利用 re.search(r\{.*\}) 配合 re.DOTALL允许匹配换行符把中间真正的 JSON 块抠了出来再用 json.loads 转成标准的 Python 字典。import json import re # 核心清洗逻辑使用正则表达式强行提取大括号包裹的内容 json_match re.search(r\{.*\}, result, re.DOTALL) if json_match: # 提取纯净的 JSON 字符串并转化为 Python 字典 data json.loads(json_match.group()) return data # 如果怎么都提不出来返回一个带 raw 标记的字典兜底 return {raw: result}只初始化一次高德地图MCP工具global _amap_mcp_tool if _amap_mcp_tool is None: _amap_mcp_tool MCPTool(...)backend/app/services/serper_service.py和backend/app/api/routes/poi.py多级搜索策略。通过动态追加 Context如‘景点’、‘landmark’进行多轮重试。如果三轮都查不到程序会果断返回 None# 策略1: 原名直搜 photos self.search_photos(name, num3) # 策略2: 加 景点 限定词Query Expansion photos self.search_photos(f{name} 景点, num3) # 策略3: 跨语言限定词 photos self.search_photos(f{name} landmark China, num3) # 终极防御宁缺毋滥 return None路由与服务解耦poi.py 里面只有 router.get它自己绝对不去发 HTTP 请求而是老老实实调用 serper_service.get_photo_url(name)。这叫职责分离。poi.pyController 层只负责接客和参数校验serper_service.pyService 层专心干苦力查数据。以后如果要换百度识图只需要改 Service 层完全不需要动 API 路由层。数据清洗# 没有直接 return response.json() for photo in results: photos.append({ url: photo.get(imageUrl), title: photo.get(title) })标准化的统一响应结构poi.py中。所有的 API 接口都必须遵守{success: bool, message: str, data: Any}的结构。这样前端在写 Axios 拦截器时就能非常轻松地全局处理成功和失败的弹窗不用每个接口都去猜数据在哪一层。return { success: True, message: 获取图片成功, data: { ... } }3.大模型输出的兜底与解析层backend/app/api/routes/trip.py控制器lan_trip 函数内部几乎没有写任何具体的 if-else 业务逻辑它只是打印了日志然后直接把请求扔给了 agent.plan_trip(request)拿到结果后立马包装返回。真正的“炒菜”全在后面的 Agent 和 Service 层。这样写代码清爽维护时一目了然。GET /health接口它不仅返回了 status: healthy还主动去试探了一下底层的 agent 能不能正常获取len(agent.agent.list_tools())。如果底层 MCP 工具挂了这个接口会立刻抛出503 (Service Unavailable)。backend/app/model/schemas.py之前在 Prompt 里嘱咐大模型“温度必须是纯数字”。但是 它还是可能由于幻觉输出了 day_temp: 25°C。如果不用 field_validatorPydantic 看到字符串 25°C 而不是整数会当场抛出 ValidationError整个行程规划直接崩溃。modebefore在 Pydantic 原生类型检查之前拦截相当于在海关门口放了一个“自动清洗机”不管大模型吐出来带什么单位全给你扒干净转成整数。柔性容错机制field_validator(day_temp, night_temp, modebefore) classmethod def parse_temperature(cls, v): 解析温度,移除°C等单位 if isinstance(v, str): v v.replace(°C, ).replace(℃, ).replace(°, ).strip() try: return int(v) except ValueError: return 0 return v自定义数据清洗器大模型在生成超长 JSON 时极度容易**“丢三落四”。如果没有Optional和default缺少一个字段就会导致整体验证失败。使用了这些特性后系统实现了优雅降级—— 核心字段带...的必填项比如名字、日期必须有非核心字段没有就塞个默认值0或者None绝不影响主流程。前端拿不到rating大不了就不显示星星但绝不会白屏。rating: Optional[float] Field(defaultNone, description评分) photos: Optional[List[str]] Field(default_factorylist, description景点图片URL列表) ticket_price: int Field(default0, description门票价格(元))嵌套树状契约 代码体现从下往上组装Location - Attraction/Hotel/Meal - DayPlan - TripPlan - TripPlanResponse。架构意义不要企图用一个几百行的巨大字典去约束复杂的返回值。这种一层套一层的组合模式不仅让代码可读性极强更重要的是当大模型的某一行 JSON 出错时Pydantic 报错堆栈会极其精准地告诉你“是 TripPlan 里的第 2 个 DayPlan 里的第 1 个 Attraction 的 Location 格式错了”。这极大地降低了后期的 Debug 成本。API 的“自说明”与 Swagger 集成这是标准的大厂 API 规范。加上example和详细的description之后FastAPI 会在/docs路径下自动生成一个可以直接进行调试、并且自带样例数据的炫酷 Swagger 接口文档。前后端联调时前端只需要看这个自动生成的文档根本不用问“这个字段是干嘛的”。class Config: json_schema_extra { example: { city: 北京, travel_days: 3, # ... } }

相关文章:

Helloagents-13travel agent学习笔记

承接上文Helloagents-13.智能旅行助手学习笔记 _helloagents旅游项目-CSDN博客 1.全链路架构梳理 1. 订单接入(用户输入 -> 后端接收) 前端 (Vue): 用户在网页上填好目的地(如“悉尼”)、天数、出发日期等&#x…...

告别窗口切换烦恼:PinWin带来的工作效率变革

告别窗口切换烦恼:PinWin带来的工作效率变革 【免费下载链接】PinWin Pin any window to be always on top of the screen 项目地址: https://gitcode.com/gh_mirrors/pin/PinWin 在繁忙的工作日,数据分析师小李正同时处理三个Excel表格、一个数据…...

proteus新手福音:用快马平台轻松生成第一个电路仿真项目

作为一个刚接触电子电路设计的萌新,第一次打开Proteus时真的被满屏的英文界面和密密麻麻的元件库吓到了。直到发现了InsCode(快马)平台,用自然语言描述就能生成完整的仿真项目,简直是新手救星!下面分享我的第一个LED闪烁电路仿真实…...

主动配电网短期负荷预测与网络重构优化分析:基于IEEE33节点的实证研究

主动配电网短期负荷预测重构 以IEEE33节点为算例,有迭代图,各个节点在重构前的电压幅值及重构前后电压幅值的对比图,优化前后网络损耗数值对比,重构优化开断支路具体情况,以及在具体某节点处接入分布式电源的容量。 有…...

从手机双摄到自动驾驶:对极几何与基础矩阵在现实场景中的三种典型应用分析

从手机双摄到自动驾驶:对极几何与基础矩阵在现实场景中的三种典型应用分析 当你在手机上使用人像模式拍照时,背景虚化的效果是如何实现的?无人机如何在飞行过程中实时估算自身位置?自动驾驶汽车又是怎样通过多摄像头系统感知周围环…...

迅为RK3588S开发板Android13系统外设功能全解析

1. RK3588S开发板与Android13系统初探 作为一款面向边缘计算场景的高性能开发平台,迅为RK3588S开发板搭载Rockchip旗舰级处理器,四核Cortex-A76四核Cortex-A55架构设计,配合Mali-G610 MP4 GPU,在Android13系统上展现出强劲的多媒体…...

Agent RAG 底层核心难点

Agent 1. 任务规划与拆解 (Reasoning & Decomposition) 递归深度失控:任务拆得太细导致逻辑迷失,或拆得太粗无法执行。目标漂移 (Goal Drift):长流程中 Agent 忘记了最初的最终目标。不可逆决策风险:在缺乏“回滚”机制的现实…...

ComfyUI 自动化生产 3D资产 工作流笔记

ComfyUI 自动化生产 3D资产 工作流笔记 概念与初衷: 针对个人开发者,实现 AI 转 高质量3D资产的 积分限制,次数限制,降低生成成本。 零、工具网站: 1、HugginFace (模型下载站) 2、魔搭社区 …...

AI辅助开发:让快马AI设计智能引擎,深度解决synaptics.exe映像损坏

最近在帮朋友解决一个头疼的Windows系统问题——synaptics.exe损坏的映像错误。这个错误不仅影响触控板功能,还会导致各种奇怪的系统行为。作为一个开发者,我决定尝试用AI辅助开发的方式,打造一个智能诊断修复工具。下面分享我的实践过程&…...

智能编程伙伴:让快马ai辅助你优化与调试keil嵌入式项目代码

智能编程伙伴:让快马AI辅助你优化与调试Keil嵌入式项目代码 最近在Keil MDK环境下开发STM32G474RET6的精密数据采集系统时,遇到了ADC采样噪声大和实时性不足的问题。作为一个嵌入式开发者,这些问题直接影响系统的精度和响应速度。通过使用In…...

从安装到实战:在快马生成项目中体验openclaw本地安装与即时数据抓取

从安装到实战:在快马生成项目中体验openclaw本地安装与即时数据抓取 最近在做一个数据采集的小项目,需要从网站上抓取一些公开信息。经过调研发现openclaw这个工具很适合我的需求,但网上关于它的本地安装和实际应用的完整教程比较少。于是我…...

从配置到实战:基于快马生成keil5双环境下的c51与stm32传感器驱动对比项目

在实际嵌入式开发中,经常需要在不同架构的MCU之间切换或协作。最近我在做一个温湿度监测项目,需要在STC89C52(C51架构)和STM32F103C8T6(ARM架构)上分别实现DHT11传感器的驱动。通过这个实战项目&#xff0c…...

告别AI代码乱炖:用GitHub Spec Kit v0.0.79,像资深架构师一样拆解复杂功能

告别AI代码乱炖:用GitHub Spec Kit v0.0.79,像资深架构师一样拆解复杂功能 在当今快节奏的开发环境中,面对一个需要多模块协作的复杂功能时,许多开发者常常陷入两难:要么盲目依赖AI生成代码导致质量失控,要…...

Pixel Language Portal 在 WSL 中的开发环境配置与性能对比

Pixel Language Portal 在 WSL 中的开发环境配置与性能对比 1. 前言:为什么选择WSL进行开发? 对于Windows系统下的AI开发者来说,WSL(Windows Subsystem for Linux)提供了一个两全其美的解决方案。它既保留了Windows系…...

三步轻松搭建你的B站离线视频库:BilibiliDown完全使用指南

三步轻松搭建你的B站离线视频库:BilibiliDown完全使用指南 【免费下载链接】BilibiliDown (GUI-多平台支持) B站 哔哩哔哩 视频下载器。支持稍后再看、收藏夹、UP主视频批量下载|Bilibili Video Downloader 😳 项目地址: https://gitcode.com/gh_mirro…...

告别模糊字体!3分钟掌握浏览器字体渲染优化神器

告别模糊字体!3分钟掌握浏览器字体渲染优化神器 【免费下载链接】GreasyFork-Scripts The open source code of this project is used for userscripts (油猴脚本) for desktop browsers, including Font Rendering (Customized) (字体渲染(自用脚本&…...

Maya Arnold前台渲染无响应问题排查与解决

1. Maya Arnold前台渲染无响应问题排查指南 最近在Maya中使用Arnold渲染时,不少朋友都遇到了前台渲染无响应的问题。点击渲染按钮后,Render View窗口毫无反应,就像什么都没发生过一样。这种情况在动画场景整合阶段尤其常见,我自己…...

5个核心价值教你如何合法突破付费内容限制:bypass-paywalls-chrome-clean工具全攻略

5个核心价值教你如何合法突破付费内容限制:bypass-paywalls-chrome-clean工具全攻略 【免费下载链接】bypass-paywalls-chrome-clean 项目地址: https://gitcode.com/GitHub_Trending/by/bypass-paywalls-chrome-clean 在信息获取日益受限的今天&#xff0c…...

如何高效管理空洞骑士模组:5个专业技巧的完整指南

如何高效管理空洞骑士模组:5个专业技巧的完整指南 【免费下载链接】Lumafly A cross platform mod manager for Hollow Knight written in Avalonia. 项目地址: https://gitcode.com/gh_mirrors/lu/Lumafly 还在为空洞骑士模组安装的复杂流程而烦恼吗&#…...

SteamAutoCrack终极指南:三步实现Steam游戏离线自由运行

SteamAutoCrack终极指南:三步实现Steam游戏离线自由运行 【免费下载链接】Steam-auto-crack Steam Game Automatic Cracker 项目地址: https://gitcode.com/gh_mirrors/st/Steam-auto-crack 对于众多Steam游戏玩家来说,你是否曾遇到过这样的困境&…...

GModPatchTool终极指南:3步解决Garry‘s Mod启动失败与浏览器问题

GModPatchTool终极指南:3步解决Garrys Mod启动失败与浏览器问题 【免费下载链接】GModPatchTool 🇬🩹🛠 Patches for Garrys Mod. Updates/Improves CEF and Fixes common launch/performance issues (esp. on Linux/Proton/macOS…...

一键隐藏桌面图标任务栏的实用工具

软件介绍 AutoDesktop是一个专门管理桌面图标显示与隐藏的小工具。它的作用很简单:一键把桌面上乱七八糟的图标和底部的任务栏全都藏起来,还你一个干干净净的桌面。 体积小巧运行轻量 整个软件才40K大小,真的非常小。双击运行后会自动关闭…...

如何精准控制绝对定位元素的垂直位置(避免蓝条错位)

本文详解如何通过修正 CSS position: absolute 的定位属性,解决蓝色导航条在页面中随机错位的问题,核心是正确使用 top 或 bottom 而非混用导致布局失控。 本文详解如何通过修正 css position: absolute 的定位属性,解决蓝色导航条在页面…...

JavaScript中全局执行上下文与函数上下文的生成过程

全局执行上下文在JS引擎启动时创建,函数执行上下文在每次调用时创建;前者作用域链仅含全局环境,后者在创建阶段就基于定义位置固定作用域链;var和function声明被提升并初始化,let/const仅注册于词法环境而处于暂时性死…...

c++如何实现基于流缓冲区派生类的高级虚流映射与内存模拟文件【底层】

不能直接继承 std::streambuf 做“虚文件”,因其仅提供 underflow()/overflow() 等底层I/O操作,缺失 open/close/seek/stat 等文件语义,需自行实现 seekoff()(区分读写位置与 end 语义)、xsputn() 回退机制等&#xff…...

SQL数据库如何删除千万级大表数据_使用TRUNCATE与Drop策略

TRUNCATE 比 DELETE 快因不写行级日志、直接释放数据页并重置高水位线,属 DDL 操作,不可回滚、不支持 WHERE;DELETE 逐行加锁写日志,大表易锁表卡死;DROP 最快但不可逆,丢失结构与权限。TRUNCATE 为什么比 …...

HTML函数开发需要多少瓦电源_整机功耗估算指南【说明】

最准方法是用电力功耗仪实测整机交流输入功率;鲁大师靠查表估算易失真;HTML开发真实耗电来自浏览器、框架、开发服务等;选电源须看12V输出能力和80 PLUS认证。怎么看当前整机真实功耗(不是TDP,是插座上真烧的电&#x…...

手机检测落地标准化:实时手机检测-通用模型企业级部署Checklist

手机检测落地标准化:实时手机检测-通用模型企业级部署Checklist 1. 引言:为什么企业需要标准化的手机检测方案? 想象一下,你是一家大型电子产品质检工厂的负责人。每天,成千上万的手机从流水线上经过,需要…...

保姆级教程:在Ubuntu 20.04上从零搭建宇树Go1机器狗的ROS仿真环境(含Gazebo避坑)

从零构建宇树Go1机器狗的ROS仿真环境:Ubuntu 20.04全流程指南 当四足机器人从实验室走向消费市场,宇树科技的Go1凭借其灵活动作和开源生态迅速成为开发者新宠。但第一次打开Gazebo看到机器狗瘫倒在地时,多数新手都会陷入手足无措的境地——依…...

Qwen3.5-9B玩转YOLOv5:智能标注建议与模型训练参数调优

Qwen3.5-9B玩转YOLOv5:智能标注建议与模型训练参数调优 1. 引言:当大模型遇上目标检测 最近在做一个YOLOv5的目标检测项目时,遇到了两个头疼的问题:一是标注数据质量参差不齐影响模型效果,二是超参数调优耗费大量时间…...