首页/新闻资讯/正文详情

大模型开发 - 手写Manus之Tavily搜索工具:04 让AI Agent接入互联网(TaoToken 统一 Key 配置版)

发布时间:2026/9/27 12:10:33 来源:云帆数科 栏目:资讯中心
大模型开发 - 手写Manus之Tavily搜索工具:04 让AI Agent接入互联网(TaoToken 统一 Key 配置版)
1. 为什么你的 Java Agent 还差一双“眼睛”大模型开发走到手写 Manus 这一步文件读写和 Docker 沙箱代码执行都已经跑通了但你会发现 Agent 依然是个“闭卷考生”。你问它“今天有什么值得关注的 AI 开源项目”它只能从训练数据里翻旧账给出的答案可能停留在几个月前。这不是模型不够聪明而是它缺少一个能实时访问互联网的搜索工具。Tavily 就是为 AI Agent 量身定做的搜索 API。它不像传统搜索引擎那样返回一堆需要解析的 HTML而是直接给你结构化的 JSON标题、链接、摘要拿来就能塞进大模型的上下文。对于 Java 手写 Manus 的场景来说这意味着你不需要写爬虫、不需要处理反爬、不需要清洗页面一个 HTTP 请求就能让 Agent 拿到互联网上的最新信息。但这里有个现实问题Tavily 的 Key 要管大模型的 Key 也要管如果后面还要接别的模型或工具环境变量会越堆越多。我试过在三个不同的配置文件里来回切换 Key最后自己都搞混了。所以这篇内容的核心思路是用 TaoToken 统一管理 Key 和 API 通道让 Tavily 搜索工具通过一个稳定的入口接入 Agent配置一次后面加工具、换模型都不用再动环境变量。适合谁看如果你正在用 Java 手写类 Manus 的 AI Agent已经完成了基础架构和沙箱执行现在想让 Agent 能搜索互联网这篇就是为你准备的。我会给出完整的config.toml和settings.json骨架、TaoToken 接入 AI Agent 的配置片段以及一次搜索请求的验证动作目标只有一个让 Agent 稳定接入互联网。2. TaoToken 前置统一 Key 与 API 通道在动手改代码之前先把 TaoToken 的接入准备好。你可以把它理解成一个“Key 管家 通道调度器”Tavily 搜索、模型对话、代码补全这些能力都通过同一个 API 入口和同一套 Key 体系来调用。这样做的好处是Agent 的配置文件里不需要散落各种厂商的 Key只需要维护一份 TaoToken 的凭证。2.1 获取 TaoToken API Key打开 TaoToken 官网注册或登录后进入控制台在 API Keys 页面创建一个新的 Key。建议按用途命名比如manus-agent-dev方便后面排查问题时区分环境。创建完成后把 Key 复制出来它只会完整显示一次。注意这个 Key 不要直接写死在 Java 代码里也不要提交到 Git 仓库。后面我们会用配置文件加环境变量的方式管理。2.2 确认 API 入口地址TaoToken 的 API 入口是https://taotoken.net/api所有通过 TaoToken 转发的请求都走这个地址。Tavily 搜索工具在底层发起 HTTP 请求时会把目标指向这个入口由 TaoToken 完成后续的通道调度。你不需要在代码里硬编码 Tavily 官方的地址统一走 TaoToken 即可。2.3 规划配置文件结构在手写 Manus 的项目里我建议把配置分成两层一层是config.toml放 Agent 运行时的全局参数另一层是settings.json放工具级别的开关和参数。TaoToken 的 Key 和 API 地址放在config.toml的[llm]和[tools]段里Tavily 搜索的具体行为参数放在settings.json里。这样后面加新工具时只需要在settings.json里加一段不用动主配置。3. 可复制配置config.toml 与 settings.json 骨架下面这份配置可以直接复制到你的项目里按实际情况改 Key 和路径即可。我尽量把注释写清楚方便你对照自己的项目结构调整。3.1 config.toml 骨架# config.toml - Agent 全局配置 [llm] # TaoToken 统一 API 入口 base_url https://taotoken.net/api # 从环境变量读取避免硬编码 api_key ${TAOTOKEN_API_KEY} # 模型名称按需替换 model claude-3-5-sonnet timeout_seconds 60 [tools] # 工具总开关 enabled [file, sandbox, tavily_search] [tools.tavily_search] # 搜索工具也走 TaoToken 统一通道 base_url https://taotoken.net/api api_key ${TAOTOKEN_API_KEY} # 单次搜索返回结果数上限 max_results 5 # 请求超时单位秒 timeout_seconds 30 [agent] workspace ./workspace max_iterations 10这里的关键点是[tools.tavily_search]段base_url和api_key都指向 TaoToken而不是 Tavily 官方地址。这样 Tavily 搜索工具在发起请求时实际是向 TaoToken 的 API 入口发送请求由 TaoToken 完成后续处理。3.2 settings.json 骨架{ tavily_search: { enabled: true, search_depth: basic, include_answer: false, include_raw_content: false, max_results: 5, search_params: { query: , topic: general } }, agent_runtime: { log_level: INFO, tool_call_timeout_ms: 30000, retry_on_failure: true, max_retries: 2 } }settings.json里放的是工具的行为参数比如搜索深度、是否包含原始内容、重试策略。这些参数和 Key 无关所以单独抽出来方便不同环境用不同的 JSON 文件覆盖。3.3 环境变量注入在启动 Agent 之前把 TaoToken 的 Key 注入环境变量export TAOTOKEN_API_KEY你的_TaoToken_API_Key如果你在 IDE 里跑可以在 Run Configuration 里加环境变量如果打包成 jar 跑用-D参数或者启动脚本里 export。这样config.toml里的${TAOTOKEN_API_KEY}就能被正确替换。4. Java 侧接入TavilySearchTool 改造配置准备好之后回到 Java 代码。原来的TavilySearchTool是直接从环境变量读 Tavily 的 Key现在要改成从config.toml读取 TaoToken 的配置。4.1 新增依赖除了原有的 langchain4j Tavily 封装还需要一个 TOML 解析库来读config.toml!-- Tavily 搜索引擎封装 -- dependency groupIddev.langchain4j/groupId artifactIdlangchain4j-web-search-engine-tavily/artifactId version0.36.2/version /dependency !-- TOML 配置解析 -- dependency groupIdcom.moandjiezana.toml/groupId artifactIdtoml4j/artifactId version0.7.2/version /dependency4.2 读取 TaoToken 配置写一个简单的配置加载类把config.toml里的[tools.tavily_search]段读出来import com.moandjiezana.toml.Toml; import java.io.File; public class AgentConfigLoader { private final Toml toml; public AgentConfigLoader(String configPath) { this.toml new Toml().read(new File(configPath)); } public String getTavilyBaseUrl() { return toml.getString(tools.tavily_search.base_url); } public String getTavilyApiKey() { String key toml.getString(tools.tavily_search.api_key); // 支持 ${ENV_VAR} 形式的环境变量替换 if (key ! null key.startsWith(${) key.endsWith(})) { String envName key.substring(2, key.length() - 1); return System.getenv(envName); } return key; } public int getTavilyMaxResults() { Long value toml.getLong(tools.tavily_search.max_results); return value ! null ? value.intValue() : 5; } }4.3 改造 TavilySearchTool原来的工具类从System.getenv(TAVILY_API_KEY)读 Key现在改成从配置加载器读public class TavilySearchTool extends BaseTool { private final WebSearchEngine searchEngine; private final int defaultMaxResults; public TavilySearchTool(AgentConfigLoader config) { super(tavily_search, Search the web for real-time information); String apiKey config.getTavilyApiKey(); if (apiKey null || apiKey.trim().isEmpty()) { throw new IllegalStateException(TaoToken API Key is required for tavily_search); } this.defaultMaxResults config.getTavilyMaxResults(); // 关键baseUrl 指向 TaoToken 统一入口 this.searchEngine TavilyWebSearchEngine.builder() .apiKey(apiKey) .baseUrl(config.getTavilyBaseUrl()) .build(); } Override public MapString, Object getParametersSchema() { MapString, MapString, Object properties new HashMap(); properties.put(query, stringParam(The search query to execute)); properties.put(max_results, intParam(Max results, default defaultMaxResults)); return buildSchema(properties, List.of(query)); } Override public ToolResult execute(MapString, Object parameters) { try { String query getString(parameters, query); if (query null || query.trim().isEmpty()) { return ToolResult.error(Query parameter is required); } int maxResults getInt(parameters, max_results, defaultMaxResults); WebSearchResults results searchEngine.search(query); MapString, Object response new HashMap(); response.put(query, query); response.put(total_results, results.results().size()); ListMapString, Object items results.results().stream() .limit(maxResults) .map(r - { MapString, Object item new HashMap(); item.put(title, r.title()); item.put(url, r.url()); item.put(snippet, r.snippet()); return item; }) .toList(); response.put(results, items); return ToolResult.success(response); } catch (Exception e) { return ToolResult.error(Search failed: e.getMessage()); } } }注意baseUrl这一行它把搜索请求的目标指向了 TaoToken 的 API 入口。Tavily 的官方 SDK 支持自定义 baseUrl所以这里不需要改底层 HTTP 逻辑只需要在构建时传入 TaoToken 的地址即可。4.4 注册到 Agent在ManusAgent的初始化流程里把配置加载器和工具注册串起来public class ManusAgent { private final ToolCollection toolCollection; public ManusAgent(String configPath) { AgentConfigLoader config new AgentConfigLoader(configPath); this.toolCollection new ToolCollection(); // 注册文件工具 toolCollection.addTool(new FileReadTool(config)); toolCollection.addTool(new FileWriteTool(config)); // 注册沙箱工具 toolCollection.addTool(new SandboxTool(config)); // 注册 Tavily 搜索工具走 TaoToken 统一通道 toolCollection.addTool(new TavilySearchTool(config)); } }到这里Java 侧的改造就完成了。Tavily 搜索工具不再依赖单独的 Tavily Key而是复用 TaoToken 的 Key 和 API 入口。5. 验证请求一次搜索的成功结果配置和代码都改完之后先别急着跑完整的 Agent 流程单独验证一次搜索请求确认 TaoToken 通道是通的。5.1 写一个最小验证类public class TavilySearchVerify { public static void main(String[] args) { AgentConfigLoader config new AgentConfigLoader(config.toml); TavilySearchTool tool new TavilySearchTool(config); MapString, Object params new HashMap(); params.put(query, Java AI Agent 开源项目 2025); params.put(max_results, 3); ToolResult result tool.execute(params); if (result.isSuccess()) { System.out.println(搜索成功结果数: result.getData().get(total_results)); ListMapString, Object items (ListMapString, Object) result.getData().get(results); for (MapString, Object item : items) { System.out.println(标题: item.get(title)); System.out.println(链接: item.get(url)); System.out.println(摘要: item.get(snippet)); System.out.println(---); } } else { System.err.println(搜索失败: result.getErrorMessage()); } } }5.2 预期输出运行这个类如果配置正确你会看到类似下面的输出搜索成功结果数: 3 标题: 2025年值得关注的Java AI Agent框架 链接: https://example.com/java-ai-agent-2025 摘要: 本文整理了当前主流的Java AI Agent开源项目... --- 标题: 手写Manus系列教程 链接: https://example.com/manus-java-tutorial 摘要: 从零用Java实现类Manus智能体涵盖架构、沙箱、搜索... --- 标题: LangChain4j 最新进展 链接: https://example.com/langchain4j-update 摘要: LangChain4j 近期新增了多个工具集成... ---5.3 接入 Agent 后的完整流程单独验证通过后把搜索工具放进 Agent 的决策链里跑一次。用户输入“搜索一下最近有哪些新的 Java AI Agent 项目把结果写到文件里”Agent 的执行流程会是这样第一步大模型推理后调用tavily_searchquery 是“Java AI Agent 新项目 2025”TaoToken 通道返回结构化搜索结果。第二步大模型从搜索结果里提取关键信息调用write_file把整理后的内容写入workspace/java_agent_projects.txt。第三步大模型判断任务完成返回finish_reasonstop。搜索结果被封装成toolMessage存入 Memory 后下一轮推理时大模型能看到完整的搜索内容并据此决定是继续搜索、提取信息还是写入文件。这就是搜索工具流入 Agent 决策链的完整路径。6. 本篇常见错排查配置和代码都给了但实际跑的时候大概率会遇到几个坑。下面这几个是我在调试时踩过的按顺序排查基本能覆盖大部分问题。6.1 搜索请求返回 401 或 403先检查config.toml里的api_key是否被正确替换成了环境变量的值。可以在AgentConfigLoader里加一行日志把读到的 Key 前几位打印出来确认。如果 Key 本身没问题检查base_url是否写成了https://taotoken.net/api注意末尾不要多加斜杠也不要写成其他路径。6.2 搜索结果为空或 total_results 为 0这种情况通常是 query 参数没传进去或者max_results被设成了 0。检查execute方法里getString(parameters, query)的返回值确认大模型调用工具时确实填了 query 字段。另外settings.json里的max_results和config.toml里的max_results如果冲突以代码里实际读取的为准建议只保留一处配置。6.3 工具注册后 Agent 不调用如果 Agent 在应该搜索的时候没有调用tavily_search先检查工具是否真的注册进了ToolCollection。可以在ManusAgent构造完成后打印一下toolCollection里的工具名称列表。另外工具的description要写清楚用途大模型是根据描述来决定调不调用的。Search the web for real-time information这种描述比search tool更容易被正确触发。6.4 超时或连接失败TaoToken 的 API 入口是 HTTPS确认你的运行环境能正常访问外网。如果公司网络有代理需要在 JVM 启动参数里配置代理设置。另外config.toml里的timeout_seconds如果设得太短搜索请求可能还没返回就被中断了建议先设 30 秒测试。6.5 环境变量没生效${TAOTOKEN_API_KEY}这种写法依赖AgentConfigLoader里的替换逻辑。如果你用的是其他 TOML 库可能不支持这种语法需要手动读取环境变量再 set 进去。最简单的验证方式是在main方法里直接System.out.println(System.getenv(TAOTOKEN_API_KEY))确认环境变量在当前进程里可见。排查完这几个点Tavily 搜索工具基本就能稳定工作了。后面如果要加新的搜索源或者换模型只需要在 TaoToken 控制台调整通道配置Java 侧不用改代码。7. 接入文档与后续工具扩展Tavily 搜索工具跑通之后你的 Agent 工具箱里就有了文件读写、沙箱执行、网页搜索三类能力。这三者组合起来能做的事情比单个工具叠加要多得多搜索获取实时信息沙箱里跑代码处理数据最后把结果写入文件。如果你在接入过程中遇到 Key 配置或通道相关的问题可以直接看 TaoToken 的接入文档里面有各语言的最小接入示例和常见错误码说明。需要管理多个 Key 或者查看调用量的话控制台里有按工具维度的统计。后续如果要给 Agent 加新的工具比如代码补全或者长文本摘要建议继续走 TaoToken 的统一通道这样配置文件里只需要加一段[tools.xxx]不用再引入新的 Key 管理体系。搜索工具只是 Agent 接入互联网的第一步。真正让 Agent 变得好用的是工具之间的组合调用而组合调用的前提是每个工具都能稳定、可配置地工作。把 TaoToken 作为统一入口后面加工具、换模型、调参数都会轻松很多。

