深入浅出:Agent如何调用工具——从OpenAI Function Call到CrewAI框架

news/2025/1/14 23:13:56/文章来源:https://www.cnblogs.com/li-jian-Lee/p/18671888

深入浅出:Agent如何调用工具——从OpenAI Function Call到CrewAI框架

嗨,大家好!作为一个喜欢折腾AI新技术的算法攻城狮,最近又学习了一些Agent工作流调用工具的文章,学完之后,我真的是“啊这”,一边感慨AI技术的强大,一边觉得自己打开了新世界的大门。于是,我决定写这篇博客,把我的学习心得分享给大家!如果你对AI智能体、工具集成,以及如何让它们更“聪明”感兴趣,那千万别错过这篇文章!


引言:Agent与工具,天作之合?

Agent,直译就是“代理”,但在AI领域,它更像是一个“智能小帮手”,可以帮用户完成各种复杂任务,比如回答问题、处理数据,甚至操控其他系统。

但问题来了:Agent再智能,它的基础能力终归有限,比如它不可能自带所有最新的数据,也不可能直接执行某些复杂操作。这时候,就需要一个“外挂”神器——工具

工具可以赋予Agent超能力,比如:

  • 调用外部API:获取实时数据,比如天气、汇率。
  • 执行函数:进行复杂计算或数据处理。
  • 访问数据库:提取大规模业务数据。

Agent+工具的组合,就像盖伦拿到了一把三相之力(好吧,暴露年龄了),能力瞬间爆炸!而这篇调研报告的核心就是:如何设计这些工具,并让Agent高效调用它们。重点关注了OpenAI的Function Call机制CrewAI框架下的工具创建方法。下面,我就把我的学习心得分享给大家。

img


正文:拆解Agent调用工具的秘密

一、 工具是什么?分类了解一下!

在AI领域,工具可以理解为一些功能模块,通过标准化接口与Agent交互。文中将工具分为以下几类:

  1. 信息获取工具:比如调用API获取实时数据,或者从网页爬取信息。
  2. 计算处理工具:执行数学运算、运行代码,甚至处理图像。
  3. 交互工具:比如发邮件、推送消息。
  4. 控制工具:调整Agent的参数,或者控制它的行为,比如让它“安静点”。

引入工具,可以让Agent像开了挂一样,具备模型本身无法完成的能力。就好比给钢铁侠的战甲装上各种黑科技,简直不要太爽!

img


二、Agent中集成工具的步骤

想要把工具整合到Agent中,大体需要以下几个步骤:

  1. 工具注册:注册工具的schema,通常包括工具的名称、功能描述和接口参数的定义。

  2. 接口设计:为工具设计标准化的接口,确保Agent能以统一的方式与工具交互。比如,使用REST API或函数接口作为工具与Agent通信的桥梁。

  3. 环境适配与优化:确保工具与Agent的协同工作状态,需要考虑操作系统兼容性、依赖库安装等问题。同时还需要优化工具的性能和响应速度。

这三个步骤确保了Agent能够正确识别和调用工具,发挥工具的功能,增强Agent的能力。

img


三、Agent如何调用工具的原理

Agent调用工具的过程涉及到任务理解工具选择参数传递结果处理。下面,我们分别看看OpenAI的Function Call机制CrewAI框架下的调用机制。

3.1 OpenAI Function Call调用机制

3.1.1 概念解析

OpenAI的Function Call机制是GPT模型的一种扩展能力,允许Agent调用预定义的工具(函数)。在这个机制中,开发者通过提供函数的签名及其功能描述,让模型能够动态地选择、调用并与这些工具交互。

调用过程的核心是:

  1. 函数注册:提供函数的名称、功能描述和参数定义。

  2. 自然语言解析:模型通过对用户输入的自然语言理解,判断是否需要调用函数来完成任务。

  3. 函数调用与返回:模型生成调用函数的参数,执行调用,接收函数返回值并完成任务。

3.1.2 数据流与调用流程

  1. 用户输入

    • 用户向Agent发送请求,例如“请帮我查询明天北京的天气”。
  2. 任务解析

    • GPT模型分析用户输入,判断是否需要调用函数。
  3. 生成函数调用参数

    • 根据函数描述,GPT模型自动生成调用所需的参数。
  4. 调用函数

    • Agent通过后端的工具接口执行实际的函数调用,并获取返回值。
  5. 返回结果

    • 函数返回的结果会被模型处理,并以自然语言的形式呈现给用户。

调用流程可以用下面这个图示简单表示:

