Agent Skills by ALSEL
Anthropic ClaudeLLM・AI開発⭐ リポ 0品質スコア 50/100

conversation-memory

LLMとの会話における短期・長期・エンティティベースの記憶を管理する永続的なメモリシステムです。会話をまたいでコンテキストや重要情報を保持し、ユーザーや概念に関する知識を蓄積・活用することができます。

description の原文を見る

Persistent memory systems for LLM conversations including short-term, long-term, and entity-based memory

SKILL.md 本文

会話メモリ

short-term、long-term、entity-based メモリを含む LLM 会話の永続的なメモリシステム

機能

  • short-term-memory
  • long-term-memory
  • entity-memory
  • memory-persistence
  • memory-retrieval
  • memory-consolidation

前提条件

  • 知識: LLM 会話パターン、データベース基礎、Key-value ストア
  • 推奨スキル: context-window-management、rag-implementation

スコープ

  • カバーしない: ナレッジグラフの構築、セマンティック検索の実装、データベース管理
  • 境界: LLM のメモリパターンに焦点、ストレージと検索戦略をカバー

エコシステム

Primary_tools

  • Mem0 - AI アプリケーション向けメモリレイヤー
  • LangChain Memory - LangChain のメモリユーティリティ
  • Redis - セッションメモリ用のインメモリデータストア

パターン

Tiered Memory System

異なる目的のための異なるメモリティア

使用時機: 会話型 AI を構築するあらゆる場面

interface MemorySystem {
    // Buffer: 現在の会話(コンテキスト内)
    buffer: ConversationBuffer;

    // Short-term: 最近のやり取り(セッション)
    shortTerm: ShortTermMemory;

    // Long-term: セッション間で永続化
    longTerm: LongTermMemory;

    // Entity: 人、場所、物などについての事実
    entity: EntityMemory;
}

class TieredMemory implements MemorySystem {
    async addMessage(message: Message): Promise<void> {
        // 常にバッファに追加
        this.buffer.add(message);

        // エンティティを抽出
        const entities = await extractEntities(message);
        for (const entity of entities) {
            await this.entity.upsert(entity);
        }

        // 記憶に値するコンテンツかチェック
        if (await isMemoryWorthy(message)) {
            await this.shortTerm.add({
                content: message.content,
                timestamp: Date.now(),
                importance: await scoreImportance(message)
            });
        }
    }

    async consolidate(): Promise<void> {
        // 重要な短期メモリを長期メモリに移動
        const memories = await this.shortTerm.getOld(24 * 60 * 60 * 1000);
        for (const memory of memories) {
            if (memory.importance > 0.7 || memory.referenced > 2) {
                await this.longTerm.add(memory);
            }
            await this.shortTerm.remove(memory.id);
        }
    }

    async buildContext(query: string): Promise<string> {
        const parts: string[] = [];

        // 関連する長期メモリ
        const longTermRelevant = await this.longTerm.search(query, 3);
        if (longTermRelevant.length) {
            parts.push('## Relevant Memories\n' +
                longTermRelevant.map(m => `- ${m.content}`).join('\n'));
        }

        // 関連するエンティティ
        const entities = await this.entity.getRelevant(query);
        if (entities.length) {
            parts.push('## Known Entities\n' +
                entities.map(e => `- ${e.name}: ${e.facts.join(', ')}`).join('\n'));
        }

        // 最近の会話
        const recent = this.buffer.getRecent(10);
        parts.push('## Recent Conversation\n' + formatMessages(recent));

        return parts.join('\n\n');
    }
}

Entity Memory

エンティティに関する事実を保存・更新

使用時機: 人、場所、物に関する詳細を記憶する必要がある場合

interface Entity {
    id: string;
    name: string;
    type: 'person' | 'place' | 'thing' | 'concept';
    facts: Fact[];
    lastMentioned: number;
    mentionCount: number;
}

interface Fact {
    content: string;
    confidence: number;
    source: string;  // どのメッセージからきたか
    timestamp: number;
}

class EntityMemory {
    async extractAndStore(message: Message): Promise<void> {
        // LLM を使用してエンティティと事実を抽出
        const extraction = await llm.complete(`
            Extract entities and facts from this message.
            Return JSON: { "entities": [
                { "name": "...", "type": "...", "facts": ["..."] }
            ]}

            Message: "${message.content}"
        `);

        const { entities } = JSON.parse(extraction);
        for (const entity of entities) {
            await this.upsert(entity, message.id);
        }
    }