相关推荐

OpenClaw 只会答不会做?用 Skills + SKILL.md 让它在嵌入式 Linux 上主动干活
OpenClaw 只会答不会做?用 Skills + SKILL.md 让它在嵌入式 Linux 上主动干活

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/27 12:10:27

分布式物联网平台如何实现设备接入到业务闭环
分布式物联网平台如何实现设备接入到业务闭环

1. 这不是又一个“平台演示”,而是一套能扛住产线压力的物联网底座乐吾乐Web组态——这个词最近在工业自动化、智慧能源和实训教学圈子里被反复提起,但很多人点开官网看到“自研分布式物联网平台”几个字,第一反应还是:又一个PPT架… · 2026/9/27 12:10:20

3类方案对比评测:怎么做网页宣传防被黑指南
3类方案对比评测:怎么做网页宣传防被黑指南

3类方案对比评测:怎么做网页宣传防被黑指南 昨晚刚帮一个做建材的老板处理完网站挂马的事,看着后台全是红色的“高危漏洞”提示,他急得直拍桌子。这种网站被黑挂马不知道怎么办,是无数中小企业主建站后的噩梦,也是我在做怎么做网页宣传方案时最警惕的隐… · 2026/9/27 12:10:14

STM32F410-Nucleo-64 开发板 RT-Thread BSP 使用指南:快速上手与源码级解析
STM32F410-Nucleo-64 开发板 RT-Thread BSP 使用指南:快速上手与源码级解析

