如何用 puter.ai.chat() 的 compaction 选项压缩长对话上下文并携带摘要进入下一轮?
【免费下载链接】puter🌐 The Internet Computer! Free, Open-Source, and Self-Hostable.项目地址: https://gitcode.com/GitHub_Trending/pu/puter
如果你在用 Puter.js 构建聊天应用,并且把多轮对话历史保存在客户端,随着轮次增加,每次请求携带的完整历史迟早会超出模型的上下文窗口。puter.ai.chat()的compaction选项(文档见 src/docs/src/AI/chat.md)可以让模型在上下文溢出之前,把较早的轮次总结成一个compaction artifact,并基于这份摘要回答而不是完整历史——请求因此保持小规模。本文讲清楚三件事:如何开启 compaction、如何拿到 artifact、如何在下一轮把它正确携带回去。
compaction 的产物长什么样
模型触发压缩后,artifact 以compaction项返回:
- 流式调用:以
type: 'compaction'的流 chunk 形式到达; - 非流式调用:挂在结果对象的
result.compaction字段上,仅在模型实际压缩了早期上下文时出现,未触发时该字段不存在(见 ChatResponse 对象)。
artifact 的结构固定为:
{ type: 'compaction', id, encrypted_content }encrypted_content是不透明的加密摘要,文档明确要求把它当黑盒处理——不解析、不改写,只在下一轮原样携带。各供应商(OpenAI、Anthropic 等)返回的这项结构完全一致,所以同一份处理代码对所有供应商通用,这一点在 ChatResponseChunk 对象 中也有说明。
开启 compaction 选项
在puter.ai.chat()的 options 对象中传入compaction,两种写法:
compaction: true— 以供应商默认配置启用;compaction: { trigger_tokens: 60000 }— 显式设定触发压缩的 token 阈值,即上下文达到多少 token 时模型开始总结较早的轮次。
需要知道一个前提:compaction 只在上下文足够大时才会触发。Anthropic 模型要求最低 50,000 token 的门槛,且对话必须实际超过你设置的trigger_tokens;OpenAI 模型没有这个下限,可以压缩更小的对话。如果你的输入没有触发压缩,说明输入低于阈值——这本身不是错误。
另外,SDK 会把compaction选项原样透传给后端 driver,浏览器端与 Node 端写法一致(见 src/puter-js/src/modules/ai/chat.js 中的PARAMS_TO_PASS)。
非流式:从result.compaction取 artifact 并进入下一轮
messages是你维护的对话messages数组(每个对象含role和content,格式见 chat.md 的 Parameters 一节)。开启 compaction 后判断result.compaction是否出现,出现了就重建下一轮的请求:
const result = await puter.ai.chat(messages, { model: 'gpt-5.5', compaction: { trigger_tokens: 60000 }, }); console.log(result.message.content); if ( result.compaction ) { // result.compaction is { type: 'compaction', id, encrypted_content } — the // same item you get from the stream. Rebuild the assistant turn from it plus // the reply text (artifact first), then add the new user message: const next = await puter.ai.chat( [ { role: 'system', content: 'You are a helpful assistant.' }, { role: 'assistant', content: [ result.compaction, { type: 'text', text: result.message.content }, ], }, { role: 'user', content: 'now compare the two approaches' }, ], { model: 'gpt-5.5', compaction: true } ); console.log(next.message.content); }下一轮请求的构造方式是文档明确规定的:把 artifact 作为产生它的那条 assistant 轮的第一个内容块,与这一轮的回复文本放在一起,再追加新的 user 消息。artifact 替代的是它压缩掉的那些较早轮次,最近的这轮交互要保留,不要丢弃。
验证方式:压缩触发当且仅当result.compaction存在;下一轮请求发出后正常拿到next.message.content即说明 artifact 被成功携带。
流式:收集compactionchunk 并处理errorchunk
流式场景下,artifact 以type: 'compaction'的 chunk 到达,与textchunk 在同一个for await...of循环里区分处理:
<html> <body> <script src="https://js.puter.com/v2/"></script> <script> const resp = await puter.ai.chat(messages, { model: 'gpt-5.5', // or 'claude-opus-4-8' — same code stream: true, compaction: { trigger_tokens: 60000 }, }); let text = ''; let compaction = null; for await ( const part of resp ) { if ( part.type === 'text' ) text += part.text; else if ( part.type === 'compaction' ) compaction = part; // { type, id, encrypted_content } else if ( part.type === 'error' ) console.error('stream error:', part.message); } // Next turn: rebuild the assistant turn from the compaction artifact + the reply // text it came with (artifact first), then add the new user message. The artifact // replaces the older compacted turns; the recent exchange is kept. Keep // compaction enabled so it can compact again later. if ( compaction ) { const next = await puter.ai.chat( [ { role: 'system', content: 'You are a helpful assistant.' }, { role: 'assistant', content: [ compaction, { type: 'text', text } ], }, { role: 'user', content: 'now compare the two approaches' }, ], { model: 'gpt-5.5', stream: true, compaction: true } ); for await ( const part of next ) { if ( part.type === 'text' ) document.write(part.text); } } </script> </body> </html>(代码取自 chat.md 的 Compaction 一节,messages替换为你自己维护的对话数组,gpt-5.5可换成文档注释中给出的claude-opus-4-8。)
流式验证方式与排查要点:
- 循环结束后
compaction变量非空,说明本轮触发了压缩,且该 chunk 携带encrypted_content字符串; - 供应商错误会以
errorchunk 到达,而不是抛出异常——例如trigger_tokens低于供应商允许的最低值时就是这样报错的,所以必须处理part.type === 'error'分支,否则错误会被静默吞掉。errorchunk 会结束流。
多轮对话中的使用纪律
文档给出的两条硬性要求,违反任一条都会破坏多轮压缩:
- 每一轮都要保持
compaction开启(true或带trigger_tokens的对象),否则对话继续增长后无法再次压缩; - artifact 必须作为其所属 assistant 轮的第一个块携带,与该轮的回复文本并列,再继续追加新轮次;被 artifact 替代的是较旧的轮次,最近的交互必须保留。
延伸阅读
- puter.ai.chat() 完整文档:
messages参数格式、stream选项与全部示例; - ChatResponse / ChatResponseChunk:非流式
compaction字段与流式compaction、errorchunk 的字段定义; - Getting Started:
npm install @heyputer/puter.js或 CDN 引入 Puter.js 的两种方式; - src/puter-js/test/ai.test.js 中的
testChatCompaction用例:演示了开启 compaction 后普通流式响应不受影响、compactionchunk 携带encrypted_content、以及把 artifact 作为消息项重发(round-trip)的完整断言,可作为你自测的参照。
【免费下载链接】puter🌐 The Internet Computer! Free, Open-Source, and Self-Hostable.项目地址: https://gitcode.com/GitHub_Trending/pu/puter
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考