AI Agent 项目学习笔记(八):Tool Calling 工具调用机制总览

1. 本期目标

前几期主要分析了 ai_agent 项目的对话主链路、Advisor、多轮记忆和 RAG 检索增强。到目前为止,智能体已经具备了这些能力:

复制代码
能够和用户多轮对话
能够记住当前会话上下文
能够参考本地知识库回答
能够通过 RAG 检索增强回答质量

但是这些能力主要还是围绕"回答问题"展开的。

这一期开始分析 Agent 中非常关键的另一类能力:

复制代码
Tool Calling 工具调用

Spring AI 官方文档中说明,Tool Calling 是 AI 应用中的常见模式,它允许模型和一组 API 或工具交互,从而扩展模型能力;工具主要用于两类场景:一类是信息检索,例如查询外部信息、数据库、文件系统或搜索引擎;另一类是执行动作,例如发送邮件、创建记录、提交表单或触发工作流。工具调用的关键点是:模型本身并不直接访问 API,而是由应用程序提供工具定义、执行工具调用,并把工具结果返回给模型。(Home)

本期主要解决几个问题:

复制代码
1. 为什么 AI Agent 需要 Tool Calling?
2. Tool Calling 和普通聊天有什么区别?
3. ai_agent 项目中有哪些工具?
4. ToolRegistration 如何统一注册工具?
5. ToolCallback[] 是什么?
6. @Tool 和 @ToolParam 分别起什么作用?
7. LoveApp 如何把工具注入模型调用?
8. 当前工具链路的完整执行流程是什么?
9. Tool Calling 有哪些安全风险和改进方向?

2. 为什么需要 Tool Calling?

普通大模型对话可以理解为:

复制代码
用户输入问题
    ↓
模型生成回答

这种方式能完成很多文本任务,但它有天然限制:

复制代码
模型不能自己访问实时网页
模型不能自己读取本地文件
模型不能自己下载资源
模型不能自己执行终端命令
模型不能自己生成真实 PDF 文件

如果用户提出的任务是:

复制代码
帮我搜索一些约会地点
抓取这个网页的内容
把这段建议保存成文件
帮我生成一份 PDF 报告
执行一个命令查看目录

普通聊天模型只能"建议你怎么做",而不能真正帮你完成。

Tool Calling 的作用就是让模型从:

复制代码
只会回答

进一步变成:

复制代码
可以调用外部工具完成任务

所以,Tool Calling 是 Agent 从"问答系统"走向"任务执行系统"的关键能力。


3. Tool Calling 不是模型直接执行工具

这里需要先澄清一个重要问题。

Tool Calling 并不是模型真的拥有了操作系统权限,也不是模型自己去执行 Java 方法。

Spring AI 文档中明确说明:模型只能请求调用某个工具,并给出输入参数;应用程序负责根据工具名称和参数执行真实工具,再把工具执行结果返回给模型。模型永远不会直接访问工具背后的 API,这也是一个关键安全点。(Home)

也就是说,真实流程是:

复制代码
模型判断需要工具
    ↓
模型生成工具调用请求
    ↓
Spring AI / 应用程序找到对应 ToolCallback
    ↓
后端执行 Java 方法
    ↓
工具结果返回给模型
    ↓
模型根据工具结果生成最终回答

所以,Tool Calling 的本质是:

复制代码
模型负责决策和组织语言
应用负责执行真实动作

这一点非常重要。

因为如果以为"模型直接执行命令",就容易忽略后端工具注册、参数校验、权限控制和安全边界。


4. 项目中的工具目录结构

ai_agent 项目的工具代码主要位于:

复制代码
src/main/java/com/ai/aiagent/tool

当前该目录下包含这些工具类:

复制代码
FileOperationTool.java
PDFGenerationTool.java
ResourceDownloadTool.java
TerminalOperationTool.java
TerminateTool.java
ToolRegistration.java
WebScrapingTool.java
WebSearchTool.java

