LangChain 中 LLM 的 bind_tools 原理
LangChain 中 LLM 的 bind_tools 原理
之前一直在写 agent,虽然知道如何使用 bind_tools,但是并不清楚底层原理。如果你也有困惑,这篇文章或许能够帮助你更好的理解 bind_tools 及其底层原理。
前言
bind_tools 是 LangChain 中 LLM 模块的核心功能之一,主要用于将外部工具与语言模型绑定,实现模型对工具的自动化调用。该机制通过结构化输入输出来协调模型与工具间的交互。
正文
如图所示,我们要知道不同的 LLM 供应商通过继承 BaseChatModel 实现自己的 LLM 接口(主要是 api 不同,也就是 post 请求,所以需要自行实现 post 请求前的数据和请求后返回的结果的代码,限于篇幅,具体细节不再展开)。

ChatModel(例如:ChatTongyi)没有绑定工具
当运行 ChatTongyi 实例(即调用 invoke、ainvoke、stream、astream 方法)的时候,这些方法在 BaseChatModel 中执行,具体的执行代码如:_generate、_stream 会在 ChatTongyi 中实现,这里给出 BaseChatModel 的 _generate、_stream 代码:
class BaseChatModel(BaseLanguageModel[AIMessage], ABC):
@abstractmethod
def _generate(
self,
messages: list[BaseMessage],
stop: list[str] | None = None,
run_manager: CallbackManagerForLLMRun | None = None,
**kwargs: Any,
) -> ChatResult:
"""Generate the result.
Args:
messages: The messages to generate from.
stop: Optional list of stop words to use when generating.
run_manager: Optional callback manager to use for this call.
**kwargs: Additional keyword arguments to pass to the model.
Returns:
The chat result.
"""
def _stream(
self,
messages: list[BaseMessage],
stop: list[str] | None = None,
run_manager: CallbackManagerForLLMRun | None = None,
**kwargs: Any,
) -> Iterator[ChatGenerationChunk]:
"""Stream the output of the model.
Args:
messages: The messages to generate from.
stop: Optional list of stop words to use when generating.
run_manager: Optional callback manager to use for this call.
**kwargs: Additional keyword arguments to pass to the model.
Yields:
The chat generation chunks.
"""
raise NotImplementedError
@abstractmethod 和 NotImplementedError 说明了继承 BaseChatModel 就必须实现这两个方法。
ChatModel(例如:ChatTongyi)绑定了工具
绑定工具需要 ChatTongyi 实例调用 bind_tools 方法,该方法在 ChatTongyi 中执行,并使用 self.bind 实现。如图所示,这里的 self.bind 来自 Runnable 类,会返回 RunnableBinding 实例。RunnableBinding 继承 RunnableBindingBase ,并且 RunnableBindingBase 继承 RunnableSerializable,因此最终绑定工具后的 ChatModel 是 RunnableBinding 实例。

梳理完 bind_tools 的原理之后,我们观察参数传递。
在 Runnable 的 bind 方法中,RunnableBinding 类传入 self(也就是创建好的 ChatTongyi 实例),kwargs(包含 ChatTongyi 调用 bind_tools 时传入的 tools 和 kwargs)。当我们需要运行实例(即调用 invoke、ainvoke、stream、astream 方法)的时候,会在 RunnableBindingBase 执行对应方法(RunnableBinding 继承 RunnableBindingBase 并且 RunnableBinding 没有对应方法)。如图所示的 invoke 方法会使用 bound(即 ChatTongyi 实例)进行 invoke,这里其实就回到了上文所说的 ChatModel(例如:ChatTongyi)没有绑定工具 的使用,只是这里传递了 tools 参数!。最终这里的参数会被解析并以 post 请求发送。
总结
因此,对于 LLM 的 bind_tools 方法,底层逻辑就是返回 RunnableBinding 实例,并在执行的时候将 tools 以 kwargs 的形式传递给 ChatModel 的执行函数。
更多推荐

所有评论(0)