{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": "# Hindsight-OpenAI Tutorial\n\n**A drop-in replacement for the OpenAI Python client with automatic memory integration**\n\n## What is Hindsight-OpenAI?\n\n`hindsight-openai` is a transparent wrapper around the official OpenAI Python client that automatically:\n\n- 🧠 **Injects relevant memories** from your Hindsight system into conversations\n- šŸ’¾ **Stores conversation history** to Hindsight for future retrieval \n- šŸ”„ **Works seamlessly** with existing OpenAI code (just change the import)\n- ⚔ **Supports both sync and async** clients\n\n## Why Use It?\n\n### The Problem\n\nAI assistants typically have no memory of previous conversations. Each interaction starts fresh, requiring you to:\n- Repeat context manually\n- Copy-paste relevant information\n- Build custom RAG pipelines\n- Manage conversation history yourself\n\n### The Solution\n\nHindsight-OpenAI gives your AI **automatic long-term memory**:\n- Remembers past conversations\n- Recalls user preferences and facts\n- Maintains context across sessions\n- Zero code changes to your existing OpenAI usage\n\n## Prerequisites\n\n1. **Hindsight API server running** (see main Hindsight README)\n2. **OpenAI API key** or compatible API (Groq, OpenRouter, etc.)\n3. **Python >= 3.10**" }, { "cell_type": "markdown", "metadata": {}, "source": "## Setup\n\nFirst, let's set up our environment and configure Hindsight integration:" }, { "cell_type": "code", "execution_count": null, "metadata": { "jupyter": { "is_executing": true } }, "outputs": [], "source": "import os\nfrom hindsight_openai import configure, AsyncOpenAI\n\n# Set your API keys\n# Option 1: Use Groq (fast and free)\nGROQ_API_KEY = os.getenv(\"GROQ_API_KEY\", \"your-groq-api-key\")\nif not GROQ_API_KEY:\n raise (\"GROQ_API_KEY not set\") \n\n# Option 2: Use OpenAI\n# OPENAI_API_KEY = os.getenv(\"OPENAI_API_KEY\", \"sk-...\")\n\n# Configure Hindsight integration\nconfigure(\n hindsight_api_url=\"http://localhost:8888\", # Your Hindsight API server\n agent_id=\"tutorial-user\", # Unique ID for this user/agent\n store_conversations=True, # Auto-save conversations\n inject_memories=True, # Auto-inject relevant context\n)\n\nprint(\"āœ“ Hindsight configured successfully!\")\nprint(\"\")\nprint(\"NOTE: This tutorial uses AsyncOpenAI which works perfectly in Jupyter notebooks.\")\nprint(\"For regular Python scripts, you can use the sync OpenAI client instead.\")" }, { "cell_type": "markdown", "metadata": {}, "source": "## Example 1: Basic Usage (No Changes Needed!)\n\nUse the OpenAI client exactly as you normally would. Hindsight works transparently in the background." }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": "# Create client (using Groq's OpenAI-compatible API)\nclient = AsyncOpenAI(\n api_key=GROQ_API_KEY,\n base_url=\"https://api.groq.com/openai/v1\",\n)\n\n# First conversation - establish some facts\nprint(\"=== First Conversation ===\")\nresponse = await client.chat.completions.create(\n model=\"llama-3.1-8b-instant\",\n messages=[\n {\"role\": \"user\", \"content\": \"My name is Alice and I love Python programming!\"}\n ],\n)\n\nprint(f\"Assistant: {response.choices[0].message.content}\\n\")\nprint(\"→ This conversation is now stored in Hindsight!\")" }, { "cell_type": "markdown", "metadata": {}, "source": "## Example 2: Memory Injection in Action\n\nNow ask a question that requires remembering the previous conversation:" }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": "print(\"=== Second Conversation (with memory) ===\")\nresponse = await client.chat.completions.create(\n model=\"llama-3.1-8b-instant\",\n messages=[\n {\"role\": \"user\", \"content\": \"What's my name and what do I like?\"}\n ],\n)\n\nprint(f\"Assistant: {response.choices[0].message.content}\\n\")\nprint(\"→ Hindsight automatically injected relevant memories before this request!\")\nprint(\"→ The AI knew your name and preferences without you repeating them.\")" }, { "cell_type": "markdown", "metadata": {}, "source": "## How It Works\n\nBehind the scenes, Hindsight-OpenAI:\n\n### 1. **Memory Storage**\nAfter each API call:\n- Captures the full conversation context\n- Stores it in Hindsight's semantic memory system\n- Indexes it for fast retrieval\n\n### 2. **Memory Injection**\nBefore each API call:\n- Extracts the user's query\n- Searches Hindsight for relevant past conversations\n- Injects top memories as a system message\n\n### What Gets Sent to OpenAI\n\nWithout Hindsight:\n```python\nmessages = [\n {\"role\": \"user\", \"content\": \"What's my name?\"}\n]\n```\n\nWith Hindsight (automatic):\n```python\nmessages = [\n {\n \"role\": \"system\",\n \"content\": \"Relevant context from your memory:\\n\\n1. User's name is Alice\\n (Date: 2024-11-18)\\n (Type: world)\"\n },\n {\"role\": \"user\", \"content\": \"What's my name?\"}\n]\n```" }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Example 3: Multi-Turn Conversations\n", "\n", "Build up context over multiple interactions:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Conversation 1: Share a preference\n", "print(\"=== Conversation 1: Sharing preferences ===\")\n", "response = await client.chat.completions.create(\n", " model=\"llama-3.1-8b-instant\",\n", " messages=[\n", " {\"role\": \"user\", \"content\": \"I'm working on a machine learning project using PyTorch.\"}\n", " ],\n", ")\n", "print(f\"Assistant: {response.choices[0].message.content}\\n\")\n", "\n", "# Conversation 2: Different topic\n", "print(\"=== Conversation 2: Different topic ===\")\n", "response = await client.chat.completions.create(\n", " model=\"llama-3.1-8b-instant\",\n", " messages=[\n", " {\"role\": \"user\", \"content\": \"I prefer functional programming over OOP.\"}\n", " ],\n", ")\n", "print(f\"Assistant: {response.choices[0].message.content}\\n\")\n", "\n", "# Conversation 3: Ask for recommendations\n", "print(\"=== Conversation 3: Getting personalized advice ===\")\n", "response = await client.chat.completions.create(\n", " model=\"llama-3.1-8b-instant\",\n", " messages=[\n", " {\"role\": \"user\", \"content\": \"Can you recommend a good book for me based on what you know?\"}\n", " ],\n", ")\n", "print(f\"Assistant: {response.choices[0].message.content}\\n\")\n", "print(\"→ The AI used your programming interests and preferences to make recommendations!\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": "## Example 4: Document Grouping\n\nGroup related conversations using `document_id`:" }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": "from hindsight_openai import configure\n\n# Configure with document ID for a specific project\nconfigure(\n hindsight_api_url=\"http://localhost:8888\",\n agent_id=\"tutorial-user\",\n document_id=\"ml-project-2024\", # All conversations tagged with this ID\n)\n\n# All these conversations will be grouped together\nconversations = [\n \"I'm using ResNet for image classification\",\n \"My dataset has 10,000 images\",\n \"Training accuracy is stuck at 65%\",\n]\n\nfor msg in conversations:\n response = await client.chat.completions.create(\n model=\"llama-3.1-8b-instant\",\n messages=[{\"role\": \"user\", \"content\": msg}],\n )\n print(f\"User: {msg}\")\n print(f\"Assistant: {response.choices[0].message.content}\\n\")\n\nprint(\"→ All these conversations are grouped under document 'ml-project-2024'\")" }, { "cell_type": "markdown", "metadata": {}, "source": "## Example 5: Async Support\n\nWorks perfectly with AsyncOpenAI for high-throughput applications:" }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": "from hindsight_openai import AsyncOpenAI\nimport asyncio\n\nasync def async_example():\n # Create async client\n async_client = AsyncOpenAI(\n api_key=GROQ_API_KEY,\n base_url=\"https://api.groq.com/openai/v1\",\n )\n \n # Store a fact\n print(\"=== Storing fact ===\")\n response = await async_client.chat.completions.create(\n model=\"llama-3.1-8b-instant\",\n messages=[{\"role\": \"user\", \"content\": \"My favorite color is blue.\"}],\n )\n print(f\"Assistant: {response.choices[0].message.content}\\n\")\n \n # Query with memory\n print(\"=== Querying with memory ===\")\n response = await async_client.chat.completions.create(\n model=\"llama-3.1-8b-instant\",\n messages=[{\"role\": \"user\", \"content\": \"What's my favorite color?\"}],\n )\n print(f\"Assistant: {response.choices[0].message.content}\\n\")\n\n# Run async example\nawait async_example()\nprint(\"→ Async operations work seamlessly with Hindsight!\")" }, { "cell_type": "markdown", "metadata": {}, "source": "## Configuration Options\n\nFine-tune Hindsight's behavior:" }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": "from hindsight_openai import configure\n\n# Full configuration example\nconfigure(\n hindsight_api_url=\"http://localhost:8888\", # Hindsight API URL\n agent_id=\"my-agent\", # Agent identifier (required)\n api_key=None, # Optional Hindsight API key\n \n # Features\n store_conversations=True, # Store conversations automatically\n inject_memories=True, # Inject memories automatically\n \n # Organization\n document_id=\"session-123\", # Optional document grouping\n \n # Control\n enabled=True, # Master on/off switch\n)\n\nprint(\"Configuration options explained:\")\nprint(\"- store_conversations: Automatically save conversations to Hindsight\")\nprint(\"- inject_memories: Automatically retrieve and inject relevant context\")\nprint(\"- document_id: Group related conversations together\")\nprint(\"- enabled=False: Disable Hindsight without changing code\")" }, { "cell_type": "markdown", "metadata": {}, "source": "## Use Cases\n\n### 1. **Personal AI Assistant**\n- Remembers your preferences, work history, and interests\n- Provides personalized recommendations\n- Maintains context across days/weeks\n\n### 2. **Customer Support Chatbot**\n- Recalls previous support tickets\n- Knows customer preferences and history\n- Provides consistent, context-aware responses\n\n### 3. **Research Assistant**\n- Remembers documents you've discussed\n- Connects related topics from different sessions\n- Builds knowledge over time\n\n### 4. **Code Review Tool**\n- Remembers project architecture decisions\n- Recalls past code review comments\n- Maintains consistency across reviews\n\n## Benefits Summary\n\nāœ… **Zero Code Changes** - Drop-in replacement for OpenAI client \nāœ… **Automatic Context** - No manual RAG pipeline needed \nāœ… **Long-term Memory** - Conversations persist across sessions \nāœ… **Smart Retrieval** - Semantic search finds relevant context \nāœ… **Both Sync/Async** - Works with any OpenAI client pattern \nāœ… **Configurable** - Fine-tune behavior to your needs \nāœ… **Transparent** - Original OpenAI responses unchanged \n\n## Next Steps\n\n- **Explore Hindsight API**: Check out the main Hindsight README for advanced features\n- **Customize Search**: Tune `memory_search_budget` for your use case\n- **Use Document IDs**: Organize conversations by project/session\n- **Try Different Models**: Works with OpenAI, Groq, Ollama, and more\n\n## Resources\n\n- [Hindsight Main README](../README.md) - Core memory system docs\n- [Hindsight-OpenAI README](README.md) - Package documentation\n- [OpenAI API Docs](https://platform.openai.com/docs/api-reference) - Original API reference" } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.11.10" } }, "nbformat": 4, "nbformat_minor": 4 }