GitHub 目录中也能看到这些文件,说明项目当前已经覆盖了搜索、网页抓取、资源下载、文件读写、终端执行、PDF 生成和任务终止等工具能力。(GitHub)

从功能上可以分成四类:

复制代码
信息获取类:
WebSearchTool
WebScrapingTool

文件与资源类:
FileOperationTool
ResourceDownloadTool
PDFGenerationTool

系统执行类:
TerminalOperationTool

流程控制类:
TerminateTool

这说明项目中的 Tool Calling 不是只做一个简单示例,而是已经形成了一组可组合工具。


5. ToolRegistration:集中注册工具

项目中负责统一注册工具的是:

复制代码
ToolRegistration

它被标注为:

复制代码
@Configuration

说明这是一个 Spring 配置类。

在这个类中,项目定义了一个 Bean:

复制代码
@Bean
public ToolCallback[] allTools()

这个方法会创建多个工具对象,包括 FileOperationToolWebSearchToolWebScrapingToolResourceDownloadToolTerminalOperationToolPDFGenerationToolTerminateTool,然后通过 ToolCallbacks.from(...) 转换成 ToolCallback[] 返回。WebSearchTool 还会使用配置项中的 search-api.api-key 作为搜索 API Key。(GitHub)

可以理解为:

复制代码
ToolRegistration
    ↓
创建所有工具对象
    ↓
ToolCallbacks.from(...)
    ↓
生成 ToolCallback[]
    ↓
交给 LoveApp 使用

所以 ToolRegistration 的作用是:

复制代码
集中管理哪些工具可以暴露给模型调用

6. ToolCallback[] 是什么?

Spring AI 文档中说明,工具是 Tool Calling 的构建块,底层通过 ToolCallback 接口进行建模;ChatClientChatModel 都可以接收一组 ToolCallback,使这些工具对模型可用。(Home)

在项目里:

复制代码
@Resource
private ToolCallback[] allTools;

LoveApp 通过 @Resource 注入了 ToolRegistration 中创建的 allTools。随后在工具调用方法中使用:

复制代码
.toolCallbacks(allTools)

把这些工具注入到本次模型调用中。(GitHub)

可以理解为:

复制代码
ToolCallback[] = 当前允许模型调用的工具列表

模型不是天然知道项目有哪些工具。

只有当后端把 ToolCallback[] 放进本次 ChatClient 调用时,模型才可以根据工具描述决定是否调用这些工具。


7. @Tool:把 Java 方法声明成工具

项目中的每个工具方法基本都使用了:

复制代码
@Tool(description = "...")

Spring AI 文档说明,可以通过 @Tool 注解把一个方法声明为工具;@Toolname 用于标识工具,未提供时默认使用方法名;description 用于帮助模型理解工具的用途和调用时机,官方也强调应该提供详细描述,否则模型可能不会在需要时调用工具,或者错误调用工具。(Home)

例如 WebSearchTool 中的方法是:

复制代码
@Tool(description = "Search for information from Baidu Search Engine")
public String searchWeb(String query)

这表示模型可以把 searchWeb 看成一个可调用工具,用于通过百度搜索引擎检索信息。项目源码中,该工具会调用 SearchAPI 接口,并设置 engine = baidu,最后提取 organic_results 的前 5 条搜索结果返回。(GitHub)

所以 @Tool 的作用可以概括为:

复制代码
告诉模型:
这个 Java 方法可以作为工具使用,
它能做什么,
什么时候适合调用它。

8. @ToolParam:描述工具参数

除了 @Tool,项目中还大量使用了:

复制代码
@ToolParam(description = "...")

它用于描述工具参数。

例如 WebSearchTool 中:

复制代码
@ToolParam(description = "Search query keyword") String query

FileOperationTool 中:

复制代码
@ToolParam(description = "Name of the file to write") String fileName
@ToolParam(description = "Content to write to the file") String content

这些参数描述会帮助模型理解工具调用时应该填什么参数。项目中的搜索、网页抓取、文件读写、下载资源、执行终端命令、生成 PDF 等工具都使用了 @ToolParam 对参数进行说明。(GitHub)