graph LR用户 --> 问题问题 --> |prompt|LLM模型LLM模型 --> |匹配可用函数/工具| 生成ToolCal生成ToolCal --> |传参并调用|应用程序应用程序 --> |执行函数| 返回ToolCallRespons返回ToolCallRespons --> LLM模型LLM模型 --> |生成自然语言的用户响应| 用户

3.1.3 技术实现

在设计和实现智能Agent时,核心挑战之一在于如何让Agent高效完成任务。Agent需要具备以下能力:理解用户意图、判断是否需要调用工具、精准生成工具调用参数,并将调用结果格式化为用户可理解的自然语言输出。

1) 理解用户意图

在OpenAI Function Call中,意图识别的核心依赖于模型对工具描述的理解。以下是具体流程:

  1. 工具描述注册

    • 在模型中注册工具时,需要提供详细的功能说明和参数说明。

      functions = [{"name": "query_weather","description": "查询天气信息。","parameters": {"type": "object","properties": {"city": {"type": "string", "description": "城市名称"},"date": {"type": "string", "description": "查询日期"}},"required": ["city", "date"]}}
      ]
      
  2. 模型推断意图

    • 用户输入后,模型通过上述工具描述推断用户意图。例如,用户输入:“查询明天北京的天气。” ,模型会识别出“query_weather”工具最符合需求。GPT会根据用户输入,自动提取并生成参数,比如从“明天北京”中提取city="北京"date="明天"

    img

  3. 动态决定调用

    • 如果function_call="auto",模型会自动判断是否需要调用工具。进一步,如果模型认为用户意图需要调用某个工具,会生成一个函数调用请求,包含工具名称和参数。
2) 判断是否需要调用工具

Agent需要根据用户输入动态判断是否调用工具。这一过程依赖于几方面的机制:

  1. 模型内能力 vs 工具能力
    • 如果任务可以通过模型自身的知识完成(例如回答“GPT是什么?”),则不调用工具。
    • 如果任务需要实时信息、外部数据或复杂计算(例如“今天的汇率是多少?”),则调用工具。
  2. 工具匹配度
    • 工具的匹配度依赖于工具的功能描述,模型通过语义相似度判断。

img

3) 精准生成工具调用参数

生成工具调用参数是工具调用中的关键步骤。参数的准确性直接影响工具的执行结果。

  1. 工具描述驱动

    • 工具的参数定义(如参数名称、类型、描述等)是模型生成参数的重要依据
    • 模型会根据用户输入中的关键信息提取参数值。
  2. 用户输入补全

    • 如果用户输入不完整,模型会尝试根据上下文或知识补全。例如,输入“查一下北京的天气”,缺少日期信息时,模型可能自动补全为当天的日期。
  3. 参数校验与修正

    • 传参前,后端需要对模型生成的参数进行校验。例如,检查日期格式是否符合要求。

img

举个栗子,假设我们有一个处理CAD文件的函数:

functions = [{"name": "process_cad_file","description": "处理CAD图纸文件,提取设备信息并生成统计报告","parameters": {"type": "object","properties": {"file_path": {"type": "string","description": "CAD文件的路径,支持.dwg格式"}},"required": ["file_path"]}},
]

当用户输入“请帮我处理这个CAD图纸:project.dwg”时,模型会自动生成函数调用:

{"function_call": {"name": "process_cad_file","arguments": "{\"file_path\": \"project.dwg\"}"}
}

3.2 CrewAI框架调用机制

CrewAI是一个基于LangChain的开源Agent框架,提供了方便的工具集成和Agent构建能力。在CrewAI中,工具的创建和调用也非常灵活。

3.2.1 工具注册与调用流程

  1. 工具定义:通过继承CrewAI的基类或使用装饰器定义工具。

  2. 工具注册:将工具注册到Agent,使其可以被调用。

  3. Agent处理用户输入:Agent会解析用户输入,自动匹配适合的工具。

  4. 执行工具逻辑:调用工具的run方法,获取结果。

  5. 结果返回:将工具结果直接返回给用户。

img


四、工具创建的具体方法

4.1 基于OpenAI Function Call的工具创建

4.1.1 工具定义与注册

在OpenAI的Function Call机制中,工具(函数)的定义需要提供详细的描述和参数schema。步骤如下:

  1. 定义函数逻辑:编写实际执行任务的函数。

  2. 编写函数描述:包括函数名称、功能描述、参数类型和说明。

  3. 注册函数:在调用模型时,通过functions参数传递函数描述列表。