操作系统嵌入式物联网嵌入式OSRTOS 【免费下载链接】rt-thread RT-Thread is an open source IoT Real-Time Operating System (RTOS). https://rt-thread.github.io/rt-thread/ 项目地址: https://gitcode.com/gh_mirrors/rt/rt-thread 点击查看 免费下载 本指南以… · 2026/9/27 13:02:28

响应式网页设计案例实现与分析:5个注意事项避免白花冤枉钱
响应式网页设计案例实现与分析:5个注意事项避免白花冤枉钱

响应式网页设计案例实现与分析:5个注意事项避免白花冤枉钱 网站做好了没人访问,这往往是老板们最头疼的事。很多甲方朋友找过来,第一句话就是:“我花了大几万做的响应式官网,怎么百度搜不到,手机上也打不开?” 这时候,问题通常不出在设计,而出在… · 2026/9/27 13:02:15

Local 与 Cloud:什么时候让它在本机做,什么时候丢到云端
Local 与 Cloud:什么时候让它在本机做,什么时候丢到云端

1 用本地 Local 的情况适合:项目只在你电脑上;需要本地数据库、硬件、GPU、私有文件;需要看实时日志;需要频繁手工调试;你想严格控制网络和文件范围。优点: 快、上下文近、能用本地环境、适合调试。风险&am… · 2026/9/27 13:02:15