可以理解为:

复制代码
@Tool:
描述这个工具能做什么。

@ToolParam:
描述调用这个工具时需要哪些参数。

工具描述越清楚,模型越容易正确选择工具和生成参数。


9. LoveApp 如何调用工具?

LoveApp 中的工具调用入口是:

复制代码
public String doChatWithTools(String message, String chatId)

核心代码可以简化为:

复制代码
ChatResponse chatResponse = chatClient
        .prompt()
        .user(message)
        .advisors(spec -> spec.param(ChatMemory.CONVERSATION_ID, chatId))
        .advisors(new MyLoggerAdvisor())
        .toolCallbacks(allTools)
        .call()
        .chatResponse();

这里最关键的是:

复制代码
.toolCallbacks(allTools)

它把前面注册好的所有工具注入到当前模型调用中。源码中也可以看到,doChatWithTools() 同时保留了 ChatMemory.CONVERSATION_ID,说明工具调用链路也支持多轮对话记忆;它还添加了 MyLoggerAdvisor,方便观察请求和响应。(GitHub)

所以 doChatWithTools() 的完整能力是:

复制代码
用户输入
    ↓
多轮记忆
    ↓
日志观察
    ↓
工具列表注入
    ↓
模型决定是否调用工具
    ↓
返回最终回答

10. Tool Calling 完整执行流程

结合 Spring AI 的 Tool Calling 机制和项目源码,可以把完整流程画成:

复制代码
用户提出任务
        ↓
LoveApp.doChatWithTools(message, chatId)
        ↓
ChatClient.prompt()
        ↓
注入 ChatMemory.CONVERSATION_ID
        ↓
注入 MyLoggerAdvisor
        ↓
注入 ToolCallback[] allTools
        ↓
模型看到可用工具定义
        ↓
模型判断是否需要调用工具
        ↓
如果需要:生成工具名和参数
        ↓
Spring AI 根据 ToolCallback 找到对应 Java 方法
        ↓
后端执行工具方法
        ↓
工具结果返回给模型
        ↓
模型结合工具结果生成最终回答
        ↓
LoveApp 返回文本结果

这一流程对应 Spring AI 文档中的 Tool Calling 生命周期:应用把工具定义放入聊天请求,模型决定调用工具并给出参数,应用执行工具并把结果返回给模型,最后模型基于工具结果生成最终响应。(Home)

一句话理解:

复制代码
模型负责"想调用什么工具、传什么参数",后端负责"真正执行工具"。

11. WebSearchTool:网页搜索工具

WebSearchTool 的作用是:

复制代码
通过搜索 API 从百度搜索引擎检索信息

它的工具方法是:

复制代码
@Tool(description = "Search for information from Baidu Search Engine")
public String searchWeb(String query)

内部逻辑大致是:

复制代码
接收 query
    ↓
构造 SearchAPI 请求参数
    ↓
设置 engine = baidu
    ↓
发送 HTTP GET 请求
    ↓
解析返回 JSON
    ↓
提取 organic_results 前 5 条
    ↓
拼接成字符串返回

源码中可以看到,该工具使用 HttpUtil.get() 请求 https://www.searchapi.io/api/v1/search,并从返回 JSON 中提取 organic_results 的前 5 条结果。(GitHub)

这个工具适合处理:

复制代码
需要实时外部信息的问题
需要搜索网页资料的问题
需要先找候选链接的问题

例如:

复制代码
帮我搜索适合情侣约会的餐厅推荐
帮我找一些七夕约会活动
帮我搜索某个城市的约会地点

12. WebScrapingTool:网页抓取工具

WebScrapingTool 的作用是:

复制代码
抓取指定网页的 HTML 内容

它的工具方法是:

复制代码
@Tool(description = "Scrape the content of a web page")
public String scrapeWebPage(String url)

源码中,该工具使用 Jsoup 连接目标 URL,并返回 document.html();如果抓取失败,则返回错误信息。(GitHub)

可以理解为:

复制代码
输入 URL
    ↓
Jsoup 访问网页
    ↓
获取网页 HTML
    ↓
返回给模型

这个工具适合和 WebSearchTool 配合使用:

复制代码
第一步:搜索得到候选网页
第二步:抓取某个网页内容
第三步:模型总结网页信息

不过当前实现直接返回完整 HTML,内容可能比较长,也可能包含大量导航、脚本和无关标签。后续可以优化成:

复制代码
只提取正文文本
过滤 script/style 标签
限制最大返回长度
提取 title、description、main content

13. ResourceDownloadTool:资源下载工具

ResourceDownloadTool 的作用是:

复制代码
根据 URL 下载资源并保存到本地

它的工具方法接收两个参数:

复制代码
url:资源地址
fileName:保存文件名

源码中,它会把文件保存到:

复制代码
FileConstant.FILE_SAVE_DIR + "/download"

FileConstant.FILE_SAVE_DIR 定义为:

复制代码
项目根目录/tmp

所以下载目录实际是:

复制代码
项目根目录/tmp/download

工具内部会创建目录,然后调用 Hutool 的 HttpUtil.downloadFile() 下载资源。(GitHub)

这个工具适合处理:

复制代码
下载图片
下载网页资源
下载文档
保存外部文件

但它也需要注意安全问题,比如 URL 白名单、文件大小限制、文件类型限制和文件名安全检查。


14. FileOperationTool:文件读写工具

FileOperationTool 提供两个工具方法:

复制代码
readFile
writeFile

它们都操作:

复制代码
FileConstant.FILE_SAVE_DIR + "/file"

也就是:

复制代码
项目根目录/tmp/file

readFile 根据文件名读取 UTF-8 文本内容;writeFile 根据文件名和内容写入文本文件,写入前会创建目录。源码中可以看到,这两个方法都通过 Hutool 的 FileUtil 完成文件读写。(GitHub)

可以理解为:

复制代码
writeFile:
把模型生成的内容保存成本地文件。

readFile:
把本地文件内容读出来交给模型。

例如,用户可以说:

复制代码
把刚才的约会计划保存成 plan.txt
读取 plan.txt 并帮我优化一下

这个工具让 Agent 具备了简单的文件状态管理能力。


15. PDFGenerationTool:PDF 生成工具

PDFGenerationTool 的作用是:

复制代码
把给定内容生成 PDF 文件

它的工具方法是:

复制代码
@Tool(description = "Generate a PDF file with given content", returnDirect = false)
public String generatePDF(String fileName, String content)

源码中,它会把 PDF 保存到:

复制代码
FileConstant.FILE_SAVE_DIR + "/pdf"

也就是:

复制代码
项目根目录/tmp/pdf

实现上,它使用 iText 创建 PdfWriterPdfDocumentDocument,并使用 STSongStd-LightUniGB-UCS2-H 字体配置来支持中文内容写入。(GitHub)

这个工具让智能体可以从"生成文字建议"进一步变成:

复制代码
生成一份真实 PDF 报告

例如:

复制代码
帮我生成一份周末约会计划 PDF
帮我把恋爱沟通建议整理成 PDF

当前方法返回的是 PDF 文件保存路径,而不是直接返回文件流。因此如果后续接入 Web 接口,还需要额外提供文件下载接口。


16. TerminalOperationTool:终端执行工具

TerminalOperationTool 的作用是:

复制代码
执行终端命令

它的工具方法接收一个参数:

复制代码
command

源码中使用:

复制代码
new ProcessBuilder("cmd.exe", "/c", command)

启动命令,因此当前实现更偏 Windows 环境。它会读取标准输出,如果退出码非 0,则追加错误退出码信息。(GitHub)

这个工具能力很强,但风险也最大。

它意味着模型可能触发系统命令执行。

在学习项目中,它可以用于验证 Agent 的自动执行能力;但在正式系统中,不能直接暴露无限制终端执行。

至少需要增加:

复制代码
命令白名单
工作目录限制
危险命令拦截
超时时间限制
输出长度限制
权限隔离
沙箱环境
人工确认机制