def calculate_sum(a, b):return a + bfunctions = [{"name": "calculate_sum","description": "计算两个数的和。","parameters": {"type": "object","properties": {"a": {"type": "number", "description": "第一个数"},"b": {"type": "number", "description": "第二个数"}},"required": ["a", "b"]}}
]

4.1.2 调用与参数处理

  1. 模型调用:设置function_call参数为"auto",模型会自动决定是否调用函数。

  2. 解析函数调用:从模型返回结果中提取function_call信息,获取函数名称和参数。

  3. 执行函数:调用实际的函数逻辑,并获取结果。

  4. 结果处理:将函数结果转换为自然语言,返回给用户。

4.2 基于CrewAI框架的工具创建

除了可以直接使用CrewAI框架下提供的工具(包括 CrewAI Toolkit 和 LangChain Tools 的工具),还可以创建自己的专属工具。

4.2.1 创建自定义工具

在CrewAI中创建工具非常简单:

  1. 使用装饰器@tool定义工具:

    from crewai.tools import tool  @tool("查询天气")  
    def query_weather(city: str, date: str):  return f"{city}在{date}的天气是晴天,气温5°C。"  
    
  2. 或者继承BaseTool实现工具:

    from crewai.tools import BaseTool  class WeatherTool(BaseTool):  name = "查询天气"  description = "根据城市和日期查询天气。"  def _run(self, city: str, date: str):  return f"{city}在{date}的天气是晴天,气温5°C。"  
    
  3. 更多的时候还可以使用API来包装函数为结构化工具

from crewai.tools.structured_tool import CrewStructuredTool
from pydantic import BaseModelclass WeatherTool(BaseModel):file_path: strprocess_type: strdef query_weather(file_path: str, process_type: str):# 实现处理逻辑return "处理结果"queryweather = CrewStructuredTool.from_function(name="查询天气",description="根据城市和日期查询天气",func=query_weather
)

CrewAI的调用机制与Function Call类似,但支持更复杂的任务分解。比如多个工具可以协同合作,完成一个复杂任务。


五、工具创建的设计考虑

在创建工具时,需要注意以下设计细节:

1. 输入与输出的明确性

  • 输入参数:定义清晰的输入结构和类型,避免模型生成无效参数。
  • 输出结构:确保输出结果可以直接供Agent使用,尽量采用标准化格式(如JSON)。

2. 错误处理

  • 参数校验:在工具逻辑中对参数进行校验,例如检查日期格式是否正确。
  • 异常处理:考虑API调用失败或超时的情况,并返回友好的错误信息。

3. 工具的功能粒度

  • 功能过于笼统可能导致工具逻辑复杂化,建议每个工具只专注于单一功能。
  • 如果任务较复杂,可以分解为多个工具,并通过Agent协调它们的调用。

我觉得,这些设计考虑对于提升Agent的开发效率和性能非常重要!毕竟,没有人喜欢和一个总是出错的Agent对话,对吧?

img


结论:Agent的未来,更智能,更无所不能

通过这篇文章,我深刻感受到,Agent的智能化很大程度上依赖工具的设计和调用能力。无论是OpenAI的Function Call,还是CrewAI框架,都在探索如何让Agent具备更强大的外部能力。

我们可以畅想一下未来:

  • 医疗助手通过调用诊断工具,秒出治疗方案。
  • 智能家居通过集成控制工具,真正实现“懒人生活”。
  • 企业AI通过调用数据工具,精准分析业务决策。

总之,Agent+工具的组合,无疑是AI发展的重要方向。如果你也是AI开发者,不妨尝试用这些技术,打造属于自己的智能Agent!

最后一句废话:作为一个热爱AI技术的算法攻城狮,我真的很享受探索这些新奇有趣的东西。学习的过程虽然有时候会遇到困难,但当你突破瓶颈的那一刻,真的是爽到飞起!好了,不扯了,期待下次能和大家分享更多有趣的内容。掰掰~

img


参考资料

  • OpenAI 官方文档
  • LangChain 文档
  • CrewAI GitHub 仓库

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/869305.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在Ubantu中安装pycharm

