[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-a8787fc9-2cfe-41e5-8ea0-ba7b7ae36487":3,"$frj2xf74DAgZbjLfvh-n1tx65K2nNQ9v5TkinKSLD530":42},{"id":4,"title":5,"description":6,"categoryId":7,"moduleId":8,"tags":9,"prompt":10,"icon":11,"source":12,"sourceUrl":13,"authorId":14,"authorName":15,"isPublic":16,"stars":17,"runs":18,"createdAt":19,"updatedAt":19,"module":20,"category":27,"packages":33},"a8787fc9-2cfe-41e5-8ea0-ba7b7ae36487","conversation-memory","用于LLM对话的持久内存系统包括","cat_coding_backend","mod_coding","sickn33,coding","---\nname: conversation-memory\ndescription: Persistent memory systems for LLM conversations including\n  short-term, long-term, and entity-based memory\nrisk: unknown\nsource: vibeship-spawner-skills (Apache 2.0)\ndate_added: 2026-02-27\n---\n\n# Conversation Memory\n\nPersistent memory systems for LLM conversations including short-term, long-term, and entity-based memory\n\n## Capabilities\n\n- short-term-memory\n- long-term-memory\n- entity-memory\n- memory-persistence\n- memory-retrieval\n- memory-consolidation\n\n## Prerequisites\n\n- Knowledge: LLM conversation patterns, Database basics, Key-value stores\n- Skills_recommended: context-window-management, rag-implementation\n\n## Scope\n\n- Does_not_cover: Knowledge graph construction, Semantic search implementation, Database administration\n- Boundaries: Focus is memory patterns for LLMs, Covers storage and retrieval strategies\n\n## Ecosystem\n\n### Primary_tools\n\n- Mem0 - Memory layer for AI applications\n- LangChain Memory - Memory utilities in LangChain\n- Redis - In-memory data store for session memory\n\n## Patterns\n\n### Tiered Memory System\n\nDifferent memory tiers for different purposes\n\n**When to use**: Building any conversational AI\n\ninterface MemorySystem {\n    \u002F\u002F Buffer: Current conversation (in context)\n    buffer: ConversationBuffer;\n\n    \u002F\u002F Short-term: Recent interactions (session)\n    shortTerm: ShortTermMemory;\n\n    \u002F\u002F Long-term: Persistent across sessions\n    longTerm: LongTermMemory;\n\n    \u002F\u002F Entity: Facts about people, places, things\n    entity: EntityMemory;\n}\n\nclass TieredMemory implements MemorySystem {\n    async addMessage(message: Message): Promise\u003Cvoid> {\n        \u002F\u002F Always add to buffer\n        this.buffer.add(message);\n\n        \u002F\u002F Extract entities\n        const entities = await extractEntities(message);\n        for (const entity of entities) {\n            await this.entity.upsert(entity);\n        }\n\n        \u002F\u002F Check for memorable content\n        if (await isMemoryWorthy(message)) {\n            await this.shortTerm.add({\n                content: message.content,\n                timestamp: Date.now(),\n                importance: await scoreImportance(message)\n            });\n        }\n    }\n\n    async consolidate(): Promise\u003Cvoid> {\n        \u002F\u002F Move important short-term to long-term\n        const memories = await this.shortTerm.getOld(24 * 60 * 60 * 1000);\n        for (const memory of memories) {\n            if (memory.importance > 0.7 || memory.referenced > 2) {\n                await this.longTerm.add(memory);\n            }\n            await this.shortTerm.remove(memory.id);\n        }\n    }\n\n    async buildContext(query: string): Promise\u003Cstring> {\n        const parts: string[] = [];\n\n        \u002F\u002F Relevant long-term memories\n        const longTermRelevant = await this.longTerm.search(query, 3);\n        if (longTermRelevant.length) {\n            parts.push('## Relevant Memories\\n' +\n                longTermRelevant.map(m => `- ${m.content}`).join('\\n'));\n        }\n\n        \u002F\u002F Relevant entities\n        const entities = await this.entity.getRelevant(query);\n        if (entities.length) {\n            parts.push('## Known Entities\\n' +\n                entities.map(e => `- ${e.name}: ${e.facts.join(', ')}`).join('\\n'));\n        }\n\n        \u002F\u002F Recent conversation\n        const recent = this.buffer.getRecent(10);\n        parts.push('## Recent Conversation\\n' + formatMessages(recent));\n\n        return parts.join('\\n\\n');\n    }\n}\n\n### Entity Memory\n\nStore and update facts about entities\n\n**When to use**: Need to remember details about people, places, things\n\ninterface Entity {\n    id: string;\n    name: string;\n    type: 'person' | 'place' | 'thing' | 'concept';\n    facts: Fact[];\n    lastMentioned: number;\n    mentionCount: number;\n}\n\ninterface Fact {\n    content: string;\n    confidence: number;\n    source: string;  \u002F\u002F Which message this came from\n    timestamp: number;\n}\n\nclass EntityMemory {\n    async extractAndStore(message: Message): Promise\u003Cvoid> {\n        \u002F\u002F Use LLM to extract entities and facts\n        const extraction = await llm.complete(`\n            Extract entities and facts from this message.\n            Return JSON: { \"entities\": [\n                { \"name\": \"...\", \"type\": \"...\", \"facts\": [\"...\"] }\n            ]}\n\n            Message: \"${message.content}\"\n        `);\n\n        const { entities } = JSON.parse(extraction);\n        for (const entity of entities) {\n            await this.upsert(entity, message.id);\n        }\n    }\n\n    async upsert(entity: ExtractedEntity, sourceId: string): Promise\u003Cvoid> {\n        const existing = await this.store.get(entity.name.toLowerCase());\n\n        if (existing) {\n            \u002F\u002F Merge facts, avoiding duplicates\n            for (const fact of entity.facts) {\n                if (!this.hasSimilarFact(existing.facts, fact)) {\n                    existing.facts.push({\n                        content: fact,\n                        confidence: 0.9,\n                        source: sourceId,\n                        timestamp: Date.now()\n                    });\n                }\n            }\n            existing.lastMentioned = Date.now();\n            existing.mentionCount++;\n            await this.store.set(existing.id, existing);\n        } else {\n            \u002F\u002F Create new entity\n            await this.store.set(entity.name.toLowerCase(), {\n                id: generateId(),\n                name: entity.name,\n                type: entity.type,\n                facts: entity.facts.map(f => ({\n                    content: f,\n                    confidence: 0.9,\n                    source: sourceId,\n                    timestamp: Date.now()\n                })),\n                lastMentioned: Date.now(),\n                mentionCount: 1\n            });\n        }\n    }\n}\n\n### Memory-Aware Prompting\n\nInclude relevant memories in prompts\n\n**When to use**: Making LLM calls with memory context\n\nasync function promptWithMemory(\n    query: string,\n    memory: MemorySystem,\n    systemPrompt: string\n): Promise\u003Cstring> {\n    \u002F\u002F Retrieve relevant memories\n    const relevantMemories = await memory.longTerm.search(query, 5);\n    const entities = await memory.entity.getRelevant(query);\n    const recentContext = memory.buffer.getRecent(5);\n\n    \u002F\u002F Build memory-augmented prompt\n    const prompt = `\n${systemPrompt}\n\n## User Context\n${entities.length ? `Known about user:\\n${entities.map(e =>\n    `- ${e.name}: ${e.facts.map(f => f.content).join('; ')}`\n).join('\\n')}` : ''}\n\n${relevantMemories.length ? `Relevant past interactions:\\n${relevantMemories.map(m =>\n    `- [${formatDate(m.timestamp)}] ${m.content}`\n).join('\\n')}` : ''}\n\n## Recent Conversation\n${formatMessages(recentContext)}\n\n## Current Query\n${query}\n    `.trim();\n\n    const response = await llm.complete(prompt);\n\n    \u002F\u002F Extract any new memories from response\n    await memory.addMessage({ role: 'assistant', content: response });\n\n    return response;\n}\n\n## Sharp Edges\n\n### Memory store grows unbounded, system slows\n\nSeverity: HIGH\n\nSituation: System slows over time, costs increase\n\nSymptoms:\n- Slow memory retrieval\n- High storage costs\n- Increasing latency over time\n\nWhy this breaks:\nEvery message stored as memory.\nNo cleanup or consolidation.\nRetrieval over millions of items.\n\nRecommended fix:\n\n\u002F\u002F Implement memory lifecycle management\n\nclass ManagedMemory {\n    \u002F\u002F Limits\n    private readonly SHORT_TERM_MAX = 100;\n    private readonly LONG_TERM_MAX = 10000;\n    private readonly CONSOLIDATION_INTERVAL = 24 * 60 * 60 * 1000;\n\n    async add(memory: Memory): Promise\u003Cvoid> {\n        \u002F\u002F Score importance before storing\n        const score = await this.scoreImportance(memory);\n        if (score \u003C 0.3) return;  \u002F\u002F Don't store low-importance\n\n        memory.importance = score;\n        await this.shortTerm.add(memory);\n\n        \u002F\u002F Check limits\n        await this.enforceShortTermLimit();\n    }\n\n    async enforceShortTermLimit(): Promise\u003Cvoid> {\n        const count = await this.shortTerm.count();\n        if (count > this.SHORT_TERM_MAX) {\n            \u002F\u002F Consolidate: move important to long-term, delete rest\n            const memories = await this.shortTerm.getAll();\n            memories.sort((a, b) => b.importance - a.importance);\n\n            const toKeep = memories.slice(0, this.SHORT_TERM_MAX * 0.7);\n            const toConsolidate = memories.slice(this.SHORT_TERM_MAX * 0.7);\n\n            for (const m of toConsolidate) {\n                if (m.importance > 0.7) {\n                    await this.longTerm.add(m);\n                }\n                await this.shortTerm.remove(m.id);\n            }\n        }\n    }\n\n    async scoreImportance(memory: Memory): Promise\u003Cnumber> {\n        const factors = {\n            hasUserPreference: \u002Fprefer|like|don't like|hate|love\u002Fi.test(memory.content) ? 0.3 : 0,\n            hasDecision: \u002Fdecided|chose|will do|won't do\u002Fi.test(memory.content) ? 0.3 : 0,\n            hasFactAboutUser: \u002Fmy|I am|I have|I work\u002Fi.test(memory.content) ? 0.2 : 0,\n            length: memory.content.length > 100 ? 0.1 : 0,\n            userMessage: memory.role === 'user' ? 0.1 : 0,\n        };\n\n        return Object.values(factors).reduce((a, b) => a + b, 0);\n    }\n}\n\n### Retrieved memories not relevant to current query\n\nSeverity: HIGH\n\nSituation: Memories included in context but don't help\n\nSymptoms:\n- Memories in context seem random\n- User asks about things already in memory\n- Confusion from irrelevant context\n\nWhy this breaks:\nSimple keyword matching.\nNo relevance scoring.\nIncluding all retrieved memories.\n\nRecommended fix:\n\n\u002F\u002F Intelligent memory retrieval\n\nasync function retrieveRelevant(\n    query: string,\n    memories: MemoryStore,\n    maxResults: number = 5\n): Promise\u003CMemory[]> {\n    \u002F\u002F 1. Semantic search\n    const candidates = await memories.semanticSearch(query, maxResults * 3);\n\n    \u002F\u002F 2. Score relevance with context\n    const scored = await Promise.all(candidates.map(async (m) => {\n        const relevanceScore = await llm.complete(`\n            Rate 0-1 how relevant this memory is to the query.\n            Query: \"${query}\"\n            Memory: \"${m.content}\"\n            Return just the number.\n        `);\n        return { ...m, relevance: parseFloat(relevanceScore) };\n    }));\n\n    \u002F\u002F 3. Filter low relevance\n    const relevant = scored.filter(m => m.relevance > 0.5);\n\n    \u002F\u002F 4. Sort and limit\n    return relevant\n        .sort((a, b) => b.relevance - a.relevance)\n        .slice(0, maxResults);\n}\n\n### Memories from one user accessible to another\n\nSeverity: CRITICAL\n\nSituation: User sees information from another user's sessions\n\nSymptoms:\n- User sees other user's information\n- Privacy complaints\n- Compliance violations\n\nWhy this breaks:\nNo user isolation in memory store.\nShared memory namespace.\nCross-user retrieval.\n\nRecommended fix:\n\n\u002F\u002F Strict user isolation in memory\n\nclass IsolatedMemory {\n    private getKey(userId: string, memoryId: string): string {\n        \u002F\u002F Namespace all keys by user\n        return `user:${userId}:memory:${memoryId}`;\n    }\n\n    async add(userId: string, memory: Memory): Promise\u003Cvoid> {\n        \u002F\u002F Validate userId is authenticated\n        if (!isValidUserId(userId)) {\n            throw new Error('Invalid user ID');\n        }\n\n        const key = this.getKey(userId, memory.id);\n        memory.userId = userId;  \u002F\u002F Tag with user\n        await this.store.set(key, memory);\n    }\n\n    async search(userId: string, query: string): Promise\u003CMemory[]> {\n        \u002F\u002F CRITICAL: Filter by user in query\n        return await this.store.search({\n            query,\n            filter: { userId: userId },  \u002F\u002F Mandatory filter\n            limit: 10\n        });\n    }\n\n    async delete(userId: string, memoryId: string): Promise\u003Cvoid> {\n        const memory = await this.get(userId, memoryId);\n        \u002F\u002F Verify ownership before delete\n        if (memory.userId !== userId) {\n            throw new Error('Access denied');\n        }\n        await this.store.delete(this.getKey(userId, memoryId));\n    }\n\n    \u002F\u002F User data export (GDPR compliance)\n    async exportUserData(userId: string): Promise\u003CMemory[]> {\n        return await this.store.getAll({ userId });\n    }\n\n    \u002F\u002F User data deletion (GDPR compliance)\n    async deleteUserData(userId: string): Promise\u003Cvoid> {\n        const memories = await this.exportUserData(userId);\n        for (const m of memories) {\n            await this.store.delete(this.getKey(userId, m.id));\n        }\n    }\n}\n\n## Validation Checks\n\n### No User Isolation in Memory\n\nSeverity: CRITICAL\n\nMessage: Memory operations without user isolation. Privacy vulnerability.\n\nFix action: Add userId to all memory operations, filter by user on retrieval\n\n### No Importance Filtering\n\nSeverity: WARNING\n\nMessage: Storing memories without importance filtering. May cause memory explosion.\n\nFix action: Score importance before storing, filter low-importance content\n\n### Memory Storage Without Retrieval\n\nSeverity: WARNING\n\nMessage: Storing memories but no retrieval logic. Memories won't be used.\n\nFix action: Implement memory retrieval and include in prompts\n\n### No Memory Cleanup\n\nSeverity: INFO\n\nMessage: No memory cleanup mechanism. Storage will grow unbounded.\n\nFix action: Implement consolidation and cleanup based on age\u002Fimportance\n\n## Collaboration\n\n### Delegation Triggers\n\n- context window|token -> context-window-management (Need context optimization)\n- rag|retrieval|vector -> rag-implementation (Need retrieval system)\n- cache|caching -> prompt-caching (Need caching strategies)\n\n### Complete Memory System\n\nSkills: conversation-memory, context-window-management, rag-implementation\n\nWorkflow:\n\n```\n1. Design memory tiers\n2. Implement storage and retrieval\n3. Integrate with context management\n4. Add consolidation and cleanup\n```\n\n## Related Skills\n\nWorks well with: `context-window-management`, `rag-implementation`, `prompt-caching`, `llm-npc-dialogue`\n\n## When to Use\n- User mentions or implies: conversation memory\n- User mentions or implies: remember\n- User mentions or implies: memory persistence\n- User mentions or implies: long-term memory\n- User mentions or implies: chat history\n\n## Limitations\n- Use this skill only when the task clearly matches the scope described above.\n- Do not treat the output as a substitute for environment-specific validation, testing, or expert review.\n- Stop and ask for clarification if required inputs, permissions, safety boundaries, or success criteria are missing.\n","","imported","https:\u002F\u002Fgithub.com\u002Fsickn33\u002Fantigravity-awesome-skills","user_system_seed","SkillOPIC",true,87,1289,"2026-05-16 13:13:15",{"id":8,"name":21,"slug":22,"icon":23,"description":24,"sort":25,"createdAt":26},"编程开发","coding","mdi-code-braces","代码生成、调试、审查，提升开发效率",2,"2026-05-16 12:53:40",{"id":7,"name":28,"slug":29,"icon":30,"description":31,"moduleId":8,"sort":25,"skillCount":32,"createdAt":26},"后端开发","backend","mdi-server","API、数据库、服务端架构",296,[34],{"id":35,"skillId":4,"version":36,"fileName":37,"fileSize":38,"filePath":39,"fileHash":40,"manifest":41,"createdAt":19},"70bf0cf1-2ed1-42b9-9055-d0d57e5565cd","1.0.0","conversation-memory.zip",4746,"uploads\u002Fskills\u002Fa8787fc9-2cfe-41e5-8ea0-ba7b7ae36487\u002Fconversation-memory.zip","6b0dbfd1f8c77249552374ce4bdbf6c7f0539bad1b96a610d385edb5dcbdae87","[{\"path\":\"SKILL.md\",\"isDirectory\":false,\"size\":14359}]",{"code":43,"message":44,"data":45},200,"success",{"items":46,"stats":47,"page":50},[],{"averageRating":48,"totalRatings":48,"ratingCounts":49},0,[48,48,48,48,48],{"limit":51,"offset":48,"hasMore":52,"nextOffset":51,"ratedOnly":16},15,false]