
Activepieces 对话记忆指令提示词深度解析用 LLM 维护用户长期记忆的一致性【免费下载链接】activepiecesAI Agents MCPs AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows AI Agents • MCPs for AI Agents项目地址: https://gitcode.com/GitHub_Trending/ac/activepieces导读chat-memory-instruction-prompt.md是 Activepieces AgentAI Agent系统中负责用户长期记忆更新与调和reconciliation的核心系统提示词它把记住一条新事实/指令这类请求交给 LLM 完成插入、覆盖、删除、去重的列表维护工作最终产出一份内部一致、无重复的 JSON 记忆清单。本文将逐条解读该提示词的完整内容与设计意图并结合agent-memory-ai.ts、agent-helpers.ts、HTTP 路由与单元测试等源码证据讲清它在 Activepieces 中的加载位置、调用链、降级策略与并发安全机制。读完后你将掌握如何理解并复用这套LLM 维护状态列表的提示词工程范式以及如何把同样的思路落地到自己的 Agent 记忆中。提示词全文与逐条设计意图该文件位于 packages/server/api/src/assets/prompts/chat-memory-instruction-prompt.md全文仅 7 行却完整定义了一次记忆更新任务的输入、输出格式、四条行为规则与一条硬性质量要求You maintain a users list of durable facts an AI assistant remembers about them. Given the current list and a new statement or instruction from the user, return the updated, reconciled list as JSON: {memories: string[]}. Rules:Integrate the new input as a short standalone fact in the users own voice.If it updates, contradicts, or duplicates an existing item, REPLACE that item — never keep two facts that conflict or overlap (e.g. do not keep both prefers pizza over burgers and prefers burgers over pizza).If the user asks to forget something, remove it.Leave unrelated items unchanged. The final list must be internally consistent and free of duplicates. Return only the JSON object.逐条拆解其设计意图角色与任务定义第 1 行将 LLM 定位为用户持久事实列表的维护者。关键词是durable facts持久事实——区别于一次性任务细节这正是长期记忆与对话上下文压缩的根本区别。任务输入是当前列表 新陈述/指令输出是更新且调和后的列表。输出契约第 1 行末尾强制使用 JSON 结构{memories: string[]}。固定且简单的输出 schema 是后续代码侧zod校验与容错解析的前提见下文JSON 解析与 schema 校验。规则一——以用户口吻写入第 3 行Integrate the new input as a short standalone fact in the users own voice。要求新事实必须是简短、独立的陈述句且保持用户自己的语气避免 LLM 以自己的口吻二次转述造成语义漂移。这与提取提示词中一条数组元素即一条离散事实的约定一致。规则二——冲突/重复必须替换第 4 行REPLACE替换而非追加并给出显式反例不能同时保留prefers pizza over burgers与prefers burgers over pizza。这条规则是记忆调和的灵魂——它把去重、矛盾消解、更新覆盖三种情况统一收敛为同一种动作替换让模型无需区分场景规则简单且不易误判。规则三——遗忘即删除第 5 行当用户要求忘记某件事时直接移除对应条目无需任何额外解释或确认逻辑由模型自行判断哪些条目属于被遗忘范围。规则四——无关条目保持不变第 6 行防止模型顺手重写或过度归纳其他记忆保证每次更新是最小变更minimal edit从而降低对未改动事实的意外破坏。最终质量要求第 7 行The final list must be internally consistent and free of duplicates. Return only the JSON object.—— 既定义验收标准内部一致、无重复又再次强调只输出 JSON为代码侧parseJsonObject直接截取{...}段做解析提供保证。从提示词工程角度看这份提示词的关键成功要素有三最小化的输出契约一个 JSON 字段、归一化的更新动作一切冲突都走替换、强制的幂等输出只输出 JSON不输出解释文字。提示词在代码中的加载与调用链加载位置该提示词由 packages/server/api/src/app/ee/agent/agent-memory-ai.ts 在模块加载时通过readFileSync读取function loadMemoryPrompt(filename: string): string { return readFileSync(path.resolve(packages/server/api/src/assets/prompts/${filename}), utf8) } const EXTRACTION_SYSTEM_PROMPT loadMemoryPrompt(chat-memory-extraction-prompt.md) const INSTRUCTION_SYSTEM_PROMPT loadMemoryPrompt(chat-memory-instruction-prompt.md)注意两个提示词被同时加载chat-memory-extraction-prompt.md负责从导入文本中提取记忆而本文主角chat-memory-instruction-prompt.md负责对已有记忆施加一条指令两者构成提取—更新的完整闭环提取提示词内容见 chat-memory-extraction-prompt.md。核心函数 applyInstruction提示词的实际消费方是applyInstructionagent-memory-ai.ts它完成读取当前记忆 → 构造提示 → 调用 LLM → 校验解析 → 合并落库的完整链路async function applyInstruction({ platformId, userId, instruction, log }: { platformId: string userId: string instruction: string log: FastifyBaseLogger }): PromiseGetAgentMemoryResponse { const trimmed instruction.trim().slice(0, MAX_INPUT_LENGTH) const current await agentHelpers.getUserMemory({ platformId, userId }) if (trimmed.length 0) { return current } const currentList current.memories.length 0 ? current.memories.map((memory) - ${memory}).join(\n) : (none yet) const parsed await runMemoryLlm({ platformId, instructions: INSTRUCTION_SYSTEM_PROMPT, prompt: Current memories:\n${currentList}\n\nInput: ${trimmed}, schema: MemoriesSchema, log }) const nextMemories isNil(parsed) ? [...current.memories, trimmed] : parsed.memories return agentHelpers.saveUserMemory({ platformId, userId, memories: nextMemories, baseMemories: current.memories }) }这段代码的关键细节输入截断MAX_INPUT_LENGTH 50_000文件顶部常量超出部分直接丢弃防止超长输入导致 LLM 调用失败或成本失控。当前列表的文本化已有记忆逐条以- memory的 Markdown 列表形式拼接若尚无记忆则写入占位符(none yet)。这个占位符非常重要——它显式告知模型列表为空避免模型幻觉出并不存在的旧记忆。用户提示词user prompt的固定模板Current memories:\n${currentList}\n\nInput: ${trimmed}。整个任务被组织为上下文当前列表 新输入一条指令两段式结构与提示词第 1 行Given the current list and a new statement or instruction from the user完全对应。降级策略若 LLM 调用失败或解析不出合法 JSONparsed为null则退化为简单追加[...current.memories, trimmed]——宁可保守地把新事实追加进去也不丢弃用户数据。落库前的三路合并saveUserMemory结合baseMemories读取时的快照做并发安全合并详见下文。LLM 调用参数runMemoryLlmagent-memory-ai.ts统一了所有记忆类 LLM 调用的行为const { text: raw } await generateText({ model: await agentHelpers.resolveFastModel({ platformId, scope: { type: platform }, log }), instructions, prompt, temperature: 0, telemetry: agentAiUtils.buildTelemetry({ functionId: agent-memory }) })模型通过agentHelpers.resolveFastModel解析平台级快速档位FAST_TIER模型见 agent-helpers.ts。记忆调和是高频低延迟操作因此刻意选择快速模型而非最强模型这也说明该任务对模型能力要求并不苛刻。temperature 0记忆维护属于确定性任务温度归零保证相同输入产出尽可能稳定的输出避免同一指令两次执行结果不一致。instructions 参数INSTRUCTION_SYSTEM_PROMPT作为系统指令传入AI SDK 的instructions字段而prompt承载当前列表与用户输入。可观测性每次调用都携带functionId: agent-memory的 telemetry便于平台侧追踪记忆类调用的用量与失败。JSON 解析与 schema 校验容错的关键一环LLM 输出天然不可靠代码通过宽松解析 严格 schema两道防线兜底。parseJsonObjectagent-memory-ai.ts先取原始文本中第一个{到最后一个}之间的片段再用 zod schema 校验const MemoriesSchema z.object({ memories: z.array(z.string().catch()).catch([]), })schema 的设计非常务实z.string().catch()数组元素若不是字符串如数字、null会被强制转为空字符串而不是让整个解析失败外层.catch([])字段缺失或类型错误时默认空数组z.object默认剥离未知字段。这种能救则救的容错配合单元测试中Sure! json\n{memories:[only fact]}\n done这类带代码围栏的脏输出用例见 agent-memory-ai.test.ts确保模型即使输出多余文字也能被正确截取。只有当文本中完全没有{...}时parseJsonObject返回null才触发上文提到的简单追加降级。持久化、容量上限与并发安全数据模型与容量约束记忆最终落在user_memory表中按platformId userId唯一由 agent-helpers.ts 的getUserMemory/capMemories/saveUserMemory管理。capMemories定义了硬性容量边界const MAX_MEMORIES 50 const MAX_MEMORY_LENGTH 280 const MAX_INSTRUCTIONS_LENGTH 4000记忆条数上限50条单条记忆最长280字符超出截断指令类记忆instructions来自提取流程最长4000字符空字符串条目被过滤重复条目用unique去重。这些上限由单元测试显式验证agent-memory-ai.test.ts400 字符的长记忆被截到 28060 条输入被收敛到 50 条空白指令被置为null。这意味着提示词让模型调和去重是一回事数据库层面还兜底做第二层去重与截断——提示词保证语义一致代码保证存储合规。三路合并并发安全的核心记忆更新的读-改-写窗口存在并发风险用户在两个会话里同时发起记忆更新后写者可能覆盖先写者刚保存的事实。saveUserMemory通过withLockedMemoryRowagent-helpers.ts在事务内对行加pessimistic_write锁并配合mergeMemories做三路合并base / incoming / currentfunction mergeMemories({ base, incoming, current }: { base: string[], incoming: string[], current: string[] }): string[] { return unique([ ...incoming.filter((memory) !base.includes(memory) || current.includes(memory)), ...current.filter((memory) !base.includes(memory)), ]) }合并语义均有对应测试用例佐证见 agent-memory-ai.test.tsbase是发起 LLM 调用前读到的快照incoming是 LLM 返回的调和结果current是加锁后数据库里的最新值保留incoming 中基于 base 新增/替换的事实保留current 中他人并发新增的事实!base.includes(memory)说明该事实在我读取之后才出现丢弃incoming 中对 base 的删除避免把他人刚加的事实删掉、以及 current 中已被我在本次调和里删除的事实。测试用例mergeMemories({ base: [burgers], incoming: [burgers, pizza], current: [burgers, cheese] })得到[burgers, pizza, cheese]正是并发新增的 cheese 不被覆盖的验证而current: []时得到[pizza]验证并发删除不被还原。这套机制保证了提示词产出的调和结果在并发场景下依然成立。触发入口HTTP API 与 Agent 工具记忆相关的 REST 路由在 agent-conversation-controller.ts 中注册了四组记忆接口路由方法行为底层函数/memoryGET读取当前用户记忆agentHelpers.getUserMemory/memoryPOST整体覆写记忆含 instructionsagentHelpers.saveUserMemory/memory/importPOST导入其他助手的记忆导出文本先提取再追加agentMemoryAi.extractsaveUserMemory/memory/instructPOST施加一条记忆指令新增/覆盖/遗忘agentMemoryAi.applyInstruction其中/memory/instruct是chat-memory-instruction-prompt.md的直接消费入口请求体只需一个instruction字符串服务端自动完成读取当前列表 → LLM 调和 → 落库。而/memory/import则先走提取提示词chat-memory-extraction-prompt.md把自由文本拆成{instructions, memories}两个桶再并入现有记忆——两条提示词在此汇合。Agent 的 ap_remember 工具除了显式 APIAgent 在对话中还可以通过内置工具ap_remember主动调用记忆更新。在 agent-tools.ts 中case ap_remember: { const memory isString(toolInput.memory) ? toolInput.memory.trim() : if (!memory) { return { success: false, error: Empty memory. } } await agentMemoryAi.applyInstruction({ platformId, userId, instruction: memory, log }) return { remembered: true } }这意味当用户对 Agent 说请记住我住在上海或我不再喜欢披萨了时Agent 可以自主决定调用ap_remember把这句话作为instruction交给applyInstruction由chat-memory-instruction-prompt.md驱动 LLM 完成对既有记忆的调和。applyInstruction的返回值更新后的完整记忆列表同时回传给 Agent使其能确认本次更新结果。提示词体系的配套关系chat-memory-instruction-prompt.md并非孤立存在它处于 Activepieces 记忆提示词体系的更新层与以下文件协作chat-memory-extraction-prompt.md负责导入把外部记忆导出文本拆为instructions语气/人设/工作方式等长期指令与memories离散持久事实两个桶同样要求去重并省略一次性任务细节chat-system-prompt.mdAgent 主对话系统提示词负责把已保存的记忆注入到每轮对话上下文中agent-builder-prompt.md 与 agent-draft-prompt.mdAgent 构建与草稿生成提示词与记忆维护相互独立。三者构成闭环提取extraction→ 更新instruction→ 注入system prompt而chat-memory-instruction-prompt.md正是中间持续演进的那一环——它保证记忆列表在多次更新后依然内部一致、无重复、不互相矛盾。总结这套提示词工程范式的可复用要点从 Activepieces 的实现中可以提炼出一套可复用的LLM 维护状态列表范式适用于任何需要长期记忆、偏好档案、配置清单等场景最小输出契约固定{memories: string[]}单一字段配合代码侧 zod schema 容错解析最大限度容忍模型输出的脏文本动作归一化把新增/更新/矛盾/重复全部归一为替换把遗忘归一为删除规则极简模型不易混淆明确验收标准显式要求内部一致、无重复、只输出 JSON并配合temperature 0保证确定性空态显式化列表为空时传入(none yet)占位符杜绝模型幻觉双层兜底提示词保证语义调和数据库层再做去重、截断50 条 / 280 字符与三路并发合并确保极端情况下数据不丢、不重、不互相覆盖优雅降级LLM 调用失败时退化为简单追加宁可冗余也不丢失用户信息。如果你正在为自己的 Agent 构建用户记忆模块可以直接把chat-memory-instruction-prompt.md的规则结构作为系统提示词模板并参考 agent-memory-ai.ts 的解析与降级策略、agent-helpers.ts 的容量约束与并发合并逻辑以及 agent-memory-ai.test.ts 中的测试用例来验证自己的实现。【免费下载链接】activepiecesAI Agents MCPs AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows AI Agents • MCPs for AI Agents项目地址: https://gitcode.com/GitHub_Trending/ac/activepieces创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考