Skip to content

Latest commit

 

History

History
578 lines (427 loc) · 19.2 KB

File metadata and controls

578 lines (427 loc) · 19.2 KB

Memory Examples

This directory contains examples demonstrating memory management capabilities in trpc-agent-go, showing different approaches to integrating memory with AI agents.

Overview

Memory enables AI agents to remember and recall information across conversations, creating more personalized and context-aware interactions. These examples showcase two primary approaches:

  1. Agentic Mode (Simple) - Manual memory tool calling with explicit control
  2. Auto Mode - Automatic background memory extraction

Available Examples

📁 simple/

Agentic Mode - Manual Memory Tool Calling

A simple example that demonstrates manual memory tool integration where LLM agent explicitly calls memory tools when needed.

Key Features:

  • Manual tool registration and control
  • Access to 6 memory tools (default: add, update, search, load; configurable: delete, clear)
  • Custom tool implementations
  • Streaming and non-streaming response modes
  • Multiple storage backends (in-memory, SQLite, Redis, MySQL, MySQL Vector, PostgreSQL, pgvector)

Use Cases:

  • When you want explicit control over memory operations
  • When you need comprehensive memory tool access with configurable options
  • When you prefer simpler setup and configuration

Getting Started:

cd examples/memory/simple
export OPENAI_API_KEY="your-api-key"
go run main.go

Read full documentation →

📁 auto/

Auto Mode - Automatic Memory Extraction

An advanced example that demonstrates automatic memory extraction running in background, without explicit tool calls.

Key Features:

  • Automatic background memory extraction
  • LLM analyzes conversations to extract memories
  • Configurable extraction checkers (message threshold, time interval)
  • Reduced manual tool configuration
  • Memory preloading into system prompt

Use Cases:

  • When you want transparent memory management
  • When you want automatic learning from conversations
  • When you want to minimize explicit memory operations

Getting Started:

cd examples/memory/auto
export OPENAI_API_KEY="your-api-key"
go run main.go

Read full documentation →

📁 mem0/

Mem0 Integration - External Long-Term Memory Platform

Demonstrates ingest-first integration with mem0.ai. The runner sends session transcripts to mem0 after each turn; the agent accesses stored memories through read-only tools.

Key Features:

  • Session ingestion via runner.WithSessionIngestor(...)
  • Read-only memory_search and optional memory_load tools
  • No local LLM extractor needed — mem0 handles extraction natively

Getting Started:

cd examples/memory/mem0
export MEM0_API_KEY="your-mem0-api-key"
export OPENAI_API_KEY="your-api-key"
go run .

Read full documentation →

📁 tencentdb/

TencentDB Agent Memory Integration - Sidecar Memory Engine

Demonstrates integration with TencentDB Agent Memory through its local gateway sidecar. The runner sends session transcripts after each turn, a plugin injects automatic recall before model calls, and the agent can use TencentDB-native read-only search tools.

Key Features:

  • Session ingestion via runner.WithSessionIngestor(...)
  • Automatic recall via runner.WithPlugins(memSvc.Plugin())
  • Native tdai_memory_search and tdai_conversation_search tools

Getting Started:

cd examples/memory/tencentdb
export OPENAI_API_KEY="your-api-key"
export TENCENTDB_AGENT_MEMORY_GATEWAY="http://127.0.0.1:8420"
go run .

Read full documentation →

📁 compare/

Retrieval Comparison - SQLite vs SQLiteVec

A small example that compares keyword-based SQLite memory (sqlite) with semantic vector memory (sqlitevec) powered by sqlite-vec.

Getting Started:

cd examples/memory/compare
export OPENAI_API_KEY="your-api-key"
go run .

Read full documentation →

Common Features

The chat examples (simple/ and auto/) share the following capabilities:

Memory Services

All examples support multiple storage backends:

Backend Description Usage
inmemory In-memory storage (default) -memory=inmemory
sqlite SQLite file storage -memory=sqlite
sqlitevec SQLite + sqlite-vec vector search (embeddings) -memory=sqlitevec
redis Redis-based storage -memory=redis
mysql MySQL-based storage -memory=mysql
mysqlvec MySQL + vector search (embeddings) -memory=mysqlvec
postgres PostgreSQL-based storage -memory=postgres
pgvector pgvector PostgreSQL storage with embeddings -memory=pgvector