    async upsert(entity: ExtractedEntity, sourceId: string): Promise<void> {
        const existing = await this.store.get(entity.name.toLowerCase());

        if (existing) {
            // 事実をマージ、重複を回避
            for (const fact of entity.facts) {
                if (!this.hasSimilarFact(existing.facts, fact)) {
                    existing.facts.push({
                        content: fact,
                        confidence: 0.9,
                        source: sourceId,
                        timestamp: Date.now()
                    });
                }
            }
            existing.lastMentioned = Date.now();
            existing.mentionCount++;
            await this.store.set(existing.id, existing);
        } else {
            // 新しいエンティティを作成
            await this.store.set(entity.name.toLowerCase(), {
                id: generateId(),
                name: entity.name,
                type: entity.type,
                facts: entity.facts.map(f => ({
                    content: f,
                    confidence: 0.9,
                    source: sourceId,
                    timestamp: Date.now()
                })),
                lastMentioned: Date.now(),
                mentionCount: 1
            });
        }
    }
}

Memory-Aware Prompting

プロンプトに関連するメモリを含める

使用時機: メモリコンテキストで LLM 呼び出しを行う場合

async function promptWithMemory(
    query: string,
    memory: MemorySystem,
    systemPrompt: string
): Promise<string> {
    // 関連するメモリを取得
    const relevantMemories = await memory.longTerm.search(query, 5);
    const entities = await memory.entity.getRelevant(query);
    const recentContext = memory.buffer.getRecent(5);

    // メモリ拡張プロンプトを構築
    const prompt = `
${systemPrompt}

## User Context
${entities.length ? `Known about user:\n${entities.map(e =>
    `- ${e.name}: ${e.facts.map(f => f.content).join('; ')}`
).join('\n')}` : ''}

${relevantMemories.length ? `Relevant past interactions:\n${relevantMemories.map(m =>
    `- [${formatDate(m.timestamp)}] ${m.content}`
).join('\n')}` : ''}

## Recent Conversation
${formatMessages(recentContext)}

## Current Query
${query}
    `.trim();

    const response = await llm.complete(prompt);

    // レスポンスから新しいメモリを抽出
    await memory.addMessage({ role: 'assistant', content: response });

    return response;
}

Sharp Edges

メモリストアが無制限に増加し、システムが遅くなる

重大度: HIGH

状況: システムが時間とともに遅くなり、コストが増加

症状:

  • メモリ取得が遅い
  • ストレージコストが高い
  • 時間とともに遅延が増加

なぜこれが機能しないか: すべてのメッセージがメモリとして保存される。 クリーンアップや統合がない。 数百万のアイテムにわたる取得。

推奨される修正:

// メモリライフサイクル管理を実装

class ManagedMemory {
    // 制限
    private readonly SHORT_TERM_MAX = 100;
    private readonly LONG_TERM_MAX = 10000;
    private readonly CONSOLIDATION_INTERVAL = 24 * 60 * 60 * 1000;

    async add(memory: Memory): Promise<void> {
        // 保存前に重要度をスコア
        const score = await this.scoreImportance(memory);
        if (score < 0.3) return;  // 低い重要度は保存しない

        memory.importance = score;
        await this.shortTerm.add(memory);

        // 制限をチェック
        await this.enforceShortTermLimit();
    }

    async enforceShortTermLimit(): Promise<void> {
        const count = await this.shortTerm.count();
        if (count > this.SHORT_TERM_MAX) {
            // 統合: 重要なものを長期メモリに移動、残りは削除
            const memories = await this.shortTerm.getAll();
            memories.sort((a, b) => b.importance - a.importance);

            const toKeep = memories.slice(0, this.SHORT_TERM_MAX * 0.7);
            const toConsolidate = memories.slice(this.SHORT_TERM_MAX * 0.7);

            for (const m of toConsolidate) {
                if (m.importance > 0.7) {
                    await this.longTerm.add(m);
                }
                await this.shortTerm.remove(m.id);
            }
        }
    }

    async scoreImportance(memory: Memory): Promise<number> {
        const factors = {
            hasUserPreference: /prefer|like|don't like|hate|love/i.test(memory.content) ? 0.3 : 0,
            hasDecision: /decided|chose|will do|won't do/i.test(memory.content) ? 0.3 : 0,
            hasFactAboutUser: /my|I am|I have|I work/i.test(memory.content) ? 0.2 : 0,
            length: memory.content.length > 100 ? 0.1 : 0,
            userMessage: memory.role === 'user' ? 0.1 : 0,
        };

        return Object.values(factors).reduce((a, b) => a + b, 0);
    }
}

取得されたメモリが現在のクエリに関連していない

重大度: HIGH

状況: メモリがコンテキストに含まれているが役に立たない