立体库堆垛机无线数据采集:Metis-I网关与Modbus链路实施详解
立体库堆垛机无线数据采集:Metis-I网关与Modbus链路实施详解

去年接手一套自动化立体库的改造项目时,最先把我卡住的不是堆垛机控制逻辑,反而是看起来最不起眼的数据采集链路。堆垛机提升机构上的高度编码器、货叉状态、防撞激光信号一直靠滑触线传到地面柜,运行半年后滑触线接触不良的次数越来越多&… · 2026/9/27 13:02:03

SVG 导出 PNG 总是缺字、发糊、图片空白:前端图表导出的六个坑
SVG 导出 PNG 总是缺字、发糊、图片空白:前端图表导出的六个坑

流程图、思维导图、各种图表&#xff0c;只要是 SVG 渲染的&#xff0c;迟早会遇到一个需求&#xff1a;导出成 PNG。 网上的标准答案只有四行&#xff1a;把 SVG 序列化成字符串&#xff0c;塞进 <img>&#xff0c;画到 canvas 上&#xff0c;toBlob 导出。 const svg… · 2026/9/27 13:01:56

WebSocket 接收不到服务器端消息排查:从 IFRAME 到 window.parent 的消息监听链路
WebSocket 接收不到服务器端消息排查:从 IFRAME 到 window.parent 的消息监听链路

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/27 13:01:50

