文档

使用 LLM 进行预测

文本嵌入

分词

管理模型

模型信息

API 参考

.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 { LMStudioClient, tool } from "@lmstudio/sdk";
import { z } from "zod";

const client = new LMStudioClient();

const multiplyTool = tool({
  name: "multiply",
  description: "Given two numbers a and b. Returns the product of them.",
  parameters: { a: z.number(), b: z.number() },
  implementation: ({ a, b }) => a * b,
});

const model = await client.llm.model("qwen2.5-7b-instruct");
await model.act("What is the result of 12345 multiplied by 54321?", [multiplyTool], {
  onMessage: (message) => console.info(message.toString()),
});

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

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

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

重要提示:模型选择

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

选择模型的一些通用指导:

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

示例:多个工具

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

import { LMStudioClient, tool } from "@lmstudio/sdk";
import { z } from "zod";

const client = new LMStudioClient();

const additionTool = tool({
  name: "add",
  description: "Given two numbers a and b. Returns the sum of them.",
  parameters: { a: z.number(), b: z.number() },
  implementation: ({ a, b }) => a + b,
});

const isPrimeTool = tool({
  name: "isPrime",
  description: "Given a number n. Returns true if n is a prime number.",
  parameters: { n: z.number() },
  implementation: ({ n }) => {
    if (n < 2) return false;
    const sqrt = Math.sqrt(n);
    for (let i = 2; i <= sqrt; i++) {
      if (n % i === 0) return false;
    }
    return true;
  },
});

const model = await client.llm.model("qwen2.5-7b-instruct");
await model.act(
  "Is the result of 12345 + 45668 a prime? Think step by step.",
  [additionTool, isPrimeTool],
  { onMessage: (message) => console.info(message.toString()) },
);

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

以下代码创建了一个与可创建文件的 LLM 代理进行对话的循环。

import { Chat, LMStudioClient, tool } from "@lmstudio/sdk";
import { existsSync } from "fs";
import { writeFile } from "fs/promises";
import { createInterface } from "readline/promises";
import { z } from "zod";

const rl = createInterface({ input: process.stdin, output: process.stdout });
const client = new LMStudioClient();
const model = await client.llm.model();
const chat = Chat.empty();

const createFileTool = tool({
  name: "createFile",
  description: "Create a file with the given name and content.",
  parameters: { name: z.string(), content: z.string() },
  implementation: async ({ name, content }) => {
    if (existsSync(name)) {
      return "Error: File already exists.";
    }
    await writeFile(name, content, "utf-8");
    return "File created.";
  },
});

while (true) {
  const input = await rl.question("You: ");
  // Append the user input to the chat
  chat.append("user", input);

  process.stdout.write("Bot: ");
  await model.act(chat, [createFileTool], {
    // When the model finish the entire message, push it to the chat
    onMessage: (message) => chat.append(message),
    onPredictionFragment: ({ content }) => {
      process.stdout.write(content);
    },
  });
  process.stdout.write("\n");
}