跳转至

连续工具调用

在实际的 AI Agent 开发中,LLM 连续使用多个工具来完成任务是很常见的场景。本示例演示了如何处理这种情况。

我们让 LLM 查询某个地点的最新天气(模拟 API 调用),天气信息通常以摄氏度返回,然后让它将温度转换为华氏度。

OpenAI 客户端实现

本示例演示了与 OpenAI API 的集成。如前文所述,我们需要手动处理连续的工具调用。

import os

from dotenv import load_dotenv
from openai import OpenAI

# Load environment variables from .env file
load_dotenv()
from toolregistry import ToolRegistry

# Initialize ToolRegistry
tool_registry = ToolRegistry()


# Register tools using decorator
@tool_registry.register
def get_weather(location: str):
    """Get the weather for a specific location"""
    return f"Weather in {location}: Sunny, 25°C"


@tool_registry.register
def c_to_f(celsius: float) -> float:
    """Convert Celsius to Fahrenheit"""
    fahrenheit = (celsius * 1.8) + 32
    return f"{celsius} celsius degree == {fahrenheit} fahrenheit degree"


# Set up OpenAI client
client = OpenAI(
    api_key=os.getenv("API_KEY", "your-api-key"),
    base_url=os.getenv("BASE_URL", "https://api.deepseek.com/"),
)


messages = [
    {
        "role": "user",
        "content": "What's the temperature of Shanghai, reply using Fahrenheit?",
    }
]
# Make the chat completion request
response = client.chat.completions.create(
    model="deepseek-v3",
    messages=messages,
    tools=tool_registry.get_schemas(),
    tool_choice="auto",
)


def handle_tool_calls(response, messages):
    """Handle tool calls in a loop until no more tool calls are needed"""
    while response.choices[0].message.tool_calls:
        tool_calls = response.choices[0].message.tool_calls
        print("Tool calls:", tool_calls)

        # Execute tool calls
        tool_responses = tool_registry.execute_tool_calls(tool_calls)

        # Construct assistant messages with results
        assistant_tool_messages = tool_registry.build_tool_call_messages(
            tool_calls, tool_responses
        )

        messages.extend(assistant_tool_messages)

        # Send the results back to the model
        response = client.chat.completions.create(
            model="deepseek-v3",
            messages=messages,
            tools=tool_registry.get_schemas(),
            tool_choice="auto",
        )
    return response


# Handle tool calls using the new function (without iteration limit)
response = handle_tool_calls(response, messages)

# Print final response
if response.choices[0].message.content:
    print(response.choices[0].message.content)

响应输出如下:

Tool calls: [ChatCompletionMessageToolCall(id='call_qcb10odnylzts5qhae9jvt7v', function=Function(arguments='{"location":"Shanghai"}', name='get_weather'), type='function', index=0)]
location='Shanghai'
Tool calls: [ChatCompletionMessageToolCall(id='call_ew7cm09z893u57102aeny2zp', function=Function(arguments='{"celsius":25}', name='c_to_f'), type='function', index=0)]
celsius=25.0
The temperature in Shanghai is 77°F.

Cicada MultiModalModel 实现

本示例展示了如何将 ToolRegistry 与 CicadaMultiModalModel 配合使用。

它的一个优点是可以自动处理连续的工具调用。

import os
from cicada.core.model import MultiModalModel
from cicada.core.utils import cprint
from toolregistry import ToolRegistry

# Initialize Cicada model
model_name = os.getenv("MODEL", "deepseek-v3")
stream = os.getenv("STREAM", "True").lower() == "true"

llm = MultiModalModel(
    api_key="your-api-key",
    api_base_url="https://api.deepseek.com/",
    model_name=model_name,
    stream=stream,
)

# Initialize ToolRegistry
tool_registry = ToolRegistry()

# Register tools
@tool_registry.register
def get_weather(location: str):
    return f"Weather in {location}: Sunny, 25°C"

@tool_registry.register
def c_to_f(celsius: float) -> float:
    fahrenheit = (celsius * 1.8) + 32
    return f"{celsius} celsius degree == {fahrenheit} fahrenheit degree"

# Query the model with tools
response = llm.query(
    "What's the temperature of Shanghai, reply using Fahrenheit?",
    tools=tool_registry,
    stream=llm.stream,
)
print(response["content"])
cprint(json.dumps(response,indent=2))

响应输出如下:

The current temperature in Shanghai is 77°F.
{
  "content": "The current temperature in Shanghai is 77\u00b0F.",
  "formatted_response": "[Response]: The current temperature in Shanghai is 77\u00b0F.",
  "tool_chain": [
    {
      "content": "",
      "tool_responses": {
        "call_mOnZUGqQhhmvj0lIKEUcncAn": "Weather in Shanghai: Sunny, 25\u00b0C"
      }
    },
    {
      "content": "",
      "tool_responses": {
        "call_lDQ0Nq0HRXHnmhoX6PJzmBHo": "25.0 celsius degree == 77.0 fahrenheit degree"
      }
    }
  ]
}