diff --git a/content/integrate/google-adk/_index.md b/content/integrate/google-adk/_index.md index fe5bd1e57b..d35618ae5e 100644 --- a/content/integrate/google-adk/_index.md +++ b/content/integrate/google-adk/_index.md @@ -23,16 +23,33 @@ weight: 30 ## Architecture -adk-redis connects three backend systems to the ADK framework: +adk-redis connects several backend systems to the ADK framework: -- **[Redis Agent Memory Server](https://github.com/redis/agent-memory-server)** handles working memory (sessions), long-term memory (extracted facts), auto-summarization, and memory search. +- **Memory backends** power the session and long-term memory services. Pick one per service with a `backend` field: + - **[Redis Agent Memory](https://redis.io/agent-memory/)** (`redis-agent-memory`, the default) is the Agent Memory service. Use this for new work. It runs either on [Redis Cloud]({{< relref "/operate/rc/context-engine/agent-memory" >}}) or [self-managed]({{< relref "/develop/ai/context-engine/agent-memory/self-managed" >}}) on your own Kubernetes cluster; both share one Data Plane API, so you pick a deployment by pointing `api_base_url` at the right endpoint. + - **[Agent Memory Server](https://github.com/redis/agent-memory-server)** (`opensource-agent-memory`) is the open source memory server, now deprecated. It is documented for existing deployments and currently remains the only backend offering auto-summarization, extraction strategies, recency-boosted search, and an MCP endpoint. - **[RedisVL]({{< relref "/develop/ai/redisvl" >}})** (Redis Vector Library) powers the search tools and local semantic cache provider. - **[LangCache](https://redis.io/langcache/)** provides managed semantic caching with server-side embeddings. +See [Redis Agent Memory]({{< relref "/integrate/google-adk/redis-agent-memory" >}}) for the feature-by-feature comparison of the two memory backends. + ## Prerequisites -- **Redis 8.4+** with vector search support -- **Agent Memory Server** for memory and session services +- **Redis 8.4+** with vector search support, for the search tools and the local semantic cache +- **A memory backend**, for the session and memory services: + - A **[Redis Agent Memory](https://redis.io/agent-memory/)** store, on Redis Cloud or self-managed, which gives you a Data Plane endpoint, an API key, and a store ID, or + - An **Agent Memory Server** (deprecated) + +### Redis Agent Memory + +This is the default backend and the recommended one. Provision a store, then pass its Data Plane endpoint, API key, and store ID to the services. + +- On **Redis Cloud**, there is nothing to run. See [Create an Agent Memory service]({{< relref "/operate/rc/context-engine/agent-memory/create-service" >}}). +- To run it **yourself**, see [Self-managed Agent Memory]({{< relref "/develop/ai/context-engine/agent-memory/self-managed" >}}) for deployment, configuration, and operations on your own Kubernetes cluster. + +Both use `backend="redis-agent-memory"`. Only `api_base_url` differs. + +### Agent Memory Server (deprecated) ```bash # Start Redis @@ -53,10 +70,14 @@ On Linux, `host.docker.internal` does not resolve by default. Use `REDIS_URL` at the Docker bridge gateway (typically `redis://172.17.0.1:6379`). +Remember to set `backend="opensource-agent-memory"` on each service config when +you use Agent Memory Server. Otherwise the services speak the Data Plane API +and will not reach your local container. + ## Installation ```bash -# Memory and session services (requires Agent Memory Server) +# Memory and session services (both backends) pip install adk-redis[memory] # Search tools via RedisVL @@ -75,6 +96,10 @@ pip install adk-redis[all] pip install 'redisvl[mcp]>=0.18.2' ``` +The `memory` extra requires `redis-agent-memory>=0.2.0` for the +`redis-agent-memory` backend and `agent-memory-client>=0.14.0` for the +deprecated `opensource-agent-memory` backend. + ## Quick start Wire up Redis Agent Memory in a few lines: @@ -84,23 +109,29 @@ from google.adk import Agent from google.adk.agents.callback_context import CallbackContext from google.adk.runners import Runner from adk_redis.sessions import ( - RedisWorkingMemorySessionService, - RedisWorkingMemorySessionServiceConfig, + RedisSessionMemoryService, + RedisSessionMemoryServiceConfig, ) from adk_redis.memory import ( RedisLongTermMemoryService, RedisLongTermMemoryServiceConfig, ) -session_service = RedisWorkingMemorySessionService( - config=RedisWorkingMemorySessionServiceConfig( - api_base_url="http://localhost:8088", +session_service = RedisSessionMemoryService( + config=RedisSessionMemoryServiceConfig( + backend="redis-agent-memory", + api_base_url="https://your-endpoint.redis.io", + api_key="your-api-key", + store_id="your-store-id", default_namespace="my_app", ) ) memory_service = RedisLongTermMemoryService( config=RedisLongTermMemoryServiceConfig( - api_base_url="http://localhost:8088", + backend="redis-agent-memory", + api_base_url="https://your-endpoint.redis.io", + api_key="your-api-key", + store_id="your-store-id", default_namespace="my_app", ) ) @@ -123,15 +154,20 @@ runner = Runner( ) ``` +To run against the deprecated Agent Memory Server instead, set +`backend="opensource-agent-memory"`, point `api_base_url` at the server (for +example `http://localhost:8088`), and drop `api_key` and `store_id` unless your +server requires them. + ## Capabilities | Capability | Description | Page | |------------|-------------|------| -| **Redis Agent Memory** | Working and long-term memory via framework services, REST tools, or MCP | [Redis Agent Memory]({{< relref "/integrate/google-adk/redis-agent-memory" >}}) | +| **Redis Agent Memory** | Session and long-term memory on Redis Cloud, self-managed, or the deprecated Agent Memory Server, via framework services, REST tools, or MCP | [Redis Agent Memory]({{< relref "/integrate/google-adk/redis-agent-memory" >}}) | | **Integration patterns** | Framework-managed, LLM-controlled REST, and MCP tools | [Integration patterns]({{< relref "/integrate/google-adk/integration-patterns" >}}) | | **Search tools** | Vector, hybrid, text, range, and SQL search via RedisVL, plus the `rvl mcp` server over `McpToolset` | [Search tools]({{< relref "/integrate/google-adk/search-tools" >}}) | -| **Semantic caching** | LLM response and tool result caching | [Semantic caching]({{< relref "/integrate/google-adk/semantic-caching" >}}) | -| **Examples** | Nine complete examples covering all capabilities | [Examples]({{< relref "/integrate/google-adk/examples" >}}) | +| **Semantic caching** | LLM response and tool result caching, with stable entry IDs and targeted invalidation | [Semantic caching]({{< relref "/integrate/google-adk/semantic-caching" >}}) | +| **Examples** | Ten complete examples covering all capabilities | [Examples]({{< relref "/integrate/google-adk/examples" >}}) | ## More info diff --git a/content/integrate/google-adk/examples.md b/content/integrate/google-adk/examples.md index 64b40239aa..c97364a314 100644 --- a/content/integrate/google-adk/examples.md +++ b/content/integrate/google-adk/examples.md @@ -11,13 +11,13 @@ categories: description: Complete examples for every adk-redis capability. group: ai stack: true -summary: Nine runnable examples covering Redis Agent Memory, search tools, semantic +summary: Ten runnable examples covering Redis Agent Memory, search tools, semantic caching, and MCP integration. type: integration weight: 5 --- -The [adk-redis repository](https://github.com/redis-developer/adk-redis/tree/main/examples) includes nine complete examples. Each focuses on a specific capability. +The [adk-redis repository](https://github.com/redis-developer/adk-redis/tree/main/examples) includes ten complete examples. Each focuses on a specific capability. ## Prerequisites @@ -25,20 +25,32 @@ All examples require: - **Python 3.10+** - **Redis 8.4+**: `docker run -d --name redis -p 6379:6379 redis:8.4-alpine` -- **Agent Memory Server** (for memory examples): See [setup instructions](https://github.com/redis/agent-memory-server) +- **A memory backend** (for memory examples): a [Redis Agent Memory]({{< relref "/integrate/google-adk/redis-agent-memory" >}}) store on Redis Cloud or self-managed, or a deprecated [Agent Memory Server](https://github.com/redis/agent-memory-server) - **API keys**: Most examples need a `GOOGLE_API_KEY` for Gemini +Each memory example is written against a specific backend, noted below. The +examples that use auto-summarization, extraction strategies, recency-boosted +search, or MCP require the Agent Memory Server backend. + +## `managed_memory_quickstart` + +**Backend:** `redis-agent-memory` · **Run:** `python main.py` + +The smallest memory example, and the counterpart to `simple_redis_memory`. Uses `redis-agent-memory`, so there is no Agent Memory Server and no Docker to set up. Wires `RedisSessionMemoryService` and `RedisLongTermMemoryService` to an agent with ADK's built-in `preload_memory` and `load_memory` tools. Intentionally avoids Agent Memory Server only features. + +[View on GitHub](https://github.com/redis-developer/adk-redis/tree/main/examples/managed_memory_quickstart) + ## `simple_redis_memory` -**Capability:** Redis Agent Memory (framework-managed) +**Backend:** `opensource-agent-memory` (Agent Memory Server) · **Run:** `python main.py` -Minimal starting point. Wires up `RedisWorkingMemorySessionService` and `RedisLongTermMemoryService` with a basic conversational agent. No search tools, no caching: just memory. +Minimal starting point for the Agent Memory Server backend. Wires up `RedisSessionMemoryService` and `RedisLongTermMemoryService` with a basic conversational agent, including auto-summarization and extraction. No search tools, no caching: just memory. [View on GitHub](https://github.com/redis-developer/adk-redis/tree/main/examples/simple_redis_memory) ## `travel_agent_memory_hybrid` -**Capability:** Redis Agent Memory + REST tools + web search + planning +**Backend:** `opensource-agent-memory` (Agent Memory Server) · **Run:** `python main.py` The most complete example. Combines framework-managed memory services with LLM-controlled memory tools, web search, itinerary planning, and calendar export. Demonstrates the [hybrid integration pattern]({{< relref "/integrate/google-adk/integration-patterns#hybrid-approach" >}}). @@ -46,31 +58,31 @@ The most complete example. Combines framework-managed memory services with LLM-c ## `travel_agent_memory_tools` -**Capability:** REST memory tools (LLM-controlled) +**Backend:** `opensource-agent-memory` (Agent Memory Server), switchable · **Run:** `adk web .` -Uses REST-based memory tools exclusively, without framework-managed services. The LLM has full control over when to search, create, update, and delete memories. +Uses REST-based memory tools exclusively, without framework-managed services. The LLM has full control over when to search, create, update, and delete memories. Set `REDIS_MEMORY_BACKEND` to switch this example to `redis-agent-memory`. [View on GitHub](https://github.com/redis-developer/adk-redis/tree/main/examples/travel_agent_memory_tools) ## `fitness_coach_mcp` -**Capability:** MCP memory tools +**Backend:** `opensource-agent-memory` (Agent Memory Server) only · **Run:** `adk web .` -Demonstrates MCP-based memory integration. The agent connects to the Agent Memory Server via SSE and manages semantic and episodic memories for workout tracking. +Demonstrates MCP-based memory integration. The agent connects to the Agent Memory Server's SSE endpoint with ADK's native `McpToolset` and manages semantic and episodic memories for workout tracking. `redis-agent-memory` has no MCP endpoint, so this example runs on Agent Memory Server only. [View on GitHub](https://github.com/redis-developer/adk-redis/tree/main/examples/fitness_coach_mcp) ## `redis_search_tools` -**Capability:** Vector, hybrid, text, and range search +**Capability:** Vector, text, and range search · **Run:** `adk web .` -Four in-process RedisVL [search tools]({{< relref "/integrate/google-adk/search-tools" >}}) plugged into a single agent with a product catalog dataset. +Three in-process RedisVL [search tools]({{< relref "/integrate/google-adk/search-tools" >}}) plugged into a single agent with a product catalog dataset. [View on GitHub](https://github.com/redis-developer/adk-redis/tree/main/examples/redis_search_tools) ## `redis_sql_search` -**Capability:** SQL `SELECT` search +**Capability:** SQL `SELECT` search · **Run:** `adk web .` A 10-product catalog with the `RedisSQLSearchTool`. The agent emits parameterized SQL (`WHERE category = 'electronics' AND price < :max_price`) to answer structured catalog questions. Requires `pip install 'adk-redis[sql]'`. @@ -78,7 +90,7 @@ A 10-product catalog with the `RedisSQLSearchTool`. The agent emits parameterize ## `redisvl_mcp_search` -**Capability:** RedisVL MCP server via ADK's `McpToolset` +**Capability:** RedisVL MCP server via ADK's `McpToolset` · **Run:** `adk web .` The MCP counterpart of `redis_search_tools`. A `rvl mcp` server hosts a knowledge-base index in hybrid (vector + BM25) mode and the agent connects via ADK's native `McpToolset`. No adk-redis wrapper involved; the standard `McpToolset` + `StdioConnectionParams` pattern is used. @@ -86,7 +98,7 @@ The MCP counterpart of `redis_search_tools`. A `rvl mcp` server hosts a knowledg ## `semantic_cache` -**Capability:** Local semantic caching (RedisVL) +**Capability:** Local semantic caching (RedisVL) · **Run:** `python main.py` Demonstrates LLM response caching and tool result caching using the `RedisVLCacheProvider` with local embeddings and ADK callbacks. @@ -94,7 +106,7 @@ Demonstrates LLM response caching and tool result caching using the `RedisVLCach ## `langcache_cache` -**Capability:** Managed semantic caching (LangCache) +**Capability:** Managed semantic caching (LangCache) · **Run:** `python main.py` Uses the managed [LangCache]({{< relref "/integrate/google-adk/semantic-caching" >}}) service for semantic caching with server-side embeddings. No local vectorizer required. @@ -102,9 +114,12 @@ Uses the managed [LangCache]({{< relref "/integrate/google-adk/semantic-caching" ## Running an example +Examples marked `python main.py` run as scripts. Examples marked `adk web .` +run in the ADK developer UI from inside the example directory. + ```bash pip install adk-redis[all] -cd examples/simple_redis_memory +cd examples/managed_memory_quickstart export GOOGLE_API_KEY=your-key python main.py ``` diff --git a/content/integrate/google-adk/integration-patterns.md b/content/integrate/google-adk/integration-patterns.md index bb2aa53b3b..666a839cd8 100644 --- a/content/integrate/google-adk/integration-patterns.md +++ b/content/integrate/google-adk/integration-patterns.md @@ -21,21 +21,27 @@ adk-redis offers three distinct approaches for connecting agents to memory. Each ## Comparison -| Approach | Control | Complexity | Protocol | Best for | -|----------|---------|-----------|----------|----------| -| **ADK services** | Framework | Low | HTTP | Invisible infrastructure | -| **REST tools** | LLM | Medium | HTTP | Explicit memory management | -| **MCP tools** | LLM | Medium | SSE | Standardized, portable | +| Approach | Control | Complexity | Protocol | Backends | Best for | +|----------|---------|-----------|----------|----------|----------| +| **ADK services** | Framework | Low | HTTP | Both backends | Invisible infrastructure | +| **REST tools** | LLM | Medium | HTTP | Both backends | Explicit memory management | +| **MCP tools** | LLM | Medium | SSE | Agent Memory Server only | Standardized, portable | + +All three approaches select a memory backend with a `backend` field: +`"redis-agent-memory"` (the default, on Redis Cloud or self-managed) or the +deprecated `"opensource-agent-memory"` (Agent Memory Server). See +[Redis Agent Memory]({{< relref "/integrate/google-adk/redis-agent-memory#choose-a-memory-backend" >}}) +for the feature comparison and the deployment options. ## 1. ADK services (framework-managed) -Configure `RedisWorkingMemorySessionService` and `RedisLongTermMemoryService`, pass them to the `Runner`, and the framework handles everything automatically. Memory extraction happens in the background. Search happens before each agent turn. The agent code never directly interacts with memory. +Configure `RedisSessionMemoryService` and `RedisLongTermMemoryService`, pass them to the `Runner`, and the framework handles everything automatically. Memory extraction happens in the background. Search happens before each agent turn. The agent code never directly interacts with memory. ```python from google.adk.runners import Runner from adk_redis.sessions import ( - RedisWorkingMemorySessionService, - RedisWorkingMemorySessionServiceConfig, + RedisSessionMemoryService, + RedisSessionMemoryServiceConfig, ) from adk_redis.memory import ( RedisLongTermMemoryService, @@ -45,15 +51,21 @@ from adk_redis.memory import ( runner = Runner( agent=agent, app_name="my_app", - session_service=RedisWorkingMemorySessionService( - config=RedisWorkingMemorySessionServiceConfig( - api_base_url="http://localhost:8088", + session_service=RedisSessionMemoryService( + config=RedisSessionMemoryServiceConfig( + backend="redis-agent-memory", + api_base_url="https://your-endpoint.redis.io", + api_key="your-api-key", + store_id="your-store-id", default_namespace="my_app", ) ), memory_service=RedisLongTermMemoryService( config=RedisLongTermMemoryServiceConfig( - api_base_url="http://localhost:8088", + backend="redis-agent-memory", + api_base_url="https://your-endpoint.redis.io", + api_key="your-api-key", + store_id="your-store-id", default_namespace="my_app", ) ), @@ -76,9 +88,11 @@ from adk_redis.tools.memory import ( ) config = MemoryToolConfig( - api_base_url="http://localhost:8088", + backend="redis-agent-memory", + api_base_url="https://your-endpoint.redis.io", + api_key="your-api-key", + store_id="your-store-id", default_namespace="my_app", - recency_boost=True, ) agent = Agent( @@ -97,14 +111,31 @@ agent = Agent( ## 3. MCP tools (Model Context Protocol) -Point ADK's `McpToolset` at the Agent Memory Server's SSE endpoint. Tool discovery happens automatically. +Point ADK's native `McpToolset` at the Agent Memory Server's SSE endpoint. Tool discovery happens automatically. + +{{< note >}} +The MCP endpoint is an Agent Memory Server feature. The `redis-agent-memory` +backend does not expose one, on Redis Cloud or self-managed. +{{< /note >}} ```python -from adk_redis.tools.mcp_memory import create_memory_mcp_toolset +import os + +from google.adk.tools.mcp_tool import McpToolset +from google.adk.tools.mcp_tool.mcp_session_manager import SseConnectionParams + +# The MCP server runs on a separate port from the REST API +memory_mcp_url = os.getenv("MEMORY_MCP_URL", "http://localhost:9000") -memory_tools = create_memory_mcp_toolset( - server_url="http://localhost:9000", - tool_filter=["search_long_term_memory", "create_long_term_memories"], +memory_tools = McpToolset( + connection_params=SseConnectionParams( + url=f"{memory_mcp_url.rstrip('/')}/sse", + ), + tool_filter=[ + "search_long_term_memory", + "create_long_term_memories", + "memory_prompt", + ], ) agent = Agent( @@ -114,7 +145,7 @@ agent = Agent( ) ``` -Available MCP tools: `search_long_term_memory`, `create_long_term_memories`, `get_long_term_memory`, `edit_long_term_memory`, `delete_long_term_memories`, `memory_prompt`, `set_working_memory`. +Available MCP tools: `search_long_term_memory`, `create_long_term_memories`, `get_long_term_memory`, `edit_long_term_memory`, `delete_long_term_memories`, `memory_prompt`, and `set_working_memory`. **Tradeoffs:** Most standardized and portable approach. Swap memory backends without changing agent code. Requires Agent Memory Server with MCP support on a separate port. @@ -148,7 +179,8 @@ The [travel_agent_memory_hybrid](https://github.com/redis-developer/adk-redis/tr ## More info -- [simple_redis_memory](https://github.com/redis-developer/adk-redis/tree/main/examples/simple_redis_memory): Framework-managed services +- [managed_memory_quickstart](https://github.com/redis-developer/adk-redis/tree/main/examples/managed_memory_quickstart): Framework services on Redis Agent Memory +- [simple_redis_memory](https://github.com/redis-developer/adk-redis/tree/main/examples/simple_redis_memory): Framework services on Agent Memory Server - [travel_agent_memory_tools](https://github.com/redis-developer/adk-redis/tree/main/examples/travel_agent_memory_tools): REST tools only - [fitness_coach_mcp](https://github.com/redis-developer/adk-redis/tree/main/examples/fitness_coach_mcp): MCP tools - [Car dealership tutorial](https://redis.io/tutorials/build-a-car-dealership-agent-with-google-adk-and-redis-agent-memory/) diff --git a/content/integrate/google-adk/redis-agent-memory.md b/content/integrate/google-adk/redis-agent-memory.md index c55ac939ad..0358b596d1 100644 --- a/content/integrate/google-adk/redis-agent-memory.md +++ b/content/integrate/google-adk/redis-agent-memory.md @@ -8,41 +8,105 @@ categories: - oss - rs - rc -description: Working and long-term memory for Google ADK agents using the Redis Agent Memory Server. +description: Session and long-term memory for Google ADK agents using Redis Agent Memory or the deprecated Agent Memory Server. group: ai stack: true -summary: Add persistent working and long-term memory to ADK agents via framework services, REST tools, or MCP. +summary: Add persistent session and long-term memory to ADK agents via framework services, REST tools, or MCP. type: integration weight: 1 --- -Redis Agent Memory gives ADK agents two tiers of persistent memory, backed by the [Redis Agent Memory Server](https://github.com/redis/agent-memory-server): +Redis Agent Memory gives ADK agents two tiers of persistent memory: -- **Working memory** — session-scoped storage for the current conversation, with automatic summarization when context grows long. -- **Long-term memory** — facts extracted from past conversations, stored as vectors in Redis and searchable by semantic similarity with optional recency boosting. +- **Session memory**: session-scoped storage for the current conversation. +- **Long-term memory**: facts extracted from past conversations, stored as vectors in Redis and searchable by semantic similarity with recency boosting. -You can wire these tiers into an ADK agent three ways: +## Choose a memory backend + +Both tiers run on either of two backends, selected per service with a `backend` field: + +| Backend | `backend` value | What it is | +|---------|-----------------|------------| +| **[Redis Agent Memory](https://redis.io/agent-memory/)** | `redis-agent-memory` (default) | The Agent Memory service, on [Redis Cloud]({{< relref "/operate/rc/context-engine/agent-memory" >}}) or [self-managed]({{< relref "/develop/ai/context-engine/agent-memory/self-managed" >}}) on your own Kubernetes cluster. | +| **Agent Memory Server** (deprecated) | `opensource-agent-memory` | The [open source memory server](https://github.com/redis/agent-memory-server). Deprecated: use `redis-agent-memory` for new work. | + +Use `redis-agent-memory` for new work. It covers both deployment models, because +Redis Cloud and self-managed Agent Memory share one +[Data Plane API]({{< relref "/develop/ai/context-engine/agent-memory/api-reference" >}}). +You select a deployment by pointing `api_base_url` at the right Data Plane, not +by changing `backend`: + +| Deployment | `backend` | `api_base_url` | Setup | +|------------|-----------|----------------|-------| +| Redis Cloud | `redis-agent-memory` | Your Redis Cloud Agent Memory endpoint | [Create an Agent Memory service]({{< relref "/operate/rc/context-engine/agent-memory/create-service" >}}) | +| Self-managed | `redis-agent-memory` | Your own Data Plane URL | [Self-managed Agent Memory]({{< relref "/develop/ai/context-engine/agent-memory/self-managed" >}}) | +| Agent Memory Server (deprecated) | `opensource-agent-memory` | Your server URL, for example `http://localhost:8088` | [Agent Memory Server](https://github.com/redis/agent-memory-server) | + +{{< note >}} +If you want to run Agent Memory yourself, use self-managed Agent Memory with +`backend="redis-agent-memory"`. Do not reach for the deprecated +`opensource-agent-memory` backend just because a deployment is self-hosted. The +two are different systems: `opensource-agent-memory` targets the open source +Agent Memory Server, not the Agent Memory Data Plane. +{{< /note >}} + +Feature availability differs between the two backends today: + +| Feature | Redis Agent Memory | Agent Memory Server (deprecated) | +|---------|--------------------|----------------------------------| +| Session persistence | Yes | Yes | +| Long-term memory search | Yes | Yes | +| Memory tools (REST) | Yes | Yes | +| Recency-boosted search | No | Yes | +| Auto-summarization | No | Yes | +| Extraction strategies | No | Yes | +| MCP endpoint | No | Yes | + +These differences follow the backend, not the deployment model. Self-managed +Agent Memory has the same feature set as Redis Cloud because both speak the same +Data Plane API. If your agent depends on one of the capabilities that is +currently Agent Memory Server only, factor that into your migration timing +rather than treating the deprecated backend as a long-term target. + +`redis-agent-memory` is the default. If you point a service at an Agent Memory +Server without setting `backend="opensource-agent-memory"`, the service still +speaks the Data Plane API and will not reach your server. + +You can wire either backend into an ADK agent three ways: | Approach | Control | Best for | |----------|---------|----------| | **Framework services** | ADK Runner (automatic) | Invisible infrastructure | | **REST tools** | LLM (explicit) | Agent autonomy over memory | -| **MCP tools** | LLM via MCP protocol | Portable, standardized | +| **MCP tools** | LLM via MCP protocol | Portable, standardized (Agent Memory Server only) | See [Integration patterns]({{< relref "/integrate/google-adk/integration-patterns" >}}) for detailed tradeoff comparison. -## Working memory +## Session memory -`RedisWorkingMemorySessionService` implements ADK's `BaseSessionService`. It stores the current conversation in the Redis Agent Memory Server and automatically summarizes older messages when the context window limit is approached. +`RedisSessionMemoryService` implements ADK's `BaseSessionService`. It stores the current conversation in the configured memory backend. ```python from adk_redis.sessions import ( - RedisWorkingMemorySessionService, - RedisWorkingMemorySessionServiceConfig, + RedisSessionMemoryService, + RedisSessionMemoryServiceConfig, ) -session_service = RedisWorkingMemorySessionService( - config=RedisWorkingMemorySessionServiceConfig( +# Redis Agent Memory (default) +session_service = RedisSessionMemoryService( + config=RedisSessionMemoryServiceConfig( + backend="redis-agent-memory", + api_base_url="https://your-endpoint.redis.io", + api_key="your-api-key", + store_id="your-store-id", + default_namespace="my_app", + ) +) + +# Agent Memory Server backend, with auto-summarization +session_service = RedisSessionMemoryService( + config=RedisSessionMemoryServiceConfig( + backend="opensource-agent-memory", api_base_url="http://localhost:8088", default_namespace="my_app", model_name="gemini-2.5-flash", @@ -51,18 +115,35 @@ session_service = RedisWorkingMemorySessionService( ) ``` +{{< note >}} +`RedisWorkingMemorySessionService` and `RedisWorkingMemorySessionServiceConfig` +were renamed to `RedisSessionMemoryService` and +`RedisSessionMemoryServiceConfig` in adk-redis 0.0.8. The old names remain as +deprecated aliases that emit a `DeprecationWarning` and will be removed in +0.1.0. The module `adk_redis.sessions.working_memory` also moved to +`adk_redis.sessions.session_memory`. +{{< /note >}} + ### Configuration | Parameter | Description | Default | |-----------|-------------|---------| -| `api_base_url` | Agent Memory Server URL | Required | -| `default_namespace` | Isolates data between applications | Required | -| `model_name` | LLM used for summarization | `None` | -| `context_window_max` | Token limit that triggers summarization | `None` | +| `backend` | `redis-agent-memory` or `opensource-agent-memory` | `redis-agent-memory` | +| `api_base_url` | Memory backend URL | `http://localhost:8000` | +| `api_key` | API key. Redis Agent Memory only. | `None` | +| `store_id` | Store ID. Redis Agent Memory only. | `None` | +| `default_namespace` | Isolates data between applications | `None` | +| `timeout` | Request timeout in seconds | `30.0` | +| `timeout_ms` | Request timeout in milliseconds. Overrides `timeout`. | `None` | +| `session_ttl_seconds` | Expiry for stored sessions | `None` | +| `model_name` | LLM used for summarization. Agent Memory Server only. | `None` | +| `context_window_max` | Token limit that triggers summarization. Agent Memory Server only. | `None` | +| `extraction_strategy` | `discrete`, `summary`, `preferences`, or `custom`. Agent Memory Server only. | `discrete` | +| `extraction_strategy_config` | Extra options for the strategy | `{}` | ### Auto-summarization -When the token count of stored messages crosses `context_window_max`, the Agent Memory Server uses the model specified in `model_name` to summarize older turns. Recent messages are preserved in full. This avoids the hard tradeoff between truncating context (losing information) and sending the full conversation (hitting token limits and costs). +Auto-summarization is an Agent Memory Server feature. When the token count of stored messages crosses `context_window_max`, the server uses the model specified in `model_name` to summarize older turns. Recent messages are preserved in full. This avoids the hard tradeoff between truncating context (losing information) and sending the full conversation (hitting token limits and costs). ### Incremental appends @@ -79,7 +160,7 @@ The service implements all of ADK's session methods: ## Long-term memory -`RedisLongTermMemoryService` implements ADK's `BaseMemoryService`. After each conversation, the Agent Memory Server extracts structured information (facts, preferences, episodic events), embeds them as vectors, and stores them in Redis for semantic search across all past sessions. +`RedisLongTermMemoryService` implements ADK's `BaseMemoryService`. After each conversation, the memory backend extracts structured information (facts, preferences, episodic events), embeds them as vectors, and stores them in Redis for semantic search across all past sessions. ```python from adk_redis.memory import ( @@ -87,14 +168,27 @@ from adk_redis.memory import ( RedisLongTermMemoryServiceConfig, ) +# Redis Agent Memory (default) memory_service = RedisLongTermMemoryService( config=RedisLongTermMemoryServiceConfig( + backend="redis-agent-memory", + api_base_url="https://your-endpoint.redis.io", + api_key="your-api-key", + store_id="your-store-id", + default_namespace="my_app", + ) +) + +# Agent Memory Server backend, with extraction and recency boosting +memory_service = RedisLongTermMemoryService( + config=RedisLongTermMemoryServiceConfig( + backend="opensource-agent-memory", api_base_url="http://localhost:8088", default_namespace="my_app", extraction_strategy="discrete", recency_boost=True, - semantic_weight=0.7, - recency_weight=0.3, + semantic_weight=0.8, + recency_weight=0.2, ) ) ``` @@ -103,28 +197,46 @@ memory_service = RedisLongTermMemoryService( | Parameter | Description | Default | |-----------|-------------|---------| -| `api_base_url` | Agent Memory Server URL | Required | -| `default_namespace` | Namespace for data isolation | Required | -| `extraction_strategy` | How conversations are broken into memories: `discrete`, `summary`, or `preferences` | `None` | -| `recency_boost` | Enable recency-weighted search | `False` | -| `semantic_weight` | Weight for vector similarity (0-1) | `0.7` | -| `recency_weight` | Weight for recency signal (0-1) | `0.3` | +| `backend` | `redis-agent-memory` or `opensource-agent-memory` | `redis-agent-memory` | +| `api_base_url` | Memory backend URL | `http://localhost:8000` | +| `api_key` | API key. Redis Agent Memory only. | `None` | +| `store_id` | Store ID. Redis Agent Memory only. | `None` | +| `default_namespace` | Namespace for data isolation | `None` | +| `timeout` | Request timeout in seconds | `30.0` | +| `search_top_k` | Maximum memories returned per search | `10` | +| `similarity_threshold` | Minimum similarity for a match (0-1) | `None` | +| `distance_threshold` | Maximum vector distance for a match (0-1) | `None` | +| `store_events_as_messages` | Store session events as chat messages | `True` | +| `default_memory_type` | Memory type applied to new memories | `semantic` | +| `default_topics` | Topics applied to new memories | `[]` | +| `extraction_strategy` | `discrete`, `summary`, `preferences`, or `custom`. Agent Memory Server only. | `discrete` | +| `extraction_strategy_config` | Extra options for the strategy | `{}` | +| `recency_boost` | Enable recency-weighted search. Agent Memory Server only. | `True` | +| `semantic_weight` | Weight for vector similarity (0-1) | `0.8` | +| `recency_weight` | Weight for recency signal (0-1) | `0.2` | +| `freshness_weight` | Weight for the freshness component of the recency signal | `0.6` | +| `novelty_weight` | Weight for the novelty component of the recency signal | `0.4` | +| `half_life_last_access_days` | Half-life for last-access decay, in days | `7.0` | +| `half_life_created_days` | Half-life for creation-time decay, in days | `30.0` | ### Extraction strategies -- **`discrete`**: Extracts individual facts as separate memories, making them independently searchable. +Extraction strategies apply to the Agent Memory Server backend. + +- **`discrete`**: Extracts individual facts as separate memories, making them independently searchable. This is the default. - **`summary`**: Creates a narrative summary of the conversation. - **`preferences`**: Focuses on user preferences and settings. +- **`custom`**: Uses the prompt and options you supply in `extraction_strategy_config`. ### Recency boosting Raw semantic similarity often isn't enough. A user might have said "I love Italian food" three years ago and "I've been getting into Japanese cuisine" last week. Both are semantically relevant, but the recent one matters more. -Recency boosting combines semantic similarity with time-based signals so that recent preferences outweigh stale ones. +Recency boosting combines semantic similarity with time-based signals so that recent preferences outweigh stale ones. It is enabled by default and takes effect on the Agent Memory Server backend. ## Framework services -Pass both services to an ADK `Runner`. The framework handles memory automatically: sessions are persisted via working memory, long-term memory is searched before each agent turn, and an `after_agent_callback` triggers extraction in the background. +Pass both services to an ADK `Runner`. The framework handles memory automatically: sessions are persisted via session memory, long-term memory is searched before each agent turn, and an `after_agent_callback` triggers extraction in the background. ```python from google.adk import Agent @@ -151,30 +263,45 @@ runner = Runner( ### Runtime flow -1. ADK creates or retrieves a session via `RedisWorkingMemorySessionService`. +1. ADK creates or retrieves a session via `RedisSessionMemoryService`. 2. Long-term memory is searched for context relevant to the current conversation. -3. User messages are appended to working memory incrementally. +3. User messages are appended to session memory incrementally. 4. The LLM generates a response using session context plus retrieved memories. 5. `after_agent_callback` triggers `add_session_to_memory()` for background extraction. -6. If the conversation grows long, working memory auto-summarizes older turns. +6. On the Agent Memory Server backend, if the conversation grows long, session memory auto-summarizes older turns. ## REST tools -Give the agent explicit memory tools that the LLM calls like any other function. The LLM decides when to search memory, what to store, and what to update. No framework services required. +Give the agent explicit memory tools that the LLM calls like any other function. The LLM decides when to search memory, what to store, and what to update. No framework services required. The tools work against either backend and share a single `MemoryToolConfig`. + +adk-redis ships six memory tools: + +| Tool | Description | +|------|-------------| +| `SearchMemoryTool` | Search long-term memories by query | +| `CreateMemoryTool` | Store new long-term memories | +| `GetMemoryTool` | Fetch a single memory by ID | +| `UpdateMemoryTool` | Update an existing memory by ID | +| `DeleteMemoryTool` | Delete memories by ID | +| `MemoryPromptTool` | Enrich the agent prompt with relevant memories | ```python from adk_redis.tools.memory import ( SearchMemoryTool, CreateMemoryTool, + GetMemoryTool, UpdateMemoryTool, DeleteMemoryTool, + MemoryPromptTool, MemoryToolConfig, ) config = MemoryToolConfig( - api_base_url="http://localhost:8088", + backend="redis-agent-memory", + api_base_url="https://your-endpoint.redis.io", + api_key="your-api-key", + store_id="your-store-id", default_namespace="my_app", - recency_boost=True, ) agent = Agent( @@ -183,24 +310,51 @@ agent = Agent( tools=[ SearchMemoryTool(config=config), CreateMemoryTool(config=config), + GetMemoryTool(config=config), UpdateMemoryTool(config=config), DeleteMemoryTool(config=config), + MemoryPromptTool(config=config), ], ) ``` Requires prompt engineering to teach the LLM memory management strategy, but gives the agent genuine autonomy over its own memory. +### Invocation-scoped users + +The memory tools resolve the acting user from the ADK `tool_context` before falling back to the user configured on `MemoryToolConfig`. A single shared `Runner` therefore stays scoped to the user of each invocation, with no per-user tool instances. + +`CreateMemoryTool.run_async()` also accepts an application-supplied `id` for idempotent writes against Redis Agent Memory. IDs are derived with namespace and user scope to prevent cross-tenant collisions, and are never exposed to the LLM. + ## MCP tools -Point ADK's `McpToolset` at the Agent Memory Server's SSE endpoint. Tool discovery happens automatically — no manual tool wiring required. +Point ADK's native `McpToolset` at the Agent Memory Server's SSE endpoint. Tool discovery happens automatically, so no manual tool wiring is required. + +{{< note >}} +The MCP endpoint is an Agent Memory Server feature. The `redis-agent-memory` +backend does not expose one, on Redis Cloud or self-managed. Use the REST +memory tools above with `redis-agent-memory`. +{{< /note >}} ```python -from adk_redis.tools.mcp_memory import create_memory_mcp_toolset +import os -memory_tools = create_memory_mcp_toolset( - server_url="http://localhost:9000", - tool_filter=["search_long_term_memory", "create_long_term_memories"], +from google.adk import Agent +from google.adk.tools.mcp_tool import McpToolset +from google.adk.tools.mcp_tool.mcp_session_manager import SseConnectionParams + +# The MCP server runs on a separate port from the REST API +memory_mcp_url = os.getenv("MEMORY_MCP_URL", "http://localhost:9000") + +memory_tools = McpToolset( + connection_params=SseConnectionParams( + url=f"{memory_mcp_url.rstrip('/')}/sse", + ), + tool_filter=[ + "search_long_term_memory", + "create_long_term_memories", + "memory_prompt", + ], ) agent = Agent( @@ -210,14 +364,15 @@ agent = Agent( ) ``` -Available MCP tools: `search_long_term_memory`, `create_long_term_memories`, `get_long_term_memory`, `edit_long_term_memory`, `delete_long_term_memories`, `memory_prompt`, `set_working_memory`. +Available MCP tools: `search_long_term_memory`, `create_long_term_memories`, `get_long_term_memory`, `edit_long_term_memory`, `delete_long_term_memories`, `memory_prompt`, and `set_working_memory`. -The most portable approach — swap memory backends without changing agent code. Requires the Agent Memory Server running with MCP support on a separate port. +This is the most portable approach: swap memory backends without changing agent code. It requires the Agent Memory Server running with MCP support on a separate port. ## More info - [Integration patterns]({{< relref "/integrate/google-adk/integration-patterns" >}}): Detailed tradeoff comparison of all three approaches -- [simple_redis_memory](https://github.com/redis-developer/adk-redis/tree/main/examples/simple_redis_memory): Minimal framework services setup +- [managed_memory_quickstart](https://github.com/redis-developer/adk-redis/tree/main/examples/managed_memory_quickstart): Redis Agent Memory, no Docker +- [simple_redis_memory](https://github.com/redis-developer/adk-redis/tree/main/examples/simple_redis_memory): Agent Memory Server with framework services - [travel_agent_memory_tools](https://github.com/redis-developer/adk-redis/tree/main/examples/travel_agent_memory_tools): REST tools only - [fitness_coach_mcp](https://github.com/redis-developer/adk-redis/tree/main/examples/fitness_coach_mcp): MCP tools - [travel_agent_memory_hybrid](https://github.com/redis-developer/adk-redis/tree/main/examples/travel_agent_memory_hybrid): Framework services + REST tools combined diff --git a/content/integrate/google-adk/semantic-caching.md b/content/integrate/google-adk/semantic-caching.md index b1e841898a..85864fadd2 100644 --- a/content/integrate/google-adk/semantic-caching.md +++ b/content/integrate/google-adk/semantic-caching.md @@ -54,17 +54,41 @@ provider = RedisVLCacheProvider( No local vectorizer needed. Embeddings are generated server-side. ```python +import os + from adk_redis.cache import LangCacheProvider, LangCacheProviderConfig provider = LangCacheProvider( config=LangCacheProviderConfig( - cache_id="your-cache-id", - api_key="your-api-key", + cache_id=os.environ["LANGCACHE_CACHE_ID"], + api_key=os.environ["LANGCACHE_API_KEY"], + server_url="https://aws-us-east-1.langcache.redis.io", ttl=3600, ) ) ``` +Set `server_url` to the endpoint for your LangCache region. + +## Cache entry IDs and targeted invalidation + +Both providers return a `CacheEntry` from `check()` and an entry ID from +`store()`. When the backend exposes a stable identifier, `CacheEntry.entry_id` +carries it, and you can retire exactly that entry with `delete_by_id()` instead +of clearing the whole cache. + +```python +entry = await provider.check(prompt="What is the return policy?") + +if entry is not None and entry.entry_id is not None: + # Retire one stale answer without touching unrelated entries + await provider.delete_by_id(entry.entry_id) +``` + +`CacheEntry` also carries the matched `prompt`, the cached `response`, the match +`distance`, and any `metadata` stored alongside the entry. `entry_id` is `None` +when the backend does not expose an identifier. + ## LLM response cache Intercepts model calls through ADK's `before_model_callback` and `after_model_callback`.