Integration

Memory for Pydantic AI agents

This page shows how to add Harny memory to a Pydantic AI agent. Harny gives each person who uses your app a private memory your agent can read, and your app calls the Memory API from your server.

Jump to the code

What Harny adds

  • Which value is current. Harny keeps dated memories, so a changed value with a newer timestamp becomes the current value and the earlier one stays answerable by date.
  • When a fact happened. You send a timestamp (ISO 8601 with zone) when you ingest a fact. Recall accepts queryTimestamp, occurredFrom and occurredTo, so your agent can ask what was true on a given date.
  • One person, one memory. Harny keeps each person's memory separate and reads it by the user id your app sends.

The pattern: memory as a tool

Write memory reads and writes as functions your agent can call as tools. Each function calls the Harny Memory API from your server.

Your app sets the user id, sends it in the X-Harny-User header with your app key, and calls Harny from the server, never from a browser.

# model: a model string or object you already use in Pydantic AI
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 pydantic_ai import Agent

agent = Agent(model, tools=make_memory_tools(user_id))
result = agent.run_sync("What is the Acme pilot budget?")
print(result.output)

What recall returns

Memory with dated sources and source labels. Every result names the data point (source) behind it and the date it happened.

  • POST https://api.harny.ai/v1/memory/ingest takes id, content, label and timestamp.
  • POST https://api.harny.ai/v1/memory/recall takes query and identity, and returns results with sources.

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 Pydantic AI's own features for what the agent needs within a single run.
  • Add Harny when the agent needs memory that lasts across sessions, keeps dates on each fact, and stays separate for each person.

Frequently asked questions

Is a separate package needed?

Use the Harny Python SDK (pip install harny) if you run the agent loop with Harny. Otherwise call the Memory API over HTTPS from your server with your app key.

Where does the user id come from?

Your app sets it. Send your own id for the person in the X-Harny-User header with your app key, or use a user key, which names its own user.

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.