diff --git a/notebooks/06-langgraph-react-agent.ipynb b/notebooks/06-langgraph-react-agent.ipynb index 7f050b4..36194f1 100644 --- a/notebooks/06-langgraph-react-agent.ipynb +++ b/notebooks/06-langgraph-react-agent.ipynb @@ -8,9 +8,18 @@ "\n", "Build a ReAct agent with LangGraph that remembers user preferences and past interactions across conversations using Hindsight memory.\n", "\n", - "This notebook demonstrates two patterns:\n", + "This notebook demonstrates three patterns:\n", "- **Tools pattern**: The agent decides when to store/retrieve memories\n", "- **Nodes pattern**: Memory injection and storage happen automatically as graph steps\n", + "- **Memory Instructions pattern**: Pre-fetch memories into a system prompt for standalone LangChain use (no graph needed)\n", + "\n", + "## Which pattern should I use?\n", + "\n", + "| Pattern | Best for | Requires LangGraph? |\n", + "|---------|----------|---------------------|\n", + "| **Tools** | ReAct agents that reason about when memory is relevant | No (works with any LangChain ChatModel) |\n", + "| **Nodes** | Graphs where you always want memory context, no LLM decision needed | Yes |\n", + "| **Memory Instructions** | Simple chains, standalone LangChain, or any context where you want a memory-enriched system prompt | No |\n", "\n", "## Prerequisites\n", "\n", @@ -378,6 +387,80 @@ "print(result[\"messages\"][-1].content)" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Pattern 3: Memory Instructions — Standalone LangChain\n", + "\n", + "Use `memory_instructions()` to pre-fetch memories and inject them into a system prompt. This works with any LangChain model — no LangGraph graph needed.\n", + "\n", + "Best when you want memory context in a simple chain or don't need the agent to decide when to use memory." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Create the Instructions Function" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from hindsight_langgraph import memory_instructions\n", + "\n", + "# memory_instructions() returns an async callable that recalls memories\n", + "# and appends them to your base instructions. If recall fails or returns\n", + "# nothing, it gracefully falls back to base_instructions alone.\n", + "get_instructions = memory_instructions(\n", + " client=client,\n", + " bank_id=\"user-alice\", # Reuse Alice's bank from Pattern 1\n", + " base_instructions=(\n", + " \"You are a helpful assistant with long-term memory. \"\n", + " \"Use what you know about the user to personalize your responses.\"\n", + " ),\n", + " budget=\"mid\",\n", + " max_results=5,\n", + ")\n", + "\n", + "# Fetch instructions with memories injected\n", + "instructions = await get_instructions()\n", + "print(\"Instructions with memories:\")\n", + "print(instructions)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Use in a Simple LangChain Call\n", + "\n", + "No graph, no tools — just a model call with memory-enriched instructions." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from langchain_openai import ChatOpenAI\n", + "\n", + "model = ChatOpenAI(model=\"gpt-4o-mini\")\n", + "\n", + "# Each call to get_instructions() re-fetches memories, so it stays up to date\n", + "instructions = await get_instructions()\n", + "response = await model.ainvoke([\n", + " {\"role\": \"system\", \"content\": instructions},\n", + " {\"role\": \"user\", \"content\": \"What programming language and IDE do I use?\"},\n", + "])\n", + "print(response.content)" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -404,6 +487,7 @@ "\n", "- **Tools pattern**: The agent decides when to store/retrieve. Best for complex reasoning flows.\n", "- **Nodes pattern**: Memory happens automatically. Best when you always want context injection.\n", + "- **Memory Instructions**: Pre-fetches memories into a system prompt. Best for standalone LangChain or simple chains.\n", "- **Dynamic banks**: Use `bank_id_from_config` or parameterized `bank_id` for per-user isolation.\n", "- **Tags**: Scope memories by source, conversation, or topic for precise recall.\n", "\n",