开源模型应用落地-LangGraph101-ToolNode-智能工具调度的核心枢纽
通过ToolNode组件实现了智能体与工具之间的无缝衔接。
·
一、前言
在构建复杂AI工作流时,如何高效协调大语言模型(LLM)与外部工具的交互是核心挑战。LangGraph框架通过ToolNode组件为此提供了标准化解决方案,其作为图状态与工具调用的桥梁,实现了智能体与工具的无缝衔接。
二、术语介绍
2.1.LangGraph
是一个基于 LangChain 构建的开源库,旨在为构建基于大语言模型(LLM)的有状态、多智能体应用程序提供一个全新的范式和强大的框架支持。
核心特点
- 支持循环图构建:与传统的基于有向无环图(DAG)的框架不同,LangGraph 允许开发者在图形结构中自由定义循环边和循环节点,这对于设计动态和迭代的智能体工作流程至关重要,能使智能体行为更贴近实际编程场景。
- 自动状态管理:具有自动状态管理能力,可在多个交互中跟踪和持久化信息。随着智能体执行任务,状态会动态更新,确保系统能维护上下文并对新输入做出适当响应。
- 多智能体协调:支持在单个图结构中协调多个智能体,每个智能体都可以有自己的提示、LLM、工具和自定义代码,方便构建多智能体系统,使多个智能体能够有效地协同工作,共同完成复杂任务。
- 灵活性与可定制性:开发者可以灵活定义自己的智能体逻辑和通信协议,根据具体用例构建高度定制化的应用,满足不同场景需求。
- 可扩展性与容错性:设计用于支持大规模多智能体应用的执行,具有强大的架构,能够处理大量交互和复杂工作流。同时,包含了优雅处理错误的机制,确保即使个别智能体遇到问题,应用也能继续运行。
工作原理
- 图结构表示:将应用视为一个有向图,其中每个节点代表一个 LLM 智能体或其他可执行的函数、工具等,边则定义了执行和数据流的方向,连接各个节点。
- 状态更新机制:通过状态图来管理在执行周期中持久化的数据,当数据在节点之间流动时,状态对象会被管理和更新,从而实现跨执行周期的状态跟踪和更新。
核心组件
- 节点(Nodes):是图结构中的执行单元,在其内部依据预设的代码逻辑进行复杂的运算与处理,最终输出一个经过更新后的全新状态。
- 边(Edges):边作为图结构中的连接要素,承担着构建节点之间逻辑关系与信息流向路径的重要职责。从类型上划分,主要涵盖了简单边和条件边这两种形式。简单边建立起节点之间最为基本的连接关系,使得前一个节点完成处理后所输出的状态信息能够顺畅地传输至下一个节点,成为其输入信息的来源,从而保障了信息在各个节点间的线性传递。而条件边则具备更为灵活和智能的特性,当一个节点的处理过程结束后,条件边会基于其内置的判断逻辑,精准地确定该节点后续应当通过哪些输出边来传递信息,极大地提高了系统的运行效率和任务处理的灵活性。
- 状态(State):作为一种共享的数据结构,其重要性不言而喻。在整个系统的运行过程中,状态如同一个公共的信息存储库,保存着应用程序在各个阶段的当前信息
应用场景
- 智能聊天机器人:能够处理各种用户请求,通过多 LLM 智能体协作,处理自然语言查询,提供准确响应,并在不同对话主题间无缝切换,提供连贯一致的用户体验。
- 自主智能体:可创建根据用户输入和预定义逻辑执行任务的自主智能体,执行复杂工作流,与其他系统交互,并动态适应新信息,适用于自动化客户支持、数据处理、系统监控等任务。
- 多智能体系统:在供应链管理、团队协作等场景中,多个智能体可分别管理库存、处理订单、协调交付等,通过 LangGraph 的协调能力,实现高效沟通、信息共享和决策同步,提升整体系统性能。
- 工作流自动化工具:用于设计智能体来处理文档处理、审批工作流、数据分析等任务,通过定义清晰的工作流和利用状态管理,无需人工干预即可执行复杂操作序列,提高工作效率并减少错误。
- 个性化推荐系统:利用多个智能体分析用户行为、偏好等数据,提供更个性化的推荐服务。
类似竞品
- AutoGen:微软推出的行业先驱,核心设计包括用户智能体和助手智能体,特别适用于软件开发领域,在处理代码编排任务时表现出色。它允许用户在智能体间进行互动和手动调整,但对于没有编程背景的用户而言,学习成本较高。
- CrewAI:以简洁直观的操作界面受到推崇,非常适合快速搭建多智能体任务,用户无需深厚的技术背景,只需编写一些简短的提示词即可创建多个智能体并完成课程演示。不过,其在灵活性和定制化方面存在局限,技术社区的支持也相对较弱。
- OpenAI Swarm:专为新手设计,以简化智能体的创建与上下文切换为主要特征,用户只需简单操作即可快速制作演示应用。但它仅支持 OpenAI API,缺乏灵活性,不适合复杂的生产环境,技术社区支持也相对匮乏。
- Magentic-One:微软最新推出的产品,目标是为 AutoGen 提供一个简化的替代方案,尤其适合缺乏编程经验的用户,内置多个智能体用于文件管理、网页浏览和代码编写等功能,支持快速配置和使用。然而,其在对开源 LLMs 的支持上相对复杂,目前的文档和社区支持也未完善。
2.2.ToolNode
是一个用于管理工具调用的核心组件,其作用在于协调智能体(Agent)与外部工具(如API、函数等)的交互流程。
核心功能特性
(1)工具触发与消息管理
- 并行执行:支持同时处理多个工具调用请求。例如,若一条消息包含多个tool_calls,ToolNode会并行执行所有工具,并将结果按顺序存入状态。
- 状态集成:ToolNode的操作基于图的状态(MessagesState),该状态保存了与LLM的交互消息和工具调用结果,确保上下文连贯。
(2)与LangChain生态的兼容性
- 工具绑定:ToolNode需配合LangChain的@tool装饰器使用,确保工具函数的参数格式符合预期(避免因类方法中的self参数导致的验证错误)。
- 模型集成:通过bind_tools()方法将工具列表绑定到聊天模型(如ChatOpenAI),模型生成的响应中会自动包含工具调用请求,供ToolNode处理。
2.3.Tavily
是一款专为人工智能应用设计的搜索引擎,旨在优化大型语言模型(LLMs)和检索增强生成(RAG)系统的搜索体验。
使用成本
- 付费方案:按调用量或按月订阅,适合企业级高频需求
- 免费层:每月 1000 次 API 调用,适合个人开发者或小规模测试
三、前置条件
3.1.基础环境及前置条件
1. 操作系统:无限
3.2.安装依赖
conda create --name langgraph python=3.10
conda activate langgraph
pip install langgraph -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install langchain_openai langchain_community -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install tavily-python -i https://pypi.tuna.tsinghua.edu.cn/simple
3.3.获取Tavily的API KEY
选择任意一种登录方式
获取API KEY
四、技术实现
4.1.手动调用单一工具
# -*- coding:utf-8 -*-
import json
import os
import traceback
import requests
from langchain_core.messages import AIMessage
from langchain_core.tools import tool
from langchain_openai import ChatOpenAI
from langgraph.prebuilt import ToolNode
from pydantic import BaseModel, Field
gaode_api_key = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
gaode_domain = "https://restapi.amap.com/v3"
class WeatherToolInput(BaseModel):
region: str = Field(description="地区,城市,例如:广州市")
@tool("get_weather", return_direct=True, args_schema=WeatherToolInput)
def get_weather(region:str):
"""根据传入的城市名查询天气"""
ad_code = None
try:
session = requests.session()
region_response = session.request(
method="GET",
url=f"{gaode_domain}/config/district?key={gaode_api_key}&keywords={region}&subdistrict=0",
headers={"Content-Type": "application/json; charset=utf-8"},
)
region_response.raise_for_status()
region_data = region_response.json()
if region_data.get("info") == "OK":
ad_code = region_data["districts"][0]["adcode"]
except:
traceback.print_exc()
return f"获取{region}代码失败"
try:
if ad_code:
weather_response = session.request(
method="GET",
url=f"{gaode_domain}/weather/weatherInfo?key={gaode_api_key}&city={ad_code}&extensions=all",
headers={"Content-Type": "application/json; charset=utf-8"},
)
weather_response.raise_for_status()
weather_data = weather_response.json()
if weather_data.get("info") == "OK":
forecasts = weather_data['forecasts']
result = json.dumps(forecasts, ensure_ascii=False)
print(f'result: {result}')
return result
return f"获取{region}天气预报信息失败"
except:
traceback.print_exc()
return f"获取{region}天气预报信息失败"
tools = [get_weather] # 将定义的工具放入列表中
tool_node = ToolNode(tools) # 使用工具列表初始化 ToolNode
message_with_single_tool_call = AIMessage(
content="",
tool_calls=[{
"name":"get_weather",
"args": {"region":"广州"},
"id": "tool_call_id",
"type": "tool_call"}
])
# 手动调用ToolNode
result = tool_node.invoke({"messages":[message_with_single_tool_call]})
print(f'result: {result}')
调用结果:
4.2.手动调用多个工具
# -*- coding:utf-8 -*-
import json
import traceback
import requests
from langchain_core.messages import AIMessage
from langchain_core.tools import tool
from langgraph.prebuilt import ToolNode
from pydantic import BaseModel, Field
from tavily import TavilyClient
gaode_api_key = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
gaode_domain = "https://restapi.amap.com/v3"
tavily_api_key = 'tvly-dev-xxxxxxxxxxxxxxxxxxxxxxxx'
class WeatherToolInput(BaseModel):
region: str = Field(description="地区,城市,例如:广州市")
@tool("get_weather", return_direct=True, args_schema=WeatherToolInput)
def get_weather(region:str):
"""根据传入的城市名查询天气"""
ad_code = None
try:
session = requests.session()
region_response = session.request(
method="GET",
url=f"{gaode_domain}/config/district?key={gaode_api_key}&keywords={region}&subdistrict=0",
headers={"Content-Type": "application/json; charset=utf-8"},
)
region_response.raise_for_status()
region_data = region_response.json()
if region_data.get("info") == "OK":
ad_code = region_data["districts"][0]["adcode"]
except:
traceback.print_exc()
return f"获取{region}代码失败"
try:
if ad_code:
weather_response = session.request(
method="GET",
url=f"{gaode_domain}/weather/weatherInfo?key={gaode_api_key}&city={ad_code}&extensions=all",
headers={"Content-Type": "application/json; charset=utf-8"},
)
weather_response.raise_for_status()
weather_data = weather_response.json()
if weather_data.get("info") == "OK":
forecasts = weather_data['forecasts']
result = json.dumps(forecasts, ensure_ascii=False)
print(f'result: {result}')
return result
return f"获取{region}天气预报信息失败"
except:
traceback.print_exc()
return f"获取{region}天气预报信息失败"
class SearchToolInput(BaseModel):
query: str = Field(description="待搜索内容,例如:广州为什么称为羊城?")
@tool("search", return_direct=True, args_schema=SearchToolInput)
def search(query):
"""根据传入的内容检索互联网信息"""
tavily = TavilyClient(api_key=tavily_api_key)
response = tavily.search(query=query)
return response
tools = [get_weather,search] # 将定义的工具放入列表中
tool_node = ToolNode(tools) # 使用工具列表初始化 ToolNode
message_with_multiple_tool_calls = AIMessage(
content="",
tool_calls=[
{
"name": "get_weather",
"args":{"region":"广州"},
"id":"tool_call_id_1",
"type": "tool_call",
},
{
"name": "search",
"args":{"query":"广州有什么好玩的地方?"},
"id":"tool_call_id_2",
"type": "tool_call"
}])
result = tool_node.invoke({"messages":[message_with_multiple_tool_calls]})
print(f'result: {result}')
调用结果:
result: [{"city": "广州市", "adcode": "440100", "province": "广东", "reporttime": "2025-03-21 12:00:38", "casts": [{"date": "2025-03-21", "week": "5", "dayweather": "晴", "nightweather": "晴", "daytemp": "27", "nighttemp": "11", "daywind": "北", "nightwind": "北", "daypower": "1-3", "nightpower": "1-3", "daytemp_float": "27.0", "nighttemp_float": "11.0"}, {"date": "2025-03-22", "week": "6", "dayweather": "晴", "nightweather": "晴", "daytemp": "27", "nighttemp": "12", "daywind": "北", "nightwind": "北", "daypower": "1-3", "nightpower": "1-3", "daytemp_float": "27.0", "nighttemp_float": "12.0"}, {"date": "2025-03-23", "week": "7", "dayweather": "晴", "nightweather": "多云", "daytemp": "28", "nighttemp": "14", "daywind": "北", "nightwind": "北", "daypower": "1-3", "nightpower": "1-3", "daytemp_float": "28.0", "nighttemp_float": "14.0"}, {"date": "2025-03-24", "week": "1", "dayweather": "晴", "nightweather": "多云", "daytemp": "28", "nighttemp": "16", "daywind": "北", "nightwind": "北", "daypower": "1-3", "nightpower": "1-3", "daytemp_float": "28.0", "nighttemp_float": "16.0"}]}]
result: {'messages': [ToolMessage(content='[{"city": "广州市", "adcode": "440100", "province": "广东", "reporttime": "2025-03-21 12:00:38", "casts": [{"date": "2025-03-21", "week": "5", "dayweather": "晴", "nightweather": "晴", "daytemp": "27", "nighttemp": "11", "daywind": "北", "nightwind": "北", "daypower": "1-3", "nightpower": "1-3", "daytemp_float": "27.0", "nighttemp_float": "11.0"}, {"date": "2025-03-22", "week": "6", "dayweather": "晴", "nightweather": "晴", "daytemp": "27", "nighttemp": "12", "daywind": "北", "nightwind": "北", "daypower": "1-3", "nightpower": "1-3", "daytemp_float": "27.0", "nighttemp_float": "12.0"}, {"date": "2025-03-23", "week": "7", "dayweather": "晴", "nightweather": "多云", "daytemp": "28", "nighttemp": "14", "daywind": "北", "nightwind": "北", "daypower": "1-3", "nightpower": "1-3", "daytemp_float": "28.0", "nighttemp_float": "14.0"}, {"date": "2025-03-24", "week": "1", "dayweather": "晴", "nightweather": "多云", "daytemp": "28", "nighttemp": "16", "daywind": "北", "nightwind": "北", "daypower": "1-3", "nightpower": "1-3", "daytemp_float": "28.0", "nighttemp_float": "16.0"}]}]', name='get_weather', tool_call_id='tool_call_id_1'), ToolMessage(content='{"query": "广州有什么好玩的地方?", "follow_up_questions": null, "answer": null, "images": [], "results": [{"title": "来广州旅游一定要去的十五个景点 - 知乎 - 知乎专栏", "url": "https://zhuanlan.zhihu.com/p/679862938", "content": "来广州旅游一定要去的十五个景点 - 知乎 首发于小可爱游记 切换模式 写文章 登录/注册 来广州旅游一定要去的十五个景点 小可爱游记 旅行、徒步(本人不删任何评论) 我最近在知乎上看到一条问题,问广州有什么景点推荐的。回答的都是什么白云山、上下九步行街、北京路、永庆坊……甚至还有推荐大夫山森林公园的。 真是看得我一肚子气! 拜托,这些回答问题的人能不能认真一点?他们推荐的这些所谓景点,只会浪费外地人的时间,并且让人留下“广州不过如此”的负面印象。我很怀疑这些人是否真的有在广州好好地旅游过?他们的回答是不是只是百度或者在小红书看到的? 我决定用心好好写一篇关于广州旅游和美食的文章,分两篇完成。我有这个资格。我在广东长大,对粤语文化比较了解;第二,广州的景点我差不多全部都去过了;第三,除了广州,国内很多地方我也去过。玩得多了,就懂得对比,知道如何筛选出精华。 首先说不该去的景点 一、白云山 白云山是5A级景区,是最名不副实的地方。风景简直可以用毫无特色、寡淡无味来形容。有些人会说站在山顶可以俯瞰整个广州市的容貌。天啊,白云山的山顶离市中心多远知道吗?能看到什么?拿望远镜看吗? 如果你本身去过许多名山大川,千万不要去白云山,去了一定会后悔。 这是我10年前在山顶拍的,你们说能看到什么? 白云山顶 广东好的山都在西北部,也就是韶关、英德和连州那一带。你们想一想,古往今来适合做都城的城市有什么特点?一是临江临河,便于物资运输发展商业。二是没有太多的高山阻隔,便于农业发展。中国是几千年的农耕文明,经济也主要靠农业。山多是无法发展农业的。所以,古往今来的省会城市都选择在临江临河并且山少的位置。广东也是多山的省,而广州市相较于其它城市,则算是山比较少的。有也是那种几十米到一两百米的山比较多。这种低海拔的山也不太有什么亮点。 二、上下九步行街以及北京路 这是曾经广州最出名的购物步行街,其实与其它城市的步行街没什么两样,并没有自己的特色。广州本地人或者长期生活在广州的人都不会去这里的。另外,广州好玩的地方那么多你不去,你去逛街? 三、陈家祠 你们现在看到的陈家祠,早已在那个疯狂畸形的年代被拆掉了。除了陈家祠,还有许许多多无价的文物古迹都在那个年代被暴力拆毁、烧毁了。如今看到的陈家祠是重建的,就好比武汉现在的黄鹤楼,根本不值得去的。当然 ,如果你打算在广州待一段时间,比如半个月,那可以去看看。 四、永庆坊 这也是新改造过的具有岭南特色的一个景点,但是,广州有比这里更具岭南特色的景点,我后面会介绍,这里不必去。 五、石室圣心大教堂 如果你没有宗教信仰,不信耶稣不信上帝,这里根本不值得一去,就是一个宗教教堂而已。 来广州必游的十五个景点 如果你打算来广州旅游,请做好一份最少请10天长假的准备。因为广州与你以往印象中的城市不一样,广州是一个非常大的城市,并且,由于历史悠久,文化底蕴也很浓厚,值得游玩的地方非常多。 一、中山纪念堂+越秀公园+南越王墓博物馆 越秀公园与南越王墓博物馆只隔着一条马路,可以一天游完。而越秀公园是被严重低估的一个公园。里面有旧时广州的形象代表“五羊石雕”,19世纪末德国制造、中国购买用来抗敌的大炮,中山纪念碑和中山纪念堂。还有明朝时期建成的古建筑“镇海楼”,如今叫广州博物馆,里面存放着不少文物古迹。 下面是10年前用手机拍的相片,清晰度和技术很渣,轻喷! 19世纪末德国生产的大炮 不得不佩服当时的德国技术,157年过去看上去还很新 19世纪中期清军生产的铸铁跑 1867年重建的石牌坊 上世纪80年代生产的公交车 1380年建成的镇海楼,如今叫广州博物馆 明代城墙 这个大树的根已经嵌入了600年历史的城墙里 五羊石雕(广州最有名的形象代表) 广州博物馆部分藏品: 东汉:水晶玛瑙珊瑚珠串 清朝乾隆年:錾胎珐琅金鼎 清代:黑漆描金银彩绘人物故事图折扇 民国:黑色绸绣花卉纹披肩 清朝:真丝地流苏罩衣 清朝:浑天仪 清朝:镀金铜胎珐琅花卉瓶钟 明朝:陶俑 宋朝:水军广州修城砖 清朝:七政仪 如果你精力旺盛,不嫌累,顺便去一趟旁边的“南越王墓博物馆”。什么叫南越王呢?就是大约在2000年前,如今的广东省、广西省以及越南一带被一个叫赵佗的汉人征服了,他自封为王,成立了一个新的国家,叫“南越国”。这个国家存在的时间不到一百年就被汉朝灭了。赵佗的墓地直到1983年才被发现。里面保存着大量2000年前的古文物,有武器,生活器具,饰品等等,很值得来游览参观。 越秀公园+南越王墓博物馆游玩建议:在地铁“纪念堂站”下,从中山纪念堂开始游玩,一直走上去就是越秀公园。越秀公园的重点是镇海楼,也就是广州博物馆,门票是10元。可以扫码购票,也可以现金支付购票。如果你想拿纸质票,扫码完之后也可以叫售票员再给你一张纸质票留作纪念。中山纪念堂和越秀公园玩完,大概需要花4个小时。 中午吃饭:可以到中山纪念堂旁边的“广东大厦”,里面也有正宗的粤菜餐厅。这个广东大厦也有37年的历史 ,是1987年建成的,之前叫广东省人民政府第一招待所。如果你不想踅回来,也可以在越秀公园的正门出去,步行至不远处的“北园酒家”。这家也是广州市最顶级的粤菜酒楼之一,创办至今已经96年历史了,也算是名胜古迹之一。吃个饭,顺便把名胜古迹也看了,多划算。 中午吃完饭,休息一会,下午再去南越王墓博物馆。 注意事项:南越王墓博物馆周一闭馆 二、长隆野生动物世界 中国最大动物园,也是亚洲最大动物园。占地面积达到了惊人的2000多亩。早上9点钟进,下午17点也未必能游览完。这么好的动物园,门票只要350元,真的是很良心价的。 我觉得这里不但是来广州的必游地之一,我甚至敢这样评价,这绝对是外国人来中国旅游必去的景点之一。很多动物园的生存空间极为狭窄,看见不免心生怜悯,好想放它们出来。但是长隆野生动物世界的里面的动物活动空间非常大,而且里面竟然养了十多只熊猫。 长隆野生动物世界是禁止游客自带食物和水进去的。这个我完全能理解。毕竟要养这么多动物,肯定需要顾客多消费才能维持开支。 里面的动物品种太多了,一天时间大概是看不完的。我筛选几张之前拍的相片,技术不好,轻喷。 吃竹笋 它发现我了 趴在冰块上降温 这是啥猴? 猴子下水捞游客投的食物 环尾狐猴 鸵鸟在监工 犀牛,最重可达3吨 大象 卿卿我我的老虎 白虎 老虎幼崽 食蚁兽,我开始分不清头尾 非常温顺的黄金蟒 树懒,一分钟可以爬行3米 看上去很假的鹦鹉 八哥 巨嘴鸟 与树枝颜色融合的猫头鹰 这张图有几种动物? 马来貘 长颈鹿和缆车 斑马和角马 牦牛和骆驼 这是羚羊吗? 狮群 奔跑速度达到100公里的猎豹 黑天鹅与某种鹤 非洲兄弟在表演 非洲姐妹在表演 三、长隆欢乐世界 我一般不太推荐游乐场所,但是,长隆是例外,因为这里真的非常好玩,有很多刺激的大型设备和惊险的杂技表演。而且它的门票不贵,只要200多元,太便宜了。要知道,现在去餐厅吃顿饭都要几百元。 下面是我10年前用手机拍的,清晰度和技术不好,轻喷。 过山车,好刺激,有些女孩子哭了,我笑了 大摆锤,这个也刺激 跳楼机,这个也爽 这个叫什么忘记了,也很舒服 鬼屋 我在亲吻一具骷髅的右手 非洲兄弟在表演 身材很好的姐姐表演杂技 欧洲兄弟姐妹在表演 四、长隆水上乐园 这里被评为全球前20名最佳水上主题公园之一。如果你是夏天来,那么可以到这里游玩。5月份到10月份都适合来。广州的10月份依然要穿短袖和开冷气。 我是2012年去的,相片找不到了。如果你们喜欢玩水,就一定要来这里。中国没有比这里玩水更好的公园了。 五、长隆国际大马戏 这不但是中国最大的马戏团,同时也是全世界最大的马戏团。我敢这么说,这绝对是人生中必看的马戏团表演之一。夜晚表演的各种马戏和魔术表演,我只能用“震撼”两字来形容。门票是350元,那些什么歌星的演唱会动不动就上千元,还不及长隆国际大马戏带给你的震撼深刻。 这个我也是2012年去的,可惜当时的手机被偷了,保存在里面的相片也没有了。 游玩长隆系列公园的建议:最少要给长隆系列准备三天时间。第一天去长隆欢乐世界,第二天长隆野生动物世界,第三天长隆水上乐园,夜晚去看长隆大马戏。为什么选择第三天看大马戏?因为玩水不怎么消耗体能。 六、广州塔 广州塔更响亮的名字叫“小蛮腰”,总高600米,目前中国最高的塔。上面有世界上最高的旋转餐厅、世界上最高的摩天轮、世界上最长的螺旋式空中云梯等等。 我10年前去的门票价格是228元,摩天轮票价是98元,一共326元。我刚刚查了一下,这里居然没有涨价,真是很良心的。这里是实名购票的,所以一定要带身份证,超过75岁不让玩摩天轮。 站在上面可以俯瞰整个广州最繁华地段的灯火璀璨的夜景,还能清晰地看到浪漫的珠江以及江上的几座大桥。要欣赏夜景,没有比来小蛮腰更合适的地方了。 下面是我10年前用手机拍的,清晰度有点渣渣,轻喷:", "score": 0.8622012, "raw_content": null}, {"title": "广州60个好玩的地方,总有一个打动你!(值得收藏) - 知乎", "url": "https://zhuanlan.zhihu.com/p/679150033", "content": "如今广州最潮的地方,莫过于此. 多少潮牌、买手店、咖啡店进驻. 让这里的潮流氛围只增不减. 04、广州动物园. 每位广州人的童年专属记忆. 20元的门票就能收获一整天的快乐. 05、越秀公园-仲元楼. 全广州独一无二的蝴蝶楼梯. 让来仲元楼打卡的人一拨又一拨", "score": 0.79958355, "raw_content": null}, {"title": "广州十大必玩景点清单!去过 7 个才算玩转,你还差多远?", "url": "https://baijiahao.baidu.com/s?id=1812220827746104005", "content": "作为广州的标志性建筑,广州塔总高度 600 米,是中国第一高、世界第三高的旅游观光塔。在 488 米的观景平台上,您可以俯瞰整个广州的壮丽景色,将繁华的都市风光尽收眼底。尤其是夜晚,广州塔璀璨的灯光秀更是美轮美奂,让人陶醉其中。", "score": 0.7402687, "raw_content": null}, {"title": "广州必去的十大旅游景点推荐 - 广州本地宝", "url": "http://gz.bendibao.com/tour/201571/ly191748.shtml", "content": "广州必去的十大旅游景点推荐. 图源:本地宝金子 推荐一:广州塔——昵称小蛮腰 推荐指数: ★★★★★★★ 景点介绍: 广州塔建筑总高度600米,其中主塔体高450米,天线桅杆高150米,以中国第一、世界第三观光塔的地位,向世人展示腾飞广州、挑战自我、面向世界的视野和气魄。", "score": 0.73868835, "raw_content": null}, {"title": "赶快收藏!广州周末漫游秘籍,10个好玩的地方,再也不怕\\"周末荒\\"了_腾讯新闻", "url": "https://news.qq.com/rain/a/20250321A00KK100", "content": "在广州打拼的人们 平时总是行色匆匆 根本没有时间静下心来 好好的欣赏这座城市 这个周末.... 广州周末漫游秘籍,10个好玩的地方,再也不怕", "score": 0.5054935, "raw_content": null}], "response_time": 1.13}', name='search', tool_call_id='tool_call_id_2')]}
4.3.接入LLM
# -*- coding:utf-8 -*-
import json
import os
import traceback
import requests
from langchain_core.messages import AIMessage
from langchain_core.tools import tool
from langchain_openai import ChatOpenAI
from langgraph.prebuilt import ToolNode
from pydantic import BaseModel, Field
from tavily import TavilyClient
gaode_api_key = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
gaode_domain = "https://restapi.amap.com/v3"
tavily_api_key = 'tvly-dev-xxxxxxxxxxxxxxxxxxxxxxxx'
openai_api_key = 'sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
os.environ["OPENAI_API_KEY"] = openai_api_key
class WeatherToolInput(BaseModel):
region: str = Field(description="地区,城市,例如:广州市")
@tool("get_weather", return_direct=True, args_schema=WeatherToolInput)
def get_weather(region:str):
"""根据传入的城市名查询天气"""
ad_code = None
try:
session = requests.session()
region_response = session.request(
method="GET",
url=f"{gaode_domain}/config/district?key={gaode_api_key}&keywords={region}&subdistrict=0",
headers={"Content-Type": "application/json; charset=utf-8"},
)
region_response.raise_for_status()
region_data = region_response.json()
if region_data.get("info") == "OK":
ad_code = region_data["districts"][0]["adcode"]
except:
traceback.print_exc()
return f"获取{region}代码失败"
try:
if ad_code:
weather_response = session.request(
method="GET",
url=f"{gaode_domain}/weather/weatherInfo?key={gaode_api_key}&city={ad_code}&extensions=all",
headers={"Content-Type": "application/json; charset=utf-8"},
)
weather_response.raise_for_status()
weather_data = weather_response.json()
if weather_data.get("info") == "OK":
forecasts = weather_data['forecasts']
result = json.dumps(forecasts, ensure_ascii=False)
print(f'result: {result}')
return result
return f"获取{region}天气预报信息失败"
except:
traceback.print_exc()
return f"获取{region}天气预报信息失败"
class SearchToolInput(BaseModel):
query: str = Field(description="待搜索内容,例如:广州为什么称为羊城?")
@tool("search", return_direct=True, args_schema=SearchToolInput)
def search(query):
"""根据传入的内容检索互联网信息"""
tavily = TavilyClient(api_key=tavily_api_key)
response = tavily.search(query=query)
return response
tools = [get_weather,search] # 将定义的工具放入列表中
tool_node = ToolNode(tools) # 使用工具列表初始化 ToolNode
if __name__ == '__main__':
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0, max_tokens=2048)
llm_with_tools = llm.bind_tools(tools)
result = tool_node.invoke({"messages":[llm_with_tools.invoke("广州最近天气如何?有什么适合游玩的地方吗?")]})
print(f'Final Answer: {result}')
调用结果:
Final Answer: {'messages': [ToolMessage(content='[{"city": "广州市", "adcode": "440100", "province": "广东", "reporttime": "2025-03-21 12:00:38", "casts": [{"date": "2025-03-21", "week": "5", "dayweather": "晴", "nightweather": "晴", "daytemp": "27", "nighttemp": "11", "daywind": "北", "nightwind": "北", "daypower": "1-3", "nightpower": "1-3", "daytemp_float": "27.0", "nighttemp_float": "11.0"}, {"date": "2025-03-22", "week": "6", "dayweather": "晴", "nightweather": "晴", "daytemp": "27", "nighttemp": "12", "daywind": "北", "nightwind": "北", "daypower": "1-3", "nightpower": "1-3", "daytemp_float": "27.0", "nighttemp_float": "12.0"}, {"date": "2025-03-23", "week": "7", "dayweather": "晴", "nightweather": "多云", "daytemp": "28", "nighttemp": "14", "daywind": "北", "nightwind": "北", "daypower": "1-3", "nightpower": "1-3", "daytemp_float": "28.0", "nighttemp_float": "14.0"}, {"date": "2025-03-24", "week": "1", "dayweather": "晴", "nightweather": "多云", "daytemp": "28", "nighttemp": "16", "daywind": "北", "nightwind": "北", "daypower": "1-3", "nightpower": "1-3", "daytemp_float": "28.0", "nighttemp_float": "16.0"}]}]', name='get_weather', tool_call_id='call_yZX2CJD0C6KN3JQ5tfaY9JI4'), ToolMessage(content='{"query": "广州适合游玩的地方", "follow_up_questions": null, "answer": null, "images": [], "results": [{"title": "来广州旅游一定要去的十五个景点 - 知乎", "url": "https://zhuanlan.zhihu.com/p/679862938", "content": "来广州旅游一定要去的十五个景点 - 知乎 首发于小可爱游记 切换模式 写文章 登录/注册 来广州旅游一定要去的十五个景点 小可爱游记 旅行、徒步(本人不删任何评论) 我最近在知乎上看到一条问题,问广州有什么景点推荐的。回答的都是什么白云山、上下九步行街、北京路、永庆坊……甚至还有推荐大夫山森林公园的。 真是看得我一肚子气! 拜托,这些回答问题的人能不能认真一点?他们推荐的这些所谓景点,只会浪费外地人的时间,并且让人留下“广州不过如此”的负面印象。我很怀疑这些人是否真的有在广州好好地旅游过?他们的回答是不是只是百度或者在小红书看到的? 我决定用心好好写一篇关于广州旅游和美食的文章,分两篇完成。我有这个资格。我在广东长大,对粤语文化比较了解;第二,广州的景点我差不多全部都去过了;第三,除了广州,国内很多地方我也去过。玩得多了,就懂得对比,知道如何筛选出精华。 首先说不该去的景点 一、白云山 白云山是5A级景区,是最名不副实的地方。风景简直可以用毫无特色、寡淡无味来形容。有些人会说站在山顶可以俯瞰整个广州市的容貌。天啊,白云山的山顶离市中心多远知道吗?能看到什么?拿望远镜看吗? 如果你本身去过许多名山大川,千万不要去白云山,去了一定会后悔。 这是我10年前在山顶拍的,你们说能看到什么? 白云山顶 广东好的山都在西北部,也就是韶关、英德和连州那一带。你们想一想,古往今来适合做都城的城市有什么特点?一是临江临河,便于物资运输发展商业。二是没有太多的高山阻隔,便于农业发展。中国是几千年的农耕文明,经济也主要靠农业。山多是无法发展农业的。所以,古往今来的省会城市都选择在临江临河并且山少的位置。广东也是多山的省,而广州市相较于其它城市,则算是山比较少的。有也是那种几十米到一两百米的山比较多。这种低海拔的山也不太有什么亮点。 二、上下九步行街以及北京路 这是曾经广州最出名的购物步行街,其实与其它城市的步行街没什么两样,并没有自己的特色。广州本地人或者长期生活在广州的人都不会去这里的。另外,广州好玩的地方那么多你不去,你去逛街? 三、陈家祠 你们现在看到的陈家祠,早已在那个疯狂畸形的年代被拆掉了。除了陈家祠,还有许许多多无价的文物古迹都在那个年代被暴力拆毁、烧毁了。如今看到的陈家祠是重建的,就好比武汉现在的黄鹤楼,根本不值得去的。当然 ,如果你打算在广州待一段时间,比如半个月,那可以去看看。 四、永庆坊 这也是新改造过的具有岭南特色的一个景点,但是,广州有比这里更具岭南特色的景点,我后面会介绍,这里不必去。 五、石室圣心大教堂 如果你没有宗教信仰,不信耶稣不信上帝,这里根本不值得一去,就是一个宗教教堂而已。 来广州必游的十五个景点 如果你打算来广州旅游,请做好一份最少请10天长假的准备。因为广州与你以往印象中的城市不一样,广州是一个非常大的城市,并且,由于历史悠久,文化底蕴也很浓厚,值得游玩的地方非常多。 一、中山纪念堂+越秀公园+南越王墓博物馆 越秀公园与南越王墓博物馆只隔着一条马路,可以一天游完。而越秀公园是被严重低估的一个公园。里面有旧时广州的形象代表“五羊石雕”,19世纪末德国制造、中国购买用来抗敌的大炮,中山纪念碑和中山纪念堂。还有明朝时期建成的古建筑“镇海楼”,如今叫广州博物馆,里面存放着不少文物古迹。 下面是10年前用手机拍的相片,清晰度和技术很渣,轻喷! 19世纪末德国生产的大炮 不得不佩服当时的德国技术,157年过去看上去还很新 19世纪中期清军生产的铸铁跑 1867年重建的石牌坊 上世纪80年代生产的公交车 1380年建成的镇海楼,如今叫广州博物馆 明代城墙 这个大树的根已经嵌入了600年历史的城墙里 五羊石雕(广州最有名的形象代表) 广州博物馆部分藏品: 东汉:水晶玛瑙珊瑚珠串 清朝乾隆年:錾胎珐琅金鼎 清代:黑漆描金银彩绘人物故事图折扇 民国:黑色绸绣花卉纹披肩 清朝:真丝地流苏罩衣 清朝:浑天仪 清朝:镀金铜胎珐琅花卉瓶钟 明朝:陶俑 宋朝:水军广州修城砖 清朝:七政仪 如果你精力旺盛,不嫌累,顺便去一趟旁边的“南越王墓博物馆”。什么叫南越王呢?就是大约在2000年前,如今的广东省、广西省以及越南一带被一个叫赵佗的汉人征服了,他自封为王,成立了一个新的国家,叫“南越国”。这个国家存在的时间不到一百年就被汉朝灭了。赵佗的墓地直到1983年才被发现。里面保存着大量2000年前的古文物,有武器,生活器具,饰品等等,很值得来游览参观。 越秀公园+南越王墓博物馆游玩建议:在地铁“纪念堂站”下,从中山纪念堂开始游玩,一直走上去就是越秀公园。越秀公园的重点是镇海楼,也就是广州博物馆,门票是10元。可以扫码购票,也可以现金支付购票。如果你想拿纸质票,扫码完之后也可以叫售票员再给你一张纸质票留作纪念。中山纪念堂和越秀公园玩完,大概需要花4个小时。 中午吃饭:可以到中山纪念堂旁边的“广东大厦”,里面也有正宗的粤菜餐厅。这个广东大厦也有37年的历史 ,是1987年建成的,之前叫广东省人民政府第一招待所。如果你不想踅回来,也可以在越秀公园的正门出去,步行至不远处的“北园酒家”。这家也是广州市最顶级的粤菜酒楼之一,创办至今已经96年历史了,也算是名胜古迹之一。吃个饭,顺便把名胜古迹也看了,多划算。 中午吃完饭,休息一会,下午再去南越王墓博物馆。 注意事项:南越王墓博物馆周一闭馆 二、长隆野生动物世界 中国最大动物园,也是亚洲最大动物园。占地面积达到了惊人的2000多亩。早上9点钟进,下午17点也未必能游览完。这么好的动物园,门票只要350元,真的是很良心价的。 我觉得这里不但是来广州的必游地之一,我甚至敢这样评价,这绝对是外国人来中国旅游必去的景点之一。很多动物园的生存空间极为狭窄,看见不免心生怜悯,好想放它们出来。但是长隆野生动物世界的里面的动物活动空间非常大,而且里面竟然养了十多只熊猫。 长隆野生动物世界是禁止游客自带食物和水进去的。这个我完全能理解。毕竟要养这么多动物,肯定需要顾客多消费才能维持开支。 里面的动物品种太多了,一天时间大概是看不完的。我筛选几张之前拍的相片,技术不好,轻喷。 吃竹笋 它发现我了 趴在冰块上降温 这是啥猴? 猴子下水捞游客投的食物 环尾狐猴 鸵鸟在监工 犀牛,最重可达3吨 大象 卿卿我我的老虎 白虎 老虎幼崽 食蚁兽,我开始分不清头尾 非常温顺的黄金蟒 树懒,一分钟可以爬行3米 看上去很假的鹦鹉 八哥 巨嘴鸟 与树枝颜色融合的猫头鹰 这张图有几种动物? 马来貘 长颈鹿和缆车 斑马和角马 牦牛和骆驼 这是羚羊吗? 狮群 奔跑速度达到100公里的猎豹 黑天鹅与某种鹤 非洲兄弟在表演 非洲姐妹在表演 三、长隆欢乐世界 我一般不太推荐游乐场所,但是,长隆是例外,因为这里真的非常好玩,有很多刺激的大型设备和惊险的杂技表演。而且它的门票不贵,只要200多元,太便宜了。要知道,现在去餐厅吃顿饭都要几百元。 下面是我10年前用手机拍的,清晰度和技术不好,轻喷。 过山车,好刺激,有些女孩子哭了,我笑了 大摆锤,这个也刺激 跳楼机,这个也爽 这个叫什么忘记了,也很舒服 鬼屋 我在亲吻一具骷髅的右手 非洲兄弟在表演 身材很好的姐姐表演杂技 欧洲兄弟姐妹在表演 四、长隆水上乐园 这里被评为全球前20名最佳水上主题公园之一。如果你是夏天来,那么可以到这里游玩。5月份到10月份都适合来。广州的10月份依然要穿短袖和开冷气。 我是2012年去的,相片找不到了。如果你们喜欢玩水,就一定要来这里。中国没有比这里玩水更好的公园了。 五、长隆国际大马戏 这不但是中国最大的马戏团,同时也是全世界最大的马戏团。我敢这么说,这绝对是人生中必看的马戏团表演之一。夜晚表演的各种马戏和魔术表演,我只能用“震撼”两字来形容。门票是350元,那些什么歌星的演唱会动不动就上千元,还不及长隆国际大马戏带给你的震撼深刻。 这个我也是2012年去的,可惜当时的手机被偷了,保存在里面的相片也没有了。 游玩长隆系列公园的建议:最少要给长隆系列准备三天时间。第一天去长隆欢乐世界,第二天长隆野生动物世界,第三天长隆水上乐园,夜晚去看长隆大马戏。为什么选择第三天看大马戏?因为玩水不怎么消耗体能。 六、广州塔 广州塔更响亮的名字叫“小蛮腰”,总高600米,目前中国最高的塔。上面有世界上最高的旋转餐厅、世界上最高的摩天轮、世界上最长的螺旋式空中云梯等等。 我10年前去的门票价格是228元,摩天轮票价是98元,一共326元。我刚刚查了一下,这里居然没有涨价,真是很良心的。这里是实名购票的,所以一定要带身份证,超过75岁不让玩摩天轮。 站在上面可以俯瞰整个广州最繁华地段的灯火璀璨的夜景,还能清晰地看到浪漫的珠江以及江上的几座大桥。要欣赏夜景,没有比来小蛮腰更合适的地方了。 下面是我10年前用手机拍的,清晰度有点渣渣,轻喷:", "score": 0.84027237, "raw_content": null}, {"title": "广州60个好玩的地方,总有一个打动你!(值得收藏) - 知乎", "url": "https://zhuanlan.zhihu.com/p/679150033", "content": "广州60个好玩的地方,总有一个打动你!(值得收藏) - 知乎 切换模式 写文章 登录/注册 广州60个好玩的地方,总有一个打动你!(值得收藏) 祯祯 广州这座城市,有很多好玩的,想拍文艺照就去红砖厂,想品位老广州建筑就去西关,想感受异国建筑风情就去沙面,想轻奢就去太古汇…… 所以今天的文章,是来告诉大家,广州好玩的地,多到数不过来啊,下面我按各区,一一说来。 天河区 01、广东树木公园 天河这个小森林,90%的老广都不知道 安静、舒适、空气清新,置身其中满是惬意 02、方所 每次路过总忍不住进去逛逛 每次逛完少不了淘上几本心水读物 在方所,时间真的会慢下来 03、广州保龄球馆 叹着空调玩的保龄球,不比飞盘香吗? 价格实惠、解压、零基础也能玩 悄悄再说一句,保龄球馆超好出片 04、广州图书馆 每逢节假日,广图就挤满人 不过这里能看书 还能吃饭、借CD、健身,也难怪大家都爱去 05、华南植物园 硕大的植物园,逛足一天也不会腻, 待秋色更浓,这里会更美。 06、广州大剧院 位于新中轴线上的广州大剧院 整体以黑白灰为主调,外观未来感十足 在外墙随意摆造型,大片秒出 越秀区 01、华侨新村 广州漫画村,就藏在华侨新村 有历史悠久的洋楼建筑,还有各式涂鸦壁画 这里就像一个巨大的街头艺术画廊 02、花园酒店博物馆 现在去花园酒店,还可以逛博物馆了! 内里记载着广州酒店发展史 来此逛逛,不失为一种了解广州的新方式 03、一方东山 如今广州最潮的地方,莫过于此 多少潮牌、买手店、咖啡店进驻 让这里的潮流氛围只增不减 04、广州动物园 每位广州人的童年专属记忆 20元的门票就能收获一整天的快乐 05、越秀公园-仲元楼 全广州独一无二的蝴蝶楼梯 让来仲元楼打卡的人一拨又一拨 06、省港大罢工纪念馆 藏在市中心的一个红色景点 不仅是拍照圣地 内里还蕴藏了很多历史文化,可以一并学习一下 07、沿江西路 沿江西一带的建筑群,散发着浓浓西洋味 漫步其中,别忘了细品这里的历史文化故事 08、流花湖公园 波光粼粼的湖面 倒映着极具欧式风情的“小白宫” 多少摄影爱好者为之而驻足 09、陈家祠 我们总是匆匆而过的陈家祠 以其精湛设计,被称为“岭南建筑艺术明珠” 趁着假期,不妨进去好好欣赏一番 10、惠吉西 欧式小洋楼+民国风情 中西合璧的元素,让人一秒穿越回上世纪 11、农讲所 红墙绿瓦,这里是广州的“小故宫” 藏身于闹市,逛完还能继续在老城区游玩 12、麓湖公园 作为市中心的世外桃源,深得街坊的喜爱 绿树成荫、园林瀑布...就算每天去都会有新感觉~ 海珠区 01、江南西日系社区 就在万国对面,这个宝藏社区还很少人知道 风格各异的小店林立 短短几百米,能逛足几小时 02、工美港 靠着一只9米高的巨兔出圈 工美港还有哪位潮人没去过! 03、南泰批发市场 从前爸爸妈妈爱去的批发市场 现在连小年轻也扎堆去 新旧魅力的碰撞,太建议去一次了 04、御溪书斋 星空下的藏书阁,超浪漫~ 这里面积不大,但设计十分出彩 走进里面,除了震撼还是震撼 05、水博苑 琶洲塔下大隐隐于市的中式园林 一个以水为主题的公园,小众但好逛 06、海珠同创汇 位于海珠湖旁,小蛮腰近在咫尺 园区内吃喝玩乐一条龙 想不到去哪玩,来这里就对了 07、晓西社区 太羡慕住在晓西社区的街坊了 每天都像误入了宫崎骏的漫画世界 商业区&居民区和谐融合 08、小洲村 昔日的文青聚集地,早已趋于平静 标志性的小洲村礼堂依旧是大家来到的打卡点 无需做攻略,随心逛也能收获一趟不错的旅程 09、海珠湿地公园 花城广州,自然少不了看花 海珠湖的花海不定期更新,逛公园之余还能赏花 荔湾区 01、粤剧艺术博物馆 这里是粤剧艺术气息最浓厚的地方 不但能现场欣赏粤剧表演,还能参观粤剧藏品 老一辈一定会喜欢这里 02、珠江钢琴·创梦园 满是音乐元素的创意园 N多个打卡点,光是拍照就要用掉半天 03、泮塘五约 西关风情和文艺气息并存", "score": 0.77405477, "raw_content": null}, {"title": "2025.2广州旅游攻略| 本地人含泪整理,全是避坑大实话!!吃住行避坑看这篇就够了! - 知乎", "url": "https://zhuanlan.zhihu.com/p/24509691049", "content": "2025.2广州旅游攻略| 本地人含泪整理,全是避坑大实话!!吃住行避坑看这篇就够了! - 知乎 首发于木鸟短租-旅游攻略 切换模式 写文章 登录/注册 2025.2广州旅游攻略| 本地人含泪整理,全是避坑大实话!!吃住行避坑看这篇就够了! 木鸟民宿\u200b 已认证账号 作为一个在广州生活过几年的“新广漂”,看着网上那些过时的旧攻略,实在没忍住!结合本地朋友的推荐和实际体验,整理了这份份兼顾经典景点、小众体验和美食打卡的广州攻略,写给2-3月打算去广州旅游的知友。 2-3月实用Tips 交通:地铁+共享单车最方便,微信小程序“羊城通”刷码乘车。 住宿:推荐住北京路或珠江新城附近,景点集中且夜生活丰富。 天气:2月广州温差大,白天单衣+薄外套,晚上加件毛衣。 广州三日游行程安排: Day 1:广州塔-陈家祠-珠江夜游 Day 2:沙面岛-石室圣心大教堂-一德路-上下九步行 Day 3:黄埔古港-广东省博物馆-珠江新城夜景 Day 1:广州塔-陈家祠-珠江夜游 想要登上小蛮腰的友友看过来,早上早上9点半前到,避开人流,先登塔俯瞰全城。千万别打车,早高峰堵到怀疑人生!坐地铁3号线广州塔站B口直达。不想登塔的就亮灯以后来!夜景很美好! 下午去陈家祠,直接地铁1号线陈家祠站A口,步行3分钟。屋顶的灰塑、砖雕,一砖一瓦都是岭南建筑的展示,记得蹭讲解了解一下会更有意思! 晚上珠江夜游选“天字码头”的航线,夜景最经典,船票提前在公众号买(推荐19:30班次,两岸灯光全开),在甲板上拍照更出片哦~ Day 2:沙面岛-石室圣心大教堂-一德路-上下九步行 上午打卡沙面岛,假装在欧洲!地铁6号线沙面站A口出来,在走5分钟就到了!黄墙绿树的洋楼、复古咖啡馆,随便一拍都是电影感。 下午石室圣心大教堂+一德路。注意石室圣心大教堂周一不开放!结束后逛一德路干货街逛逛,可以带点瑶柱、虾干当手信 晚上去上下九步行街,每个城市都有一个出名的商业街!这里的“南信牛奶甜品”的双皮奶、“陈添记”的鱼皮,街边牛杂摊一定别错过! Day 3:黄埔古港-广东省博物馆-珠江新城夜景 上午黄埔古港,地铁5号线到黄埔客运港站,转公交229路到黄埔古港站。这里是广州海上丝绸之路起点,逛古港遗址、吃艇仔粥,好像穿越到了古代! 下午广东省博物馆,APM线大剧院站B口,步行5分钟。重点看“海洋馆”和“潮州木雕展”。提前预约,免费参观,周一闭馆! 晚上珠江新城夜景海心沙公园看广州塔灯光秀(19:00-22:00),花城广场的“广州大剧院”和“图书馆”夜景也很绝。 广州美食红黑榜 ✅必吃清单 早茶:点都德(红米肠、虾饺)、陶陶居(冰镇咕噜肉),人均60元吃到撑913。 烧腊:“炳胜品味”的叉烧,肥而不腻,入口即化! 糖水:“百花甜品店”的凤凰奶糊、“沙湾姜撞奶”热乎暖胃。 街边小吃:宝华路的“顺记冰室”椰子雪糕、西华路的“腾元生煎”爆汁生煎包。 ❌避雷提示 北京路步行街的“网红店”慎选,排队久且味道一般。 凉茶别乱喝!癍痧凉茶苦到怀疑人生,建议从“罗汉果茶”入门。 广州民宿推荐 推荐:【塔宿珍品】 3.8米超大飘窗采光十足,依靠在床沿迎着落日的暖阳配上一杯下午茶,可将城中美景尽收眼底。晚上的时候看出去就能看到广州塔。房源位于繁华的黄埔佳纷天地广场,紧邻南岗万达。巨幕投影、洗衣机、干湿分离卫生间、厨房用品,房间内一切都齐全,床品舒适! 民宿都有自己的专属代码 \\\\in9209952\\\\ni ,可以住俩人。 【木鸟民宿】...Ãpp上“馊”这7位数的代码轻松get房源,设施齐全,床品舒适! 希望这份攻略能帮你玩转广州!如果时间充裕,还可以去长隆欢乐世界玩一玩,广州本地的朋友刷到可以在评论区留下一些本地人建议~ 喜欢记得关注我,我是木鸟民宿APP!旅游在外住民宿别忘了木鸟民宿APP!各种不同价位和风格的民宿可以选择~ 相关推荐: 木鸟民宿:2025青岛旅游全攻略:一年去了5次青岛!全都是避坑大实话+超实用攻略!!写给2-3月去青岛的知友! 木鸟民宿:2025成都旅游全攻略:一年去了5次成都!全都是避坑大实话+超实用攻略!!写给2-3月去成都的知友! 发布于 2025-02-18 15:18・IP 属地河北 内容所属专栏 木鸟短租-旅游攻略 景点、美食、交通、住宿,一个攻略满足你!持续更新~ 订阅专栏 广州旅游 广州旅游攻略 广州生活 \u200b赞同 1\u200b\u200b添加评论 \u200b分享 \u200b喜欢\u200b收藏\u200b申请转载", "score": 0.62000114, "raw_content": null}, {"title": "广州市 10 大景点玩乐 - Tripadvisor", "url": "https://cn.tripadvisor.com/Attractions-g298555-Activities-Guangzhou_Guangdong.html", "content": "广州市景点玩乐:在Tripadvisor上查看中国广州市景点玩乐相关点评和照片。", "score": 0.55709904, "raw_content": null}, {"title": "赶快收藏!广州周末漫游秘籍,10个好玩的地方,再也不怕\\"周末荒\\"了_腾讯新闻", "url": "https://news.qq.com/rain/a/20250321A00KK100", "content": "图片来源@新叶 你上一次静静的欣赏广州是什么时候? 在广州打拼的人们 平时总是行色匆匆 根本没有时间静下心来 好好的欣赏这座城市 这个周末", "score": 0.4338141, "raw_content": null}], "response_time": 1.29}', name='search', tool_call_id='call_I7q8R4mThO6Hq1tpY4xAknrQ')]}
五、附带说明
5.1.tavily集成LangChain的使用方式
@tool("search", return_direct=True, args_schema=SearchToolInput)
def search(query):
"""根据传入的内容检索互联网信息"""
os.environ["TAVILY_API_KEY"] = 'tvly-dev-xxxxxxxxxxxxxxxxxxxxxxxxxx'
retriever = TavilySearchAPIRetriever(k=3)
response = retriever.invoke(query)
return response
更多推荐
所有评论(0)