MATLAB雷达信号脉冲压缩仿真:LFM线性调频、匹配滤波与距离分辨率实现
MATLAB雷达信号脉冲压缩仿真:LFM线性调频、匹配滤波与距离分辨率实现

简介&#xff1a;这套Matlab仿真工具完整呈现雷达信号脉冲压缩过程&#xff0c;从线性调频&#xff08;LFM&#xff09;信号生成、目标回波仿真到匹配滤波压缩处理均有可运行代码支撑&#xff0c;面向电子信息工程、计算机、数学等专业学生&#xff0c;适用于课程设计、期末大作… · 2026/9/27 0:00:01

汕头网站建设制作厂家避坑指南:5大注意事项救急
汕头网站建设制作厂家避坑指南:5大注意事项救急

汕头网站建设制作厂家避坑指南:5大注意事项救急 改个需求建站公司拖一周,这种憋屈事我见得太多了。 很多汕头老板找本地建站团队,签合同前看着方案挺美,一上线就变脸。 今天不聊虚的,直接拆解找 汕头网站建设制作厂家 时的5个核心 注意事项… · 2026/9/27 0:00:01

多模态虚假新闻检测实战:BERT+ResNet双塔与对比学习
多模态虚假新闻检测实战:BERT+ResNet双塔与对比学习