否则会带来严重安全风险。


17. TerminateTool:任务终止工具

TerminateTool 是一个比较特殊的工具。

它不是获取信息,也不是执行系统动作,而是用于流程控制。

源码中它的描述是:当请求已经满足,或者助手无法继续推进任务时,调用该工具终止交互;工具方法 doTerminate() 返回"任务结束"。(GitHub)

可以理解为:

复制代码
让自主规划型智能体知道什么时候停下来

在复杂 Agent 中,模型可能会循环执行:

复制代码
搜索
抓取
分析
再搜索
再抓取
再分析

如果没有终止机制,智能体可能不知道什么时候结束任务。

TerminateTool 的作用就是给模型一个明确的结束动作。


18. 当前工具能力之间如何组合?

这些工具单独看都比较简单,但真正有价值的是组合。

例如用户提出:

复制代码
帮我做一份周末约会计划,并保存成 PDF。

模型可能形成这样的工具调用链:

复制代码
1. 调用 WebSearchTool 搜索约会地点
2. 调用 WebScrapingTool 抓取相关网页内容
3. 整理出约会路线和建议
4. 调用 PDFGenerationTool 生成 PDF
5. 调用 TerminateTool 结束任务

再比如用户提出:

复制代码
把这份计划保存到文件里,之后我再修改。

工具链可能是:

复制代码
1. 模型生成计划文本
2. 调用 FileOperationTool.writeFile 写入 plan.txt
3. 后续调用 FileOperationTool.readFile 读取 plan.txt
4. 模型继续优化内容

所以 Tool Calling 的价值不在于某个工具本身,而在于:

复制代码
模型可以根据任务目标,动态选择和组合多个工具。

19. Tool Calling 和 RAG 的区别

Tool Calling 和 RAG 都能增强模型能力,但它们解决的问题不同。

复制代码
RAG:
从知识库中检索已有知识,增强回答依据。

Tool Calling:
调用外部工具获取信息或执行动作。

举个例子:

复制代码
用户问:异地恋如何维持关系?

适合 RAG:
检索本地恋爱知识库中的"异地恋沟通建议"。

用户问:帮我搜索这个周末北京有什么适合情侣的活动。

适合 Tool Calling:
调用 WebSearchTool 搜索最新网页信息。

也可以组合:

复制代码
RAG 提供稳定领域知识
Tool Calling 获取实时外部信息
模型整合两者生成回答

所以两者不是替代关系,而是互补关系。


20. Tool Calling 和 Advisor 的区别

前面几期分析过 Advisor。

这里也要区分:

复制代码
Advisor:
增强模型调用流程。

Tool Calling:
让模型可以调用外部能力。

例如:

复制代码
MessageChatMemoryAdvisor:
负责把历史对话加入上下文。

QuestionAnswerAdvisor:
负责把检索文档加入上下文。

MyLoggerAdvisor:
负责记录请求和响应。

ToolCallback[]:
负责暴露一组可以被模型调用的工具。

LoveApp 中,Advisor 是这样接入的:

复制代码
.advisors(...)

工具是这样接入的:

复制代码
.toolCallbacks(allTools)

源码中 doChatWithTools() 同时使用了这两者:它用 Advisor 注入会话 ID 和日志能力,用 toolCallbacks(allTools) 注入工具能力。(GitHub)

所以二者处于不同层次:

复制代码
Advisor 是对话链路增强器
Tool 是模型可调用的外部执行能力

21. 当前实现的优点

21.1 工具集中注册

所有工具都在 ToolRegistration 中集中创建,并统一转换成 ToolCallback[]

这样 LoveApp 不需要逐个 new 工具,只需要注入:

复制代码
@Resource
private ToolCallback[] allTools;

这让工具管理更清晰。(GitHub)


21.2 工具类型覆盖较全

当前项目已经包含:

复制代码
搜索
抓取
下载
文件读写
终端执行
PDF 生成
任务终止

