Integration
Memory for Google ADK agents
Google ADK keeps the state of each agent session, and that state is what the agent sees on its next turn. Session state is not built to record which value is current, what it replaced, or what was true on a given date. This page shows how to add Harny memory to a Google ADK agent so each user gets a private, dated memory the agent can read.
What the framework does not keep
- Which value is current. ADK keeps the state you write, but it does not mark one value as the current one and retire the older value. Harny memory is dated: a changed value with a newer timestamp becomes the current value, and the earlier value stays answerable by date.
- When a fact happened. Session state records the values you save, not when the event in the fact took place. Harny takes a
timestampon each memory, so you can recall as of a past date withqueryTimestamp. - One person across sessions. Session state is tied to a session. Harny keeps one private memory per person, keyed by the user id your app sends in
X-Harny-User.
The pattern: memory as a tool
Your tool is a plain Python function. ADK reads its name, type hints and docstring to build the tool, so the function signature is the contract the model sees. The function calls the Memory API on your server and returns the recalled result to the agent.
The code binds the signed-in user to the tool call, so the model never chooses whose memory it reads. The model passes only the query, and the user id comes from your app's session.
import os
import requests
BASE = "https://api.harny.ai/v1/memory"
def make_memory_tools(user_id: str):
headers = {
"Authorization": f"Bearer {os.environ['HARNY_APP_KEY']}",
"X-Harny-User": user_id, # set by your application, never by the model
}
def recall_memory(question: str) -> str:
"""Look up what is known about this user that is relevant to a question."""
r = requests.post(f"{BASE}/recall", headers=headers,
json={"query": question, "identity": user_id})
return r.text
def store_memory(text: str, happened_at: str) -> str:
"""Save a fact with the ISO time it happened."""
r = requests.post(f"{BASE}/ingest", headers=headers,
json={"content": text, "timestamp": happened_at})
return r.text
return [recall_memory, store_memory]
from google.adk.agents import Agent
root_agent = Agent(
name="account_assistant",
model=MODEL, # the Gemini model you already use in ADK
instruction="Call recall_memory before you answer a question about a customer.",
tools=make_memory_tools(user_id),
)What recall returns
Each result carries an id, a rank, occurredAt, content and sources. Every source names the data point (sourceId), the date it happened (occurredAt) and its label.
POST https://api.harny.ai/v1/memory/ingesttakesid,content,labelandtimestamp.POST https://api.harny.ai/v1/memory/recalltakesqueryandidentity, and returns results withsources.
Example: your agent asks “what is the Acme pilot budget?” and gets this back. Your code hands the model the content and the source label, so it can say who said it and when.
{
"asOf": "2026-07-29T00:00:00Z",
"results": [
{
"rank": 1,
"occurredAt": "2026-07-28T16:00:00Z",
"content": "Acme pilot budget: currently 40k.",
"sources": [
{ "sourceId": "call-8821", "label": "Email from Nadia" }
]
}
]
}When to use which
- Use Google ADK's own session state for the working data of one run, such as the current step or the values the agent needs in the next turn of the same conversation.
- Add Harny when facts must last across sessions, change over time, or need to be read as of a past date for each user.
Frequently asked questions
Is a package needed?
Call the Memory API over HTTPS from your server with your app key in the Authorization header and the user id in X-Harny-User.
Where does the user id come from?
Use the id your app already has for the person, and send it in the X-Harny-User header from your server. The person does not need a Harny account.
Go on. Get Harny.
The first 500 monthly-active end users are free for good. Create an app key and make your first call in minutes.