返回顶部
热门问答 更多热门问答
技术文章 更多技术文章

又一突破!跨模型的Function_Calling来了

[复制链接]
链载Ai 显示全部楼层 发表于 1 小时前 |阅读模式 打印 上一主题 下一主题

本文经翻译并二次整理自Tool Calling with LangChain一文。为了简化和统一与各种大型语言模型(LLM)提供商的工具调用API的交互,LangChain正在针对 AIMessage 引入一个名为 tool_calls 的新属性。本系列合集,点击链接查看

介绍

大型语言模型(LLM)通过工具调用能够与外部数据源进行交互。这项技术让开发者能够利用LLM来获取、交互和操作外部资源(比如数据库、文件和API等)。

随着越来越多的LLM提供商开始提供工具调用功能,我们注意到市场上出现了多种多样的接口。为了解决这个问题,LangChain推出了一个标准化的接口,这样用户就可以轻松地在不同的LLM提供商之间进行切换。

这个标准化接口包括以下几个方面:

  • ChatModel.bind_tools:这个方法允许您将工具的定义附加到模型的调用过程中。
  • AIMessage.tool_calls:这是一个新增的属性,它使得从模型返回的 AIMessage 中获取工具调用变得更加简单。
  • create_tool_calling_agent:这是一个构建代理的函数,适用于任何实现了 bind_tools 并且能够返回 tool_calls 的模型。

下面,我们将详细解释这些组件。

ChatModel.bind_tools

为了让模型能够使用工具,我们需要告诉它哪些工具是可以使用的。这可以通过向模型提供一个包含工具定义的列表来实现,这些工具定义包括了工具参数的模式。不同的模型提供商可能需要不同的格式,但是 ChatModel.bind_tools 提供了一个统一的接口,让您可以指定哪些工具对模型来说是可用的。

这意味着,无论您使用的是哪种工具调用模型,代码的结构都将非常相似。

fromlangchain_anthropicimportChatAnthropic
fromlangchain_core.pydantic_v1importBaseModel,Field
fromlangchain_core.toolsimporttool

#✅Pydantic类
classmultiply(BaseModel):
"""返回'x'和'y'的乘积。"""
x:float=Field(...,description="第一个因子")
y:float=Field(...,description="第二个因子")

#✅LangChain工具
@tool
defexponentiate(x:float,y:float)->float:
"""将'x'乘以'y'。"""
returnx**y

#✅函数

defsubtract(x:float,y:float)->float:
"""从'y'中减去'x'。"""
returny-x

#✅OpenAI格式字典
#还可以传入一个带有"title"和"description"的JSON模式
add={
"name":"add",
"description":"将'x'和'y'相加。",
"parameters":{
"type":"object",
"properties":{
"x":{"type":"number","description":"要相加的第一个数字"},
"y":{"type":"number","description":"要相加的第二个数字"}
},
"required":["x","y"]
}
}

llm=ChatAnthropic(model="claude-3-sonnet-20240229",temperature=0)

#每当我们调用`llm_with_tool`时,这三个工具定义
#都会被传递给模型。
llm_with_tools=llm.bind_tools([multiply,exponentiate,add,subtract])

如果我们想使用不同的工具调用模型,我们的代码看起来会非常相似:

fromlangchain_openaiimportChatOpenAI

llm=ChatOpenAI(model="gpt-4-turbo",temperature=0)
llm_with_tools=llm.bind_tools([multiply,exponentiate,add,subtract])

那么调用 llm_with_tools 会是什么样子呢?这就是 AIMessage.tool_calls 的用武之地。

AIMessage.tool_calls

在过去,当使用工具调用模型时,模型返回的工具调用可能会放在 AIMessage.additional_kwargsAIMessage.content 中,这取决于模型提供商的API,并遵循特定于提供商的格式。现在,AIMessage.tool_calls 提供了一个标准化的接口来获取模型的工具调用。这样,在调用了绑定了工具的模型之后,您将得到一个包含 tool_calls 属性的输出,其中列出了所有的工具调用。

在调用了绑定工具的模型之后,您将得到以下形式的输出:

llm_with_tools.invoke([
("system","你是一个有用的助手"),
("human","5的2.743次方是多少"),
])

#?注意tool_calls属性?