这些能力覆盖了一个 Agent 从信息获取到结果交付的基本流程。(GitHub)


21.3 与 ChatClient 主链路结合自然

工具调用没有另起一套系统,而是直接挂在:

复制代码
chatClient.prompt()

链路上。

这说明项目仍然保持了统一的智能体调用结构:

复制代码
ChatClient 主链路
    + ChatMemory
    + MyLoggerAdvisor
    + ToolCallback[]

21.4 可扩展性强

新增工具时,只需要:

复制代码
1. 新建一个工具类
2. 写一个带 @Tool 的方法
3. 在 ToolRegistration 中注册

这样模型就可以在工具列表中看到这个新工具。


22. 当前实现可以改进的地方

22.1 工具权限需要分级

当前 doChatWithTools() 一次性注入了所有工具:

复制代码
.toolCallbacks(allTools)

这意味着模型在该模式下可以看到全部工具,包括终端执行工具。(GitHub)

更安全的方式是按场景分组:

复制代码
基础工具组:
文件读写、PDF 生成

联网工具组:
网页搜索、网页抓取、资源下载

高风险工具组:
终端执行

流程工具组:
任务终止

不同任务只注入必要工具。


22.2 TerminalOperationTool 需要沙箱

当前终端工具直接执行:

复制代码
cmd.exe /c command

这在正式环境中风险很高。(GitHub)

建议增加:

复制代码
命令白名单
禁止 rm/del/format 等危险命令
限制工作目录
限制执行时间
限制输出长度
以低权限用户运行
Docker 沙箱隔离
高风险命令人工确认

22.3 文件名需要安全校验

FileOperationToolResourceDownloadToolPDFGenerationTool 都根据用户提供的 fileName 拼接本地路径。(GitHub)

这需要防止:

复制代码
../ 路径穿越
特殊字符
覆盖关键文件
超长文件名
非法扩展名

可以把文件名限制为:

复制代码
字母、数字、下划线、短横线、点号

并且强制所有文件只能写入 tmp 子目录。


22.4 网页抓取结果需要清洗

WebScrapingTool 当前返回的是完整 HTML。(GitHub)

后续可以改成:

复制代码
只返回正文文本
过滤 script/style
限制最大字符数
提取标题和段落
保留链接来源

这样可以减少无关内容进入模型上下文。


22.5 搜索结果需要结构化

WebSearchTool 当前把前 5 条搜索结果的 JSON 对象拼接成字符串返回。(GitHub)

后续可以把结果整理成更清晰的格式:

复制代码
标题
摘要
链接
来源
排名

这样模型更容易使用搜索结果。


22.6 工具调用需要审计日志

当前有 MyLoggerAdvisor 观察模型请求和响应,但工具执行本身也应该有独立日志。

建议记录:

复制代码
工具名称
调用参数
调用时间
执行耗时
执行结果摘要
是否成功
错误信息
调用用户
会话 ID

尤其是文件写入、资源下载和终端执行这类工具,必须有审计记录。


23. 当前项目中暂未重点使用 ToolContext

Spring AI 中除了普通工具参数外,还可以使用一些更高级的工具上下文机制。但从当前 tool 目录下这些工具类的源码看,项目主要使用的是 @Tool@ToolParam,没有明显看到工具方法中使用 ToolContext 传递用户 ID、会话 ID 或其他运行时上下文。(GitHub)

后续如果要做正式 Agent,可以考虑引入工具上下文,用于传递:

复制代码
当前用户 ID
当前会话 ID
当前权限级别
当前工作目录
当前任务 ID
是否允许联网
是否允许执行高风险工具

这样工具执行就可以结合业务身份和权限控制,而不是只依赖模型生成的参数。


24. 我的理解

我认为 ai_agent 项目的 Tool Calling 设计,最值得学习的是它展示了一个 Agent 从"问答"到"执行"的基本扩展方式。

前面的 ChatClient、Advisor、ChatMemory、RAG 主要解决:

复制代码
如何让模型更好地回答?

而 Tool Calling 解决的是:

