# 谷歌实时信息搜索插件的集成与编写
# 01. Serper谷歌搜索
谷歌官方虽然提供了 API 搜索功能,但是体验感并不好,而且访问速度非常慢,所以在这里我们考虑使用第三方的谷歌搜索提供商——Serper,Serper 提供的谷歌搜索会在后台浏览器模拟真实的页面运行,完全模仿人类的操作,可以确保获得用户真正看到的内容(目前体验测试来看,Serper 比谷歌官方提供的检索服务内容更全面,响应速度更快)。
参考资料:
LangChain Serper 谷歌搜索集成:https://imooc-langchain.shortvar.com/docs/integrations/tools/google_serper/
Serper 官网:https://serper.dev/
可以使用任意的邮箱/Github/Google账号注册登录 SerperAPI 官网, 并管理和创建 API 秘钥,将其配置到环境变量中,如下:
# 谷歌Serper搜索
SERPER_API_KEY=9b5bd82f638b1e51a9bf14802a0a2799286b194e
2
在 LangChain 中,已经为 Serper 搜索接口进行了工具的封装,目前有两个内置工具: GoogleSerperRun、GoogleSerperResults ,其中 GoogleSerperRun 会单纯返回搜索文本的内容,而 GoogleSerperResults 还会包含检索网页链接等元数据。
不过 LangChain 封装的 GoogleSerperRun 工具内部并没有添加 工具参数说明 ,并且 工具描述 也是英文的,对于一些参数量比较小,需要将其相应的描述等改成中文情景。
另外 Serper谷歌搜索 还有一个很接近的工具—— SerpAPI ,这两个产品在名字和功能上非常接近,而且也特别容易弄混,该工具在 LangChain 中也进行封装,参考资料:
LangChain SerpAPI 谷歌搜索集成:https://imooc-langchain.shortvar.com/docs/integrations/tools/serpapi/
SerpAPI 官网:https://serpapi.com/
# 02. 谷歌实时信息搜索工具实现
在 LangChain 中,实现对 GoogleSerperRun 工具的二次封装其实非常简单,甚至不需要重新定义一个工具类,只需要在实例化的时候,传递对应的参数即可,示例如下:
import dotenv
from langchain_community.tools import GoogleSerperRun
from langchain_community.utilities import GoogleSerperAPIWrapper
from langchain_core.pydantic_v1 import BaseModel, Field
class GoogleSerperArgsSchema(BaseModel):
query: str = Field(description="执行谷歌搜索的查询语句")
dotenv.load_dotenv()
google_serper = GoogleSerperRun(
name="google_serper",
description=(
"一个低成本的谷歌搜索API。"
"当你需要回答有关时事的问题时,可以调用该工具。"
"该工具的输入是搜索查询语句。"
),
args_schema=GoogleSerperArgsSchema,
api_wrapper=GoogleSerperAPIWrapper(),
)
print(google_serper.invoke("马拉松的世界记录是多少?"))
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
输出示例:
2004年1月1日,国际田联宣布,马拉松开始拥有世界纪录。 2023年10月8日晚(北京时间),在芝加哥马拉松比赛中,肯尼亚人基普图姆在芝加哥马拉松比赛中以2小时00分35秒的成绩打破基普乔格保持的世界纪录。
# 最新版 LangChain 用法提示
新版 LangChain 更推荐用 LCEL、
Runnable、ChatModel.bind_tools()、结构化输出和 LangGraph 来组织复杂链路;老式Chain、部分AgentExecutor写法可以读懂,但新项目应优先选择更清晰的图或 Runnable 编排。工具调用相关代码要区分两层:模型是否原生支持 tool/function calling,以及业务侧如何定义工具 schema、参数校验、错误兜底和观测日志。
如果示例中的导入路径和你当前安装版本不同,优先查当前版本包内导出位置;常见迁移方向是从
langchain拆到langchain-core、langchain-community、langchain-openai、langgraph等包。
# 拓展
工具或插件不要只看能不能调通,更要看是否可观测、可限流、可重试、可审计。联网类工具还要处理超时、空结果、搜索噪声和结果时效性。
Agent 场景里,Prompt 只是调度策略的一部分;工具描述、参数 schema、历史状态、错误反馈、停止条件和人工介入点同样会影响最终稳定性。
# 常见问题
为什么模型没有调用工具?常见原因是工具描述不清晰、参数 schema 过宽或过窄、用户问题不需要工具、模型本身不支持工具调用,或者工具绑定位置不对。
为什么工具调用后回答仍然不准?先看工具返回是否正确,再看工具结果是否被放回模型上下文,最后检查输出解析、历史消息和异常兜底是否覆盖了真实错误。
# 面试题
解释函数调用、工具调用和 Agent 的区别。
LangChain 中 tool schema 的作用是什么?为什么参数校验对生产环境很重要?
ReACT Agent 和 tool-calling Agent 的核心差异是什么?分别适合什么场景?
LangGraph 相比 LCEL 更适合解决哪些复杂编排问题?
# 生产问题排查
| 问题 | 常见原因 | 处理方式 |
|---|---|---|
| 工具没有被调用 | 工具描述弱、绑定失败、模型不支持 | 打印绑定后的模型配置,补充工具描述,换用支持工具调用的模型 |
| 参数格式错误 | schema 设计不清晰,模型生成字段不稳定 | 使用 Pydantic/JSON Schema 校验,失败后把错误反馈给模型重试 |
| 联网结果不可用 | 搜索为空、接口超时、命中低质量页面 | 增加超时、重试、结果过滤、来源白名单和降级回答 |
| Agent 循环不停止 | 缺少终止条件或工具返回被误判 | 设置最大迭代次数,记录每轮 thought/action/observation,增加停止规则 |
| 线上难以复现 | 缺少输入、工具请求和模型响应日志 | 给每次调用加 trace id,记录工具入参、出参、耗时和异常 |