Session Management

  • Multi-turn conversations with context preservation
  • Session isolation and switching
  • Session history tracking

Streaming Output

  • Real-time streaming responses (default)
  • Batch mode for complete responses
  • Configurable via -streaming flag

Tool Visualization

  • Clear display of memory tool calls
  • Tool execution status and responses
  • Arguments and results visibility

Comparison

Feature Agentic Mode (Simple) Auto Mode (Auto)
Tool Registration Manual (WithTools) Automatic (WithExtractor)
Memory Extraction Agent calls tools directly Background extraction
Tools Available 6 tools (4 default, 2 configurable) memory_search by default; configurable memory_load; enabled write tools exposable
Control Level High (explicit) Medium (background)
Setup Complexity Simple Complex
Best For Fine-grained control needs Transparent memory needs

Memory Tools

Memory provides 6 tools with different availability in each mode:

Tool Function Agentic Mode (Simple) Auto Extraction Mode (Auto) Description
memory_add Add new memory ✅ Default ⚙️ Hidden by default Create new memory entry
memory_update Update memory ✅ Default ⚙️ Hidden by default Modify existing memory
memory_search Search memory ✅ Default ✅ Default Search relevant memories
memory_load Load memories ✅ Default ⚙️ Configurable Load recent memories
memory_delete Delete memory ⚙️ Configurable ⚙️ Hidden by default Delete single memory
memory_clear Clear memories ⚙️ Configurable ⚙️ Disabled by default Delete all memories

Notes:

  • Agentic Mode (Simple): Agent actively calls tools to manage memory, all tools are configurable
    • Default enabled: memory_add, memory_update, memory_search, memory_load
    • Default disabled: memory_delete, memory_clear
    • Can be enabled/disabled via WithToolEnabled()
  • Auto Mode: LLM extractor handles write operations in background; memory_search is exposed by default, memory_load is configurable, and enabled write tools can be exposed with WithAutoMemoryExposedTools()
    • Default enabled: memory_add, memory_update, memory_delete, memory_search
    • Default disabled: memory_load, memory_clear
    • Hidden by default: memory_add, memory_update, memory_delete
    • Use WithAutoMemoryExposedTools() to selectively expose enabled write tools such as memory_add

Prerequisites

  • Go 1.21 or later
  • Valid OpenAI API key (or compatible API endpoint)

Environment Variables

Required

Variable Description Default
OPENAI_API_KEY API key for model service (empty)

Optional

Variable Description Default
OPENAI_BASE_URL Base URL for model API https://api.openai.com/v1
SQLITE_MEMORY_DSN SQLite DSN for memory store file:memories.db?_busy_timeout=5000
SQLITEVEC_MEMORY_DSN SQLiteVec DSN for memory store file:memories_vec.db?_busy_timeout=5000
SQLITEVEC_EMBEDDER_MODEL Embedder model for SQLiteVec text-embedding-3-small
OPENAI_EMBEDDING_API_KEY API key for embedding model (optional) (empty)
OPENAI_EMBEDDING_BASE_URL Base URL for embedding API (optional) (empty)
OPENAI_EMBEDDING_MODEL Override embedding model name (optional) (empty)
REDIS_ADDR Redis server address localhost:6379
PG_HOST PostgreSQL host localhost
PG_PORT PostgreSQL port 5432
PG_USER PostgreSQL user postgres
PG_PASSWORD PostgreSQL password (empty)
PG_DATABASE PostgreSQL database trpc-agent-go-pgmemory
PGVECTOR_HOST pgvector PostgreSQL host localhost
PGVECTOR_PORT pgvector PostgreSQL port 5432
PGVECTOR_USER pgvector PostgreSQL user postgres
PGVECTOR_PASSWORD pgvector PostgreSQL password (empty)
PGVECTOR_DATABASE pgvector PostgreSQL database trpc-agent-go-pgmemory
PGVECTOR_EMBEDDER_MODEL pgvector embedder model text-embedding-3-small
MYSQL_HOST MySQL host localhost
MYSQL_PORT MySQL port 3306
MYSQL_USER MySQL user root
MYSQL_PASSWORD MySQL password (empty)
MYSQL_DATABASE MySQL database trpc_agent_go
MYSQLVEC_HOST MySQL Vector host localhost
MYSQLVEC_PORT MySQL Vector port 3306
MYSQLVEC_USER MySQL Vector user root
MYSQLVEC_PASSWORD MySQL Vector password (empty)
MYSQLVEC_DATABASE MySQL Vector database trpc_agent_go
MYSQLVEC_EMBEDDER_MODEL MySQL Vector embedder model text-embedding-3-small