症状:

  • コンテキスト内のメモリがランダムに見える
  • ユーザーが既にメモリにあるものについて尋ねる
  • 無関係なコンテキストからの混乱

なぜこれが機能しないか: 単純なキーワードマッチング。 関連性スコアリングがない。 取得されたすべてのメモリを含める。

推奨される修正:

// インテリジェントなメモリ取得

async function retrieveRelevant(
    query: string,
    memories: MemoryStore,
    maxResults: number = 5
): Promise<Memory[]> {
    // 1. セマンティック検索
    const candidates = await memories.semanticSearch(query, maxResults * 3);

    // 2. コンテキストで関連性をスコア
    const scored = await Promise.all(candidates.map(async (m) => {
        const relevanceScore = await llm.complete(`
            Rate 0-1 how relevant this memory is to the query.
            Query: "${query}"
            Memory: "${m.content}"
            Return just the number.
        `);
        return { ...m, relevance: parseFloat(relevanceScore) };
    }));

    // 3. 低い関連性をフィルター
    const relevant = scored.filter(m => m.relevance > 0.5);

    // 4. ソートと制限
    return relevant
        .sort((a, b) => b.relevance - a.relevance)
        .slice(0, maxResults);
}

ある ユーザーのメモリが別のユーザーにアクセス可能

重大度: CRITICAL

状況: ユーザーが別のユーザーのセッションの情報を見ている

症状:

  • ユーザーが別のユーザーの情報を見る
  • プライバシーに関する苦情
  • コンプライアンス違反

なぜこれが機能しないか: メモリストアにユーザー隔離がない。 共有メモリ名前空間。 クロスユーザー取得。

推奨される修正:

// メモリ内の厳密なユーザー隔離

class IsolatedMemory {
    private getKey(userId: string, memoryId: string): string {
        // すべてのキーをユーザー別に名前空間化
        return `user:${userId}:memory:${memoryId}`;
    }

    async add(userId: string, memory: Memory): Promise<void> {
        // userId が認証済みであることを検証
        if (!isValidUserId(userId)) {
            throw new Error('Invalid user ID');
        }

        const key = this.getKey(userId, memory.id);
        memory.userId = userId;  // ユーザーでタグ付け
        await this.store.set(key, memory);
    }

    async search(userId: string, query: string): Promise<Memory[]> {
        // 重要: クエリでユーザーでフィルター
        return await this.store.search({
            query,
            filter: { userId: userId },  // 必須フィルター
            limit: 10
        });
    }

    async delete(userId: string, memoryId: string): Promise<void> {
        const memory = await this.get(userId, memoryId);
        // 削除前に所有権を検証
        if (memory.userId !== userId) {
            throw new Error('Access denied');
        }
        await this.store.delete(this.getKey(userId, memoryId));
    }

    // ユーザーデータエクスポート(GDPR コンプライアンス)
    async exportUserData(userId: string): Promise<Memory[]> {
        return await this.store.getAll({ userId });
    }

    // ユーザーデータ削除(GDPR コンプライアンス)
    async deleteUserData(userId: string): Promise<void> {
        const memories = await this.exportUserData(userId);
        for (const m of memories) {
            await this.store.delete(this.getKey(userId, m.id));
        }
    }
}

検証チェック

メモリにユーザー隔離がない

重大度: CRITICAL

メッセージ: ユーザー隔離のないメモリ操作。プライバシーの脆弱性。

修正アクション: すべてのメモリ操作に userId を追加し、取得時にユーザーでフィルター

重要度フィルタリングがない

重大度: WARNING

メッセージ: 重要度フィルタリングなしでメモリを保存。メモリが爆発する可能性。

修正アクション: 保存前に重要度をスコア、低い重要度のコンテンツをフィルター

取得ロジックのないメモリストレージ

重大度: WARNING

メッセージ: メモリは保存されているが取得ロジックがない。メモリが使用されない。

修正アクション: メモリ取得を実装し、プロンプトに含める

メモリクリーンアップメカニズムがない

重大度: INFO

メッセージ: メモリクリーンアップメカニズムがない。ストレージが無制限に増加します。

修正アクション: 年齢/重要度に基づく統合とクリーンアップを実装

コラボレーション

委任トリガー

  • context window|token -> context-window-management (コンテキスト最適化が必要)
  • rag|retrieval|vector -> rag-implementation (検索システムが必要)
  • cache|caching -> prompt-caching (キャッシング戦略が必要)

完全なメモリシステム

スキル: conversation-memory、context-window-management、rag-implementation

ワークフロー:

1. メモリティアを設計
2. ストレージと取得を実装
3. コンテキスト管理と統合
4. 統合とクリーンアップを追加

