使用 Prompt API 进行会话管理的最佳实践

发布日期:2025 年 1 月 27 日

说明类视频 Web 扩展程序 Chrome 状态 目的
GitHub 源试用 源试用 Chrome 138 查看 实验意向
GitHub 源试用 采样参数的源试用 Chrome 148 查看 实验意向

Prompt API 的一项关键功能是会话。 借助会话,您可以与 AI 模型进行一次或多次持续对话,而模型不会丢失所说内容的上下文。本指南介绍了使用语言模型进行会话管理的最佳实践。

如果您要构建一个经典聊天机器人(其中一个用户与 AI 互动),则可能需要针对一个或多个并行会话进行会话管理。或者,如果您有一个客户关系管理系统,其中一个支持代理并行处理多个客户,并利用 AI 来帮助支持代理跟踪各种对话。

使用初始提示初始化会话

初始提示会在开始时设置会话的上下文。例如,您可以使用初始提示来告知模型应如何响应。

const languageModel = await LanguageModel.create({
  initialPrompts: [{
    role: 'system',
    content: 'You are a helpful assistant and you speak like a pirate.'
  }],
});
console.log(await languageModel.prompt('Tell me a joke.'));
// 'Avast ye, matey! What do you call a lazy pirate?\n\nA **sail-bum!**\n\nAhoy
// there, me hearties!  Want to hear another one? \n'

克隆主会话

如果您想在会话结束后开始新会话,或者想并行进行多个独立对话,可以克隆主会话。

克隆会话会继承潜在的初始提示和系统提示,以及任何会话互动历史记录。例如,如果您使用初始提示初始化了主会话,则此功能非常有用。这样,您的应用只需执行一次此操作,所有克隆会话都会继承主会话的初始提示。

const languageModel = await LanguageModel.create({
  initialPrompts: [{
    role: 'system',
    content: 'You are a helpful assistant and you speak like a pirate.'
  }]
});

// The original session `languageModel` remains unchanged, and
// the two clones can be interacted with independently from each other.
const firstClonedLanguageModel = await languageModel.clone();
const secondClonedLanguageModel = await languageModel.clone();
// Interact with the sessions independently.
await firstClonedLanguageModel.prompt('Tell me a joke about parrots.');
await secondClonedLanguageModel.prompt('Tell me a joke about treasure troves.');
// Each session keeps its own context.
// The first session's context is jokes about parrots.
await firstClonedLanguageModel.prompt('Tell me another.');
// The second session's context is jokes about treasure troves.
await secondClonedLanguageModel.prompt('Tell me another.');

恢复过去的会话

借助 初始提示,您可以为模型提供一组示例提示 和响应,以生成更好的结果。这通常用于 n-shot 提示,以创建符合您预期的响应。

如果您跟踪与模型进行的持续对话,则可以使用此实践来恢复会话。例如,在浏览器重启后,您可以帮助用户从上次中断的地方继续与模型互动。一种方法是在本地存储中跟踪会话历史记录。

// Restore the session from localStorage, or initialize a new session.
// The UUID is hardcoded here, but would come from a
// session picker in your user interface.
const uuid = '7e62c0e0-6518-4658-bc38-e7a43217df87';

function getSessionData(uuid) {
  try {
    const storedSession = localStorage.getItem(uuid);
    return storedSession ? JSON.parse(storedSession) : false;
  } catch {
    return false;
  }
}

let sessionData = getSessionData(uuid);

// Initialize a new session.
if (!sessionData) {  
  sessionData = {
    initialPrompts: [],
  };
}

// Initialize the session with the (previously stored or new) session data.
const languageModel = await LanguageModel.create(sessionData);

// Keep track of the ongoing conversion and store it in localStorage.
const prompt = 'Tell me a joke';
try {
  const stream = languageModel.promptStreaming(prompt);
  let result = '';
  // You can already work with each `chunk`, but then store
  // the final `result` in history.
  for await (const chunk of stream) {
    // In practice, you'd render the chunk.
    console.log(chunk);
    result = chunk;
  }

  sessionData.initialPrompts.push(
    { role: 'user', content: prompt },
    { role: 'assistant', content: result },
  );

  // To avoid growing localStorage infinitely, make sure to delete
  // no longer used sessions from time to time.
  localStorage.setItem(uuid, JSON.stringify(sessionData));
} catch (err) {
  console.error(err.name, err.message);
}

让用户停止模型,以保留会话配额

每个会话都有一个上下文窗口,您可以通过访问会话的相关字段 contextWindowcontextUsage 来查看该窗口。

const { contextWindow, contextUsage } = languageModel;
const contextWindowLeft = contextWindow - contextUsage;

当超出此上下文窗口时,会话将无法跟踪最旧的消息。如果上下文很重要,这可能会导致结果变差。 为了保留配额,如果用户确定模型的回答没有用,请允许他们使用 AbortController 停止会话。

prompt()promptStreaming() 方法都接受带有 signal 字段的可选第二个参数,以允许用户停止会话。

const controller = new AbortController();
stopButton.onclick = () => controller.abort();

try {
  const stream = languageModel.promptStreaming('Write me a poem!', {
    signal: controller.signal,
  });
  for await (const chunk of stream) {
    console.log(chunk);
  }
} catch (err) {
  // Ignore `AbortError` errors.
  if (err.name !== 'AbortError') {
    console.error(err.name, err.message);
  }
}

移除未使用的会话

每个会话都会消耗内存。如果您启动了多个大型会话,这可能会成为一个问题。 销毁未使用的会话以提高 资源可用性。

演示

AI 会话管理演示中了解 AI 会话管理的实际应用。 使用 Prompt API 创建多个并行对话,重新加载标签页,或 甚至重启浏览器,然后从上次中断的地方继续。请参阅 GitHub 上的源代码

充分发掘 Prompt API 的潜力

通过使用这些技术和最佳实践来周全地管理 AI 会话,您可以充分发掘 Prompt API 的潜力,从而提供更高效、响应更快且以用户为中心的应用。您还可以将这些方法结合使用,例如,让用户克隆恢复的过去会话,以便他们运行“假设”场景。

致谢

本指南由 Sebastian BenzAndre BandarraFrançois BeaufortAlexandra Klepper审核。