Quick Start

1. Set up your API key

export OPENAI_API_KEY="your-api-key-here"

2. Choose your example

Agentic Mode (Simple):

cd examples/memory/simple
go run main.go

Auto Mode:

cd examples/memory/auto
go run main.go

3. Interact with the agent

Both examples provide an interactive chat interface:

  • Type your message and press Enter
  • Use /memory to view stored memories
  • Use /new to start a new session
  • Use /exit to exit

Advanced Usage

Using Different Memory Backends

# Default in-memory memory service
go run main.go

# Redis memory service (using default or environment variable)
go run main.go -memory redis

# MySQL memory service (using environment variables)
export MYSQL_HOST=localhost
export MYSQL_PORT=3306
export MYSQL_USER=root
export MYSQL_PASSWORD=password
export MYSQL_DATABASE=trpc_agent_go
go run main.go -memory mysql

# MySQL Vector memory service (with embeddings)
export MYSQLVEC_HOST=localhost
export MYSQLVEC_PORT=3306
export MYSQLVEC_USER=root
export MYSQLVEC_PASSWORD=password
export MYSQLVEC_DATABASE=trpc_agent_go
export MYSQLVEC_EMBEDDER_MODEL=text-embedding-3-small
go run main.go -memory mysqlvec

# PostgreSQL memory service (using environment variables)
export PG_HOST=localhost
export PG_PORT=5432
export PG_USER=postgres
export PG_PASSWORD=""
export PG_DATABASE=trpc-agent-go-pgmemory
go run main.go -memory postgres

# pgvector memory service (using environment variables)
export PGVECTOR_HOST=localhost
export PGVECTOR_PORT=5432
export PGVECTOR_USER=postgres
export PGVECTOR_PASSWORD=""
export PGVECTOR_DATABASE=trpc-agent-go-pgmemory
export PGVECTOR_EMBEDDER_MODEL=text-embedding-3-small
go run main.go -memory pgvector

Custom Models

# Using a specific model
go run main.go -model=gpt-4o

Non-streaming Mode

# Get complete responses at once
go run main.go -streaming=false

Architecture

Memory Integration Pattern

Both examples follow a three-step memory integration pattern:

// Step 1: Create the memory service.
// Auto mode must be enabled here with an extractor.
memoryService := memoryinmemory.NewMemoryService(
    // memoryinmemory.WithExtractor(memExtractor), // Enable auto mode.
)

// Step 2: Wire memory into the agent and runner.
llmAgent := llmagent.New(
    agentName,
    llmagent.WithModel(modelInstance),
    llmagent.WithTools(memoryService.Tools()), // Optional for agentic or hybrid mode.
    llmagent.WithPreloadMemory(-1),            // Optional preload enhancement.
)

// Step 3: Set memory service in runner.
runner := runner.NewRunner(
    appName,
    llmAgent,
    runner.WithSessionService(sessionService),
    runner.WithMemoryService(memoryService),
)

Memory Flow

User Input
    ↓
Runner
    ↓
Agent (LLM)
    ↓
[Agentic: Tool Calls] OR [Auto: Background Extraction]
    ↓
Memory Service
    ↓
Storage Backend (InMemory/Redis/MySQL/PostgreSQL)

Extensibility

Custom Memory Tools

Both examples support custom memory tool implementations:

func customMemoryTool() tool.Tool {
    return function.NewFunctionTool(
        customFunc,
        function.WithName(memory.CustomToolName),
        function.WithDescription("Custom memory operation"),
    )
}

memoryService := memoryinmemory.NewMemoryService(
    memoryinmemory.WithCustomTool(memory.CustomToolName, customMemoryTool),
)

Tool Enablement and Configuration