関連スキル

相性が良い: context-window-managementrag-implementationprompt-cachingllm-npc-dialogue

使用時機

  • ユーザーが以下を言及または示唆: conversation memory
  • ユーザーが以下を言及または示唆: remember
  • ユーザーが以下を言及または示唆: memory persistence
  • ユーザーが以下を言及または示唆: long-term memory
  • ユーザーが以下を言及または示唆: chat history

制限事項

  • このスキルは、タスクが上記で説明されたスコープと明確に一致する場合にのみ使用してください。
  • 出力を環境固有の検証、テスト、または専門家レビューの代わりとして扱わないでください。
  • 必要な入力、権限、安全境界、または成功基準が不足している場合は、一度立ち止まり明確化を求めてください。

ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ

詳細情報

作者
sickn33
リポジトリ
sickn33/antigravity-awesome-skills
ライセンス
MIT
最終更新
不明

Source: https://github.com/sickn33/antigravity-awesome-skills / ライセンス: MIT

関連スキル

OpenAILLM・AI開発⭐ リポ 6,054

agent-browser

AI エージェント向けのブラウザ自動化 CLI です。ウェブサイトとの対話が必要な場合に使用します。ページ遷移、フォーム入力、ボタンクリック、スクリーンショット取得、データ抽出、ウェブアプリのテスト、ブラウザ操作の自動化など、あらゆるブラウザタスクに対応できます。「ウェブサイトを開く」「フォームに記入する」「ボタンをクリックする」「スクリーンショットを取得する」「ページからデータを抽出する」「このウェブアプリをテストする」「サイトにログインする」「ブラウザ操作を自動化する」といった要求や、プログラマティックなウェブ操作が必要なタスクで起動します。

by JimmyLv
汎用LLM・AI開発⭐ リポ 1,982

anyskill

AnySkill — あなたのプライベート・スキルクラウド。GitHubを基盤としたリポジトリからエージェントスキルを管理、同期、動的にロードできます。自然言語でクラウドスキルを検索し、オンデマンドでプロンプトを自動ロード、カスタムスキルのアップロードと共有、スキルバンドルの一括インストールが可能です。OpenClaw、Antigravity、Claude Code、Cursorに対応しています。

by LeoYeAI
汎用LLM・AI開発⭐ リポ 1,982

engram

AIエージェント向けの永続的なメモリシステムです。バグ修正、意思決定、発見、設定変更の後はmem_saveを使用してください。ユーザーが「覚えている」「記憶している」と言及した場合、または以前のセッションと重複する作業を開始する際はmem_searchを使用します。セッション終了前にmem_session_summaryを使用して、コンテキストを保持してください。

by LeoYeAI
汎用LLM・AI開発⭐ リポ 21,584

skyvern

AI駆動のブラウザ自動化により、任意のウェブサイトを自動化できます。フォーム入力、データ抽出、ファイルダウンロード、ログイン、複数ステップのワークフロー実行など、ユーザーがウェブサイトと連携する必要があるときに使用します。Skyvernは、LLMとコンピュータビジョンを活用して、未知のサイトも自動操作可能です。Python SDK、TypeScript SDK、REST API、MCPサーバー、またはCLIを通じて統合できます。

by Skyvern-AI
汎用LLM・AI開発⭐ リポ 1,149

pinchbench

PinchBenchベンチマークを実行して、OpenClawエージェントの実世界タスクにおけるパフォーマンスを評価できます。モデルの機能テスト、モデル間の比較、ベンチマーク結果のリーダーボード提出、またはOpenClawのセットアップがカレンダー、メール、リサーチ、コーディング、複数ステップのワークフローにどの程度対応しているかを確認する際に使用します。

by pinchbench
汎用LLM・AI開発⭐ リポ 4,693

openui

OpenUIとOpenUI Langを使用してジェネレーティブUIアプリを構築できます。これらはLLM生成インターフェースのためのトークン効率的なオープン標準です。OpenUI、@openuidev、ジェネレーティブUI、LLMからのストリーミングUI、AI向けコンポーネントライブラリ、またはjson-render/A2UIの置き換えについて述べる際に使用します。スキャフォルディング、defineComponent、システムプロンプト、Renderer、およびOpenUI Lang出力のデバッグに対応しています。

by thesysdev
本サイトは GitHub 上で公開されているオープンソースの SKILL.md ファイルをクロール・インデックス化したものです。 各スキルの著作権は原作者に帰属します。掲載に問題がある場合は info@alsel.co.jp または /takedown フォームよりご連絡ください。
原作者: sickn33 · sickn33/antigravity-awesome-skills · ライセンス: MIT