#->AIMessage(
#content=...,
#additional_kwargs={...},
#tool_calls=[{'name':'exponentiate','args':{'y':2.743,'x':5.0},'id':'54c166b2-f81a-481a-9289-eea68fc84e4f'}]
#response_metadata={...},
#id='...'
#)

其中 AIMessage 有一个 tool_calls: List[ToolCall] 属性,如果有工具调用,它将被填充,并将遵循工具调用的标准接口:

classToolCall(TypedDict):
name:str
argsict[str,Any]
id:Optional[str]

也就是说,无论您是在调用 Anthropic、OpenAI、Gemini 等,只要有工具调用,它将以 AIMessage.tool_calls 形式作为 ToolCall 出现。

我们还添加了一些其他属性,用于处理流式工具调用块和无效工具调用。有关这些的更多信息,请阅读工具调用文档 这里。

create_tool_calling_agent

利用LLM的工具调用能力来构建代理是一个非常强大的应用场景。我们已经有了一个 create_openai_tools_agent() 构造函数,它可以方便地构建一个符合OpenAI工具调用API的代理。但是,这个构造函数并不适用于Anthropic和Gemini等模型。现在,有了 bind_tools()tool_calls 这两个新接口,我们推出了 create_tool_calling_agent(),它能够与任何支持工具调用的模型一起工作。

fromlangchain_core.promptsimportChatPromptTemplate
fromlangchain_core.runnablesimportConfigurableField
fromlangchain_core.toolsimporttool
fromlangchain.agentsimportcreate_tool_calling_agent,AgentExecutor

@tool
defmultiply(x:float,y:float)->float:
"""将'x'乘以'y'。"""
returnx*y

@tool
defexponentiate(x:float,y:float)->float:
"""将'x'乘以'y'的指数。"""
returnx**y

@tool
defadd(x:float,y:float)->float:
"""将'x'和'y'相加。"""
returnx+y

prompt=ChatPromptTemplate.from_messages([
("system","你是一个有用的助手"),
("human","{input}"),
("placeholder","{agent_scratchpad}"),
])

tools=[multiply,exponentiate,add]

llm=ChatAnthropic(model="claude-3-sonnet-20240229",temperature=0)

agent=create_tool_calling_agent(llm,tools,prompt)
agent_executor=AgentExecutor(agent=agent,tools=tools,verbose=True)

agent_executor.invoke({"input":"3 加上 5 的 2.743 次方是多少。还有 17.24 减去 918.1241 是多少。"})

我们可以使用 VertexAI 替代:

fromlangchain_google_vertexaiimportChatVertexAI

llm=ChatVertexAI(
model="gemini-pro",
temperature=0,
convert_system_message_to_human=True
)
agent=create_tool_calling_agent(llm,tools,prompt)
agent_executor=AgentExecutor(agent=agent,tools=tools,verbose=True)

agent_executor.invoke({"input":"3 加上 5 的 2.743 次方是多少。还有 17.24 减去 918.1241 是多少。"})

或者 OpenAI:

llm=ChatOpenAI(model="gpt-3.5-turbo-0125",temperature=0)

agent=create_tool_calling_agent(llm,tools,prompt)
agent_executor=AgentExecutor(agent=agent,tools=tools,verbose=True)

agent_executor.invoke({"input":"3 加上 5 的 2.743 次方是多少。还有 17.24 减去 918.1241 是多少。"})

等等。

有关新代理的完整文档,请查看 https://python.langchain.com/docs/modules/agents/agent_types/tool_calling。

总结

我们预计,将原生工具调用功能引入LLM的趋势将继续下去。我们希望这个标准化的工具调用接口能够帮助LangChain用户节省时间和精力,并使他们能够更容易地在不同的LLM提供商之间进行切换。

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

链载AI是专业的生成式人工智能教程平台。提供Stable Diffusion、Midjourney AI绘画教程,Suno AI音乐生成指南,以及Runway、Pika等AI视频制作与动画生成实战案例。从提示词编写到参数调整,手把手助您从入门到精通。
  • 官方手机版

  • 微信公众号

  • 商务合作

  • Powered by Discuz! X3.5 | Copyright © 2025-2025. | 链载Ai
  • 桂ICP备2024021734号 | 营业执照 | |广西笔趣文化传媒有限公司|| QQ