文档

快速入门

使用 LLM 进行预测

文本嵌入

分词

管理模型

模型信息

.act() 调用

自动工具调用

我们引入了执行“轮次”的概念,以描述运行工具、向 LLM 提供其输出,然后等待 LLM 决定下一步行动的组合过程。

执行轮次

 • run a tool →
 ↑   • provide the result to the LLM →
 │       • wait for the LLM to generate a response

 └────────────────────────────────────────┘ └➔ (return)

模型可能会选择多次运行工具,然后才返回最终结果。例如,如果 LLM 正在编写代码,它可能会选择编译或运行程序、修复错误,然后再运行一次,反复操作直到获得所需的结果。

考虑到这一点,我们称 .act() API 是一个自动的“多轮”工具调用 API。

快速示例

import lmstudio as lms

def multiply(a: float, b: float) → float:
    """Given two numbers a and b. Returns the product of them."""
    return a * b

model = lms.llm("qwen2.5-7b-instruct")
model.act(
  "What is the result of 12345 multiplied by 54321?",
  [multiply],
  on_message=print,
)

LLM “使用工具”意味着什么?

LLM 主要是一种文本输入、文本输出的程序。所以,你可能会问“LLM 如何使用工具?”答案是,一些 LLM 经过训练,会要求人类替它们调用工具,并期望工具输出以某种格式返回。

想象一下你正在通过电话为某人提供计算机支持。你可能会说:“替我运行这个命令……好的,它输出了什么?……好的,现在点击那里告诉我它说什么……”在这种情况下,你就是 LLM!你正在通过电话另一端的人“间接调用工具”。

重要提示:模型选择

用于工具使用的模型将极大地影响性能。

选择模型的一些通用指导

  • 并非所有模型都能够智能地使用工具
  • 越大越好(即,7B 参数模型通常会比 3B 参数模型表现更好)
  • 我们观察到 Qwen2.5-7B-Instruct 在各种情况下表现良好
  • 此指导可能会更改

示例:多工具

以下代码演示了如何在单个 .act() 调用中提供多个工具。

import math
import lmstudio as lms

def add(a: int, b: int) → int:
    """Given two numbers a and b, returns the sum of them."""
    return a + b

def is_prime(n: int) → bool:
    """Given a number n, returns True if n is a prime number."""
    if n < 2:
        return False
    sqrt = int(math.sqrt(n))
    for i in range(2, sqrt):
        if n % i == 0:
            return False
    return True

model = lms.llm("qwen2.5-7b-instruct")
model.act(
  "Is the result of 12345 + 45668 a prime? Think step by step.",
  [add, is_prime],
  on_message=print,
)

示例:带文件创建工具的聊天循环

以下代码创建了一个与 LLM 智能体对话的循环,该智能体可以创建文件。

import readline # Enables input line editing
from pathlib import Path

import lmstudio as lms

def create_file(name: str, content: str):
    """Create a file with the given name and content."""
    dest_path = Path(name)
    if dest_path.exists():
        return "Error: File already exists."
    try:
        dest_path.write_text(content, encoding="utf-8")
    except Exception as exc:
        return "Error: {exc!r}"
    return "File created."

def print_fragment(fragment, round_index=0):
    # .act() supplies the round index as the second parameter
    # Setting a default value means the callback is also
    # compatible with .complete() and .respond().
    print(fragment.content, end="", flush=True)

model = lms.llm()
chat = lms.Chat("You are a task focused AI assistant")

while True:
    try:
        user_input = input("You (leave blank to exit): ")
    except EOFError:
        print()
        break
    if not user_input:
        break
    chat.add_user_message(user_input)
    print("Bot: ", end="", flush=True)
    model.act(
        chat,
        [create_file],
        on_message=chat.append,
        on_prediction_fragment=print_fragment,
    )
    print()

进度回调

与使用工具的智能体进行复杂交互可能需要一些时间来处理。

任何预测请求的常规进度回调均可用,但其预期功能与单轮预测的功能有所不同。

  • on_prompt_processing_progress:在每个预测轮次的提示处理过程中调用。接收进度比率(浮点数)和轮次索引作为位置参数。
  • on_first_token:在每个预测轮次的提示处理完成后调用。接收轮次索引作为其唯一参数。
  • on_prediction_fragment:为客户端接收到的每个预测片段调用。接收预测片段和轮次索引作为位置参数。
  • on_message:在每个预测轮次完成后,以及在每个工具调用请求完成后,用助理响应消息和工具结果消息调用。旨在将接收到的消息附加到聊天历史实例,因此接收轮次索引作为参数。

以下额外回调可用于监控预测轮次

  • on_round_start:在提交每个轮次的预测请求之前调用。接收轮次索引作为其唯一参数。
  • on_prediction_completed:在轮次预测完成后调用,但在任何请求的工具调用启动之前。接收该轮次的预测结果作为其唯一参数。轮次预测结果是一个常规预测结果,并带有一个额外的 round_index 属性。
  • on_round_end:在轮次的所有工具调用请求都已解决后调用。

最后,当智能体发出无效工具请求时,应用程序可以请求通知

  • handle_invalid_tool_request:当工具请求无法处理时调用。接收即将报告的异常,以及导致问题的原始工具请求。如果没有提供工具请求,这纯粹是在智能体交互引发给定异常之前的一个不可恢复错误的通知(允许应用程序引发自己的异常)。如果提供了工具请求,则表示异常的文本描述将作为失败工具请求的结果返回给智能体,而不是在本地引发。在这些情况下,回调可以返回 None 以指示应将错误描述发送给智能体,在本地引发给定异常(或不同的异常),或者返回一个应发送给智能体而不是错误描述的文本字符串。

有关定义工具的更多详细信息,以及覆盖无效工具请求处理以在本地引发所有异常而不是将其传递回智能体的示例,请参阅工具定义