Agent 反馈闭环设计:用户纠正如何回写进系统提示和记忆 Agent 反馈闭环设计用户纠正如何回写进系统提示和记忆用户说你搞错了——这句话比任何训练数据都值钱前提是你把它用对了。一、场景痛点你的 Agent 在对话中犯了一个错误把北京的年均降雨量答成了 500mm实际是 630mm。用户纠正了北京年均降雨量是 630mm 左右。Agent 回复了谢谢纠正我记住了。但下次用户再问同样的问题Agent 还是答 500mm——因为记住了只是一句礼貌回复纠正信息没有被写进任何持久化存储。更严重的是系统性错误Agent 对某个领域比如中国行政区划的知识有偏差不同用户反复纠正同一个错误。你希望把这些纠正自动写入系统提示或记忆库让所有后续对话都能利用这些纠正而不是每个用户都重复纠正一次。核心矛盾用户的纠正是最有价值的数据但它被浪费了——没有机制把纠正写入 Agent 的持久化知识纠正只影响当前对话不影响后续对话。二、底层机制与原理剖析2.1 反馈闭环的三层写入2.2 纠正类型的分类纠正类型写入目标验证要求示例事实纠正system_knowledge必须验证北京降雨量是 630mm偏好纠正user_memory无需验证我喜欢简短回答流程纠正system_prompt需审核生成代码时先写注释再写逻辑否定反馈session_memory不持久化这个回答不对没有提供正确信息关键区分事实纠正需要验证才能全局写入用户也可能犯错偏好纠正不需要验证可以直接写入个人记忆偏好没有对错。2.3 纠正检测的触发机制Agent 需要在对话中自动识别用户是否在提供纠正信息。触发信号明确纠正词不对、搞错了、应该是、实际上、你说的有误提供替代信息用户给出了与 Agent 之前回答不同的具体数值或事实否定 新信息先否定再提供正确答案三、生产级代码实现3.1 纠正检测与分类器// correction-detector.ts —— 用户纠正检测与分类 export enum CorrectionType { FACTUAL factual, // 事实纠正需要验证后全局写入 PREFERENCE preference, // 偐好纠正直接写入用户记忆 PROCESS process, // 流程纠正需要审核后写入系统提示 NEGATIVE negative, // 否定反馈仅写入会话记忆 } export interface DetectedCorrection { type: CorrectionType; originalStatement: string; // Agent 的原始错误陈述 correctedStatement: string; // 用户提供的纠正内容 confidence: number; // 纠正置信度0-1 topic: string; // 纠正的主题领域 source: string; // 纠正来源用户ID } export class CorrectionDetector { private correctionPatterns: string[]; private preferencePatterns: string[]; private processPatterns: string[]; constructor() { // 纠正触发词模式中文 英文 this.correctionPatterns [ 不对, 搞错了, 应该是, 实际上, 你说的有误, 错了, 纠正, 更正, 不是, 不准确, wrong, incorrect, actually, should be, that\s not right, the correct, ]; this.preferencePatterns [ 我希望, 我更喜欢, 我习惯, 我喜欢, 不要, 别, 以后, 下次, I prefer, I like, I want, don\t, ]; this.processPatterns [ 先写, 再写, 应该先, 流程应该是, 步骤应该是, 按这个顺序, first write, then do, the process should, ]; } /** 检测用户消息中的纠正信息 */ detectCorrection( userMessage: string, agentHistory: string[], context: { userId: string; sessionId: string } ): DetectedCorrection | null { // Step 1: 检测是否有纠正触发词 const hasCorrectionSignal this.correctionPatterns.some( (p) userMessage.toLowerCase().includes(p.toLowerCase()) ); const hasPreferenceSignal this.preferencePatterns.some( (p) userMessage.toLowerCase().includes(p.toLowerCase()) ); const hasProcessSignal this.processPatterns.some( (p) userMessage.toLowerCase().includes(p.toLowerCase()) ); if (!hasCorrectionSignal !hasPreferenceSignal !hasProcessSignal) { // 无明确纠正信号检查隐式纠正 // 隐式纠正用户提供了与 Agent 不同的信息但没有说你搞错了 return this.detectImplicitCorrection(userMessage, agentHistory, context); } // Step 2: 分类纠正类型 if (hasProcessSignal) { return this.buildProcessCorrection(userMessage, agentHistory, context); } else if (hasPreferenceSignal) { return this.buildPreferenceCorrection(userMessage, context); } else if (hasCorrectionSignal) { return this.buildFactualCorrection(userMessage, agentHistory, context); } return null; } /** 构建事实纠正对象 */ private buildFactualCorrection( userMessage: string, agentHistory: string[], context: { userId: string; sessionId: string } ): DetectedCorrection { // 找出 Agent 之前的错误陈述 // 从最近的 agentHistory 中找到与用户纠正相关的原始陈述 const originalStatement this.findOriginalStatement(userMessage, agentHistory); // 提取纠正后的内容去掉纠正触发词保留事实信息 const correctedStatement this.extractCorrectedContent(userMessage); // 计算置信度基于纠正的明确程度 // 包含具体数值的纠正置信度高只有否定没有替代信息的置信度低 const confidence this.calculateConfidence(userMessage, correctedStatement); return { type: CorrectionType.FACTUAL, originalStatement, correctedStatement, confidence, topic: this.extractTopic(originalStatement ?? userMessage), source: context.userId, }; } /** 检测隐式纠正用户提供了不同信息但没有明确纠正 */ private detectImplicitCorrection( userMessage: string, agentHistory: string[], context: { userId: string; sessionId: string } ): DetectedCorrection | null { // 对比用户消息与 Agent 最近陈述的关键信息 // 如果用户给出了不同的数值/事实可能是隐式纠正 const recentAgentMsg agentHistory[agentHistory.length - 1] ?? ; // 提取数值信息对比 const agentNumbers this.extractNumbers(recentAgentMsg); const userNumbers this.extractNumbers(userMessage); if (agentNumbers.length 0 userNumbers.length 0) { // 用户和 Agent 都提供了数值且数值不同 → 可能是隐式纠正 const commonTopics this.findCommonKeywords(recentAgentMsg, userMessage); if (commonTopics.length 0 agentNumbers[0] ! userNumbers[0]) { return { type: CorrectionType.FACTUAL, originalStatement: recentAgentMsg, correctedStatement: userMessage, confidence: 0.6, // 隐式纠正置信度较低用户可能只是补充信息 topic: commonTopics[0], source: context.userId, }; } } // 检查否定反馈只有否定没有纠正内容 const negativePatterns [不对, 错了, 这不行, 不好, wrong]; const hasNegative negativePatterns.some(p userMessage.includes(p)); if (hasNegative) { return { type: CorrectionType.NEGATIVE, originalStatement: recentAgentMsg, correctedStatement: , // 否定反馈没有纠正内容 confidence: 0.3, topic: this.extractTopic(recentAgentMsg), source: context.userId, }; } return null; } /** 提取数值信息从文本中找出所有数值 */ private extractNumbers(text: string): number[] { const matches text.match(/\d\.?\d*/g); return matches ? matches.map(Number) : []; } /** 找出共同关键词判断用户和 Agent 是否在讨论同一话题 */ private findCommonKeywords(text1: string, text2: string): string[] { const keywords1 this.extractKeywords(text1); const keywords2 this.extractKeywords(text2); return keywords1.filter((k) keywords2.includes(k)); } /** 提取关键词去掉停用词后剩下的实词 */ private extractKeywords(text: string): string[] { const stopWords [的, 了, 是, 在, 有, the, is, a, an]; return text .split(/\s/) .filter((w) w.length 1 !stopWords.includes(w.toLowerCase())); } /** 计算纠正置信度 */ private calculateConfidence(userMessage: string, correctedContent: string): number { // 包含具体数值 → 高置信度 if (this.extractNumbers(correctedContent).length 0) return 0.9; // 包含来源引用 → 高置信度 if (correctedContent.includes(根据) || correctedContent.includes(据)) return 0.85; // 只有否定没有替代 → 低置信度 if (!correctedContent || correctedContent.trim().length 5) return 0.3; // 一般纠正 → 中置信度 return 0.7; } private extractCorrectedContent(message: string): string { // 去掉纠正触发词保留事实信息 let content message; for (const pattern of this.correctionPatterns) { content content.replace(pattern, ); } return content.trim(); } private findOriginalStatement(message: string, history: string[]): string { // 从历史中找与纠正内容相关的 Agent 陈述 const keywords this.extractKeywords(message); for (let i history.length - 1; i 0; i--) { const agentKeywords this.extractKeywords(history[i]); const overlap keywords.filter((k) agentKeywords.includes(k)); if (overlap.length 2) return history[i]; } return ; } private extractTopic(text: string): string { const keywords this.extractKeywords(text); return keywords.slice(0, 3).join(_); } private buildPreferenceCorrection(userMessage: string, context: { userId: string }): DetectedCorrection { return { type: CorrectionType.PREFERENCE, originalStatement: , correctedStatement: userMessage, confidence: 1.0, // 偐好不需要验证 topic: user_preference, source: context.userId, }; } private buildProcessCorrection(userMessage: string, history: string[], context: { userId: string }): DetectedCorrection { return { type: CorrectionType.PROCESS, originalStatement: , correctedStatement: userMessage, confidence: 0.8, topic: process_guidance, source: context.userId, }; } }3.2 纠正写入器// correction-writer.ts —— 将纠正写入不同存储层 export interface MemoryStore { write(key: string, value: string, ttl?: number): Promisevoid; read(key: string): Promisestring | null; } export interface KnowledgeStore { write(topic: string, correction: string, confidence: number, source: string): Promiseboolean; query(topic: string): Promisestring | null; } export class CorrectionWriter { private sessionMemory: MemoryStore; private userMemory: MemoryStore; private systemKnowledge: KnowledgeStore; private confidenceThreshold: number; constructor( sessionMemory: MemoryStore, userMemory: MemoryStore, systemKnowledge: KnowledgeStore, confidenceThreshold: number 0.7 // 写入系统知识需要 ≥0.7 置信度 ) { this.sessionMemory sessionMemory; this.userMemory userMemory; this.systemKnowledge systemKnowledge; this.confidenceThreshold confidenceThreshold; } /** 根据纠正类型写入对应存储层 */ async writeCorrection( correction: DetectedCorrection, userId: string, sessionId: string ): Promise{ writtenTo: string[]; verificationStatus: string } { const writtenTo: string[] []; switch (correction.type) { case CorrectionType.FACTUAL: // 事实纠正三层写入策略 // 1. 会话记忆立即写入当前对话立即可用 await this.sessionMemory.write( correction:${sessionId}:${correction.topic}, JSON.stringify(correction), 3600 // 1小时 TTL会话结束后清理 ); writtenTo.push(session_memory); // 2. 系统知识置信度 ≥ 阈值时写入 if (correction.confidence this.confidenceThreshold) { // 写入前验证与现有知识交叉检查 const existing await this.systemKnowledge.query(correction.topic); const verificationResult await this.verifyCorrection( correction, existing ); if (verificationResult.verified) { await this.systemKnowledge.write( correction.topic, correction.correctedStatement, correction.confidence, correction.source ); writtenTo.push(system_knowledge); } else { // 验证失败降级到用户记忆只在该用户对话中生效 await this.userMemory.write( correction:${userId}:${correction.topic}, correction.correctedStatement ); writtenTo.push(user_memory); } } else { // 置信度不足降级到用户记忆 await this.userMemory.write( correction:${userId}:${correction.topic}, correction.correctedStatement ); writtenTo.push(user_memory); } return { writtenTo, verificationStatus: correction.confidence this.confidenceThreshold ? verified : pending, }; case CorrectionType.PREFERENCE: // 偐好纠正只写入用户记忆 // 不需要验证偏好没有对错之分 await this.userMemory.write( preference:${userId}, correction.correctedStatement ); writtenTo.push(user_memory); return { writtenTo, verificationStatus: accepted }; case CorrectionType.PROCESS: // 流程纠正写入用户记忆 提交审核队列 await this.userMemory.write( process:${userId}, correction.correctedStatement ); writtenTo.push(user_memory); // 高置信度的流程纠正提交审核审核通过后写入系统提示 if (correction.confidence 0.8) { await this.submitForReview(correction); writtenTo.push(review_queue); } return { writtenTo, verificationStatus: review_pending }; case CorrectionType.NEGATIVE: // 否定反馈只写入会话记忆不持久化 await this.sessionMemory.write( negative:${sessionId}:${correction.topic}, JSON.stringify(correction), 3600 ); writtenTo.push(session_memory); return { writtenTo, verificationStatus: logged }; } } /** 验证事实纠正与现有知识交叉检查 */ private async verifyCorrection( correction: DetectedCorrection, existingKnowledge: string | null ): Promise{ verified: boolean; reason: string } { // 验证策略 // 1. 如果系统知识库中没有该主题的现有知识 → 新知识高置信度直接接受 // 2. 如果现有知识与纠正一致 → 确认直接接受 // 3. 如果现有知识与纠正矛盾 → 需要进一步验证人工审核 if (!existingKnowledge) { return { verified: true, reason: New knowledge entry, no conflict }; } if (existingKnowledge correction.correctedStatement) { return { verified: true, reason: Consistent with existing knowledge }; } // 矛盾情况需要人工审核 // 不能自动覆盖现有知识——用户也可能犯错 return { verified: false, reason: Conflict with existing knowledge: ${existingKnowledge}. Requires human review., }; } /** 提交审核队列需要人工确认的纠正 */ private async submitForReview(correction: DetectedCorrection): Promisevoid { // 审核队列存到数据库运营人员定期审核 // 审核通过后写入系统提示模板 // 审核不通过则丢弃或降级到用户记忆 console.info( Correction submitted for review: type${correction.type}, topic${correction.topic}, confidence${correction.confidence} ); } }3.3 系统提示动态注入# prompt_injector.py —— 将验证通过的纠正注入系统提示 import json from datetime import datetime class PromptInjector: 动态注入纠正信息到 Agent 的系统提示中 def __init__(self, knowledge_store): self.knowledge knowledge_store def build_system_prompt(self, base_prompt: str, user_id: str, session_id: str) - str: 构建完整的系统提示 基础指令 用户偏好 系统纠正 # 基础指令不变的 Agent 行为规范 sections [base_prompt] # 系统纠正从知识库中加载与当前对话相关的纠正 # 这些纠正已经通过验证可以信任 corrections self.knowledge.get_all_verified() if corrections: correction_text self.format_corrections(corrections) sections.append(f## Verified Knowledge Corrections\n{correction_text}) # 用户偏好从用户记忆中加载该用户的偏好设置 user_preferences self.knowledge.get_user_preferences(user_id) if user_preferences: preference_text self.format_preferences(user_preferences) sections.append(f## User Preferences\n{preference_text}) return \n\n.join(sections) def format_corrections(self, corrections: list) - str: 格式化系统纠正为提示文本 lines [] for c in corrections: # 纠正格式原始错误 → 正确答案 # Agent 看到后会避免重复犯错 lines.append( f- **{c[topic]}**: {c[corrected_statement]} f(previously incorrectly stated as: \{c[original_statement]}\) ) return \n.join(lines) def format_preferences(self, preferences: list) - str: 格式化用户偏好为提示文本 lines [] for p in preferences: lines.append(f- {p[content]}) return \n.join(lines)四、边界分析与架构权衡4.1 自动验证的局限性与现有知识库交叉检查只能发现矛盾不能验证新信息的正确性。如果知识库本身有错误与知识库一致不代表纠正正确。如果知识库中没有该主题无冲突不代表用户提供的信息正确。对策置信度阈值分层。0.7-0.85 置信度的纠正写入用户记忆影响范围小0.85 置信度且与知识库一致的纠正写入系统知识影响范围大。0.7 以下的纠正只写入会话记忆。4.2 系统提示的膨胀问题每次纠正都追加到系统提示长期运行后提示越来越长token 消耗增加。100 条纠正约占 2000 token10 条纠正就占了 GPT-4 的 1% token 限额。对策根据对话主题动态筛选相关纠正——只注入与当前对话主题相关的纠正不注入所有纠正。定期清理过时的纠正TTL 30 天。4.3 适用边界与禁用场景适用知识密集型 AgentFAQ、教育、咨询、多用户共享的通用 Agent、需要持续改进的对话系统禁用创意型 Agent纠正没有对错之分、低频使用的 Agent纠正积累太慢、安全敏感场景用户纠正可能包含恶意信息4.4 纠正冲突的处理两个用户对同一主题提供了不同的纠正比如一个说北京降雨量 630mm另一个说580mm。矛盾纠正不能同时写入系统知识。需要人工审核决定哪个正确或者标注存在争议让 Agent 回答时说明。五、总结Agent 反馈闭环的核心是检测→分类→验证→写入四步流程。纠正检测识别用户的纠正意图分类器区分事实纠正/偏好纠正/流程纠正/否定反馈。事实纠正需要验证与知识库交叉检查置信度阈值才能写入系统知识偏好纠正直接写入用户记忆流程纠正提交审核后写入系统提示。三层写入会话记忆当前对话、用户记忆该用户所有对话、系统知识所有用户所有对话。置信度 0.7 以下只写会话记忆0.7-0.85 写用户记忆0.85 且验证通过写系统知识。系统提示需要动态筛选相关纠正防止 token 膨胀。