You can enable or disable specific memory tools and use custom implementations:

Default Tool Status

Tool Default Status Description
memory_add ✅ Enabled Add a new memory entry
memory_update ✅ Enabled Update an existing memory
memory_search ✅ Enabled Search memories by query
memory_load ✅ Enabled Load recent memories
memory_delete ❌ Disabled Delete a memory entry
memory_clear ❌ Disabled Clear all memories for a user

Enabling/Disabling Tools

// Enable delete tool
memoryService := memoryinmemory.NewMemoryService(
    memoryinmemory.WithToolEnabled(memory.DeleteToolName, true),
)

// Enable clear tool
memoryService := memoryinmemory.NewMemoryService(
    memoryinmemory.WithToolEnabled(memory.ClearToolName, true),
)

// Enable both delete and clear tools
memoryService := memoryinmemory.NewMemoryService(
    memoryinmemory.WithToolEnabled(memory.DeleteToolName, true),
    memoryinmemory.WithToolEnabled(memory.ClearToolName, true),
)

Using Custom Tools

// Custom clear tool example
func customClearMemoryTool() tool.Tool {
    clearFunc := func(ctx context.Context, _ *toolmemory.ClearMemoryRequest) (*toolmemory.ClearMemoryResponse, error) {
        fmt.Println("🧹 [Custom Clear Tool] Clearing memories...")

        memSvc, err := toolmemory.GetMemoryServiceFromContext(ctx)
        if err != nil {
            return nil, fmt.Errorf("custom clear tool: %w", err)
        }

        appName, userID, err := toolmemory.GetAppAndUserFromContext(ctx)
        if err != nil {
            return nil, fmt.Errorf("custom clear tool: %w", err)
        }

        if err := memSvc.ClearMemories(ctx, memory.UserKey{AppName: appName, UserID: userID}); err != nil {
            return nil, fmt.Errorf("custom clear tool: failed to clear memories: %w", err)
        }

        return &toolmemory.ClearMemoryResponse{
            Message: "✅ Memories cleared successfully!",
        }, nil
    }

    return function.NewFunctionTool(
        clearFunc,
        function.WithName(memory.ClearToolName),
        function.WithDescription("🧹 Clear all memories for the user"),
    )
}

// Use custom clear tool
memoryService := memoryinmemory.NewMemoryService(
    memoryinmemory.WithCustomTool(memory.ClearToolName, customClearMemoryTool),
)

Backend-Specific Options

Each backend supports the same tool configuration options. See the source code comments in util.go for backend-specific usage examples.

Custom Extraction Checkers (Auto Mode)

memExtractor := extractor.NewExtractor(
    extractModel,
    // Extract when messages > 5 OR every 3 minutes
    extractor.WithCheckersAny(
        extractor.CheckMessageThreshold(5),
        extractor.CheckTimeInterval(3*time.Minute),
    ),
)

Best Practices

  1. Choose the Right Mode:

    • Use Agentic Mode (Simple) for explicit control and full tool access
    • Use Auto Mode for transparent learning and reduced configuration
  2. Memory Persistence:

    • Use in-memory for testing and development
    • Use Redis for production with scalability needs
    • Use MySQL/PostgreSQL for relational queries and analytics
  3. Session Management:

    • Use /new to reset conversation context
    • Memories persist across sessions by default
    • Consider memory cleanup for production use
  4. Performance:

    • Use streaming for better user experience
    • Configure extraction checkers to balance CPU and memory
    • Monitor memory usage in production

Troubleshooting

Memory Not Working

  1. Check if memory service is properly initialized
  2. Verify environment variables for storage backends
  3. Check if memory tools are enabled
  4. Review logs for tool call execution

Connection Issues

  1. Verify storage backend is running
  2. Check connection parameters (host, port, credentials)
  3. Ensure network connectivity
  4. Review firewall rules

Extraction Issues (Auto Mode)

  1. Verify extraction model is accessible
  2. Check extraction checker configuration
  3. Review background worker settings
  4. Monitor extraction queue and timeout

Additional Resources

Contributing

Contributions are welcome! Please feel free to submit issues or pull requests.

License

Copyright (C) 2025 Tencent. All rights reserved.

trpc-agent-go is licensed under Apache License Version 2.0.