跳转至

简单聊天示例

chat 端点自 v0.1.14 版本起可用,是使用 Ollama 从 LLM 生成文本的两种方式之一。在高层次上,您向端点提供一个指定了角色和内容的消息对象数组。然后,随着每次输出和提示,您添加更多消息,这样就构建了历史记录。

运行示例

npm start

代码审查

您可以看到实际调用端点的 chat 函数非常简单:

const body = {
  model: model,
  messages: messages
}

const response = await fetch("http://localhost:11434/api/chat", {
  method: "POST",
  body: JSON.stringify(body)
})

使用 generate 端点时,您需要提供一个 prompt。但使用 chat 时,您提供的是 messages。结果响应流包括一个带有 content 字段的 message 对象。

最终的 JSON 对象并不提供完整的内容,因此您需要自己构建内容。在此示例中,chat 接收消息的完整数组,并输出此次聊天端点调用的结果消息。

askQuestion 函数中,我们收集 user_input 并将其作为消息添加到我们的消息中,然后传递给聊天函数。当 LLM 完成响应后,输出作为另一个消息添加到消息数组中。

最后,您将看到所有消息的打印输出。

接下来的步骤

在这个示例中,保留了所有生成的内容。您可能想尝试总结超过 10 次对话的所有内容,以便在使用更少的上下文时启用更长的历史记录。

源码

client.ts

import * as readline from "readline";

const model = "llama2";
type Message = {
  role: "assistant" | "user" | "system";
  content: string;
}
const messages: Message[] = [{
  role: "system",
  content: "You are a helpful AI agent."
}]

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
})

async function chat(messages: Message[]): Promise<Message> {
  const body = {
    model: model,
    messages: messages
  }

  const response = await fetch("http://localhost:11434/api/chat", {
    method: "POST",
    body: JSON.stringify(body)
  })

  const reader = response.body?.getReader()
  if (!reader) {
    throw new Error("Failed to read response body")
  }
  let content = ""
  while (true) {
    const { done, value } = await reader.read()
    if (done) {
      break;
    }
    const rawjson = new TextDecoder().decode(value);
    const json = JSON.parse(rawjson)

    if (json.done === false) {
      process.stdout.write(json.message.content);
      content += json.message.content
    }

  }
  return { role: "assistant", content: content };
}

async function askQuestion(): Promise<void> {
  return new Promise<void>((resolve) => {
    rl.question("\n\nAsk a question: (press enter alone to quit)\n\n", async (user_input) => {
      if (user_input.trim() === "") {
        rl.close();
        console.log("Thankyou. Goodbye.\n")
        console.log("=======\nHere is the message history that was used in this conversation.\n=======\n")
        messages.forEach(message => {
          console.log(message)
        })
        resolve();
      } else {
        console.log();
        messages.push({ role: "user", content: user_input });
        messages.push(await chat(messages));
        await askQuestion(); // Ask the next question
      }
    });
  });
}

async function main() {
  await askQuestion();

}

main();