1、Agent的工具有哪些类型?
在往期文章中我们知道Agent的工具有五类:感知、执行、协作、用户沟通 以及事件触发。

(1)感知工具
这是Agent主动 获取信息、感知世界的方式,例如网络搜索工具和内部知识库检索工具。感知工具的设计关键在于控制输出信息量,防止上下文爆炸。
(2)执行工具
这是Agent改变外部世界的方式,例如命令行工具和发送邮件工具。执行工具相较感知工具他的错误代价可能极高 ,安全约束是其设计的核心。
(3)协作工具
这是Agent与其他Agent以及人类协作的方式,例如创建子Agent和发现系统中可用的Agent。在多Agent架构中,使用不同的模型、工具、提示词和上下文执行不同的任务能实现更好地效果。
(4)用户沟通工具
这是Agent主动向用户传递信息的方式,例如回复用户消息和++发送结构化卡片消息++ 。当Agent与用户的沟通从单一会话内的一问一答扩展到多渠道异步消息时,沟通本身也需要成为显式工具调用。
(5)事件触发工具
这是外部世界驱动Agent行动的方式,例如设置定时器和连接外部事件源。注册时 由Agent主动调用工具,声明自己关心什么事件;触发时由外部事件异步回调,唤醒Agent开始处理。
2、一个工具应该封装多大粒度的操作?
ACI(Agent-Computer Interface):工具应该对应Agent的目标而不是底层API操作。
工具封装的粒度主要是针对专用工具 而言的,粒度应该偏向++整合++而非细分。粒度太细会导致工具数量激增从而增加LLM的选择负担;粒度过粗又会使得单个工具过于复杂。
判断的核心标准:功能相似性 以及适用场景的重叠度,以文档处理举个例子:
存在extract_pdf_text、extract_docx_content、extract_pptx_content等多个工具,其共性在于都是从文档提取文本,输入的是文件路径,输出的是文本字符串。但是更好地设计方案是提供一个统一的read_document工具,内部通过file_type参数区分具体格式是PDF/DOC/PPTX。这样的整合降低了LLM的认知负担,他只需要理解读取文档就用read_document工具这一简单规则,使描述更清晰,也便于扩展(新增支持的格式只需要增加一个file_type选项)。
3、什么时候用专用工具,什么时候用通用执行器配合Skill?
专用工具:结构化的函数调用,确定性高、可测试、参数受schema约束,代价是每个工具的定义要占用数百个token;
Skill :用自然语言编写的skill文档来描述操作流程,Agent通过终端或代码解释器来执行,只需要少量的通用工具就能覆盖大量场景,一份skill在目录里只占用几十个token,正文用到时才读。
通用工具优于专用工具,除非有明确的安全、权限或性能理由。提供通用工具相当于给Agent一个"元能力"。
以下四种情况值得保留独立的专用工具:
(1)安全、权限与审计:涉及生产数据库写操作这类场景,专用工具能提供更精细的权限控制与审计粒度,一个开放的通用工具往往做不到;
(2)屏蔽平台差异、给出更好反馈:文件系统的grep和find虽然都能通过bash(通用工具)实现,但是在不同操作系统上的语法各不相同,因此大多数Coding Agent仍会保留专门的grep和find工具,以给出更清晰的行号反馈、并屏蔽平台间的参数差异;
(3)使用频率极高:高频的操作值得一个专属入口,哪怕它在功能上已经被通用工具覆盖;
(4)参数结构复杂:设计嵌套对象、多字段联合校验、复杂类型约束的操作,结构化schema能更好的引导模型正常传参。
而Skill的优势是对人类编写者更加友好,由于他对格式和语法没有严格要求,不会像代码那样因局部语法错误而牵一发动全身。
决策选择对照表
核心结论:专用工具强调安全性、结构化和执行确定性;通用执行器配合Skill强调灵活性、低成本维护和能力复用。实际Agent生产系统常采用混合设计:稳定、高风险的底层操作封装为专用工具,灵活多变的业务流程交给skill指导,底层执行权限始终由运行时控制。
4、工具描述怎样写,Agent才能知道何时调用?
工具描述的质量决定了Agent使用工具的准确性,它的核心是让LLM知道什么时候用而不只是能做什么。具体来说有以下几点需要注意:
(1)边界的声明:清晰列出工具的边界条件(做不到什么、不接受什么输入)往往比描述能力本身更加重要,因为大多数工具调用失败的根因不是模型不知道工具能做什么,而是不知道工具不能做什么;
(2)参数描述用具体例子代替抽象规范:虽然LLM在专注处理一个问题时能理解这些抽象术语,但是在执行复杂任务时,只能分出一部分注意力来确认参数格式,容易出错。例如不要写"phone:使用 E.164 格式",而应写"phone:电话号码,使用 E.164 格式(国家代码 + 号码,无空格或特殊字符),例如 +8613888888888(中国)或 +12025551234(美国)"。具体例子会让Agent直接套用,无需额外的思考步骤;
(3)返回值描述:"返回JSON数组,每个元素包含title、url、snippet三个字段"这类说明能减少后续解析时出错;对于耗时较长工具,注明执行代价有助于LLM合理规划调用顺序;
(4)附带真实调用示例:JSON Schema只能描述参数类型,却无法表达调用方式和典型的参数组合(时间戳按照秒还是毫秒、过滤条件如何嵌套)这类隐式约定用例子最容易传达。
当一个Agent频繁选错工具时,应优先检查工具描述而不是换模型。
5、为什么工具不能悄悄修改传入的参数?
下面以两种比较隐蔽的模式说明工具的参数问题:
(1)静默输入转换
工具在执行前悄悄修正模型的输入参数,导致实际操作偏离了模型的意图。
比如:一个工具接收old_string和new_string两个参数,在文件中精确匹配并替换。工具的参数传递层会将中文弯引号(" " ' ')静默转换为英文直引号(" " ' ')这导致模型极度困惑:模型通过读取工具看到文件中包含弯引号的文本(读取工具原样返回了弯引号,没有做转换)于是将其原样传入替换工具的old_string参数,但是参数传递层已经把弯引号换成了直引号,与文件中实际内容不匹配,工具返回未找到匹配。
(2)静默参数注入
工具在模型不知情的情况下向命令追加额外的参数。
例如某个IDE的bash工具为例,它在执行所有git commit命令时会自动添加一个额外参数,用于标记本次提交是AI生成,如果用户Git版本较低不支持该参数,这个静默的注入会导致提交报错。
故:模型感知到的世界与工具操作的世界之间,不能存在系统性的偏差。