为Hermes智能体集成Brave Search实时搜索插件:本地大模型联网实践
1. 项目概述与核心价值最近在折腾本地大模型应用特别是想让它们能“联网”获取实时信息而不是只依赖训练时那个“陈旧的知识库”。试过不少方案比如让模型自己写代码去爬取或者集成一些通用的搜索API但总感觉要么太笨重要么不够稳定。直到我发现了 Hermes 这个框架以及围绕它构建的插件生态才算是找到了一个优雅的解法。今天要聊的这个hermes-brave-search-plugin就是一个专门为 Hermes 智能体Agent接入 Brave Search 实时搜索能力的插件。简单来说它给你的本地大模型装上了一双“眼睛”让它能直接看到互联网上最新的信息。这个插件本身并不复杂核心就是注册一个名为brave_web_search的工具Tool并将其打包成一个名为brave-search的工具集Toolset。当你为某个对话平台比如命令行、Web界面启用这个工具集后运行在该平台上的 Hermes 智能体就能在需要时调用 Brave Search 的 API 去查询实时网页信息并把结果整合到它的思考和回答中。这解决了本地模型最大的痛点之一——信息滞后。无论是查询最新的新闻、股价、体育赛事结果还是查找某个刚刚发布的技术文档它都能胜任。这个项目特别适合两类朋友一是已经在使用 Hermes 框架构建智能体应用的开发者你们可以快速为应用增添强大的实时信息检索能力二是对 AI 智能体Agent和工具调用Tool Calling机制感兴趣的学习者通过剖析这个轻量级但功能完整的插件你能清晰地理解一个工具是如何被定义、注册并最终被模型调用的完整链路。接下来我会带你从设计思路到实操部署完整地走一遍这个插件的“里里外外”。2. 核心设计思路与方案选型2.1 为什么选择 Brave Search API在决定为 Hermes 集成搜索能力时市面上可选的后端不少比如 Google Custom Search JSON API、SerpAPI、DuckDuckGo Instant Answer API 等等。但这个插件作者选择了 Brave Search API我认为背后有几个很实际的考量。首先是隐私与独立性。Brave 浏览器本身就以隐私保护著称其搜索 API 也延续了这一理念承诺不追踪用户、不构建个人档案。对于部署在本地、处理可能包含敏感信息查询的智能体应用来说选择一个更注重隐私的搜索服务提供商在心理和合规层面都更让人安心。其次Brave Search 是一个相对独立的搜索引擎不像某些 API 只是大厂搜索的代理这在一定程度上避免了商业政策突然变动导致服务不可用的风险。其次是API 的简洁性与成本。Brave Search API 的设计非常 RESTful 和直观返回的结构化数据JSON干净利落包含了网页标题、摘要、链接等关键信息没有过多冗余的广告或杂项。这对于需要从搜索结果中快速提取关键信息喂给大模型的场景来说减少了大量的数据清洗工作。在成本方面Brave Search API 提供了一定的免费额度对于个人开发者或中等使用频率的场景非常友好避免了初期就需要绑定信用卡的麻烦。最后是结果质量。经过我个人实测Brave Search 的搜索结果质量在多数通用领域和部分技术领域都相当不错能够返回相关且信息量充足的链接。这对于智能体获取有效信息至关重要。综合来看在隐私、易用性、成本和效果之间Brave Search API 找到了一个不错的平衡点成为这个插件的首选后端也就不足为奇了。2.2 Hermes 插件机制解析要理解这个插件如何工作必须先搞懂 Hermes 框架中“插件”Plugin和“工具”Tool的概念。Hermes 是一个用于构建和运行基于大模型的对话智能体Agent的本地框架。它的一个强大特性是支持“工具调用”即智能体可以根据对话上下文自主决定调用某个外部工具如计算器、搜索、查数据库来获取信息或执行操作然后将工具结果融入后续的回复中。“插件”在 Hermes 中就是一个封装了一个或多个相关“工具”的模块化包。它提供了一种标准化的方式来打包工具代码、配置清单和依赖使得工具的安装、启用和管理变得非常方便。一个典型的 Hermes 插件目录结构就像本项目展示的那样plugin.yaml: 插件的“身份证”和“说明书”定义了插件元数据、依赖的环境变量等。schemas.py: 定义了工具的“调用规范”。这里用 Pydantic 模型描述了brave_web_search工具需要什么参数比如查询关键词以及返回的数据结构。这个 schema 会暴露给大模型模型据此来知道如何调用这个工具。tools.py: 工具的“大脑”和“双手”。这里包含了实际的 API 调用逻辑接收参数调用 Brave Search API处理响应并返回格式化的结果。__init__.py: 插件的“接线板”。它负责将定义好的工具注册到 Hermes 的插件系统中。install.sh: 一键安装脚本方便用户部署。这种设计的好处是解耦和复用。工具的实现细节被隐藏在插件内部Hermes 核心框架只关心如何发现和调用这些符合规范的工具。开发者可以专注于编写单个工具的逻辑而用户可以通过简单的配置选择性地为不同的对话场景平台启用不同的工具集灵活性极高。3. 插件部署与配置实战3.1 环境准备与前置条件在开始安装插件之前我们需要确保基础环境已经就绪。首先你必须在你的系统上已经安装并成功运行了Hermes。你可以通过其官方仓库的 README 进行安装。通常使用 pip 安装是最简单的方式pip install hermes-agent。安装后建议先运行hermes --version确认安装成功并运行hermes tools list查看当前可用的工具集这会帮助你熟悉 Hermes 的基本操作。其次也是最关键的一步是获取Brave Search API 密钥。这个插件本身不提供搜索服务它只是一个“桥梁”真正的搜索能力需要你去 Brave 官方申请。访问 Brave Search API 官网 。点击注册或登录通常可以使用 GitHub 或 Google 账户快速关联。在控制台Dashboard中你应该能找到创建新 API 密钥的选项。创建一个新的密钥并妥善保存。这个密钥通常是一长串由数字和字母组成的字符串。重要Brave Search API 有免费 tier但通常有每日或每月的调用次数限制。请务必在控制台查看你的额度和使用条款避免超限导致服务中断。拿到 API 密钥后你需要将其设置为环境变量。这是插件在运行时读取配置的标准方式避免了将敏感信息硬编码在代码中。# 在 Linux/macOS 的终端中将以下命令中的 YOUR_API_KEY_HERE 替换为你的真实密钥 export BRAVE_API_KEYYOUR_API_KEY_HERE # 为了让这个环境变量在每次打开终端时都生效可以将其添加到你的 shell 配置文件中如 ~/.bashrc, ~/.zshrc echo export BRAVE_API_KEYYOUR_API_KEY_HERE ~/.zshrc source ~/.zshrc在 Windows 系统上你可以在命令提示符中使用set命令临时或在系统属性中设置用户环境变量永久# 命令提示符临时 set BRAVE_API_KEYYOUR_API_KEY_HERE # PowerShell临时 $env:BRAVE_API_KEYYOUR_API_KEY_HERE设置完成后可以在终端中执行echo $BRAVE_API_KEY(Linux/macOS) 或echo %BRAVE_API_KEY%(Windows cmd) 来验证是否设置成功。3.2 两种安装方式详解项目提供了两种安装方式一键安装和手动安装。我强烈建议初学者使用一键安装它更省心而手动安装则有助于你理解插件的文件结构方便后续的定制或调试。方案一一键安装推荐这是最快捷的方式。只需要在终端中执行项目提供的那条命令curl -fsSL https://raw.githubusercontent.com/rabilrbl/hermes-brave-search-plugin/main/install.sh | bash这条命令做了以下几件事curl -fsSL从指定的 URL 安全地下载install.sh脚本的内容。-f表示静默失败-s表示静默模式-S表示显示错误-L表示跟随重定向。| bash将下载的脚本内容通过管道传递给bash解释器执行。脚本内部逻辑我们可以查看其内容来理解在 Hermes 的配置目录通常是~/.hermes/下创建plugins-src/brave-search目录。使用git clone将插件仓库克隆到该目录。在~/.hermes/plugins/目录下创建一个指向源码目录的符号链接symlink。Hermes 在启动时会扫描plugins/目录来发现插件。注意使用curl ... | bash这种模式时从安全角度出发你应该对来源有一定的信任。最好能先查看一下install.sh脚本的内容直接访问那个 URL确认它没有执行危险操作如rm -rf等。本项目脚本内容清晰是安全的。方案二手动安装手动安装步骤清晰适合喜欢掌控一切或网络环境特殊的用户。# 1. 克隆插件仓库到 Hermes 的插件源码目录 git clone https://github.com/rabilrbl/hermes-brave-search-plugin.git ~/.hermes/plugins-src/brave-search # 2. 创建符号链接使 Hermes 能识别此插件 ln -sfn ~/.hermes/plugins-src/brave-search ~/.hermes/plugins/brave-search这里有两个关键目录~/.hermes/plugins-src/: 建议用来存放插件源码便于管理和更新。~/.hermes/plugins/: Hermes 实际加载插件的目录。通过符号链接我们可以让多个“源”指向同一个“目标”保持源码独立的同时完成安装。执行完上述任何一组命令后你可以通过ls -la ~/.hermes/plugins/查看是否有一个名为brave-search的链接指向了源码目录。3.3 在 Hermes 中启用与验证插件安装完成并不意味着插件立刻生效。我们需要在 Hermes 中显式地为某个“平台”Platform启用这个插件提供的工具集。列出可用工具集首先查看插件是否被正确发现。hermes tools list在输出列表中你应该能看到一个名为brave-search的工具集其下包含brave_web_search工具。启用工具集Hermes 支持多个前端平台如cli(命令行)、web(网页界面) 等。你需要决定在哪个平台上启用搜索功能。例如为命令行平台启用hermes tools enable cli brave-search这条命令的含义是在cli这个平台上启用brave-search这个工具集。重启 Hermes 服务任何工具集的启用或禁用更改都需要重启 Hermes 服务才能生效。如果你是在开发模式直接运行hermes命令直接退出后重新启动即可。如果 Hermes 是作为后台服务运行例如通过 systemd 或 docker则需要重启对应的服务。功能验证重启后启动一个与 Hermes 的对话例如在命令行输入hermes进入交互模式。然后尝试问一个需要最新信息的问题例如“今天北京天气怎么样”“特斯拉最新的股价是多少”“帮我搜索一下‘如何用Python解析JSON’的最新教程。” 观察 Hermes 的回复。如果插件工作正常你应该能在回复中看到它提及“我搜索了一下网络”或类似表述并且给出的信息是新鲜和准确的。你也可以在 Hermes 的详细日志中如果日志级别足够高看到它调用brave_web_search工具并接收返回结果的记录。4. 插件核心代码深度剖析仅仅会用还不够理解其内部实现能让你在出问题时快速排查甚至进行定制化修改。我们来深入看看插件最核心的几个文件。4.1 插件清单plugin.yaml这个文件是插件的入口点Hermes 首先读取它。# 这是一个示例结构具体内容可能随版本更新 name: brave-search version: 0.1.0 description: A plugin to add Brave Search web search capability to Hermes. author: rabilrbl env: - BRAVE_API_KEY toolsets: brave-search: - brave_web_searchname和version: 插件的标识。description和author: 描述信息。env:至关重要。这里声明了本插件运行所必需的环境变量列表。Hermes 在加载插件时会检查这些变量是否已设置如果BRAVE_API_KEY缺失插件加载可能会失败或工具无法正常工作。toolsets: 定义了本插件提供的工具集。这里定义了一个名为brave-search的工具集其中包含一个工具brave_web_search。这个名称与后续代码中的工具名必须对应。4.2 工具契约schemas.py这个文件使用 Pydantic 模型定义工具的输入和输出格式这是大模型能正确调用工具的关键。from pydantic import BaseModel, Field from typing import List, Optional class BraveWebSearchInput(BaseModel): query: str Field(descriptionThe search query string to send to Brave Search.) class BraveWebSearchResult(BaseModel): title: str url: str snippet: Optional[str] None # 摘要可能为空 class BraveWebSearchOutput(BaseModel): results: List[BraveWebSearchResult] Field(descriptionA list of search results.)BraveWebSearchInput: 定义了调用brave_web_search工具时需要传入的参数。这里只有一个query字段描述清晰告诉模型“你需要给我一个查询字符串”。BraveWebSearchResult和BraveWebSearchOutput: 定义了工具返回的数据结构。返回一个包含多个结果的列表每个结果有标题、链接和摘要。这个结构化的输出便于模型理解和提取信息用于构建最终的回答。为什么需要 Schema大模型如 GPT在决定调用工具时需要精确知道工具的“函数签名”。这个 Schema 就是函数的类型提示它让模型知道“我需要提供一个字符串参数query然后我会收到一个results列表”。没有这个模型就无法正确生成工具调用的请求。4.3 工具实现tools.py这是插件的“引擎室”包含了实际的网络请求和数据处理逻辑。import os import requests from typing import List from .schemas import BraveWebSearchInput, BraveWebSearchOutput, BraveWebSearchResult def brave_web_search(input_data: BraveWebSearchInput) - BraveWebSearchOutput: Perform a web search using the Brave Search API. api_key os.getenv(BRAVE_API_KEY) if not api_key: raise ValueError(BRAVE_API_KEY environment variable is not set.) endpoint https://api.search.brave.com/res/v1/web/search headers { Accept: application/json, Accept-Encoding: gzip, X-Subscription-Token: api_key } params { q: input_data.query, count: 5, # 限制返回结果数量避免信息过载 safesearch: moderate # 安全搜索级别 } try: response requests.get(endpoint, headersheaders, paramsparams, timeout10) response.raise_for_status() # 如果状态码不是200抛出HTTPError data response.json() except requests.exceptions.RequestException as e: # 网络或API错误处理 return BraveWebSearchOutput(results[BraveWebSearchResult( titleSearch Error, url, snippetfFailed to perform search: {str(e)} )]) # 解析 Brave Search API 返回的 JSON 结构 # 实际结构可能需要根据 API 文档调整 web_results data.get(web, {}).get(results, []) formatted_results [] for item in web_results[:5]: # 确保不超过5个 formatted_results.append( BraveWebSearchResult( titleitem.get(title, ), urlitem.get(url, ), snippetitem.get(description, ) # API中摘要可能叫 description ) ) return BraveWebSearchOutput(resultsformatted_results)关键点解析环境变量读取os.getenv(“BRAVE_API_KEY”)从系统环境变量中读取密钥这是配置与代码分离的最佳实践。API 调用使用requests库向 Brave Search API 端点发送 GET 请求。headers中包含了认证信息 (X-Subscription-Token) 和接受的数据格式。params定义了查询参数其中count控制了返回结果的数量这对于控制上下文长度和 API 调用成本很重要。错误处理使用try-except包裹网络请求捕获超时、连接错误或 HTTP 错误。在出错时返回一个友好的错误信息结果而不是让整个智能体对话崩溃这增强了鲁棒性。数据解析与格式化从 API 返回的 JSON 中提取web.results字段并将其映射到我们之前定义的BraveWebSearchResultPydantic 模型。这个过程确保了返回给 Hermes 和大模型的数据结构是统一和预期的。结果数量限制即使在参数中指定了count代码中再次使用切片web_results[:5]进行限制这是一个很好的防御性编程习惯确保输出不会意外地包含过多结果挤占模型有限的上下文窗口。4.4 插件注册__init__.py这个文件通常很短但它是连接插件和 Hermes 框架的桥梁。from hermes.plugin import Plugin from .tools import brave_web_search plugin Plugin( namebrave-search, tools[brave_web_search], # 将工具函数注册到插件 )它创建了一个Plugin实例并将tools.py中定义的函数brave_web_search添加到这个插件的工具列表中。当 Hermes 加载这个插件时就会发现这个工具并将其与plugin.yaml中声明的工具集关联起来。5. 高级使用技巧与场景优化插件安装好并能基础使用后我们可以探讨一些进阶用法和优化策略让它更好地服务于你的具体场景。5.1 工具调用策略与提示工程默认情况下Hermes 的智能体会根据对话上下文自行判断是否需要调用搜索工具。但有时候模型的判断可能不够精准或者你希望在某些对话中强制使用或禁止使用搜索功能。这时可以通过系统提示词System Prompt来引导模型。当你启动 Hermes 对话时可以传入一个更具体的系统指令。例如如果你正在构建一个专注于技术问答的助手你可以这样设置你是一个技术助手专注于回答编程和IT基础设施问题。当用户的问题涉及最新的版本号、官方文档、错误解决方案或近期技术动态时你必须使用brave_web_search工具来获取最新信息。对于通用的概念解释或历史性知识你可以依赖自身知识库。通过这样的提示你给模型制定了更明确的工具使用规则。在 Hermes 中系统提示词通常可以通过配置文件或启动参数设置。你需要查阅 Hermes 的文档来了解具体如何为你的平台如 CLI设置持久的系统提示。5.2 搜索结果的处理与精炼brave_web_search工具默认返回最靠前的几个结果。但有时这些结果的摘要可能不完整或者模型需要更深入的信息。一个常见的进阶模式是让智能体进行多步推理和精炼。初步搜索与筛选智能体首先调用brave_web_search获取一批结果。结果评估模型快速浏览返回的标题和摘要判断哪些链接最有希望包含答案。内容提取对于最有希望的1-2个链接智能体可以再调用一个“网页内容抓取”工具如果存在的话获取页面的完整文本。信息综合基于抓取到的详细内容结合初步搜索结果生成更准确、信息量更丰富的最终回答。目前这个插件只提供了搜索没有提供内容抓取。你可以考虑在此基础上进行扩展或者结合其他插件如一个通用的fetch_webpage工具来实现这个工作流。这体现了智能体“工具组合”的强大能力。5.3 性能优化与成本控制对于频繁使用搜索的应用性能和成本是需要考虑的因素。缓存策略对于重复或相似的查询可以考虑在插件层面或应用层面增加缓存。例如使用functools.lru_cache装饰器对brave_web_search函数的结果进行短期内存缓存注意缓存键需要包含查询字符串。这能显著减少对 API 的调用次数提升响应速度并节省 API 调用额度。但缓存过期时间要设置合理对于实时性要求高的信息如股价缓存时间应非常短或禁用缓存。结果数量调优tools.py中的count参数默认是 5。你可以根据你的需求调整。如果智能体通常只需要一个最精确的答案可以设为 3 甚至 1以减少网络传输的数据量和模型处理负担。如果需要更全面的信息可以适当增加但要注意上下文长度限制。异步调用如果 Hermes 框架和你的使用场景支持异步可以考虑将requests.get改为aiohttp之类的异步 HTTP 客户端避免在等待网络响应时阻塞整个智能体。这需要对插件代码进行更大的改造。6. 常见问题排查与调试记录在实际部署和使用过程中你可能会遇到一些问题。下面是我在测试和使用中遇到的一些典型情况及其解决方法。6.1 插件加载失败问题现象执行hermes tools list时看不到brave-search工具集或者 Hermes 启动时在日志中报错找不到插件。排查步骤检查安装路径确认符号链接是否正确创建。执行ls -la ~/.hermes/plugins/确认brave-search是否存在并正确链接到~/.hermes/plugins-src/brave-search目录。如果链接是红色的或者显示“broken”说明目标不存在需要重新克隆仓库。检查目录权限确保当前用户对~/.hermes/及其子目录有读取和执行权限。检查plugin.yaml语法YAML 对缩进非常敏感。确保plugin.yaml文件格式正确没有语法错误。可以尝试用在线 YAML 校验器检查。查看 Hermes 日志以更详细的日志级别启动 Hermes例如添加--verbose或--debug参数查看加载插件时的具体错误信息。6.2 工具调用失败或返回错误问题现象在对话中模型尝试搜索但失败或者返回“Search Error”。排查步骤确认环境变量这是最常见的问题。在运行 Hermes 的同一终端环境中执行echo $BRAVE_API_KEY确保输出的是正确的密钥而不是空值。特别注意如果你在某个终端窗口设置了环境变量然后在另一个窗口或通过系统服务启动 Hermes环境变量是不会传递过去的。确保在启动 Hermes 的环境中设置了该变量。检查 API 密钥有效性你的 Brave Search API 密钥可能已过期、被禁用或者免费额度已用尽。可以尝试直接在命令行用curl测试 APIcurl -H “X-Subscription-Token: YOUR_API_KEY” “https://api.search.brave.com/res/v1/web/search?qtestcount1”如果返回401 Unauthorized或403 Forbidden说明密钥有问题。检查网络连接确保运行 Hermes 的机器可以访问api.search.brave.com。可能存在防火墙或代理问题。查看工具函数内部错误在tools.py的brave_web_search函数中异常被捕获并返回了一个错误结果。你可以临时修改代码将异常信息打印到标准输出或日志文件以便看到更详细的错误原因例如网络超时、JSON 解析错误等。记得修改后要重启 Hermes。6.3 搜索结果不相关或质量差问题现象智能体调用了搜索但返回的结果似乎与问题无关导致最终答案质量不高。分析与解决优化查询词大模型生成的搜索查询词可能不够精确。这属于“提示工程”问题。你可以在系统提示词中指导模型如何构建更好的查询例如“当你需要搜索时请将用户的问题提炼成简短、包含关键实体如产品名、错误代码、版本号的搜索短语。”调整搜索参数Brave Search API 可能支持更多高级参数来优化结果如指定语言 (lang)、地区 (country)、时间范围 (freshness) 等。你可以修改tools.py中的params字典加入这些参数来获得更符合预期的结果。需要查阅最新的 Brave Search API 文档。结果后处理如果 API 返回的结果质量不稳定可以在tools.py的数据解析部分加入一些简单的过滤逻辑。例如优先选择来自特定域名如stackoverflow.com,github.com, 官方文档域名的结果或者根据标题和摘要中的关键词进行相关性排序。6.4 与其他插件或工具的冲突问题现象启用了多个工具集但智能体在某些情况下没有选择brave_web_search或者行为异常。排查思路工具集启用状态再次确认hermes tools enable platform brave-search已成功执行并且没有在其他平台意外禁用。使用hermes tools list --platform cli以 cli 为例查看特定平台下启用的工具集。工具功能重叠如果你的 Hermes 还安装了其他搜索插件例如一个 Google 搜索插件那么智能体面前就有多个搜索工具可选。模型会根据工具的描述在 schema 中定义和当前上下文来选择。确保你的brave_web_search工具描述清晰独特。如果存在重叠你可能需要禁用其中一个或者通过更精细的系统提示来指导模型的选择。Hermes 版本兼容性确保你使用的 Hermes 版本支持插件系统并且与hermes-brave-search-plugin的版本兼容。插件的plugin.yaml中可能声明了兼容的 Hermes 版本范围。如果版本不匹配可能导致不可预知的行为。这个插件是一个绝佳的起点它清晰地展示了如何为一个强大的本地 AI 智能体框架赋予实时信息获取能力。从申请 API 密钥到理解插件架构再到最后的调试优化整个过程本身就是一次对 AI 应用开发生态的深入实践。我最深的体会是在 AI 应用开发中“让模型学会使用工具”比“让模型无所不知”更可行、也更强大。hermes-brave-search-plugin这类项目正是构建这种“增强型智能体”的基石。如果你在集成后发现模型开始能聊今天的新闻、能解答最新的技术问题那种感觉是非常奇妙的——它真的从一本静态的百科全书变成了一个能与你同步探索世界的伙伴。