|
129 | 129 | "metadata": {},
|
130 | 130 | "outputs": [],
|
131 | 131 | "source": [
|
132 |
| - "from langgraph.store.memory import InMemoryStore\n", |
133 | 132 | "from langchain_openai import OpenAIEmbeddings\n",
|
| 133 | + "from langgraph.store.redis import RedisStore\n", |
| 134 | + "from langgraph.store.base import IndexConfig\n", |
134 | 135 | "\n",
|
135 |
| - "in_memory_store = InMemoryStore(\n", |
136 |
| - " index={\n", |
137 |
| - " \"embed\": OpenAIEmbeddings(model=\"text-embedding-3-small\"),\n", |
138 |
| - " \"dims\": 1536,\n", |
139 |
| - " }\n", |
140 |
| - ")" |
| 136 | + "# Set up Redis connection\n", |
| 137 | + "REDIS_URI = \"redis://redis:6379\"\n", |
| 138 | + "\n", |
| 139 | + "# Create index configuration for vector search\n", |
| 140 | + "index_config: IndexConfig = {\n", |
| 141 | + " \"dims\": 1536,\n", |
| 142 | + " \"embed\": OpenAIEmbeddings(model=\"text-embedding-3-small\"),\n", |
| 143 | + " \"ann_index_config\": {\n", |
| 144 | + " \"vector_type\": \"vector\",\n", |
| 145 | + " },\n", |
| 146 | + " \"distance_type\": \"cosine\",\n", |
| 147 | + "}\n", |
| 148 | + "\n", |
| 149 | + "# Initialize the Redis store\n", |
| 150 | + "redis_store = None\n", |
| 151 | + "with RedisStore.from_conn_string(REDIS_URI, index=index_config) as s:\n", |
| 152 | + " s.setup()\n", |
| 153 | + " redis_store = s" |
141 | 154 | ]
|
142 | 155 | },
|
143 | 156 | {
|
|
153 | 166 | "execution_count": 4,
|
154 | 167 | "id": "2a30a362-528c-45ee-9df6-630d2d843588",
|
155 | 168 | "metadata": {},
|
156 |
| - "outputs": [], |
| 169 | + "outputs": [ |
| 170 | + { |
| 171 | + "name": "stdout", |
| 172 | + "output_type": "stream", |
| 173 | + "text": [ |
| 174 | + "21:40:15 redisvl.index.index INFO Index already exists, not overwriting.\n", |
| 175 | + "21:40:15 redisvl.index.index INFO Index already exists, not overwriting.\n", |
| 176 | + "21:40:15 redisvl.index.index INFO Index already exists, not overwriting.\n" |
| 177 | + ] |
| 178 | + } |
| 179 | + ], |
157 | 180 | "source": [
|
158 | 181 | "import uuid\n",
|
159 | 182 | "from typing import Annotated\n",
|
|
162 | 185 | "from langchain_anthropic import ChatAnthropic\n",
|
163 | 186 | "from langchain_core.runnables import RunnableConfig\n",
|
164 | 187 | "from langgraph.graph import StateGraph, MessagesState, START\n",
|
165 |
| - "from langgraph.checkpoint.memory import MemorySaver\n", |
| 188 | + "from langgraph.checkpoint.redis import RedisSaver\n", |
166 | 189 | "from langgraph.store.base import BaseStore\n",
|
167 | 190 | "\n",
|
168 | 191 | "\n",
|
|
194 | 217 | "builder.add_node(\"call_model\", call_model)\n",
|
195 | 218 | "builder.add_edge(START, \"call_model\")\n",
|
196 | 219 | "\n",
|
| 220 | + "# Set up Redis connection for checkpointer\n", |
| 221 | + "REDIS_URI = \"redis://redis:6379\"\n", |
| 222 | + "checkpointer = None\n", |
| 223 | + "with RedisSaver.from_conn_string(REDIS_URI) as cp:\n", |
| 224 | + " cp.setup()\n", |
| 225 | + " checkpointer = cp\n", |
| 226 | + "\n", |
197 | 227 | "# NOTE: we're passing the store object here when compiling the graph\n",
|
198 |
| - "graph = builder.compile(checkpointer=MemorySaver(), store=in_memory_store)\n", |
| 228 | + "graph = builder.compile(checkpointer=checkpointer, store=redis_store)\n", |
199 | 229 | "# If you're using LangGraph Cloud or LangGraph Studio, you don't need to pass the store or checkpointer when compiling the graph, since it's done automatically."
|
200 | 230 | ]
|
201 | 231 | },
|
|
243 | 273 | "Hi! Remember: my name is Bob\n",
|
244 | 274 | "==================================\u001b[1m Ai Message \u001b[0m==================================\n",
|
245 | 275 | "\n",
|
246 |
| - "Hello Bob! It's nice to meet you. I'll remember that your name is Bob. How can I assist you today?\n" |
| 276 | + "Hello Bob! It's great to meet you. I'll remember that your name is Bob for our conversation. Is there anything specific you'd like to chat about or any questions you have? I'm here to help with information or discussion on a wide range of topics.\n" |
247 | 277 | ]
|
248 | 278 | }
|
249 | 279 | ],
|
|
285 | 315 | "id": "80fd01ec-f135-4811-8743-daff8daea422",
|
286 | 316 | "metadata": {},
|
287 | 317 | "source": [
|
288 |
| - "We can now inspect our in-memory store and verify that we have in fact saved the memories for the user:" |
| 318 | + "We can now inspect our Redis store and verify that we have in fact saved the memories for the user:" |
289 | 319 | ]
|
290 | 320 | },
|
291 | 321 | {
|
|
303 | 333 | }
|
304 | 334 | ],
|
305 | 335 | "source": [
|
306 |
| - "for memory in in_memory_store.search((\"memories\", \"1\")):\n", |
| 336 | + "for memory in redis_store.search((\"memories\", \"1\")):\n", |
307 | 337 | " print(memory.value)"
|
308 | 338 | ]
|
309 | 339 | },
|
|
330 | 360 | "what is my name?\n",
|
331 | 361 | "==================================\u001b[1m Ai Message \u001b[0m==================================\n",
|
332 | 362 | "\n",
|
333 |
| - "I apologize, but I don't have any information about your name. As an AI assistant, I don't have access to personal information about users unless it's specifically provided in our conversation. If you'd like, you can tell me your name and I'll be happy to use it in our discussion.\n" |
| 363 | + "I apologize, but I don't have any information about your name. As an AI language model, I don't have access to personal information about users unless it has been explicitly provided in the conversation. If you'd like, you can tell me your name, and I'll be happy to use it in our conversation.\n" |
334 | 364 | ]
|
335 | 365 | }
|
336 | 366 | ],
|
|
0 commit comments