复制代码
如何让模型借助外部工具完成任务?

在这个项目中,工具调用链路可以总结为:

复制代码
Tool 类定义能力
@Tool 描述能力
ToolRegistration 注册能力
ToolCallback[] 暴露能力
LoveApp 注入能力
模型选择能力
后端执行能力
模型整合结果

这就是 Agent 的基本执行闭环。


25. 本期重点理解

这一期最重要的是理解 Tool Calling 的基本机制。

可以总结为五点:

复制代码
第一,Tool Calling 让模型可以请求调用外部工具,从而突破纯文本回答的限制。
第二,模型本身不直接执行工具,真实执行由应用程序完成。
第三,项目通过 @Tool 和 @ToolParam 把 Java 方法声明为可调用工具。
第四,ToolRegistration 负责统一创建工具对象,并转换成 ToolCallback[]。
第五,LoveApp 通过 .toolCallbacks(allTools) 把工具列表注入当前 ChatClient 调用。

一句话概括:

复制代码
ai_agent 的 Tool Calling 机制,是通过 ToolRegistration 把一组 Java 工具方法注册为 ToolCallback[],再由 LoveApp 注入模型调用,使模型能够根据任务需要调用搜索、抓取、下载、文件、终端和 PDF 等外部能力。

26. 本期小结

本期主要分析了 ai_agent 项目中的 Tool Calling 工具调用机制。项目在 tool 目录下实现了多个工具类,包括网页搜索、网页抓取、资源下载、文件读写、终端执行、PDF 生成和任务终止。每个工具方法通过 @Tool 声明为可调用工具,并通过 @ToolParam 描述参数含义。ToolRegistration 作为集中注册类,创建所有工具对象,并通过 ToolCallbacks.from(...) 转换为 ToolCallback[]。在 LoveAppdoChatWithTools() 方法中,系统通过 .toolCallbacks(allTools) 把工具列表注入到当前模型调用中,使模型能够根据用户任务自动选择工具、生成参数,并在工具执行结果返回后组织最终回答。

这一期可以用一句话总结:

复制代码
Tool Calling 让 LoveApp 从"能够回答恋爱问题的智能体",进一步变成"能够搜索信息、读写文件、下载资源、执行命令并生成 PDF 的任务型智能体"。

下一期可以继续分析:

AI Agent 项目学习笔记(九):网页搜索、网页抓取与资源下载工具

下一期重点分析 WebSearchToolWebScrapingToolResourceDownloadTool 的源码实现,理解 Agent 如何通过联网工具获取外部信息,并讨论搜索结果清洗、网页正文抽取、下载安全和工具调用审计等问题。

相关推荐
企学宝1 小时前
企学宝5月专题课程丨《OpenClaw AI 智能体实战营:从零基础部署到全场景自动化落地》
人工智能·ai·企业培训
冬奇Lab2 小时前
让 AI Agent 更可靠:Harness Engineering 与多 Agent 系统工程实践
人工智能·llm·agent
放下华子我只抽RuiKe52 小时前
React 从入门到生产(四):自定义 Hook
前端·javascript·人工智能·深度学习·react.js·自然语言处理·前端框架
想你依然心痛2 小时前
HarmonyOS 6(API 23)实战:基于悬浮导航、沉浸光感与HMAF的“文思智脑“——PC端AI智能体沉浸式智能写作工作台
人工智能·ar·harmonyos·ai写作
冬奇Lab2 小时前
一天一个开源项目(第108篇):Andrej Karpathy Skills - 用一个 CLAUDE.md 文件修复 LLM 编码的四个顽疾
人工智能·开源·资讯
涛声依旧-底层原理研究所2 小时前
残差连接与层归一化通俗易懂的详解
人工智能·python·神经网络·transformer
fantasy_arch2 小时前
pytorch人脸匹配模型
人工智能·pytorch·python
科技那些事儿2 小时前
实时洞察,视觉赋能:国内情绪识别API公司推荐及计算机视觉流派深度解析
人工智能·计算机视觉