简介&#xff1a;基于PyTorch的多模态虚假新闻检测项目完整代码包&#xff0c;面向自然语言处理与计算机视觉交叉方向的开发者、科研人员及毕业设计选题者&#xff0c;解决社交媒体中文本与图像联合识别虚假新闻的问题。系统以BERT预训练模型提取文本语义特征&#xff0c;以Res… · 2026/9/27 0:00:01

MATLAB雷达信号脉冲压缩仿真:LFM线性调频、匹配滤波与距离分辨率实现
MATLAB雷达信号脉冲压缩仿真:LFM线性调频、匹配滤波与距离分辨率实现

简介&#xff1a;这套Matlab仿真工具完整呈现雷达信号脉冲压缩过程&#xff0c;从线性调频&#xff08;LFM&#xff09;信号生成、目标回波仿真到匹配滤波压缩处理均有可运行代码支撑&#xff0c;面向电子信息工程、计算机、数学等专业学生&#xff0c;适用于课程设计、期末大作… · 2026/9/27 0:00:01

汕头网站建设制作厂家避坑指南:5大注意事项救急
汕头网站建设制作厂家避坑指南:5大注意事项救急

汕头网站建设制作厂家避坑指南:5大注意事项救急 改个需求建站公司拖一周,这种憋屈事我见得太多了。 很多汕头老板找本地建站团队,签合同前看着方案挺美,一上线就变脸。 今天不聊虚的,直接拆解找 汕头网站建设制作厂家 时的5个核心 注意事项… · 2026/9/27 0:00:01

多模态虚假新闻检测实战:BERT+ResNet双塔与对比学习
多模态虚假新闻检测实战:BERT+ResNet双塔与对比学习

简介&#xff1a;基于PyTorch的多模态虚假新闻检测项目完整代码包&#xff0c;面向自然语言处理与计算机视觉交叉方向的开发者、科研人员及毕业设计选题者&#xff0c;解决社交媒体中文本与图像联合识别虚假新闻的问题。系统以BERT预训练模型提取文本语义特征&#xff0c;以Res… · 2026/9/27 0:00:01

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码