Blog: Adding Long-Term Memory to LangGraph and LangChain Agents (#637)
* Add blog post: Adding Long-Term Memory to LangGraph and LangChain Agents * blog: update langgraph post date to 2026-03-24 and add cover image * blog: fix claude-code-telegram filename to match frontmatter date (2026-03-25) * blog: set claude-code-telegram date to 2026-03-23 * blog: fix date timezone offset by adding T12:00 to all post dates * ci: trigger fresh CI run * blog: fix broken docs link (routeBasePath is /)
This commit is contained in:
parent
39bf6820d6
commit
0ad6ee3156
29 changed files with 1116 additions and 851 deletions
|
|
@ -4,7 +4,7 @@ description: Learn how Hindsight handles contradictory information by tracking t
|
|||
authors: [chrislatimer]
|
||||
|
||||
image: /img/blog/2026-02-09/consolidation-pipeline.png
|
||||
date: 2026-02-09
|
||||
date: 2026-02-09T12:00
|
||||
hide_table_of_contents: true
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
title: "What's new in Hindsight 0.4.11"
|
||||
description: New features and improvements in Hindsight 0.4.11
|
||||
authors: [nicoloboschi]
|
||||
date: 2026-02-13
|
||||
date: 2026-02-13T12:00
|
||||
hide_table_of_contents: true
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
title: "What's new in Hindsight 0.4.12"
|
||||
description: New features and improvements in Hindsight 0.4.12
|
||||
authors: [nicoloboschi]
|
||||
date: 2026-02-18
|
||||
date: 2026-02-18T12:00
|
||||
hide_table_of_contents: true
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
title: "Your Vercel Chat SDK bot forgets everything. Hindsight fixes that."
|
||||
authors: [nicoloboschi]
|
||||
date: 2026-02-26
|
||||
date: 2026-02-26T12:00
|
||||
tags: [chat-sdk, slack, discord, typescript, memory]
|
||||
image: /img/blog/vercel-chat.png
|
||||
---
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
title: "What's new in Hindsight 0.4.13 and 0.4.14"
|
||||
description: New features and improvements in Hindsight 0.4.13 and 0.4.14
|
||||
authors: [nicoloboschi]
|
||||
date: 2026-02-27
|
||||
date: 2026-02-27T12:00
|
||||
hide_table_of_contents: true
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -1,253 +1,253 @@
|
|||
---
|
||||
title: "Your CrewAI Agents Forget Everything Between Runs. Here's the Fix."
|
||||
---
|
||||
title: "Your CrewAI Agents Forget Everything Between Runs. Here's the Fix."
|
||||
authors: [benfrank241]
|
||||
|
||||
date: 2026-03-02
|
||||
tags: [crewai, agents, python, memory, tutorial]
|
||||
image: /img/blog/crewai-memory.png
|
||||
---
|
||||
|
||||
CrewAI agents lose all memory when a crew finishes. `hindsight-crewai` plugs into CrewAI's ExternalMemory to persist knowledge across runs -- three lines of setup, and your agents automatically store task outputs and recall relevant context.
|
||||
|
||||
<!-- truncate -->
|
||||
|
||||
---
|
||||
|
||||
## The Problem: Stateless Crews
|
||||
|
||||
CrewAI has a memory system. Short-term, long-term, entity memory. It works well within a single `kickoff()`.
|
||||
|
||||
Then the process exits.
|
||||
|
||||
Next run, the crew starts from zero. Every fact learned, every decision made, every entity discovered -- gone.
|
||||
|
||||
This matters when you build crews that run repeatedly:
|
||||
|
||||
- A research crew that deepens knowledge over time
|
||||
- A support crew that remembers customer history
|
||||
- A planning crew that tracks decisions across sprints
|
||||
|
||||
CrewAI's built-in memory backends (RAG storage, SQLite) are designed for single-run persistence. For cross-run, cross-session memory that actually compounds, you need something else.
|
||||
|
||||
That's what the `hindsight-crewai` package does. It implements CrewAI's `Storage` interface using Hindsight's memory engine, so your crews remember everything -- across runs, across days, across weeks.
|
||||
|
||||
---
|
||||
|
||||
## Architecture
|
||||
|
||||
Here's how it fits together:
|
||||
|
||||
```
|
||||
CrewAI Crew
|
||||
└─ ExternalMemory
|
||||
└─ HindsightStorage (implements Storage interface)
|
||||
├─ save() → Hindsight retain (extract facts, entities, relationships)
|
||||
├─ search() → Hindsight recall (semantic + graph + temporal retrieval)
|
||||
└─ reset() → Hindsight delete_bank + recreate
|
||||
```
|
||||
|
||||
CrewAI calls `save()` after each task completes and `search()` before each task starts. You don't manage the lifecycle -- CrewAI drives it, Hindsight stores it.
|
||||
|
||||
Under the hood, Hindsight does more than store text. It extracts structured facts, identifies entities, builds a knowledge graph, and runs multi-strategy retrieval (semantic search, BM25, graph traversal, temporal ranking) with cross-encoder reranking.
|
||||
|
||||
Your crew gets a real memory system, not a vector dump.
|
||||
|
||||
---
|
||||
|
||||
## Step 1 -- Start Hindsight
|
||||
|
||||
Install and start the memory server:
|
||||
|
||||
```bash
|
||||
pip install hindsight-all
|
||||
```
|
||||
|
||||
```bash
|
||||
export HINDSIGHT_API_LLM_API_KEY=YOUR_OPENAI_KEY
|
||||
hindsight-api
|
||||
```
|
||||
|
||||
This runs locally at `http://localhost:8888` with embedded Postgres, embeddings, and reranking. No external infra needed.
|
||||
|
||||
> **Note:** You can also use [Hindsight Cloud](https://ui.hindsight.vectorize.io/signup) and skip the self-hosted setup entirely.
|
||||
|
||||
---
|
||||
|
||||
## Step 2 -- Install the Integration
|
||||
|
||||
```bash
|
||||
pip install hindsight-crewai
|
||||
```
|
||||
|
||||
This pulls in `hindsight-client` and `crewai` as dependencies.
|
||||
|
||||
---
|
||||
|
||||
## Step 3 -- Wire It Up
|
||||
|
||||
```python
|
||||
from hindsight_crewai import configure, HindsightStorage
|
||||
from crewai.memory.external.external_memory import ExternalMemory
|
||||
from crewai import Agent, Crew, Task
|
||||
|
||||
# Point at your Hindsight instance
|
||||
configure(hindsight_api_url="http://localhost:8888")
|
||||
|
||||
# Create agents
|
||||
researcher = Agent(
|
||||
role="Researcher",
|
||||
goal="Find accurate, detailed information on the given topic.",
|
||||
backstory="You are a thorough researcher who digs deep into topics.",
|
||||
llm="openai/gpt-4o-mini",
|
||||
)
|
||||
|
||||
writer = Agent(
|
||||
role="Writer",
|
||||
goal="Write clear, well-structured content based on research.",
|
||||
backstory="You are a technical writer who values clarity and precision.",
|
||||
llm="openai/gpt-4o-mini",
|
||||
)
|
||||
|
||||
# Create a task
|
||||
research_task = Task(
|
||||
description="Research the benefits of Rust for CLI tools.",
|
||||
expected_output="A detailed summary of Rust's strengths for CLI development.",
|
||||
agent=researcher,
|
||||
)
|
||||
|
||||
write_task = Task(
|
||||
description="Write a short article based on the research.",
|
||||
expected_output="A polished 3-paragraph article.",
|
||||
agent=writer,
|
||||
)
|
||||
|
||||
# Create the crew with persistent memory
|
||||
crew = Crew(
|
||||
agents=[researcher, writer],
|
||||
tasks=[research_task, write_task],
|
||||
external_memory=ExternalMemory(
|
||||
storage=HindsightStorage(
|
||||
bank_id="research-crew",
|
||||
mission="Track research findings, technical comparisons, and writing preferences.",
|
||||
)
|
||||
),
|
||||
)
|
||||
|
||||
crew.kickoff()
|
||||
```
|
||||
|
||||
That's it. After `kickoff()`, every task output is retained in Hindsight. Next time you run this crew, it recalls relevant prior work before starting each task.
|
||||
|
||||
---
|
||||
|
||||
## Step 4 -- Run It Again
|
||||
|
||||
Second run, different topic:
|
||||
|
||||
```python
|
||||
research_task = Task(
|
||||
description="Research how Go compares to Rust for CLI tools.",
|
||||
expected_output="A comparison of Go vs Rust for CLI development.",
|
||||
agent=researcher,
|
||||
)
|
||||
```
|
||||
|
||||
Now the researcher has context from the first run. It knows what it already found about Rust. The writer remembers the style and structure from the previous article.
|
||||
|
||||
Third run:
|
||||
|
||||
```python
|
||||
research_task = Task(
|
||||
description="Which language should I pick for a new CLI tool?",
|
||||
expected_output="A recommendation based on all prior research.",
|
||||
agent=researcher,
|
||||
)
|
||||
```
|
||||
|
||||
The crew now draws on two prior research sessions. Knowledge compounds.
|
||||
|
||||
---
|
||||
|
||||
## Step 5 -- Add Reflect for Deeper Synthesis
|
||||
|
||||
CrewAI's Storage interface has `save` and `search`. But Hindsight also supports `reflect` -- a synthesis operation that reasons across all relevant memories instead of returning raw facts.
|
||||
|
||||
Since `reflect` doesn't map to the Storage interface, it's exposed as a CrewAI Tool:
|
||||
|
||||
```python
|
||||
from hindsight_crewai import HindsightReflectTool
|
||||
|
||||
reflect_tool = HindsightReflectTool(
|
||||
bank_id="research-crew",
|
||||
budget="mid",
|
||||
reflect_context="You are helping a development team evaluate programming languages.",
|
||||
)
|
||||
|
||||
researcher = Agent(
|
||||
role="Researcher",
|
||||
goal="Provide deep, synthesized analysis on technical topics.",
|
||||
backstory="You are a senior researcher. Use the hindsight_reflect tool to review what you already know before starting new research.",
|
||||
tools=[reflect_tool],
|
||||
llm="openai/gpt-4o-mini",
|
||||
)
|
||||
```
|
||||
|
||||
When the agent calls `hindsight_reflect`, it gets a synthesized, reasoned response that draws on the full knowledge graph -- not just the top-k vector matches.
|
||||
|
||||
---
|
||||
|
||||
## Per-Agent Memory Banks
|
||||
|
||||
By default, all agents share one bank. If you want each agent to have isolated memory:
|
||||
|
||||
```python
|
||||
storage = HindsightStorage(
|
||||
bank_id="research-crew",
|
||||
per_agent_banks=True,
|
||||
)
|
||||
```
|
||||
|
||||
The researcher writes to `research-crew-researcher`, the writer to `research-crew-writer`. Each agent builds its own knowledge base.
|
||||
|
||||
For full control, use a custom resolver:
|
||||
|
||||
```python
|
||||
storage = HindsightStorage(
|
||||
bank_id="research-crew",
|
||||
bank_resolver=lambda base, agent: f"{base}-{agent.lower()}" if agent else base,
|
||||
)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Pitfalls and Edge Cases
|
||||
|
||||
**1. Bank ID collisions.** If multiple unrelated crews share a `bank_id`, their memories mix. Use unique bank IDs per crew or project.
|
||||
|
||||
**2. Large task outputs.** CrewAI passes the full task output to `save()`. If your tasks produce very long outputs, Hindsight handles the chunking, but retain latency increases. Set a reasonable `expected_output` length in your task definitions.
|
||||
|
||||
**3. Recall budget tuning.** The default `budget="mid"` balances speed and thoroughness. For latency-sensitive crews, use `"low"`. For deep analysis, use `"high"`. Budget affects how many retrieval strategies run and how much reranking happens.
|
||||
|
||||
**4. Async event loop conflicts.** CrewAI runs inside an async event loop. The integration handles this transparently via a dedicated thread pool, but if you're also doing async work in custom tools, avoid calling `hindsight-client` directly from the same event loop. Use the `HindsightStorage` and `HindsightReflectTool` abstractions instead.
|
||||
|
||||
---
|
||||
|
||||
## Recap
|
||||
|
||||
- `hindsight-crewai` gives CrewAI agents persistent, compounding memory
|
||||
- It implements CrewAI's `Storage` interface, so integration is three lines
|
||||
- Memories are automatically stored after tasks and recalled before tasks
|
||||
- `HindsightReflectTool` adds on-demand synthesis for deeper reasoning
|
||||
- Per-agent banks let you isolate or share knowledge as needed
|
||||
|
||||
The integration handles the hard parts: async compatibility, thread safety, fact extraction, multi-strategy retrieval. You just point it at a bank and let your crews learn.
|
||||
|
||||
---
|
||||
|
||||
## Next Steps
|
||||
|
||||
- **Try it locally**: `pip install hindsight-all hindsight-crewai` and run the example above
|
||||
- **Use Hindsight Cloud**: Skip self-hosting with a [free account](https://ui.hindsight.vectorize.io/signup)
|
||||
- **Add tags for scoped memory**: Use `tags` on retain and `recall_tags` on search to partition memories by project, environment, or topic
|
||||
- **Inspect memories in the web UI**: Run `hindsight-control-plane` locally or use the cloud dashboard to browse facts, entities, and mental models
|
||||
- **Combine with per-agent banks**: Give specialized agents their own memory while sharing a common bank for cross-agent knowledge
|
||||
date: 2026-03-02T12:00
|
||||
tags: [crewai, agents, python, memory, tutorial]
|
||||
image: /img/blog/crewai-memory.png
|
||||
---
|
||||
|
||||
CrewAI agents lose all memory when a crew finishes. `hindsight-crewai` plugs into CrewAI's ExternalMemory to persist knowledge across runs -- three lines of setup, and your agents automatically store task outputs and recall relevant context.
|
||||
|
||||
<!-- truncate -->
|
||||
|
||||
---
|
||||
|
||||
## The Problem: Stateless Crews
|
||||
|
||||
CrewAI has a memory system. Short-term, long-term, entity memory. It works well within a single `kickoff()`.
|
||||
|
||||
Then the process exits.
|
||||
|
||||
Next run, the crew starts from zero. Every fact learned, every decision made, every entity discovered -- gone.
|
||||
|
||||
This matters when you build crews that run repeatedly:
|
||||
|
||||
- A research crew that deepens knowledge over time
|
||||
- A support crew that remembers customer history
|
||||
- A planning crew that tracks decisions across sprints
|
||||
|
||||
CrewAI's built-in memory backends (RAG storage, SQLite) are designed for single-run persistence. For cross-run, cross-session memory that actually compounds, you need something else.
|
||||
|
||||
That's what the `hindsight-crewai` package does. It implements CrewAI's `Storage` interface using Hindsight's memory engine, so your crews remember everything -- across runs, across days, across weeks.
|
||||
|
||||
---
|
||||
|
||||
## Architecture
|
||||
|
||||
Here's how it fits together:
|
||||
|
||||
```
|
||||
CrewAI Crew
|
||||
└─ ExternalMemory
|
||||
└─ HindsightStorage (implements Storage interface)
|
||||
├─ save() → Hindsight retain (extract facts, entities, relationships)
|
||||
├─ search() → Hindsight recall (semantic + graph + temporal retrieval)
|
||||
└─ reset() → Hindsight delete_bank + recreate
|
||||
```
|
||||
|
||||
CrewAI calls `save()` after each task completes and `search()` before each task starts. You don't manage the lifecycle -- CrewAI drives it, Hindsight stores it.
|
||||
|
||||
Under the hood, Hindsight does more than store text. It extracts structured facts, identifies entities, builds a knowledge graph, and runs multi-strategy retrieval (semantic search, BM25, graph traversal, temporal ranking) with cross-encoder reranking.
|
||||
|
||||
Your crew gets a real memory system, not a vector dump.
|
||||
|
||||
---
|
||||
|
||||
## Step 1 -- Start Hindsight
|
||||
|
||||
Install and start the memory server:
|
||||
|
||||
```bash
|
||||
pip install hindsight-all
|
||||
```
|
||||
|
||||
```bash
|
||||
export HINDSIGHT_API_LLM_API_KEY=YOUR_OPENAI_KEY
|
||||
hindsight-api
|
||||
```
|
||||
|
||||
This runs locally at `http://localhost:8888` with embedded Postgres, embeddings, and reranking. No external infra needed.
|
||||
|
||||
> **Note:** You can also use [Hindsight Cloud](https://ui.hindsight.vectorize.io/signup) and skip the self-hosted setup entirely.
|
||||
|
||||
---
|
||||
|
||||
## Step 2 -- Install the Integration
|
||||
|
||||
```bash
|
||||
pip install hindsight-crewai
|
||||
```
|
||||
|
||||
This pulls in `hindsight-client` and `crewai` as dependencies.
|
||||
|
||||
---
|
||||
|
||||
## Step 3 -- Wire It Up
|
||||
|
||||
```python
|
||||
from hindsight_crewai import configure, HindsightStorage
|
||||
from crewai.memory.external.external_memory import ExternalMemory
|
||||
from crewai import Agent, Crew, Task
|
||||
|
||||
# Point at your Hindsight instance
|
||||
configure(hindsight_api_url="http://localhost:8888")
|
||||
|
||||
# Create agents
|
||||
researcher = Agent(
|
||||
role="Researcher",
|
||||
goal="Find accurate, detailed information on the given topic.",
|
||||
backstory="You are a thorough researcher who digs deep into topics.",
|
||||
llm="openai/gpt-4o-mini",
|
||||
)
|
||||
|
||||
writer = Agent(
|
||||
role="Writer",
|
||||
goal="Write clear, well-structured content based on research.",
|
||||
backstory="You are a technical writer who values clarity and precision.",
|
||||
llm="openai/gpt-4o-mini",
|
||||
)
|
||||
|
||||
# Create a task
|
||||
research_task = Task(
|
||||
description="Research the benefits of Rust for CLI tools.",
|
||||
expected_output="A detailed summary of Rust's strengths for CLI development.",
|
||||
agent=researcher,
|
||||
)
|
||||
|
||||
write_task = Task(
|
||||
description="Write a short article based on the research.",
|
||||
expected_output="A polished 3-paragraph article.",
|
||||
agent=writer,
|
||||
)
|
||||
|
||||
# Create the crew with persistent memory
|
||||
crew = Crew(
|
||||
agents=[researcher, writer],
|
||||
tasks=[research_task, write_task],
|
||||
external_memory=ExternalMemory(
|
||||
storage=HindsightStorage(
|
||||
bank_id="research-crew",
|
||||
mission="Track research findings, technical comparisons, and writing preferences.",
|
||||
)
|
||||
),
|
||||
)
|
||||
|
||||
crew.kickoff()
|
||||
```
|
||||
|
||||
That's it. After `kickoff()`, every task output is retained in Hindsight. Next time you run this crew, it recalls relevant prior work before starting each task.
|
||||
|
||||
---
|
||||
|
||||
## Step 4 -- Run It Again
|
||||
|
||||
Second run, different topic:
|
||||
|
||||
```python
|
||||
research_task = Task(
|
||||
description="Research how Go compares to Rust for CLI tools.",
|
||||
expected_output="A comparison of Go vs Rust for CLI development.",
|
||||
agent=researcher,
|
||||
)
|
||||
```
|
||||
|
||||
Now the researcher has context from the first run. It knows what it already found about Rust. The writer remembers the style and structure from the previous article.
|
||||
|
||||
Third run:
|
||||
|
||||
```python
|
||||
research_task = Task(
|
||||
description="Which language should I pick for a new CLI tool?",
|
||||
expected_output="A recommendation based on all prior research.",
|
||||
agent=researcher,
|
||||
)
|
||||
```
|
||||
|
||||
The crew now draws on two prior research sessions. Knowledge compounds.
|
||||
|
||||
---
|
||||
|
||||
## Step 5 -- Add Reflect for Deeper Synthesis
|
||||
|
||||
CrewAI's Storage interface has `save` and `search`. But Hindsight also supports `reflect` -- a synthesis operation that reasons across all relevant memories instead of returning raw facts.
|
||||
|
||||
Since `reflect` doesn't map to the Storage interface, it's exposed as a CrewAI Tool:
|
||||
|
||||
```python
|
||||
from hindsight_crewai import HindsightReflectTool
|
||||
|
||||
reflect_tool = HindsightReflectTool(
|
||||
bank_id="research-crew",
|
||||
budget="mid",
|
||||
reflect_context="You are helping a development team evaluate programming languages.",
|
||||
)
|
||||
|
||||
researcher = Agent(
|
||||
role="Researcher",
|
||||
goal="Provide deep, synthesized analysis on technical topics.",
|
||||
backstory="You are a senior researcher. Use the hindsight_reflect tool to review what you already know before starting new research.",
|
||||
tools=[reflect_tool],
|
||||
llm="openai/gpt-4o-mini",
|
||||
)
|
||||
```
|
||||
|
||||
When the agent calls `hindsight_reflect`, it gets a synthesized, reasoned response that draws on the full knowledge graph -- not just the top-k vector matches.
|
||||
|
||||
---
|
||||
|
||||
## Per-Agent Memory Banks
|
||||
|
||||
By default, all agents share one bank. If you want each agent to have isolated memory:
|
||||
|
||||
```python
|
||||
storage = HindsightStorage(
|
||||
bank_id="research-crew",
|
||||
per_agent_banks=True,
|
||||
)
|
||||
```
|
||||
|
||||
The researcher writes to `research-crew-researcher`, the writer to `research-crew-writer`. Each agent builds its own knowledge base.
|
||||
|
||||
For full control, use a custom resolver:
|
||||
|
||||
```python
|
||||
storage = HindsightStorage(
|
||||
bank_id="research-crew",
|
||||
bank_resolver=lambda base, agent: f"{base}-{agent.lower()}" if agent else base,
|
||||
)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Pitfalls and Edge Cases
|
||||
|
||||
**1. Bank ID collisions.** If multiple unrelated crews share a `bank_id`, their memories mix. Use unique bank IDs per crew or project.
|
||||
|
||||
**2. Large task outputs.** CrewAI passes the full task output to `save()`. If your tasks produce very long outputs, Hindsight handles the chunking, but retain latency increases. Set a reasonable `expected_output` length in your task definitions.
|
||||
|
||||
**3. Recall budget tuning.** The default `budget="mid"` balances speed and thoroughness. For latency-sensitive crews, use `"low"`. For deep analysis, use `"high"`. Budget affects how many retrieval strategies run and how much reranking happens.
|
||||
|
||||
**4. Async event loop conflicts.** CrewAI runs inside an async event loop. The integration handles this transparently via a dedicated thread pool, but if you're also doing async work in custom tools, avoid calling `hindsight-client` directly from the same event loop. Use the `HindsightStorage` and `HindsightReflectTool` abstractions instead.
|
||||
|
||||
---
|
||||
|
||||
## Recap
|
||||
|
||||
- `hindsight-crewai` gives CrewAI agents persistent, compounding memory
|
||||
- It implements CrewAI's `Storage` interface, so integration is three lines
|
||||
- Memories are automatically stored after tasks and recalled before tasks
|
||||
- `HindsightReflectTool` adds on-demand synthesis for deeper reasoning
|
||||
- Per-agent banks let you isolate or share knowledge as needed
|
||||
|
||||
The integration handles the hard parts: async compatibility, thread safety, fact extraction, multi-strategy retrieval. You just point it at a bank and let your crews learn.
|
||||
|
||||
---
|
||||
|
||||
## Next Steps
|
||||
|
||||
- **Try it locally**: `pip install hindsight-all hindsight-crewai` and run the example above
|
||||
- **Use Hindsight Cloud**: Skip self-hosting with a [free account](https://ui.hindsight.vectorize.io/signup)
|
||||
- **Add tags for scoped memory**: Use `tags` on retain and `recall_tags` on search to partition memories by project, environment, or topic
|
||||
- **Inspect memories in the web UI**: Run `hindsight-control-plane` locally or use the cloud dashboard to browse facts, entities, and mental models
|
||||
- **Combine with per-agent banks**: Give specialized agents their own memory while sharing a common bank for cross-agent knowledge
|
||||
|
|
|
|||
|
|
@ -1,314 +1,314 @@
|
|||
---
|
||||
title: "I Gave 100+ LLMs a Permanent Memory With One Python Package"
|
||||
---
|
||||
title: "I Gave 100+ LLMs a Permanent Memory With One Python Package"
|
||||
authors: [benfrank241]
|
||||
|
||||
date: 2026-03-03
|
||||
tags: [litellm, python, memory, openai, anthropic, tutorial]
|
||||
image: /img/blog/litellm-memory.png
|
||||
---
|
||||
|
||||
`hindsight-litellm` adds persistent memory to any LLM provider via LiteLLM — OpenAI, Anthropic, Groq, Azure, Bedrock, Vertex AI, and 100+ more. Three lines of setup, and every LLM call automatically gets context from past conversations.
|
||||
|
||||
<!-- truncate -->
|
||||
|
||||
---
|
||||
|
||||
## The Problem: Stateless LLM Calls
|
||||
|
||||
You build an app with an LLM. User talks to it on Monday. Comes back Tuesday. The LLM has no idea who they are.
|
||||
|
||||
This is true for every provider. OpenAI, Anthropic, Groq, Azure — every API call is a blank slate. The LLM doesn't remember preferences, past conversations, or anything you've discussed before.
|
||||
|
||||
Most teams work around this by stuffing the last N messages into the context window. But that's not memory — it's a sliding window that drops everything older than your token limit. The user's preferences from last week? Gone. The project context from last month? Gone.
|
||||
|
||||
What if every LLM call automatically had the right context from past conversations?
|
||||
|
||||
---
|
||||
|
||||
## The Fix: Three Lines, Any Provider
|
||||
|
||||
`hindsight-litellm` hooks into LiteLLM to intercept every LLM call. Before the call, it retrieves relevant memories from Hindsight and injects them into the prompt. After the call, it stores the conversation for future retrieval.
|
||||
|
||||
```
|
||||
Your code ──→ hindsight_litellm.completion()
|
||||
│
|
||||
├─→ 1. Recall/Reflect from Hindsight (relevant memories)
|
||||
├─→ 2. Inject memories into prompt
|
||||
├─→ 3. Forward to LLM (any provider via LiteLLM)
|
||||
├─→ 4. Store conversation to Hindsight
|
||||
└─→ 5. Return response
|
||||
```
|
||||
|
||||
Here's the setup:
|
||||
|
||||
```python
|
||||
import hindsight_litellm
|
||||
|
||||
hindsight_litellm.configure(
|
||||
hindsight_api_url="http://localhost:8888",
|
||||
)
|
||||
|
||||
hindsight_litellm.set_defaults(
|
||||
bank_id="my-agent",
|
||||
)
|
||||
|
||||
hindsight_litellm.enable()
|
||||
```
|
||||
|
||||
That's it. Now every `completion()` call has memory:
|
||||
|
||||
```python
|
||||
response = hindsight_litellm.completion(
|
||||
model="gpt-4o-mini",
|
||||
messages=[{"role": "user", "content": "Help me with my Python project"}],
|
||||
hindsight_query="What do I know about the user's Python project?",
|
||||
)
|
||||
```
|
||||
|
||||
The `hindsight_query` tells Hindsight what to search for in memory. The response comes back with context from past conversations — the LLM knows about the user's project, their preferences, their tech stack.
|
||||
|
||||
> **Note:** You can also use [Hindsight Cloud](https://ui.hindsight.vectorize.io/signup) and skip the self-hosted setup entirely.
|
||||
|
||||
---
|
||||
|
||||
## Any Provider, Same Memory
|
||||
|
||||
Because the integration runs through LiteLLM, it works with every provider LiteLLM supports. Switch models freely — memory follows:
|
||||
|
||||
```python
|
||||
messages = [{"role": "user", "content": "What did we discuss last time?"}]
|
||||
query = "What have I discussed with this user?"
|
||||
|
||||
# OpenAI
|
||||
hindsight_litellm.completion(model="gpt-4o", messages=messages, hindsight_query=query)
|
||||
|
||||
# Anthropic
|
||||
hindsight_litellm.completion(model="claude-sonnet-4-20250514", messages=messages, hindsight_query=query)
|
||||
|
||||
# Groq
|
||||
hindsight_litellm.completion(model="groq/llama-3.1-70b-versatile", messages=messages, hindsight_query=query)
|
||||
|
||||
# Azure OpenAI
|
||||
hindsight_litellm.completion(model="azure/gpt-4", messages=messages, hindsight_query=query)
|
||||
|
||||
# AWS Bedrock
|
||||
hindsight_litellm.completion(model="bedrock/anthropic.claude-3", messages=messages, hindsight_query=query)
|
||||
|
||||
# Google Vertex AI
|
||||
hindsight_litellm.completion(model="vertex_ai/gemini-pro", messages=messages, hindsight_query=query)
|
||||
```
|
||||
|
||||
Same bank, same memories, any model. Migrate from OpenAI to Anthropic and your agent still knows everything.
|
||||
|
||||
---
|
||||
|
||||
## Two Memory Modes
|
||||
|
||||
### Recall: Raw Memories
|
||||
|
||||
The default mode retrieves individual memory facts and injects them as a numbered list:
|
||||
|
||||
```python
|
||||
hindsight_litellm.set_defaults(bank_id="my-agent", use_reflect=False)
|
||||
```
|
||||
|
||||
The LLM sees something like:
|
||||
|
||||
```
|
||||
# Relevant Memories
|
||||
1. [WORLD] User is building a FastAPI application
|
||||
2. [WORLD] User prefers pytest for testing
|
||||
3. [OBSERVATION] User likes type hints
|
||||
```
|
||||
|
||||
Best for precise, factual context where the LLM needs individual data points.
|
||||
|
||||
### Reflect: Synthesized Context
|
||||
|
||||
Reflect mode synthesizes memories into a coherent paragraph instead of raw facts:
|
||||
|
||||
```python
|
||||
hindsight_litellm.set_defaults(
|
||||
bank_id="my-agent",
|
||||
use_reflect=True,
|
||||
reflect_context="I am a coding assistant helping with Python projects.",
|
||||
)
|
||||
```
|
||||
|
||||
The LLM sees something like:
|
||||
|
||||
```
|
||||
The user is an experienced Python developer working on a FastAPI application.
|
||||
They prefer pytest for testing and value type hints. In past conversations,
|
||||
they asked about async patterns and database migrations.
|
||||
```
|
||||
|
||||
Best for natural, conversational context. The `reflect_context` parameter shapes how Hindsight reasons about the memories without affecting what it retrieves.
|
||||
|
||||
---
|
||||
|
||||
## Direct Memory APIs
|
||||
|
||||
Sometimes you want to query memory outside of an LLM call. The direct APIs give you full control:
|
||||
|
||||
### Recall — query raw memories
|
||||
|
||||
```python
|
||||
from hindsight_litellm import recall
|
||||
|
||||
memories = recall("what projects is the user working on?", budget="mid")
|
||||
for m in memories:
|
||||
print(f"- [{m.fact_type}] {m.text}")
|
||||
```
|
||||
|
||||
### Reflect — synthesized context
|
||||
|
||||
```python
|
||||
from hindsight_litellm import reflect
|
||||
|
||||
result = reflect(
|
||||
"what do you know about the user's preferences?",
|
||||
context="I am a customer support agent.",
|
||||
)
|
||||
print(result.text)
|
||||
```
|
||||
|
||||
### Retain — store memories manually
|
||||
|
||||
```python
|
||||
from hindsight_litellm import retain
|
||||
|
||||
retain(
|
||||
content="User mentioned they're switching from Flask to FastAPI",
|
||||
context="Discussion about web frameworks",
|
||||
)
|
||||
```
|
||||
|
||||
All three have async variants: `arecall()`, `areflect()`, `aretain()`.
|
||||
|
||||
---
|
||||
|
||||
## Per-Call Overrides
|
||||
|
||||
Defaults are convenient, but sometimes you need per-call control:
|
||||
|
||||
```python
|
||||
response = hindsight_litellm.completion(
|
||||
model="gpt-4o-mini",
|
||||
messages=[...],
|
||||
hindsight_query="What do I know about Alice?",
|
||||
hindsight_bank_id="other-agent", # Different bank for this call
|
||||
hindsight_budget="high", # More thorough retrieval
|
||||
hindsight_reflect_context="Currently helping with onboarding",
|
||||
)
|
||||
```
|
||||
|
||||
Any default can be overridden with a `hindsight_*` prefix.
|
||||
|
||||
---
|
||||
|
||||
## Native SDK Wrappers
|
||||
|
||||
If you use the OpenAI or Anthropic SDKs directly (without LiteLLM), there are native wrappers:
|
||||
|
||||
### OpenAI
|
||||
|
||||
```python
|
||||
from openai import OpenAI
|
||||
from hindsight_litellm import wrap_openai
|
||||
|
||||
client = OpenAI()
|
||||
wrapped = wrap_openai(
|
||||
client,
|
||||
bank_id="my-agent",
|
||||
hindsight_api_url="http://localhost:8888",
|
||||
)
|
||||
|
||||
response = wrapped.chat.completions.create(
|
||||
model="gpt-4o",
|
||||
messages=[{"role": "user", "content": "What do you know about me?"}]
|
||||
)
|
||||
```
|
||||
|
||||
### Anthropic
|
||||
|
||||
```python
|
||||
from anthropic import Anthropic
|
||||
from hindsight_litellm import wrap_anthropic
|
||||
|
||||
client = Anthropic()
|
||||
wrapped = wrap_anthropic(
|
||||
client,
|
||||
bank_id="my-agent",
|
||||
hindsight_api_url="http://localhost:8888",
|
||||
)
|
||||
|
||||
response = wrapped.messages.create(
|
||||
model="claude-sonnet-4-20250514",
|
||||
max_tokens=1024,
|
||||
messages=[{"role": "user", "content": "Hello!"}]
|
||||
)
|
||||
```
|
||||
|
||||
Same memory, no LiteLLM dependency.
|
||||
|
||||
---
|
||||
|
||||
## Context Manager
|
||||
|
||||
For temporary memory integration:
|
||||
|
||||
```python
|
||||
from hindsight_litellm import hindsight_memory
|
||||
import litellm
|
||||
|
||||
with hindsight_memory(
|
||||
hindsight_api_url="http://localhost:8888",
|
||||
bank_id="user-123",
|
||||
):
|
||||
response = litellm.completion(
|
||||
model="gpt-4o",
|
||||
messages=[{"role": "user", "content": "Hello!"}],
|
||||
hindsight_query="greeting context",
|
||||
)
|
||||
# Memory integration automatically disabled after the block
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Bank Missions
|
||||
|
||||
Tell Hindsight what kind of knowledge the bank should build. This shapes how memories are consolidated into mental models. Pass `mission` and `bank_name` to `configure()`:
|
||||
|
||||
```python
|
||||
hindsight_litellm.configure(
|
||||
hindsight_api_url="http://localhost:8888",
|
||||
mission="""This agent routes customer support requests.
|
||||
Remember which issue types go to which teams (billing, technical, sales).
|
||||
Track customer preferences and past resolutions.""",
|
||||
bank_name="Customer Support Router",
|
||||
)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Recap
|
||||
|
||||
- `hindsight-litellm` gives any LLM persistent memory across conversations
|
||||
- Works with 100+ providers via LiteLLM, plus native OpenAI and Anthropic wrappers
|
||||
- Three lines of setup: `configure()`, `set_defaults()`, `enable()`
|
||||
- Two modes: `recall` for raw facts, `reflect` for synthesized context
|
||||
- Direct APIs (`recall`, `reflect`, `retain`) for manual memory control
|
||||
- Per-call overrides, bank missions, async support, and debug mode
|
||||
|
||||
The integration handles memory retrieval, prompt injection, and conversation storage automatically. You just call `completion()` as usual — the LLM remembers everything.
|
||||
|
||||
---
|
||||
|
||||
## Next Steps
|
||||
|
||||
- **Try it locally**: `pip install hindsight-all hindsight-litellm` and run the quick start above
|
||||
- **Use Hindsight Cloud**: Skip self-hosting with a [free account](https://ui.hindsight.vectorize.io/signup)
|
||||
- **Explore memory modes**: Try `use_reflect=True` for synthesized context vs raw facts
|
||||
- **Set a bank mission**: Shape what knowledge your agent accumulates
|
||||
- **Inspect with debug mode**: Set `verbose=True` and call `get_last_injection_debug()` to see exactly what memories are injected
|
||||
date: 2026-03-03T12:00
|
||||
tags: [litellm, python, memory, openai, anthropic, tutorial]
|
||||
image: /img/blog/litellm-memory.png
|
||||
---
|
||||
|
||||
`hindsight-litellm` adds persistent memory to any LLM provider via LiteLLM — OpenAI, Anthropic, Groq, Azure, Bedrock, Vertex AI, and 100+ more. Three lines of setup, and every LLM call automatically gets context from past conversations.
|
||||
|
||||
<!-- truncate -->
|
||||
|
||||
---
|
||||
|
||||
## The Problem: Stateless LLM Calls
|
||||
|
||||
You build an app with an LLM. User talks to it on Monday. Comes back Tuesday. The LLM has no idea who they are.
|
||||
|
||||
This is true for every provider. OpenAI, Anthropic, Groq, Azure — every API call is a blank slate. The LLM doesn't remember preferences, past conversations, or anything you've discussed before.
|
||||
|
||||
Most teams work around this by stuffing the last N messages into the context window. But that's not memory — it's a sliding window that drops everything older than your token limit. The user's preferences from last week? Gone. The project context from last month? Gone.
|
||||
|
||||
What if every LLM call automatically had the right context from past conversations?
|
||||
|
||||
---
|
||||
|
||||
## The Fix: Three Lines, Any Provider
|
||||
|
||||
`hindsight-litellm` hooks into LiteLLM to intercept every LLM call. Before the call, it retrieves relevant memories from Hindsight and injects them into the prompt. After the call, it stores the conversation for future retrieval.
|
||||
|
||||
```
|
||||
Your code ──→ hindsight_litellm.completion()
|
||||
│
|
||||
├─→ 1. Recall/Reflect from Hindsight (relevant memories)
|
||||
├─→ 2. Inject memories into prompt
|
||||
├─→ 3. Forward to LLM (any provider via LiteLLM)
|
||||
├─→ 4. Store conversation to Hindsight
|
||||
└─→ 5. Return response
|
||||
```
|
||||
|
||||
Here's the setup:
|
||||
|
||||
```python
|
||||
import hindsight_litellm
|
||||
|
||||
hindsight_litellm.configure(
|
||||
hindsight_api_url="http://localhost:8888",
|
||||
)
|
||||
|
||||
hindsight_litellm.set_defaults(
|
||||
bank_id="my-agent",
|
||||
)
|
||||
|
||||
hindsight_litellm.enable()
|
||||
```
|
||||
|
||||
That's it. Now every `completion()` call has memory:
|
||||
|
||||
```python
|
||||
response = hindsight_litellm.completion(
|
||||
model="gpt-4o-mini",
|
||||
messages=[{"role": "user", "content": "Help me with my Python project"}],
|
||||
hindsight_query="What do I know about the user's Python project?",
|
||||
)
|
||||
```
|
||||
|
||||
The `hindsight_query` tells Hindsight what to search for in memory. The response comes back with context from past conversations — the LLM knows about the user's project, their preferences, their tech stack.
|
||||
|
||||
> **Note:** You can also use [Hindsight Cloud](https://ui.hindsight.vectorize.io/signup) and skip the self-hosted setup entirely.
|
||||
|
||||
---
|
||||
|
||||
## Any Provider, Same Memory
|
||||
|
||||
Because the integration runs through LiteLLM, it works with every provider LiteLLM supports. Switch models freely — memory follows:
|
||||
|
||||
```python
|
||||
messages = [{"role": "user", "content": "What did we discuss last time?"}]
|
||||
query = "What have I discussed with this user?"
|
||||
|
||||
# OpenAI
|
||||
hindsight_litellm.completion(model="gpt-4o", messages=messages, hindsight_query=query)
|
||||
|
||||
# Anthropic
|
||||
hindsight_litellm.completion(model="claude-sonnet-4-20250514", messages=messages, hindsight_query=query)
|
||||
|
||||
# Groq
|
||||
hindsight_litellm.completion(model="groq/llama-3.1-70b-versatile", messages=messages, hindsight_query=query)
|
||||
|
||||
# Azure OpenAI
|
||||
hindsight_litellm.completion(model="azure/gpt-4", messages=messages, hindsight_query=query)
|
||||
|
||||
# AWS Bedrock
|
||||
hindsight_litellm.completion(model="bedrock/anthropic.claude-3", messages=messages, hindsight_query=query)
|
||||
|
||||
# Google Vertex AI
|
||||
hindsight_litellm.completion(model="vertex_ai/gemini-pro", messages=messages, hindsight_query=query)
|
||||
```
|
||||
|
||||
Same bank, same memories, any model. Migrate from OpenAI to Anthropic and your agent still knows everything.
|
||||
|
||||
---
|
||||
|
||||
## Two Memory Modes
|
||||
|
||||
### Recall: Raw Memories
|
||||
|
||||
The default mode retrieves individual memory facts and injects them as a numbered list:
|
||||
|
||||
```python
|
||||
hindsight_litellm.set_defaults(bank_id="my-agent", use_reflect=False)
|
||||
```
|
||||
|
||||
The LLM sees something like:
|
||||
|
||||
```
|
||||
# Relevant Memories
|
||||
1. [WORLD] User is building a FastAPI application
|
||||
2. [WORLD] User prefers pytest for testing
|
||||
3. [OBSERVATION] User likes type hints
|
||||
```
|
||||
|
||||
Best for precise, factual context where the LLM needs individual data points.
|
||||
|
||||
### Reflect: Synthesized Context
|
||||
|
||||
Reflect mode synthesizes memories into a coherent paragraph instead of raw facts:
|
||||
|
||||
```python
|
||||
hindsight_litellm.set_defaults(
|
||||
bank_id="my-agent",
|
||||
use_reflect=True,
|
||||
reflect_context="I am a coding assistant helping with Python projects.",
|
||||
)
|
||||
```
|
||||
|
||||
The LLM sees something like:
|
||||
|
||||
```
|
||||
The user is an experienced Python developer working on a FastAPI application.
|
||||
They prefer pytest for testing and value type hints. In past conversations,
|
||||
they asked about async patterns and database migrations.
|
||||
```
|
||||
|
||||
Best for natural, conversational context. The `reflect_context` parameter shapes how Hindsight reasons about the memories without affecting what it retrieves.
|
||||
|
||||
---
|
||||
|
||||
## Direct Memory APIs
|
||||
|
||||
Sometimes you want to query memory outside of an LLM call. The direct APIs give you full control:
|
||||
|
||||
### Recall — query raw memories
|
||||
|
||||
```python
|
||||
from hindsight_litellm import recall
|
||||
|
||||
memories = recall("what projects is the user working on?", budget="mid")
|
||||
for m in memories:
|
||||
print(f"- [{m.fact_type}] {m.text}")
|
||||
```
|
||||
|
||||
### Reflect — synthesized context
|
||||
|
||||
```python
|
||||
from hindsight_litellm import reflect
|
||||
|
||||
result = reflect(
|
||||
"what do you know about the user's preferences?",
|
||||
context="I am a customer support agent.",
|
||||
)
|
||||
print(result.text)
|
||||
```
|
||||
|
||||
### Retain — store memories manually
|
||||
|
||||
```python
|
||||
from hindsight_litellm import retain
|
||||
|
||||
retain(
|
||||
content="User mentioned they're switching from Flask to FastAPI",
|
||||
context="Discussion about web frameworks",
|
||||
)
|
||||
```
|
||||
|
||||
All three have async variants: `arecall()`, `areflect()`, `aretain()`.
|
||||
|
||||
---
|
||||
|
||||
## Per-Call Overrides
|
||||
|
||||
Defaults are convenient, but sometimes you need per-call control:
|
||||
|
||||
```python
|
||||
response = hindsight_litellm.completion(
|
||||
model="gpt-4o-mini",
|
||||
messages=[...],
|
||||
hindsight_query="What do I know about Alice?",
|
||||
hindsight_bank_id="other-agent", # Different bank for this call
|
||||
hindsight_budget="high", # More thorough retrieval
|
||||
hindsight_reflect_context="Currently helping with onboarding",
|
||||
)
|
||||
```
|
||||
|
||||
Any default can be overridden with a `hindsight_*` prefix.
|
||||
|
||||
---
|
||||
|
||||
## Native SDK Wrappers
|
||||
|
||||
If you use the OpenAI or Anthropic SDKs directly (without LiteLLM), there are native wrappers:
|
||||
|
||||
### OpenAI
|
||||
|
||||
```python
|
||||
from openai import OpenAI
|
||||
from hindsight_litellm import wrap_openai
|
||||
|
||||
client = OpenAI()
|
||||
wrapped = wrap_openai(
|
||||
client,
|
||||
bank_id="my-agent",
|
||||
hindsight_api_url="http://localhost:8888",
|
||||
)
|
||||
|
||||
response = wrapped.chat.completions.create(
|
||||
model="gpt-4o",
|
||||
messages=[{"role": "user", "content": "What do you know about me?"}]
|
||||
)
|
||||
```
|
||||
|
||||
### Anthropic
|
||||
|
||||
```python
|
||||
from anthropic import Anthropic
|
||||
from hindsight_litellm import wrap_anthropic
|
||||
|
||||
client = Anthropic()
|
||||
wrapped = wrap_anthropic(
|
||||
client,
|
||||
bank_id="my-agent",
|
||||
hindsight_api_url="http://localhost:8888",
|
||||
)
|
||||
|
||||
response = wrapped.messages.create(
|
||||
model="claude-sonnet-4-20250514",
|
||||
max_tokens=1024,
|
||||
messages=[{"role": "user", "content": "Hello!"}]
|
||||
)
|
||||
```
|
||||
|
||||
Same memory, no LiteLLM dependency.
|
||||
|
||||
---
|
||||
|
||||
## Context Manager
|
||||
|
||||
For temporary memory integration:
|
||||
|
||||
```python
|
||||
from hindsight_litellm import hindsight_memory
|
||||
import litellm
|
||||
|
||||
with hindsight_memory(
|
||||
hindsight_api_url="http://localhost:8888",
|
||||
bank_id="user-123",
|
||||
):
|
||||
response = litellm.completion(
|
||||
model="gpt-4o",
|
||||
messages=[{"role": "user", "content": "Hello!"}],
|
||||
hindsight_query="greeting context",
|
||||
)
|
||||
# Memory integration automatically disabled after the block
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Bank Missions
|
||||
|
||||
Tell Hindsight what kind of knowledge the bank should build. This shapes how memories are consolidated into mental models. Pass `mission` and `bank_name` to `configure()`:
|
||||
|
||||
```python
|
||||
hindsight_litellm.configure(
|
||||
hindsight_api_url="http://localhost:8888",
|
||||
mission="""This agent routes customer support requests.
|
||||
Remember which issue types go to which teams (billing, technical, sales).
|
||||
Track customer preferences and past resolutions.""",
|
||||
bank_name="Customer Support Router",
|
||||
)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Recap
|
||||
|
||||
- `hindsight-litellm` gives any LLM persistent memory across conversations
|
||||
- Works with 100+ providers via LiteLLM, plus native OpenAI and Anthropic wrappers
|
||||
- Three lines of setup: `configure()`, `set_defaults()`, `enable()`
|
||||
- Two modes: `recall` for raw facts, `reflect` for synthesized context
|
||||
- Direct APIs (`recall`, `reflect`, `retain`) for manual memory control
|
||||
- Per-call overrides, bank missions, async support, and debug mode
|
||||
|
||||
The integration handles memory retrieval, prompt injection, and conversation storage automatically. You just call `completion()` as usual — the LLM remembers everything.
|
||||
|
||||
---
|
||||
|
||||
## Next Steps
|
||||
|
||||
- **Try it locally**: `pip install hindsight-all hindsight-litellm` and run the quick start above
|
||||
- **Use Hindsight Cloud**: Skip self-hosting with a [free account](https://ui.hindsight.vectorize.io/signup)
|
||||
- **Explore memory modes**: Try `use_reflect=True` for synthesized context vs raw facts
|
||||
- **Set a bank mission**: Shape what knowledge your agent accumulates
|
||||
- **Inspect with debug mode**: Set `verbose=True` and call `get_last_injection_debug()` to see exactly what memories are injected
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
title: "What's new in Hindsight 0.4.15"
|
||||
description: New features and improvements in Hindsight 0.4.15
|
||||
authors: [nicoloboschi]
|
||||
date: 2026-03-03
|
||||
date: 2026-03-03T12:00
|
||||
hide_table_of_contents: true
|
||||
image: /img/blog/release0415.png
|
||||
---
|
||||
|
|
|
|||
|
|
@ -1,267 +1,267 @@
|
|||
---
|
||||
title: "The Open-Source MCP Memory Server Your AI Agent Is Missing"
|
||||
---
|
||||
title: "The Open-Source MCP Memory Server Your AI Agent Is Missing"
|
||||
authors: [benfrank241]
|
||||
|
||||
date: 2026-03-04
|
||||
tags: [mcp, memory, agents, docker, tutorial]
|
||||
image: /img/blog/mcp-agent-memory.png
|
||||
hide_table_of_contents: true
|
||||
---
|
||||
|
||||
AI agents forget everything between sessions. Hindsight gives them persistent, structured memory via MCP. One Docker command to run the full stack locally. Connect any MCP-compatible client. Three core operations: `retain` (store), `recall` (search), `reflect` (reason) — plus mental models that auto-update as memories grow.
|
||||
|
||||
<!-- truncate -->
|
||||
|
||||
---
|
||||
|
||||
## TL;DR
|
||||
|
||||
- AI agents forget everything between sessions. Hindsight gives them persistent, structured memory via MCP.
|
||||
- One Docker command to run the full stack locally. Connect any MCP-compatible client.
|
||||
- Three core operations: `retain` (store), `recall` (search), `reflect` (reason). Plus mental models — living documents that auto-update as memories grow.
|
||||
- Hindsight isn't a vector database. It extracts structured facts, resolves entities, builds a knowledge graph, and uses cross-encoder reranking to surface what actually matters.
|
||||
- Open source: [github.com/vectorize-io/hindsight](https://github.com/vectorize-io/hindsight).
|
||||
|
||||
---
|
||||
|
||||
## The Problem
|
||||
|
||||
AI agents are stateless. Every session starts from zero.
|
||||
|
||||
You tell your coding assistant your tech stack, your deployment preferences, your team's conventions. Next session — gone. You explain the same architecture decisions, re-establish the same context, re-state the same constraints. Every time.
|
||||
|
||||
People work around this by pasting context into system prompts or maintaining notes they copy in manually. That works for a while, but it doesn't scale. It can't capture the kind of nuanced, evolving knowledge that accumulates over weeks of working with an agent — things like "this user prefers functional patterns," "their team uses PostgreSQL 16," or "they tried Redis caching last month and rolled it back."
|
||||
|
||||
What you actually want is for your agent to build up memory over time. Store what matters, retrieve it when relevant, and learn from the accumulation.
|
||||
|
||||
Hindsight is an open-source memory system designed for exactly this. It connects to any MCP-compatible agent and gives it persistent, structured long-term memory.
|
||||
|
||||
---
|
||||
|
||||
## The Approach
|
||||
|
||||
```
|
||||
Your MCP Client ──MCP (HTTP)──> Hindsight API
|
||||
(Claude, Cursor, │
|
||||
VS Code, etc.) ├── Memory Engine (retain/recall/reflect)
|
||||
├── Fact Extraction + Entity Resolution
|
||||
├── Embeddings + Cross-Encoder Reranking
|
||||
├── Knowledge Graph Traversal
|
||||
└── PostgreSQL + pgvector
|
||||
```
|
||||
|
||||
Your agent connects to Hindsight over MCP (Model Context Protocol). MCP is an open standard — any client that speaks it can use Hindsight as a memory backend.
|
||||
|
||||
When your agent stores a memory via `retain`, Hindsight doesn't just dump raw text into a vector database. It extracts structured facts, resolves entities ("Alice" and "my coworker Alice" are the same person), generates embeddings, and indexes everything for retrieval.
|
||||
|
||||
When your agent needs context via `recall`, Hindsight runs four retrieval strategies in parallel — semantic search, BM25 keyword matching, entity graph traversal, and temporal filtering — then reranks results with a cross-encoder. What comes back is the most relevant subset of your memories, not a raw dump.
|
||||
|
||||
This matters because naive RAG (embed text, cosine similarity, return top-k) breaks down when you have hundreds of memories spanning different topics and time periods. Hindsight's multi-strategy approach ensures that a question like "what did we decide about caching?" finds the right answer even when the memory uses different terminology.
|
||||
|
||||
---
|
||||
|
||||
## Implementation
|
||||
|
||||
### Step 1: Start Hindsight
|
||||
|
||||
The quickest way to run Hindsight is with Docker. One command gives you the full stack — API server, embedded PostgreSQL, local embedding models, and MCP endpoints:
|
||||
|
||||
```bash
|
||||
docker run --rm -it --pull always -p 8888:8888 -p 9999:9999 \
|
||||
-e HINDSIGHT_API_LLM_API_KEY=YOUR_LLM_API_KEY \
|
||||
-v $HOME/.hindsight-docker:/home/hindsight/.pg0 \
|
||||
ghcr.io/vectorize-io/hindsight:latest
|
||||
```
|
||||
|
||||
You'll need an LLM API key for Hindsight's internal processing (fact extraction, entity resolution, reflect). Hindsight supports multiple LLM providers — OpenAI, Anthropic, Gemini, Groq, or a local model via Ollama or LM Studio. Set the provider explicitly if you're not using OpenAI:
|
||||
|
||||
```bash
|
||||
docker run --rm -it --pull always -p 8888:8888 -p 9999:9999 \
|
||||
-e HINDSIGHT_API_LLM_PROVIDER=gemini \
|
||||
-e HINDSIGHT_API_LLM_API_KEY=YOUR_GEMINI_API_KEY \
|
||||
-e HINDSIGHT_API_LLM_MODEL=gemini-2.5-flash \
|
||||
-v $HOME/.hindsight-docker:/home/hindsight/.pg0 \
|
||||
ghcr.io/vectorize-io/hindsight:latest
|
||||
```
|
||||
|
||||
The `-v` flag persists your data across container restarts. Without it, memories are lost when the container stops. Port 8888 is the API and MCP endpoint; port 9999 is an optional admin UI for browsing memories.
|
||||
|
||||
Once running, the MCP endpoint is available at `http://localhost:8888/mcp/your_bank_id/` (replace `your_bank_id` with any name you like).
|
||||
|
||||
**Or use Hindsight Cloud** — skip Docker entirely. [Sign up for a free account](https://ui.hindsight.vectorize.io/signup), grab your API key, and connect via MCP:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"hindsight": {
|
||||
"type": "http",
|
||||
"url": "https://api.hindsight.vectorize.io/mcp/your_bank_id/",
|
||||
"headers": {
|
||||
"Authorization": "Bearer YOUR_API_KEY"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Or with Claude Code:
|
||||
|
||||
```bash
|
||||
claude mcp add --transport http hindsight \
|
||||
https://api.hindsight.vectorize.io/mcp/your_bank_id/ \
|
||||
--header "Authorization: Bearer YOUR_API_KEY"
|
||||
```
|
||||
|
||||
### Step 2: Connect Your MCP Client
|
||||
|
||||
Hindsight works with any MCP-compatible client. Add the following JSON to your client's config file:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"hindsight": {
|
||||
"type": "http",
|
||||
"url": "http://localhost:8888/mcp/your_bank_id/"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Config file locations by client:
|
||||
|
||||
| Client | Config File |
|
||||
|--------|-------------|
|
||||
| Claude Desktop | `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows) |
|
||||
| Cursor | `.cursor/mcp.json` (project) or `~/.cursor/mcp.json` (global) |
|
||||
| VS Code | `.vscode/mcp.json` — uses `"servers"` instead of `"mcpServers"` |
|
||||
| Windsurf | `~/.codeium/windsurf/mcp_config.json` — uses `"serverUrl"` instead of `"url"` |
|
||||
|
||||
**Claude Code** — use the CLI instead:
|
||||
|
||||
```bash
|
||||
claude mcp add --transport http hindsight http://localhost:8888/mcp/your_bank_id/
|
||||
```
|
||||
|
||||
Restart your client to pick up the changes.
|
||||
|
||||
### Step 3: Verify It's Working
|
||||
|
||||
Ask your agent:
|
||||
|
||||
> "What memory tools do you have available?"
|
||||
|
||||
It should list Hindsight's memory tools, including the three core operations (`retain`, `recall`, `reflect`), six mental model tools, and additional tools for browsing memories, managing documents, and bank administration.
|
||||
|
||||
---
|
||||
|
||||
## The Memory Tools
|
||||
|
||||
Once connected, your agent has access to three core operations and a set of mental model tools.
|
||||
|
||||
**Retain** — Store a memory:
|
||||
|
||||
Tell your agent something you want it to remember. It will call `retain` automatically based on the tool's built-in instructions, or you can be explicit:
|
||||
|
||||
> "Remember that I prefer TypeScript over JavaScript for all new projects."
|
||||
|
||||
Behind the scenes, Hindsight extracts structured facts, resolves entities, and indexes the memory for later retrieval. A single `retain` call on "Alice from engineering recommended we switch to Postgres 16 for the new JSONB features" produces:
|
||||
|
||||
- A fact: "Alice recommended switching to Postgres 16 for JSONB features"
|
||||
- Entity resolution: "Alice" linked to "Alice from engineering"
|
||||
- Temporal indexing: when this was mentioned
|
||||
- Embeddings: for semantic search later
|
||||
|
||||
**Recall** — Search memories:
|
||||
|
||||
Your agent will proactively recall relevant context when you ask questions. You can also prompt it directly:
|
||||
|
||||
> "What do you know about my programming preferences?"
|
||||
|
||||
Recall runs four retrieval strategies in parallel — semantic search, keyword matching (BM25), graph traversal, and temporal filtering — then reranks the results with a cross-encoder. This is what makes it work better than a simple vector search.
|
||||
|
||||
**Reflect** — Synthesize insights:
|
||||
|
||||
Reflect goes deeper than recall. Instead of returning raw facts, it reasons across your memories using an LLM:
|
||||
|
||||
> "Based on what you know about me, what tech stack would you recommend for my next side project?"
|
||||
|
||||
This is useful for questions that require connecting dots across multiple memories.
|
||||
|
||||
**Mental Models** — Living documents:
|
||||
|
||||
Mental models are summaries that automatically stay up to date as new memories are added. Think of them as pre-computed reflections that refresh themselves:
|
||||
|
||||
> "Create a mental model called 'My Tech Stack' that tracks what languages, frameworks, and tools I use."
|
||||
|
||||
You can list, retrieve, update, and delete mental models. They're useful for maintaining an always-current view of a topic without running a full `reflect` every time.
|
||||
|
||||
---
|
||||
|
||||
## Memory Banks
|
||||
|
||||
The URL path controls which memory bank you're using. In the examples above, `/mcp/your_bank_id/` scopes all operations to that bank.
|
||||
|
||||
Banks are isolated stores — think of each one as a separate brain. You can run separate banks for different contexts:
|
||||
|
||||
- `my-project` for a specific project
|
||||
- `team-knowledge` for shared team information
|
||||
- One bank per user in a multi-agent system
|
||||
|
||||
Banks are created automatically on first use. To use a different bank, change the URL path:
|
||||
|
||||
```
|
||||
http://localhost:8888/mcp/project-x/
|
||||
```
|
||||
|
||||
If you want your agent to manage multiple banks in a single session, connect to the multi-bank endpoint at `/mcp/` instead. This adds `bank_id` as a parameter to every tool and includes additional bank management tools like `list_banks`, `create_bank`, and `get_bank_stats`.
|
||||
|
||||
---
|
||||
|
||||
## Pitfalls & Edge Cases
|
||||
|
||||
### Memory processing is async
|
||||
|
||||
When your agent calls `retain`, fact extraction and indexing happen in the background. If you store something and immediately try to recall it, it might not be there yet. Give it a few seconds for complex memories.
|
||||
|
||||
### Token limits on recall
|
||||
|
||||
By default, `recall` returns up to 4096 tokens of memory content. For banks with extensive history, some older or lower-relevance memories may be trimmed from the response. This is intentional — it keeps the context window manageable.
|
||||
|
||||
### Mental model creation is async too
|
||||
|
||||
When you create or refresh a mental model, the LLM-powered generation runs in the background. The initial call returns an `operation_id`. The content will be available shortly after — typically a few seconds, depending on how many memories need to be synthesized.
|
||||
|
||||
### LLM key is for Hindsight, not your agent
|
||||
|
||||
The `HINDSIGHT_API_LLM_API_KEY` is used by Hindsight internally for fact extraction, entity resolution, and reflect operations. It's separate from whatever LLM your agent uses. You can use a cheap, fast model here (Gemini Flash, Groq, etc.) — it doesn't need to be the same model powering your agent.
|
||||
|
||||
---
|
||||
|
||||
## When Hindsight Works Well
|
||||
|
||||
- You want structured memory, not just vector search over conversation logs
|
||||
- You need memory that works across sessions, clients, and agents
|
||||
- You want entity resolution, temporal awareness, and multi-strategy retrieval out of the box
|
||||
- You're building agents that accumulate knowledge over time
|
||||
|
||||
---
|
||||
|
||||
## Recap
|
||||
|
||||
Hindsight gives any MCP-compatible agent persistent long-term memory. One Docker command to start, a few lines of JSON to connect.
|
||||
|
||||
The key insight is that memory isn't just storage and retrieval. Hindsight extracts structured facts from raw input, links entities, tracks temporal data, and uses cross-encoder reranking to surface the most relevant memories. That's what separates it from stuffing conversation logs into a vector database.
|
||||
|
||||
The MCP tools cover the full lifecycle: `retain` to store, `recall` to search with multi-strategy retrieval, `reflect` to synthesize insights, mental model tools for maintaining living documents that auto-update, and utility tools for browsing and managing memories, documents, and tags.
|
||||
|
||||
> **Want managed hosting?** [Hindsight Cloud](https://ui.hindsight.vectorize.io) runs the full stack for you — no Docker, no infrastructure. Sign up, grab an API key, and connect over HTTPS.
|
||||
|
||||
---
|
||||
|
||||
## Next Steps
|
||||
|
||||
- **Build up your memory**: Start using your agent normally. Tell it your preferences, your project context, your decisions. It will retain what matters.
|
||||
- **Explore mental models**: Create living documents that auto-update as your memory grows. Try: `"Create a mental model that summarizes my project architecture."`
|
||||
- **Try multi-bank setups**: Run separate banks for different projects or agents. Connect to `/mcp/` for multi-bank mode.
|
||||
- **Use the SDK directly**: Beyond MCP, Hindsight has [Python](https://pypi.org/project/hindsight-client/) and [TypeScript](https://www.npmjs.com/package/@vectorize-io/hindsight-client) SDKs for integrating memory into your own applications.
|
||||
- **Check out the docs**: Full API reference, SDK guides, and more at [hindsight.vectorize.io](https://hindsight.vectorize.io).
|
||||
date: 2026-03-04T12:00
|
||||
tags: [mcp, memory, agents, docker, tutorial]
|
||||
image: /img/blog/mcp-agent-memory.png
|
||||
hide_table_of_contents: true
|
||||
---
|
||||
|
||||
AI agents forget everything between sessions. Hindsight gives them persistent, structured memory via MCP. One Docker command to run the full stack locally. Connect any MCP-compatible client. Three core operations: `retain` (store), `recall` (search), `reflect` (reason) — plus mental models that auto-update as memories grow.
|
||||
|
||||
<!-- truncate -->
|
||||
|
||||
---
|
||||
|
||||
## TL;DR
|
||||
|
||||
- AI agents forget everything between sessions. Hindsight gives them persistent, structured memory via MCP.
|
||||
- One Docker command to run the full stack locally. Connect any MCP-compatible client.
|
||||
- Three core operations: `retain` (store), `recall` (search), `reflect` (reason). Plus mental models — living documents that auto-update as memories grow.
|
||||
- Hindsight isn't a vector database. It extracts structured facts, resolves entities, builds a knowledge graph, and uses cross-encoder reranking to surface what actually matters.
|
||||
- Open source: [github.com/vectorize-io/hindsight](https://github.com/vectorize-io/hindsight).
|
||||
|
||||
---
|
||||
|
||||
## The Problem
|
||||
|
||||
AI agents are stateless. Every session starts from zero.
|
||||
|
||||
You tell your coding assistant your tech stack, your deployment preferences, your team's conventions. Next session — gone. You explain the same architecture decisions, re-establish the same context, re-state the same constraints. Every time.
|
||||
|
||||
People work around this by pasting context into system prompts or maintaining notes they copy in manually. That works for a while, but it doesn't scale. It can't capture the kind of nuanced, evolving knowledge that accumulates over weeks of working with an agent — things like "this user prefers functional patterns," "their team uses PostgreSQL 16," or "they tried Redis caching last month and rolled it back."
|
||||
|
||||
What you actually want is for your agent to build up memory over time. Store what matters, retrieve it when relevant, and learn from the accumulation.
|
||||
|
||||
Hindsight is an open-source memory system designed for exactly this. It connects to any MCP-compatible agent and gives it persistent, structured long-term memory.
|
||||
|
||||
---
|
||||
|
||||
## The Approach
|
||||
|
||||
```
|
||||
Your MCP Client ──MCP (HTTP)──> Hindsight API
|
||||
(Claude, Cursor, │
|
||||
VS Code, etc.) ├── Memory Engine (retain/recall/reflect)
|
||||
├── Fact Extraction + Entity Resolution
|
||||
├── Embeddings + Cross-Encoder Reranking
|
||||
├── Knowledge Graph Traversal
|
||||
└── PostgreSQL + pgvector
|
||||
```
|
||||
|
||||
Your agent connects to Hindsight over MCP (Model Context Protocol). MCP is an open standard — any client that speaks it can use Hindsight as a memory backend.
|
||||
|
||||
When your agent stores a memory via `retain`, Hindsight doesn't just dump raw text into a vector database. It extracts structured facts, resolves entities ("Alice" and "my coworker Alice" are the same person), generates embeddings, and indexes everything for retrieval.
|
||||
|
||||
When your agent needs context via `recall`, Hindsight runs four retrieval strategies in parallel — semantic search, BM25 keyword matching, entity graph traversal, and temporal filtering — then reranks results with a cross-encoder. What comes back is the most relevant subset of your memories, not a raw dump.
|
||||
|
||||
This matters because naive RAG (embed text, cosine similarity, return top-k) breaks down when you have hundreds of memories spanning different topics and time periods. Hindsight's multi-strategy approach ensures that a question like "what did we decide about caching?" finds the right answer even when the memory uses different terminology.
|
||||
|
||||
---
|
||||
|
||||
## Implementation
|
||||
|
||||
### Step 1: Start Hindsight
|
||||
|
||||
The quickest way to run Hindsight is with Docker. One command gives you the full stack — API server, embedded PostgreSQL, local embedding models, and MCP endpoints:
|
||||
|
||||
```bash
|
||||
docker run --rm -it --pull always -p 8888:8888 -p 9999:9999 \
|
||||
-e HINDSIGHT_API_LLM_API_KEY=YOUR_LLM_API_KEY \
|
||||
-v $HOME/.hindsight-docker:/home/hindsight/.pg0 \
|
||||
ghcr.io/vectorize-io/hindsight:latest
|
||||
```
|
||||
|
||||
You'll need an LLM API key for Hindsight's internal processing (fact extraction, entity resolution, reflect). Hindsight supports multiple LLM providers — OpenAI, Anthropic, Gemini, Groq, or a local model via Ollama or LM Studio. Set the provider explicitly if you're not using OpenAI:
|
||||
|
||||
```bash
|
||||
docker run --rm -it --pull always -p 8888:8888 -p 9999:9999 \
|
||||
-e HINDSIGHT_API_LLM_PROVIDER=gemini \
|
||||
-e HINDSIGHT_API_LLM_API_KEY=YOUR_GEMINI_API_KEY \
|
||||
-e HINDSIGHT_API_LLM_MODEL=gemini-2.5-flash \
|
||||
-v $HOME/.hindsight-docker:/home/hindsight/.pg0 \
|
||||
ghcr.io/vectorize-io/hindsight:latest
|
||||
```
|
||||
|
||||
The `-v` flag persists your data across container restarts. Without it, memories are lost when the container stops. Port 8888 is the API and MCP endpoint; port 9999 is an optional admin UI for browsing memories.
|
||||
|
||||
Once running, the MCP endpoint is available at `http://localhost:8888/mcp/your_bank_id/` (replace `your_bank_id` with any name you like).
|
||||
|
||||
**Or use Hindsight Cloud** — skip Docker entirely. [Sign up for a free account](https://ui.hindsight.vectorize.io/signup), grab your API key, and connect via MCP:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"hindsight": {
|
||||
"type": "http",
|
||||
"url": "https://api.hindsight.vectorize.io/mcp/your_bank_id/",
|
||||
"headers": {
|
||||
"Authorization": "Bearer YOUR_API_KEY"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Or with Claude Code:
|
||||
|
||||
```bash
|
||||
claude mcp add --transport http hindsight \
|
||||
https://api.hindsight.vectorize.io/mcp/your_bank_id/ \
|
||||
--header "Authorization: Bearer YOUR_API_KEY"
|
||||
```
|
||||
|
||||
### Step 2: Connect Your MCP Client
|
||||
|
||||
Hindsight works with any MCP-compatible client. Add the following JSON to your client's config file:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"hindsight": {
|
||||
"type": "http",
|
||||
"url": "http://localhost:8888/mcp/your_bank_id/"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Config file locations by client:
|
||||
|
||||
| Client | Config File |
|
||||
|--------|-------------|
|
||||
| Claude Desktop | `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows) |
|
||||
| Cursor | `.cursor/mcp.json` (project) or `~/.cursor/mcp.json` (global) |
|
||||
| VS Code | `.vscode/mcp.json` — uses `"servers"` instead of `"mcpServers"` |
|
||||
| Windsurf | `~/.codeium/windsurf/mcp_config.json` — uses `"serverUrl"` instead of `"url"` |
|
||||
|
||||
**Claude Code** — use the CLI instead:
|
||||
|
||||
```bash
|
||||
claude mcp add --transport http hindsight http://localhost:8888/mcp/your_bank_id/
|
||||
```
|
||||
|
||||
Restart your client to pick up the changes.
|
||||
|
||||
### Step 3: Verify It's Working
|
||||
|
||||
Ask your agent:
|
||||
|
||||
> "What memory tools do you have available?"
|
||||
|
||||
It should list Hindsight's memory tools, including the three core operations (`retain`, `recall`, `reflect`), six mental model tools, and additional tools for browsing memories, managing documents, and bank administration.
|
||||
|
||||
---
|
||||
|
||||
## The Memory Tools
|
||||
|
||||
Once connected, your agent has access to three core operations and a set of mental model tools.
|
||||
|
||||
**Retain** — Store a memory:
|
||||
|
||||
Tell your agent something you want it to remember. It will call `retain` automatically based on the tool's built-in instructions, or you can be explicit:
|
||||
|
||||
> "Remember that I prefer TypeScript over JavaScript for all new projects."
|
||||
|
||||
Behind the scenes, Hindsight extracts structured facts, resolves entities, and indexes the memory for later retrieval. A single `retain` call on "Alice from engineering recommended we switch to Postgres 16 for the new JSONB features" produces:
|
||||
|
||||
- A fact: "Alice recommended switching to Postgres 16 for JSONB features"
|
||||
- Entity resolution: "Alice" linked to "Alice from engineering"
|
||||
- Temporal indexing: when this was mentioned
|
||||
- Embeddings: for semantic search later
|
||||
|
||||
**Recall** — Search memories:
|
||||
|
||||
Your agent will proactively recall relevant context when you ask questions. You can also prompt it directly:
|
||||
|
||||
> "What do you know about my programming preferences?"
|
||||
|
||||
Recall runs four retrieval strategies in parallel — semantic search, keyword matching (BM25), graph traversal, and temporal filtering — then reranks the results with a cross-encoder. This is what makes it work better than a simple vector search.
|
||||
|
||||
**Reflect** — Synthesize insights:
|
||||
|
||||
Reflect goes deeper than recall. Instead of returning raw facts, it reasons across your memories using an LLM:
|
||||
|
||||
> "Based on what you know about me, what tech stack would you recommend for my next side project?"
|
||||
|
||||
This is useful for questions that require connecting dots across multiple memories.
|
||||
|
||||
**Mental Models** — Living documents:
|
||||
|
||||
Mental models are summaries that automatically stay up to date as new memories are added. Think of them as pre-computed reflections that refresh themselves:
|
||||
|
||||
> "Create a mental model called 'My Tech Stack' that tracks what languages, frameworks, and tools I use."
|
||||
|
||||
You can list, retrieve, update, and delete mental models. They're useful for maintaining an always-current view of a topic without running a full `reflect` every time.
|
||||
|
||||
---
|
||||
|
||||
## Memory Banks
|
||||
|
||||
The URL path controls which memory bank you're using. In the examples above, `/mcp/your_bank_id/` scopes all operations to that bank.
|
||||
|
||||
Banks are isolated stores — think of each one as a separate brain. You can run separate banks for different contexts:
|
||||
|
||||
- `my-project` for a specific project
|
||||
- `team-knowledge` for shared team information
|
||||
- One bank per user in a multi-agent system
|
||||
|
||||
Banks are created automatically on first use. To use a different bank, change the URL path:
|
||||
|
||||
```
|
||||
http://localhost:8888/mcp/project-x/
|
||||
```
|
||||
|
||||
If you want your agent to manage multiple banks in a single session, connect to the multi-bank endpoint at `/mcp/` instead. This adds `bank_id` as a parameter to every tool and includes additional bank management tools like `list_banks`, `create_bank`, and `get_bank_stats`.
|
||||
|
||||
---
|
||||
|
||||
## Pitfalls & Edge Cases
|
||||
|
||||
### Memory processing is async
|
||||
|
||||
When your agent calls `retain`, fact extraction and indexing happen in the background. If you store something and immediately try to recall it, it might not be there yet. Give it a few seconds for complex memories.
|
||||
|
||||
### Token limits on recall
|
||||
|
||||
By default, `recall` returns up to 4096 tokens of memory content. For banks with extensive history, some older or lower-relevance memories may be trimmed from the response. This is intentional — it keeps the context window manageable.
|
||||
|
||||
### Mental model creation is async too
|
||||
|
||||
When you create or refresh a mental model, the LLM-powered generation runs in the background. The initial call returns an `operation_id`. The content will be available shortly after — typically a few seconds, depending on how many memories need to be synthesized.
|
||||
|
||||
### LLM key is for Hindsight, not your agent
|
||||
|
||||
The `HINDSIGHT_API_LLM_API_KEY` is used by Hindsight internally for fact extraction, entity resolution, and reflect operations. It's separate from whatever LLM your agent uses. You can use a cheap, fast model here (Gemini Flash, Groq, etc.) — it doesn't need to be the same model powering your agent.
|
||||
|
||||
---
|
||||
|
||||
## When Hindsight Works Well
|
||||
|
||||
- You want structured memory, not just vector search over conversation logs
|
||||
- You need memory that works across sessions, clients, and agents
|
||||
- You want entity resolution, temporal awareness, and multi-strategy retrieval out of the box
|
||||
- You're building agents that accumulate knowledge over time
|
||||
|
||||
---
|
||||
|
||||
## Recap
|
||||
|
||||
Hindsight gives any MCP-compatible agent persistent long-term memory. One Docker command to start, a few lines of JSON to connect.
|
||||
|
||||
The key insight is that memory isn't just storage and retrieval. Hindsight extracts structured facts from raw input, links entities, tracks temporal data, and uses cross-encoder reranking to surface the most relevant memories. That's what separates it from stuffing conversation logs into a vector database.
|
||||
|
||||
The MCP tools cover the full lifecycle: `retain` to store, `recall` to search with multi-strategy retrieval, `reflect` to synthesize insights, mental model tools for maintaining living documents that auto-update, and utility tools for browsing and managing memories, documents, and tags.
|
||||
|
||||
> **Want managed hosting?** [Hindsight Cloud](https://ui.hindsight.vectorize.io) runs the full stack for you — no Docker, no infrastructure. Sign up, grab an API key, and connect over HTTPS.
|
||||
|
||||
---
|
||||
|
||||
## Next Steps
|
||||
|
||||
- **Build up your memory**: Start using your agent normally. Tell it your preferences, your project context, your decisions. It will retain what matters.
|
||||
- **Explore mental models**: Create living documents that auto-update as your memory grows. Try: `"Create a mental model that summarizes my project architecture."`
|
||||
- **Try multi-bank setups**: Run separate banks for different projects or agents. Connect to `/mcp/` for multi-bank mode.
|
||||
- **Use the SDK directly**: Beyond MCP, Hindsight has [Python](https://pypi.org/project/hindsight-client/) and [TypeScript](https://www.npmjs.com/package/@vectorize-io/hindsight-client) SDKs for integrating memory into your own applications.
|
||||
- **Check out the docs**: Full API reference, SDK guides, and more at [hindsight.vectorize.io](https://hindsight.vectorize.io).
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
title: "Give Your OpenAI App a Memory in 5 Minutes"
|
||||
authors: [benfrank241]
|
||||
date: 2026-03-05
|
||||
date: 2026-03-05T12:00
|
||||
tags: [memory, openai, python, docker, rag, llm, vector, embedding]
|
||||
image: /img/blog/add-memory-to-openai-application.png
|
||||
hide_table_of_contents: true
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
title: "What's new in Hindsight 0.4.16"
|
||||
description: New features and improvements in Hindsight 0.4.16
|
||||
authors: [nicoloboschi]
|
||||
date: 2026-03-05
|
||||
date: 2026-03-05T12:00
|
||||
hide_table_of_contents: true
|
||||
image: /img/blog/release0416.png
|
||||
---
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
title: "The Memory Upgrade Every OpenClaw User Needs"
|
||||
authors: [benfrank241]
|
||||
date: 2026-03-06
|
||||
date: 2026-03-06T12:00
|
||||
tags: [openclaw]
|
||||
image: /img/blog/adding-memory-to-openclaw-with-hindsight.png
|
||||
hide_table_of_contents: true
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
title: "What's New in Hindsight Cloud: Document File Upload"
|
||||
authors: [benfrank241]
|
||||
date: 2026-03-09
|
||||
date: 2026-03-09T12:00
|
||||
tags: [hindsight-cloud, release, memory]
|
||||
hide_table_of_contents: true
|
||||
---
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
title: "Pydantic AI Persistent Memory: Add It in 5 Lines of Code"
|
||||
authors: [benfrank241]
|
||||
date: 2026-03-09
|
||||
date: 2026-03-09T12:00
|
||||
tags: [memory, openai, anthropic, gemini, python, rust, agents, rag, vector, pydantic-ai, knowledge-graph]
|
||||
image: /img/blog/pydantic-ai-persistent-memory.png
|
||||
hide_table_of_contents: true
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
title: "Run Hindsight with Ollama: Local AI Memory, No API Keys Needed"
|
||||
authors: [hindsight]
|
||||
date: 2026-03-10
|
||||
date: 2026-03-10T12:00
|
||||
tags: [ollama, tutorial, python, memory, local, privacy, hindsight, llm, open-source]
|
||||
image: /img/blog/run-hindsight-with-ollama.png
|
||||
hide_table_of_contents: true
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
title: "What's new in Hindsight 0.4.17"
|
||||
description: New features and improvements in Hindsight 0.4.17
|
||||
authors: [nicoloboschi]
|
||||
date: 2026-03-10
|
||||
date: 2026-03-10T12:00
|
||||
hide_table_of_contents: true
|
||||
image: /img/blog/release0417.png
|
||||
---
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
title: "What's New in Hindsight Cloud: Programmatic API Key Management"
|
||||
authors: [benfrank241]
|
||||
date: 2026-03-11
|
||||
date: 2026-03-11T12:00
|
||||
tags: [hindsight-cloud, release, api]
|
||||
hide_table_of_contents: true
|
||||
---
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
title: "How We Built Time-Aware Spreading Activation for Memory Graphs"
|
||||
authors: [chrislatimer]
|
||||
date: 2026-03-12
|
||||
date: 2026-03-12T12:00
|
||||
tags: [retrieval, graph, temporal, spreading-activation, memory]
|
||||
image: /img/blog/spreading-activation-memory-graphs.png
|
||||
---
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
title: "How We Built Disposition-Aware Agents That Actually Think Differently"
|
||||
authors: [chrislatimer]
|
||||
date: 2026-03-13
|
||||
date: 2026-03-13T12:00
|
||||
tags: [disposition, personality, skepticism, empathy, reflect, agents]
|
||||
image: /img/blog/disposition-aware-agents.png
|
||||
---
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
title: "What's new in Hindsight 0.4.18"
|
||||
description: New features and improvements in Hindsight 0.4.18
|
||||
authors: [nicoloboschi]
|
||||
date: 2026-03-13
|
||||
date: 2026-03-13T12:00
|
||||
hide_table_of_contents: true
|
||||
image: /img/blog/release0418.png
|
||||
---
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
title: "Give the Only Self-Improving AI Agent (Hermes) a Memory Upgrade It Deserves"
|
||||
authors: [benfrank241]
|
||||
date: 2026-03-17
|
||||
date: 2026-03-17T12:00
|
||||
tags: [hermes, agents, python, memory, tutorial, plugin]
|
||||
image: /img/blog/hermes-agent-memory.png
|
||||
---
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
title: "I Built a Chatbot That Never Forgets — In 80 Lines of Python"
|
||||
authors: [benfrank241]
|
||||
date: 2026-03-17
|
||||
date: 2026-03-17T12:00
|
||||
tags: [streamlit, tutorial, python, memory, chatbot, web-ui]
|
||||
slug: python-chatbot-memory-streamlit
|
||||
image: /img/blog/streamlit-chatbot-memory.png
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
title: "What's new in Hindsight 0.4.19"
|
||||
description: New features and improvements in Hindsight 0.4.19
|
||||
authors: [nicoloboschi]
|
||||
date: 2026-03-18
|
||||
date: 2026-03-18T12:00
|
||||
hide_table_of_contents: true
|
||||
image: /img/blog/release0419.jpg
|
||||
---
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ slug: sandboxed-agent-persistent-memory-nemoclaw
|
|||
title: "Give NemoClaw the Best Agent Memory Available In One Command"
|
||||
description: Add persistent memory to a NemoClaw sandboxed AI agent without changing code. One command, one network policy, memories survive across sessions.
|
||||
authors: [hindsight]
|
||||
date: 2026-03-19
|
||||
date: 2026-03-19T12:00
|
||||
image: /img/blog/2026-03-19/nemoclaw-memory.png
|
||||
hide_table_of_contents: true
|
||||
---
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
title: "Agent Memory Benchmark: A Manifesto"
|
||||
authors: [nicoloboschi]
|
||||
date: 2026-03-23
|
||||
date: 2026-03-23T12:00
|
||||
tags: [benchmark, memory, agents, evaluation, longmemeval, locomo, open-source]
|
||||
image: /img/blog/amb/explorer-0.png
|
||||
hide_table_of_contents: true
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
title: "OpenClaude: Build a Claude Code Agent with Long-Term Memory — and Take It Everywhere"
|
||||
authors: [fabioscarsi, nicoloboschi]
|
||||
date: 2026-03-25
|
||||
date: 2026-03-23T12:00
|
||||
tags: [claude-code, telegram, hindsight, memory, mcp, agents, tutorial]
|
||||
image: /img/blog/claude-code-telegram.png
|
||||
hide\_table\_of\_contents: true
|
||||
|
|
|
|||
259
hindsight-docs/blog/2026-03-24-langgraph-longterm-memory.md
Normal file
259
hindsight-docs/blog/2026-03-24-langgraph-longterm-memory.md
Normal file
|
|
@ -0,0 +1,259 @@
|
|||
---
|
||||
title: "Adding Long-Term Memory to LangGraph and LangChain Agents"
|
||||
description: Learn how to add long-term memory to LangGraph and LangChain agents using three integration patterns — tools, nodes, and BaseStore — with per-user memory banks and semantic recall.
|
||||
authors: [DK09876]
|
||||
date: 2026-03-24T12:00
|
||||
tags: [langgraph, langchain, integrations, agents, memory]
|
||||
image: /img/blog/langgraph-longterm-memory.png
|
||||
hide_table_of_contents: true
|
||||
---
|
||||
|
||||

|
||||
|
||||
LangGraph agents are stateful by design — checkpointers save graph state between steps, and the Store API persists data across threads. But neither gives agents true long-term memory: the ability to extract meaning from conversations, build up knowledge over time, and recall it semantically when relevant.
|
||||
|
||||
That's what Hindsight adds. Hindsight is a memory layer for LLM applications that automatically extracts facts from conversations, builds entity graphs, and retrieves relevant context using four parallel recall strategies. The `hindsight-langgraph` package brings that to LangGraph — and since the memory tools are standard LangChain `@tool` functions, they work with plain LangChain too.
|
||||
|
||||
<!-- truncate -->
|
||||
|
||||
## The problem
|
||||
|
||||
LangGraph's built-in persistence is designed for graph state — checkpoints, intermediate values, cross-thread key-value storage. It's good at "what did this graph do last time?" but not at "what does this agent know about this user?"
|
||||
|
||||
Consider a support agent that talks to the same customer across dozens of sessions. With checkpointers alone, each new thread starts cold. With `InMemoryStore` or `PostgresStore`, you can manually store and retrieve facts, but you're responsible for:
|
||||
|
||||
- Deciding what to store (fact extraction)
|
||||
- Deciding what's relevant (semantic retrieval)
|
||||
- Handling contradictions and updates
|
||||
- Building knowledge graphs from raw conversations
|
||||
|
||||
Hindsight does all of this automatically. You retain conversations, and it extracts facts, builds entity graphs, and retrieves relevant memories using four parallel strategies: **semantic** (embedding similarity), **BM25** (keyword overlap), **graph traversal** (entity relationships), and **temporal** (recency weighting). Each strategy catches different things — semantic recall finds conceptually similar memories, graph traversal finds memories linked through shared entities, and temporal weighting surfaces recent context before older facts. Together they substantially outperform single-strategy retrieval.
|
||||
|
||||
## Three integration patterns
|
||||
|
||||
We built three ways to add Hindsight memory to LangGraph, at different abstraction levels.
|
||||
|
||||
### 1. Tools — the agent decides (LangChain & LangGraph)
|
||||
|
||||
Give the agent retain/recall/reflect tools and let it decide when to use memory. These are standard LangChain `@tool` functions, so they work with both LangGraph (via `create_react_agent`) and plain LangChain (via `bind_tools()`).
|
||||
|
||||
```python
|
||||
from hindsight_client import Hindsight
|
||||
from hindsight_langgraph import create_hindsight_tools
|
||||
from langchain_openai import ChatOpenAI
|
||||
from langgraph.prebuilt import create_react_agent
|
||||
|
||||
client = Hindsight(base_url="http://localhost:8888")
|
||||
tools = create_hindsight_tools(client=client, bank_id="user-123")
|
||||
|
||||
# With LangGraph
|
||||
agent = create_react_agent(ChatOpenAI(model="gpt-4o"), tools=tools)
|
||||
|
||||
# Or with plain LangChain
|
||||
model = ChatOpenAI(model="gpt-4o").bind_tools(tools)
|
||||
```
|
||||
|
||||
The agent gets three tools:
|
||||
|
||||
- **`hindsight_retain`** — stores the conversation and extracts facts from it
|
||||
- **`hindsight_recall`** — searches the memory bank for relevant context
|
||||
- **`hindsight_reflect`** — synthesizes across multiple memories to produce a summary or answer a question about what the agent knows (useful for questions like "what has this user told me about their stack?")
|
||||
|
||||
The agent calls these based on conversation context — storing facts when the user shares something important, recalling when asked about past context, and reflecting when it needs to synthesize accumulated knowledge.
|
||||
|
||||
**Best for**: ReAct agents that need to reason about when memory is relevant. Works with LangGraph for automatic tool execution loops or with plain LangChain if you manage the loop yourself.
|
||||
|
||||
### 2. Nodes — memory as graph steps
|
||||
|
||||
Add recall and retain as automatic nodes in your graph. No tool-calling required — memory runs on every turn.
|
||||
|
||||
```python
|
||||
from hindsight_langgraph import create_recall_node, create_retain_node
|
||||
from langgraph.graph import StateGraph, MessagesState, START, END
|
||||
|
||||
recall = create_recall_node(client=client, bank_id_from_config="user_id")
|
||||
retain = create_retain_node(client=client, bank_id_from_config="user_id")
|
||||
|
||||
builder = StateGraph(MessagesState)
|
||||
builder.add_node("recall", recall)
|
||||
builder.add_node("agent", agent_node)
|
||||
builder.add_node("retain", retain)
|
||||
builder.add_edge(START, "recall")
|
||||
builder.add_edge("recall", "agent")
|
||||
builder.add_edge("agent", "retain")
|
||||
builder.add_edge("retain", END)
|
||||
```
|
||||
|
||||
The recall node runs before the LLM, searches Hindsight for memories relevant to the user's message, and injects them as a `SystemMessage`. The retain node runs after, storing the conversation. Both resolve per-user bank IDs from `RunnableConfig` at runtime.
|
||||
|
||||
**Best for**: Agents where you always want memory context injected automatically, without relying on the LLM to decide when to use memory tools.
|
||||
|
||||
### 3. BaseStore — drop-in backend
|
||||
|
||||
Replace LangGraph's `InMemoryStore` with Hindsight as the storage backend. If your team already uses LangGraph's store patterns, this is the lowest-friction path.
|
||||
|
||||
```python
|
||||
from hindsight_langgraph import HindsightStore
|
||||
|
||||
store = HindsightStore(client=client)
|
||||
graph = builder.compile(checkpointer=checkpointer, store=store)
|
||||
```
|
||||
|
||||
Namespace tuples map to Hindsight bank IDs (`("user", "123")` → bank `user.123`), banks are auto-created, and `search()` uses Hindsight's full semantic recall instead of basic vector similarity.
|
||||
|
||||
**Best for**: Teams already using LangGraph's `store` patterns who want better retrieval without restructuring their graph.
|
||||
|
||||
---
|
||||
|
||||
### Which pattern fits your use case?
|
||||
|
||||
| | Tools | Nodes | BaseStore |
|
||||
|---|---|---|---|
|
||||
| Works with plain LangChain | Yes | No | No |
|
||||
| Memory runs automatically | No (LLM decides) | Yes | Yes |
|
||||
| Uses existing store interface | No | No | Yes |
|
||||
| LLM controls when to remember | Yes | No | No |
|
||||
| Lowest migration cost | — | Low | Lowest |
|
||||
|
||||
---
|
||||
|
||||
## Complete working example
|
||||
|
||||
Here's a full support agent that remembers each user across sessions using the nodes pattern. This is copy-pasteable and runnable against either self-hosted Hindsight or Hindsight Cloud.
|
||||
|
||||
```python
|
||||
import asyncio
|
||||
from hindsight_client import Hindsight
|
||||
from hindsight_langgraph import create_recall_node, create_retain_node
|
||||
from langchain_openai import ChatOpenAI
|
||||
from langchain_core.messages import HumanMessage, SystemMessage
|
||||
from langgraph.graph import StateGraph, MessagesState, START, END
|
||||
from langgraph.checkpoint.memory import MemorySaver
|
||||
|
||||
# --- Setup ---
|
||||
|
||||
client = Hindsight(base_url="http://localhost:8888")
|
||||
# For Hindsight Cloud:
|
||||
# client = Hindsight(base_url="https://api.hindsight.vectorize.io", api_key="...")
|
||||
|
||||
llm = ChatOpenAI(model="gpt-4o")
|
||||
checkpointer = MemorySaver()
|
||||
|
||||
# --- Memory nodes ---
|
||||
# bank_id_from_config pulls the user ID from RunnableConfig at runtime,
|
||||
# so one graph definition serves all users with isolated memory banks.
|
||||
|
||||
recall = create_recall_node(client=client, bank_id_from_config="user_id")
|
||||
retain = create_retain_node(client=client, bank_id_from_config="user_id")
|
||||
|
||||
# --- Agent node ---
|
||||
|
||||
async def agent_node(state: MessagesState):
|
||||
system = SystemMessage(content=(
|
||||
"You are a helpful support agent. "
|
||||
"Relevant memories about this user have been injected above. "
|
||||
"Use them to personalize your response."
|
||||
))
|
||||
response = await llm.ainvoke([system] + state["messages"])
|
||||
return {"messages": [response]}
|
||||
|
||||
# --- Graph ---
|
||||
|
||||
builder = StateGraph(MessagesState)
|
||||
builder.add_node("recall", recall)
|
||||
builder.add_node("agent", agent_node)
|
||||
builder.add_node("retain", retain)
|
||||
builder.add_edge(START, "recall")
|
||||
builder.add_edge("recall", "agent")
|
||||
builder.add_edge("agent", "retain")
|
||||
builder.add_edge("retain", END)
|
||||
|
||||
graph = builder.compile(checkpointer=checkpointer)
|
||||
|
||||
# --- Run ---
|
||||
|
||||
async def chat(user_id: str, thread_id: str, message: str):
|
||||
config = {
|
||||
"configurable": {
|
||||
"user_id": user_id,
|
||||
"thread_id": thread_id,
|
||||
}
|
||||
}
|
||||
result = await graph.ainvoke(
|
||||
{"messages": [HumanMessage(content=message)]},
|
||||
config=config,
|
||||
)
|
||||
return result["messages"][-1].content
|
||||
|
||||
|
||||
async def main():
|
||||
# Session 1: user shares context
|
||||
print("Session 1")
|
||||
print(await chat("user-42", "thread-1", "Hi! I'm running into issues with our Postgres connection pool. We're on SQLAlchemy 2.0."))
|
||||
print(await chat("user-42", "thread-1", "We're using async sessions with asyncpg. The pool keeps exhausting under load."))
|
||||
|
||||
# Session 2: new thread, same user — agent remembers
|
||||
print("\nSession 2 (new thread)")
|
||||
print(await chat("user-42", "thread-2", "Hey, back again. Still fighting the connection pool issue."))
|
||||
# Agent recalls SQLAlchemy 2.0, asyncpg, and the pool exhaustion context
|
||||
# without the user having to repeat themselves.
|
||||
|
||||
|
||||
asyncio.run(main())
|
||||
```
|
||||
|
||||
What Hindsight extracts from Session 1 and stores in `user-42`'s memory bank:
|
||||
|
||||
```
|
||||
- Uses SQLAlchemy 2.0 with async sessions
|
||||
- Uses asyncpg driver
|
||||
- Experiencing connection pool exhaustion under load
|
||||
- Running Postgres
|
||||
```
|
||||
|
||||
When Session 2 starts on a fresh thread, the recall node searches the memory bank for context relevant to "Still fighting the connection pool issue" and injects those facts as a `SystemMessage` before the LLM responds. The agent picks up exactly where the last session ended.
|
||||
|
||||
---
|
||||
|
||||
## Per-user memory in one line
|
||||
|
||||
All three patterns support dynamic bank IDs. Instead of hardcoding a bank, resolve it from the graph's config at runtime:
|
||||
|
||||
```python
|
||||
recall = create_recall_node(client=client, bank_id_from_config="user_id")
|
||||
|
||||
# Each invocation gets its own isolated memory bank
|
||||
await graph.ainvoke(
|
||||
{"messages": [...]},
|
||||
config={"configurable": {"user_id": "user-456"}},
|
||||
)
|
||||
```
|
||||
|
||||
One graph definition serves all users. Memory banks are created automatically and kept fully isolated.
|
||||
|
||||
## Getting started
|
||||
|
||||
```bash
|
||||
pip install hindsight-langgraph
|
||||
```
|
||||
|
||||
Works with both self-hosted Hindsight and [Hindsight Cloud](https://ui.hindsight.vectorize.io/signup). For cloud, pass your API key when creating the client:
|
||||
|
||||
```python
|
||||
client = Hindsight(base_url="https://api.hindsight.vectorize.io", api_key="your-key")
|
||||
# or
|
||||
from hindsight_client import configure
|
||||
configure(api_key="your-key") # defaults to the cloud URL
|
||||
```
|
||||
|
||||
## What to build with this
|
||||
|
||||
Long-term memory unlocks a different class of agent behavior. A few patterns we've seen work well:
|
||||
|
||||
- **Support agents** that remember each customer's history, preferences, and past issues across sessions
|
||||
- **Sales assistants** that accumulate context about prospects over multiple touchpoints
|
||||
- **Personal productivity agents** that build up a model of a user's work style, priorities, and decisions
|
||||
|
||||
In all three cases, the agent gets meaningfully better the longer it runs — not just because of a longer context window, but because Hindsight distills conversations into structured knowledge it can retrieve precisely when relevant.
|
||||
|
||||
Full docs: [LangGraph integration](/sdks/integrations/langgraph) | [GitHub](https://github.com/vectorize-io/hindsight/tree/main/hindsight-integrations/langgraph)
|
||||
|
|
@ -20,6 +20,12 @@ chrislatimer:
|
|||
url: https://github.com/chrislatimer
|
||||
image_url: https://github.com/chrislatimer.png
|
||||
|
||||
DK09876:
|
||||
name: DK09876
|
||||
title: Hindsight Team
|
||||
url: https://github.com/DK09876
|
||||
image_url: https://github.com/DK09876.png
|
||||
|
||||
fabioscarsi:
|
||||
name: Fabio Scarsi
|
||||
title: Contributor
|
||||
|
|
|
|||
BIN
hindsight-docs/static/img/blog/langgraph-longterm-memory.png
Normal file
BIN
hindsight-docs/static/img/blog/langgraph-longterm-memory.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 309 KiB |
Loading…
Reference in a new issue