1.下载pycharm linux版,我下载的是2022.3.3专业版 2. 更改host文件,输入: sudo gedit /etc/hosts在弹出的文件中的末尾加以下代码: 0.0.0.0 account.jetbrains.com3.激活pycharm: 将pycharm补丁jet-netfilter拷入ubantu中某一路径(注意是整个文件夹放进去,不要只放jar包…

docker-compose自动部署go项目全流程,本地到镜像仓库到服务器,踩坑笔记

声明:个人所学记录,有可以改进的地方希望不吝指教 Dockerfile # 使用golang官方镜像作为构建环境 FROM golang:1.23-alpine AS builder# 设置工作目录 WORKDIR /app# 设置环境变量镜像变量 ENV GO111MODULE=on ENV GOPROXY=https://goproxy.cn,direct# 复制go.mod 和 go.sum文…

docker部署d2l环境

编写dockerfile # 使用NVIDIA提供的CUDA基础镜像,包含CUDA 11.8.0和cuDNN 8,基于Ubuntu 22.04 FROM nvidia/cuda:11.8.0-cudnn8-devel-ubuntu22.04 # 设置维护者信息 MAINTAINER watcherprime <woma@126.com># 设置环境变量,包括时区、非交互式前端和PATH变量 ENV TZ=…

【TCP协议】TCP Keepalive 指南

1、什么是 TCP Keepalive?TCP Keepalive 是一种 TCP 协议内置的探测机制,用于检测长时间未活动的连接是否仍然存活。当启用了 Keepalive 后,TCP 会在连接空闲一定时间后,定期向对端发送探测包,如果未收到对端的响应,则会尝试多次探测,最终关闭连接。 用途: 检测并清理死…

《CPython Internals》阅读笔记:p151-p151

《CPython Internals》学习第 9天,p151-p1510 总结,总计 1 页。 一、技术总结 无。 二、英语总结(生词:1) 1.marshal (1)marshaling Marshalling or marshaling(US spelling) is the process of transforming the memory representation of an object into a data form su…

# vm逆向

vm逆向 虚拟机逆向与实现-CSDN博客 对上面博客的总结。 引 vm逆向题,一般是小型虚拟机程序,可以理解为一种模拟器,有start,dispatcher,opcode等结构。常见使用while-switch/if这类循环+选择结构来实现简单的虚拟机模拟,如下:逆向重点:分析入口,搞清输入和opcode的位置理…

【Gossip 协议】Redis 集群中节点之间的通信方式?

# 分布式系统 # Gossip 协议 在分布式系统中,不同的节点进行数据/信息共享是一个基本的需求。 一种比较简单粗暴的方法就是 集中式发散消息,简单来说就是一个主节点同时共享最新信息给其他所有节点,比较适合中心化系统。这种方法的缺陷也很明显,节点多的时候不光同步消息的…

推荐一款超棒的 Minecraft 启动器:Voxelum/x-minecraft-launcher

X Minecraft Launcher (XMCL) 是一个便于你管理多种整合包、模组、资源包、光影包的现代化启动器。它还支持 Minecraft Forge、 Fabric、Quilt、CurseForge 和 Modrinth它具有以下令人心动的特点:多版本兼容性:支持多个 Minecraft 版本,正式版和愚人节版本。自动化资源下载与…

互联网大中小厂实习面经:滴滴、美团、货拉拉、蔚来、信通院等

本文介绍Momenta、蔚来、中国信息通信研究院、昆仑万维、滴滴、易智瑞等企业各类技术岗位的暑期实习、日常实习面试流程与具体问题~本文介绍Momenta、蔚来、中国信息通信研究院、昆仑万维、滴滴、易智瑞等企业各类技术岗位的暑期实习、日常实习面试流程与具体问题。在前一段时间…

2025年1月买的几个好用的「新物件」

前言 去年底比较忙,换工作+搬家什么的,一堆事情凑在一起,很多24年买的东西还没发开箱 只能后面慢慢补上了,现在先把1月份买的一些东西发一下 红米k80手机 本来我是不想买手机的 不过办了新的套餐,营业厅送了购机补贴,不是很多,所以在补贴范围内选择了「看起来」性价比最…

安卓平板使用can-utils检查can通信功能

安装 termux 打开安卓平板 USB 调试模式,并确保电脑安装了 adb。 下载 termux,通过adb install ./termux.exe安装 termux 到安卓平板。 设置 termux 换源 安装好 termux 后打开,进行换源操作。 termux 中输入termux-change-repo。空格切换选中状态,移动方向键切换选中项目,…

最小系统板五要素

最小系统板五要素 电源在进入芯片的时候需要旁路电容将高频杂散干扰旁路掉VBAT:备用电池 VDD:普通电源 VDDA:ADC信号的电源地VSS:普通地 VSSA:ADC的地晶振给单片机提供时钟脉冲,具体的电容值参考晶振手册??OSC: 外部高速晶振 OSC32: 外部低速晶振复位上电复位和按键复位…