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

发布时间:2025 年 1 月 27 日

说明类视频 Web 扩展程序 Chrome 状态 目的
GitHub 源试用Origin 试用 Chrome 138 视图 实验意向

提示 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' 

克隆主会话

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

克隆会继承会话参数(例如 temperaturetopK)以及任何会话互动历史记录。如果您使用初始提示初始化了主会话,此功能会很有用。这样,您的应用只需执行一次此操作,所有克隆会话都会继承主会话的初始提示。

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 prompting,以生成符合您预期的回答。

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

// 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) {   // Get the current default parameters so they can be restored as they were,   // even if the default values change in the future.   const { defaultTopK, defaultTemperature } =     await LanguageModel.params();   sessionData = {     initialPrompts: [],     topK: defaultTopK,     temperature: defaultTemperature,   }; }  // 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); } 

允许用户停止模型,从而保留会话配额

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

const { inputQuota, inputUsage } = languageModel; const inputQuotaLeft = inputQuota - inputUsage; 

如果超出此上下文窗口,会话将无法跟踪最旧的消息。如果上下文很重要,这可能会导致结果变差。 为了节省配额,如果用户认为模型的回答没有用,请允许他们使用 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