From fbcb8a911b626b4373fd4aff9624124e9532987f Mon Sep 17 00:00:00 2001 From: Mason Daugherty Date: Mon, 26 Jan 2026 01:00:16 -0500 Subject: [PATCH] docs: update notebook links and add archival notices for examples (#6720) Addresses some comments in #6682 - Update links in notebooks to point to the new documentation location. - Add archival notices indicating that the examples are no longer updated. - Remove some obsolete notebooks that have been moved to the new documentation. Please comment here if you encounter any issues --- examples/README.md | 2 +- examples/async.ipynb | 33 -- examples/branching.ipynb | 33 -- .../agent-simulation-evaluation.ipynb | 10 +- ...angsmith-agent-simulation-evaluation.ipynb | 10 +- .../information-gather-prompting.ipynb | 10 +- .../langgraph_to_langgraph_cloud.ipynb | 33 -- .../langgraph_code_assistant.ipynb | 10 +- .../langgraph_code_assistant_mistral.ipynb | 419 +++++++++++++- examples/configuration.ipynb | 33 -- examples/create-react-agent-hitl.ipynb | 33 -- examples/create-react-agent-memory.ipynb | 33 -- .../create-react-agent-system-prompt.ipynb | 33 -- examples/create-react-agent.ipynb | 33 -- .../customer-support/customer-support.ipynb | 10 +- examples/extraction/retries.ipynb | 10 +- .../human_in_the_loop/wait-user-input.ipynb | 10 +- examples/input_output_schema.ipynb | 33 -- examples/lats/lats.ipynb | 10 +- examples/llm-compiler/LLMCompiler.ipynb | 10 +- examples/map-reduce.ipynb | 33 -- .../add-summary-conversation-history.ipynb | 33 -- examples/memory/delete-messages.ipynb | 33 -- .../memory/manage-conversation-history.ipynb | 33 -- .../hierarchical_agent_teams.ipynb | 10 +- .../multi-agent-collaboration.ipynb | 10 +- examples/node-retries.ipynb | 33 -- examples/pass-config-to-tools.ipynb | 33 -- examples/pass-run-time-values-to-tools.ipynb | 33 -- examples/pass_private_state.ipynb | 33 -- examples/persistence.ipynb | 33 -- examples/persistence_mongodb.ipynb | 33 -- examples/persistence_postgres.ipynb | 33 -- examples/persistence_redis.ipynb | 33 -- .../plan-and-execute/plan-and-execute.ipynb | 10 +- examples/rag/langgraph_adaptive_rag.ipynb | 8 + .../rag/langgraph_adaptive_rag_cohere.ipynb | 542 +++++++++++++++++- .../rag/langgraph_adaptive_rag_local.ipynb | 8 + examples/rag/langgraph_agentic_rag.ipynb | 14 +- examples/rag/langgraph_crag.ipynb | 8 + examples/rag/langgraph_crag_local.ipynb | 8 + examples/rag/langgraph_self_rag.ipynb | 8 + examples/rag/langgraph_self_rag_local.ipynb | 8 + .../langgraph_self_rag_pinecone_movies.ipynb | 316 +++++++++- examples/react-agent-from-scratch.ipynb | 9 +- examples/react-agent-structured-output.ipynb | 9 +- examples/recursion-limit.ipynb | 33 -- examples/reflection/reflection.ipynb | 10 +- examples/reflexion/reflexion.ipynb | 10 +- examples/rewoo/rewoo.ipynb | 10 +- examples/run-id-langsmith.ipynb | 9 +- examples/self-discover/self-discover.ipynb | 10 +- examples/state-model.ipynb | 33 -- examples/storm/storm.ipynb | 33 -- examples/stream-multiple.ipynb | 33 -- examples/stream-updates.ipynb | 33 -- examples/stream-values.ipynb | 33 -- examples/streaming-content.ipynb | 33 -- ...-from-within-tools-without-langchain.ipynb | 33 -- .../streaming-events-from-within-tools.ipynb | 33 -- examples/streaming-from-final-node.ipynb | 33 -- examples/streaming-subgraphs.ipynb | 33 -- .../streaming-tokens-without-langchain.ipynb | 33 -- examples/streaming-tokens.ipynb | 33 -- examples/subgraph-transform-state.ipynb | 33 -- examples/subgraph.ipynb | 9 +- examples/subgraphs-manage-state.ipynb | 33 -- examples/tool-calling-errors.ipynb | 33 -- examples/tool-calling.ipynb | 9 +- examples/tutorials/sql-agent.ipynb | 10 +- examples/tutorials/tnt-llm/tnt-llm.ipynb | 10 +- examples/usaco/usaco.ipynb | 10 +- examples/visualization.ipynb | 33 -- examples/web-navigation/web_voyager.ipynb | 10 +- libs/langgraph/langgraph/types.py | 16 +- 75 files changed, 1517 insertions(+), 1339 deletions(-) delete mode 100644 examples/async.ipynb delete mode 100644 examples/branching.ipynb delete mode 100644 examples/cloud_examples/langgraph_to_langgraph_cloud.ipynb delete mode 100644 examples/configuration.ipynb delete mode 100644 examples/create-react-agent-hitl.ipynb delete mode 100644 examples/create-react-agent-memory.ipynb delete mode 100644 examples/create-react-agent-system-prompt.ipynb delete mode 100644 examples/create-react-agent.ipynb delete mode 100644 examples/input_output_schema.ipynb delete mode 100644 examples/map-reduce.ipynb delete mode 100644 examples/memory/add-summary-conversation-history.ipynb delete mode 100644 examples/memory/delete-messages.ipynb delete mode 100644 examples/memory/manage-conversation-history.ipynb delete mode 100644 examples/node-retries.ipynb delete mode 100644 examples/pass-config-to-tools.ipynb delete mode 100644 examples/pass-run-time-values-to-tools.ipynb delete mode 100644 examples/pass_private_state.ipynb delete mode 100644 examples/persistence.ipynb delete mode 100644 examples/persistence_mongodb.ipynb delete mode 100644 examples/persistence_postgres.ipynb delete mode 100644 examples/persistence_redis.ipynb delete mode 100644 examples/recursion-limit.ipynb delete mode 100644 examples/state-model.ipynb delete mode 100644 examples/storm/storm.ipynb delete mode 100644 examples/stream-multiple.ipynb delete mode 100644 examples/stream-updates.ipynb delete mode 100644 examples/stream-values.ipynb delete mode 100644 examples/streaming-content.ipynb delete mode 100644 examples/streaming-events-from-within-tools-without-langchain.ipynb delete mode 100644 examples/streaming-events-from-within-tools.ipynb delete mode 100644 examples/streaming-from-final-node.ipynb delete mode 100644 examples/streaming-subgraphs.ipynb delete mode 100644 examples/streaming-tokens-without-langchain.ipynb delete mode 100644 examples/streaming-tokens.ipynb delete mode 100644 examples/subgraph-transform-state.ipynb delete mode 100644 examples/subgraphs-manage-state.ipynb delete mode 100644 examples/tool-calling-errors.ipynb delete mode 100644 examples/visualization.ipynb diff --git a/examples/README.md b/examples/README.md index 4ab3d1dbb..45dcc79c2 100644 --- a/examples/README.md +++ b/examples/README.md @@ -1,3 +1,3 @@ # LangGraph examples -This directory should NOT be used for documentation. All new documentation must be added to `docs/docs/` directory. \ No newline at end of file +This directory is retained purely for archival purposes and is no longer updated. The examples previously found here have been moved to the newly [consolidated LangChain documentation](https://docs.langchain.com/oss/python/langgraph/overview). Please refer to the LangChain docs for the most up-to-date examples and usage guidelines for LangGraph. diff --git a/examples/async.ipynb b/examples/async.ipynb deleted file mode 100644 index 9a641c887..000000000 --- a/examples/async.ipynb +++ /dev/null @@ -1,33 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "23544406", - "metadata": {}, - "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/how-tos/async.ipynb" - ] - } - ], - "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.12.2" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/examples/branching.ipynb b/examples/branching.ipynb deleted file mode 100644 index 4b27bfd35..000000000 --- a/examples/branching.ipynb +++ /dev/null @@ -1,33 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "14f7ca50", - "metadata": {}, - "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/how-tos/branching.ipynb" - ] - } - ], - "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.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/examples/chatbot-simulation-evaluation/agent-simulation-evaluation.ipynb b/examples/chatbot-simulation-evaluation/agent-simulation-evaluation.ipynb index 0b61a48ed..eddf0570b 100644 --- a/examples/chatbot-simulation-evaluation/agent-simulation-evaluation.ipynb +++ b/examples/chatbot-simulation-evaluation/agent-simulation-evaluation.ipynb @@ -5,7 +5,15 @@ "id": "10251c1c", "metadata": {}, "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/tutorials/chatbot-simulation-evaluation/agent-simulation-evaluation.ipynb" + "[This file has been moved](https://github.com/langchain-ai/langgraph/blob/23961cff61a42b52525f3b20b4094d8d2fba1744/docs/docs/tutorials/chatbot-simulation-evaluation/agent-simulation-evaluation.ipynb)" + ] + }, + { + "cell_type": "markdown", + "id": "c5fc63df", + "metadata": {}, + "source": [ + "This directory is retained purely for archival purposes and is no longer updated. The examples previously found here have been moved to the newly [consolidated LangChain documentation](https://docs.langchain.com/oss/python/langgraph/overview)." ] } ], diff --git a/examples/chatbot-simulation-evaluation/langsmith-agent-simulation-evaluation.ipynb b/examples/chatbot-simulation-evaluation/langsmith-agent-simulation-evaluation.ipynb index fa6531b45..9d29ab5a2 100644 --- a/examples/chatbot-simulation-evaluation/langsmith-agent-simulation-evaluation.ipynb +++ b/examples/chatbot-simulation-evaluation/langsmith-agent-simulation-evaluation.ipynb @@ -5,7 +5,15 @@ "id": "a4351a24", "metadata": {}, "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/tutorials/chatbot-simulation-evaluation/langsmith-agent-simulation-evaluation.ipynb" + "[This file has been moved](https://github.com/langchain-ai/langgraph/blob/23961cff61a42b52525f3b20b4094d8d2fba1744/docs/docs/tutorials/chatbot-simulation-evaluation/langsmith-agent-simulation-evaluation.ipynb)" + ] + }, + { + "cell_type": "markdown", + "id": "4cc9af1e", + "metadata": {}, + "source": [ + "This directory is retained purely for archival purposes and is no longer updated. The examples previously found here have been moved to the newly [consolidated LangChain documentation](https://docs.langchain.com/oss/python/langgraph/overview)." ] } ], diff --git a/examples/chatbots/information-gather-prompting.ipynb b/examples/chatbots/information-gather-prompting.ipynb index 719ca2c89..2a9d52aae 100644 --- a/examples/chatbots/information-gather-prompting.ipynb +++ b/examples/chatbots/information-gather-prompting.ipynb @@ -5,7 +5,15 @@ "id": "a9014f94", "metadata": {}, "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/tutorials/chatbots/information-gather-prompting.ipynb" + "[This file has been moved](https://github.com/langchain-ai/langgraph/blob/23961cff61a42b52525f3b20b4094d8d2fba1744/docs/docs/tutorials/chatbots/information-gather-prompting.ipynb)" + ] + }, + { + "cell_type": "markdown", + "id": "f47ce992", + "metadata": {}, + "source": [ + "This directory is retained purely for archival purposes and is no longer updated. The examples previously found here have been moved to the newly [consolidated LangChain documentation](https://docs.langchain.com/oss/python/langgraph/overview)." ] } ], diff --git a/examples/cloud_examples/langgraph_to_langgraph_cloud.ipynb b/examples/cloud_examples/langgraph_to_langgraph_cloud.ipynb deleted file mode 100644 index 0cdef035c..000000000 --- a/examples/cloud_examples/langgraph_to_langgraph_cloud.ipynb +++ /dev/null @@ -1,33 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "2b789e16", - "metadata": {}, - "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/cloud/how-tos/langgraph_to_langgraph_cloud.ipynb" - ] - } - ], - "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.1" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/examples/code_assistant/langgraph_code_assistant.ipynb b/examples/code_assistant/langgraph_code_assistant.ipynb index 530c7de61..3b0c4c9d9 100644 --- a/examples/code_assistant/langgraph_code_assistant.ipynb +++ b/examples/code_assistant/langgraph_code_assistant.ipynb @@ -5,7 +5,15 @@ "id": "1f2f13ca", "metadata": {}, "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/tutorials/code_assistant/langgraph_code_assistant.ipynb" + "[This file has been moved](https://github.com/langchain-ai/langgraph/blob/23961cff61a42b52525f3b20b4094d8d2fba1744/docs/docs/tutorials/code_assistant/langgraph_code_assistant.ipynb)" + ] + }, + { + "cell_type": "markdown", + "id": "5e4c9bfe", + "metadata": {}, + "source": [ + "This directory is retained purely for archival purposes and is no longer updated. The examples previously found here have been moved to the newly [consolidated LangChain documentation](https://docs.langchain.com/oss/python/langgraph/overview)." ] } ], diff --git a/examples/code_assistant/langgraph_code_assistant_mistral.ipynb b/examples/code_assistant/langgraph_code_assistant_mistral.ipynb index 1c666241f..4b5468e26 100644 --- a/examples/code_assistant/langgraph_code_assistant_mistral.ipynb +++ b/examples/code_assistant/langgraph_code_assistant_mistral.ipynb @@ -1,5 +1,13 @@ { "cells": [ + { + "cell_type": "markdown", + "id": "1d38cbab", + "metadata": {}, + "source": [ + "This directory is retained purely for archival purposes and is no longer updated. Please see the newly [consolidated LangChain documentation](https://docs.langchain.com/oss/python/langgraph/overview) for the most current information and resources." + ] + }, { "attachments": { "15d3ac32-cdf3-4800-a30c-f26d828d69c8.png": { @@ -33,7 +41,9 @@ "id": "e501686f-323f-4b87-8f9c-8ba89133078b", "metadata": {}, "outputs": [], - "source": ["! pip install -U langchain_community langchain-mistralai langchain langgraph"] + "source": [ + "! pip install -U langchain_community langchain-mistralai langchain langgraph" + ] }, { "cell_type": "markdown", @@ -51,7 +61,12 @@ "id": "982e4609-86e4-4934-828f-e03d89c20393", "metadata": {}, "outputs": [], - "source": ["import os\n\nos.environ[\"TOKENIZERS_PARALLELISM\"] = \"true\"\nmistral_api_key = os.getenv(\"MISTRAL_API_KEY\") # Ensure this is set"] + "source": [ + "import os\n", + "\n", + "os.environ[\"TOKENIZERS_PARALLELISM\"] = \"true\"\n", + "mistral_api_key = os.getenv(\"MISTRAL_API_KEY\") # Ensure this is set" + ] }, { "cell_type": "markdown", @@ -69,7 +84,12 @@ "id": "37b172d2-3a9d-49a8-898c-22ed0cb45c88", "metadata": {}, "outputs": [], - "source": ["os.environ[\"LANGCHAIN_TRACING_V2\"] = \"true\"\nos.environ[\"LANGCHAIN_ENDPOINT\"] = \"https://api.smith.langchain.com\"\nos.environ[\"LANGCHAIN_API_KEY\"] = \"\"\nos.environ[\"LANGCHAIN_PROJECT\"] = \"Mistral-code-gen-testing\""] + "source": [ + "os.environ[\"LANGCHAIN_TRACING_V2\"] = \"true\"\n", + "os.environ[\"LANGCHAIN_ENDPOINT\"] = \"https://api.smith.langchain.com\"\n", + "os.environ[\"LANGCHAIN_API_KEY\"] = \"\"\n", + "os.environ[\"LANGCHAIN_PROJECT\"] = \"Mistral-code-gen-testing\"" + ] }, { "cell_type": "markdown", @@ -87,7 +107,42 @@ "id": "a188c8ca-c053-4e6d-b7af-38a3b6b371c7", "metadata": {}, "outputs": [], - "source": ["# Select LLM\nfrom langchain_core.prompts import ChatPromptTemplate\nfrom langchain_core.pydantic_v1 import BaseModel, Field\nfrom langchain_mistralai import ChatMistralAI\n\nmistral_model = \"mistral-large-latest\"\nllm = ChatMistralAI(model=mistral_model, temperature=0)\n\n# Prompt\ncode_gen_prompt_claude = ChatPromptTemplate.from_messages(\n [\n (\n \"system\",\n \"\"\"You are a coding assistant. Ensure any code you provide can be executed with all required imports and variables \\n\n defined. Structure your answer: 1) a prefix describing the code solution, 2) the imports, 3) the functioning code block.\n \\n Here is the user question:\"\"\",\n ),\n (\"placeholder\", \"{messages}\"),\n ]\n)\n\n\n# Data model\nclass code(BaseModel):\n \"\"\"Code output\"\"\"\n\n prefix: str = Field(description=\"Description of the problem and approach\")\n imports: str = Field(description=\"Code block import statements\")\n code: str = Field(description=\"Code block not including import statements\")\n description = \"Schema for code solutions to questions about LCEL.\"\n\n\n# LLM\ncode_gen_chain = llm.with_structured_output(code, include_raw=False)"] + "source": [ + "# Select LLM\n", + "from langchain_core.prompts import ChatPromptTemplate\n", + "from langchain_core.pydantic_v1 import BaseModel, Field\n", + "from langchain_mistralai import ChatMistralAI\n", + "\n", + "mistral_model = \"mistral-large-latest\"\n", + "llm = ChatMistralAI(model=mistral_model, temperature=0)\n", + "\n", + "# Prompt\n", + "code_gen_prompt_claude = ChatPromptTemplate.from_messages(\n", + " [\n", + " (\n", + " \"system\",\n", + " \"\"\"You are a coding assistant. Ensure any code you provide can be executed with all required imports and variables \\n\n", + " defined. Structure your answer: 1) a prefix describing the code solution, 2) the imports, 3) the functioning code block.\n", + " \\n Here is the user question:\"\"\",\n", + " ),\n", + " (\"placeholder\", \"{messages}\"),\n", + " ]\n", + ")\n", + "\n", + "\n", + "# Data model\n", + "class code(BaseModel):\n", + " \"\"\"Code output\"\"\"\n", + "\n", + " prefix: str = Field(description=\"Description of the problem and approach\")\n", + " imports: str = Field(description=\"Code block import statements\")\n", + " code: str = Field(description=\"Code block not including import statements\")\n", + " description = \"Schema for code solutions to questions about LCEL.\"\n", + "\n", + "\n", + "# LLM\n", + "code_gen_chain = llm.with_structured_output(code, include_raw=False)" + ] }, { "cell_type": "code", @@ -95,7 +150,10 @@ "id": "9fc0290d-5a04-4514-8664-91f9dbf2da7b", "metadata": {}, "outputs": [], - "source": ["question = \"Write a function for fibonacci.\"\nmessages = [(\"user\", question)]"] + "source": [ + "question = \"Write a function for fibonacci.\"\n", + "messages = [(\"user\", question)]" + ] }, { "cell_type": "code", @@ -114,7 +172,11 @@ "output_type": "execute_result" } ], - "source": ["# Test\nresult = code_gen_chain.invoke(messages)\nresult"] + "source": [ + "# Test\n", + "result = code_gen_chain.invoke(messages)\n", + "result" + ] }, { "cell_type": "markdown", @@ -130,7 +192,28 @@ "id": "183d77b8-f180-4815-b39f-8ef507ec0534", "metadata": {}, "outputs": [], - "source": ["from typing import Annotated, TypedDict\n\nfrom langgraph.graph.message import AnyMessage, add_messages\n\n\nclass GraphState(TypedDict):\n \"\"\"\n Represents the state of our graph.\n\n Attributes:\n error : Binary flag for control flow to indicate whether test error was tripped\n messages : With user question, error messages, reasoning\n generation : Code solution\n iterations : Number of tries\n \"\"\"\n\n error: str\n messages: Annotated[list[AnyMessage], add_messages]\n generation: str\n iterations: int"] + "source": [ + "from typing import Annotated, TypedDict\n", + "\n", + "from langgraph.graph.message import AnyMessage, add_messages\n", + "\n", + "\n", + "class GraphState(TypedDict):\n", + " \"\"\"\n", + " Represents the state of our graph.\n", + "\n", + " Attributes:\n", + " error : Binary flag for control flow to indicate whether test error was tripped\n", + " messages : With user question, error messages, reasoning\n", + " generation : Code solution\n", + " iterations : Number of tries\n", + " \"\"\"\n", + "\n", + " error: str\n", + " messages: Annotated[list[AnyMessage], add_messages]\n", + " generation: str\n", + " iterations: int" + ] }, { "cell_type": "markdown", @@ -146,7 +229,163 @@ "id": "14bc89d1-3ca6-4847-a048-1803e0e4600e", "metadata": {}, "outputs": [], - "source": ["import uuid\n\nfrom langchain_core.pydantic_v1 import BaseModel, Field\n\n### Parameters\nmax_iterations = 3\n\n\n### Nodes\ndef generate(state: GraphState):\n \"\"\"\n Generate a code solution\n\n Args:\n state (dict): The current graph state\n\n Returns:\n state (dict): New key added to state, generation\n \"\"\"\n\n print(\"---GENERATING CODE SOLUTION---\")\n\n # State\n messages = state[\"messages\"]\n iterations = state[\"iterations\"]\n\n # Solution\n code_solution = code_gen_chain.invoke(messages)\n messages += [\n (\n \"assistant\",\n f\"Here is my attempt to solve the problem: {code_solution.prefix} \\n Imports: {code_solution.imports} \\n Code: {code_solution.code}\",\n )\n ]\n\n # Increment\n iterations = iterations + 1\n return {\"generation\": code_solution, \"messages\": messages, \"iterations\": iterations}\n\n\ndef code_check(state: GraphState):\n \"\"\"\n Check code\n\n Args:\n state (dict): The current graph state\n\n Returns:\n state (dict): New key added to state, error\n \"\"\"\n\n print(\"---CHECKING CODE---\")\n\n # State\n messages = state[\"messages\"]\n code_solution = state[\"generation\"]\n iterations = state[\"iterations\"]\n\n # Get solution components\n imports = code_solution.imports\n code = code_solution.code\n\n # Check imports\n try:\n exec(imports)\n except Exception as e:\n print(\"---CODE IMPORT CHECK: FAILED---\")\n error_message = [\n (\n \"user\",\n f\"Your solution failed the import test. Here is the error: {e}. Reflect on this error and your prior attempt to solve the problem. (1) State what you think went wrong with the prior solution and (2) try to solve this problem again. Return the FULL SOLUTION. Use the code tool to structure the output with a prefix, imports, and code block:\",\n )\n ]\n messages += error_message\n return {\n \"generation\": code_solution,\n \"messages\": messages,\n \"iterations\": iterations,\n \"error\": \"yes\",\n }\n\n # Check execution\n try:\n combined_code = f\"{imports}\\n{code}\"\n print(f\"CODE TO TEST: {combined_code}\")\n # Use a shared scope for exec\n global_scope = {}\n exec(combined_code, global_scope)\n except Exception as e:\n print(\"---CODE BLOCK CHECK: FAILED---\")\n error_message = [\n (\n \"user\",\n f\"Your solution failed the code execution test: {e}) Reflect on this error and your prior attempt to solve the problem. (1) State what you think went wrong with the prior solution and (2) try to solve this problem again. Return the FULL SOLUTION. Use the code tool to structure the output with a prefix, imports, and code block:\",\n )\n ]\n messages += error_message\n return {\n \"generation\": code_solution,\n \"messages\": messages,\n \"iterations\": iterations,\n \"error\": \"yes\",\n }\n\n # No errors\n print(\"---NO CODE TEST FAILURES---\")\n return {\n \"generation\": code_solution,\n \"messages\": messages,\n \"iterations\": iterations,\n \"error\": \"no\",\n }\n\n\n### Conditional edges\n\n\ndef decide_to_finish(state: GraphState):\n \"\"\"\n Determines whether to finish.\n\n Args:\n state (dict): The current graph state\n\n Returns:\n str: Next node to call\n \"\"\"\n error = state[\"error\"]\n iterations = state[\"iterations\"]\n\n if error == \"no\" or iterations == max_iterations:\n print(\"---DECISION: FINISH---\")\n return \"end\"\n else:\n print(\"---DECISION: RE-TRY SOLUTION---\")\n return \"generate\"\n\n\n### Utilities\n\n\ndef _print_event(event: dict, _printed: set, max_length=1500):\n current_state = event.get(\"dialog_state\")\n if current_state:\n print(\"Currently in: \", current_state[-1])\n message = event.get(\"messages\")\n if message:\n if isinstance(message, list):\n message = message[-1]\n if message.id not in _printed:\n msg_repr = message.pretty_repr(html=True)\n if len(msg_repr) > max_length:\n msg_repr = msg_repr[:max_length] + \" ... (truncated)\"\n print(msg_repr)\n _printed.add(message.id)"] + "source": [ + "import uuid\n", + "\n", + "from langchain_core.pydantic_v1 import BaseModel, Field\n", + "\n", + "### Parameters\n", + "max_iterations = 3\n", + "\n", + "\n", + "### Nodes\n", + "def generate(state: GraphState):\n", + " \"\"\"\n", + " Generate a code solution\n", + "\n", + " Args:\n", + " state (dict): The current graph state\n", + "\n", + " Returns:\n", + " state (dict): New key added to state, generation\n", + " \"\"\"\n", + "\n", + " print(\"---GENERATING CODE SOLUTION---\")\n", + "\n", + " # State\n", + " messages = state[\"messages\"]\n", + " iterations = state[\"iterations\"]\n", + "\n", + " # Solution\n", + " code_solution = code_gen_chain.invoke(messages)\n", + " messages += [\n", + " (\n", + " \"assistant\",\n", + " f\"Here is my attempt to solve the problem: {code_solution.prefix} \\n Imports: {code_solution.imports} \\n Code: {code_solution.code}\",\n", + " )\n", + " ]\n", + "\n", + " # Increment\n", + " iterations = iterations + 1\n", + " return {\"generation\": code_solution, \"messages\": messages, \"iterations\": iterations}\n", + "\n", + "\n", + "def code_check(state: GraphState):\n", + " \"\"\"\n", + " Check code\n", + "\n", + " Args:\n", + " state (dict): The current graph state\n", + "\n", + " Returns:\n", + " state (dict): New key added to state, error\n", + " \"\"\"\n", + "\n", + " print(\"---CHECKING CODE---\")\n", + "\n", + " # State\n", + " messages = state[\"messages\"]\n", + " code_solution = state[\"generation\"]\n", + " iterations = state[\"iterations\"]\n", + "\n", + " # Get solution components\n", + " imports = code_solution.imports\n", + " code = code_solution.code\n", + "\n", + " # Check imports\n", + " try:\n", + " exec(imports)\n", + " except Exception as e:\n", + " print(\"---CODE IMPORT CHECK: FAILED---\")\n", + " error_message = [\n", + " (\n", + " \"user\",\n", + " f\"Your solution failed the import test. Here is the error: {e}. Reflect on this error and your prior attempt to solve the problem. (1) State what you think went wrong with the prior solution and (2) try to solve this problem again. Return the FULL SOLUTION. Use the code tool to structure the output with a prefix, imports, and code block:\",\n", + " )\n", + " ]\n", + " messages += error_message\n", + " return {\n", + " \"generation\": code_solution,\n", + " \"messages\": messages,\n", + " \"iterations\": iterations,\n", + " \"error\": \"yes\",\n", + " }\n", + "\n", + " # Check execution\n", + " try:\n", + " combined_code = f\"{imports}\\n{code}\"\n", + " print(f\"CODE TO TEST: {combined_code}\")\n", + " # Use a shared scope for exec\n", + " global_scope = {}\n", + " exec(combined_code, global_scope)\n", + " except Exception as e:\n", + " print(\"---CODE BLOCK CHECK: FAILED---\")\n", + " error_message = [\n", + " (\n", + " \"user\",\n", + " f\"Your solution failed the code execution test: {e}) Reflect on this error and your prior attempt to solve the problem. (1) State what you think went wrong with the prior solution and (2) try to solve this problem again. Return the FULL SOLUTION. Use the code tool to structure the output with a prefix, imports, and code block:\",\n", + " )\n", + " ]\n", + " messages += error_message\n", + " return {\n", + " \"generation\": code_solution,\n", + " \"messages\": messages,\n", + " \"iterations\": iterations,\n", + " \"error\": \"yes\",\n", + " }\n", + "\n", + " # No errors\n", + " print(\"---NO CODE TEST FAILURES---\")\n", + " return {\n", + " \"generation\": code_solution,\n", + " \"messages\": messages,\n", + " \"iterations\": iterations,\n", + " \"error\": \"no\",\n", + " }\n", + "\n", + "\n", + "### Conditional edges\n", + "\n", + "\n", + "def decide_to_finish(state: GraphState):\n", + " \"\"\"\n", + " Determines whether to finish.\n", + "\n", + " Args:\n", + " state (dict): The current graph state\n", + "\n", + " Returns:\n", + " str: Next node to call\n", + " \"\"\"\n", + " error = state[\"error\"]\n", + " iterations = state[\"iterations\"]\n", + "\n", + " if error == \"no\" or iterations == max_iterations:\n", + " print(\"---DECISION: FINISH---\")\n", + " return \"end\"\n", + " else:\n", + " print(\"---DECISION: RE-TRY SOLUTION---\")\n", + " return \"generate\"\n", + "\n", + "\n", + "### Utilities\n", + "\n", + "\n", + "def _print_event(event: dict, _printed: set, max_length=1500):\n", + " current_state = event.get(\"dialog_state\")\n", + " if current_state:\n", + " print(\"Currently in: \", current_state[-1])\n", + " message = event.get(\"messages\")\n", + " if message:\n", + " if isinstance(message, list):\n", + " message = message[-1]\n", + " if message.id not in _printed:\n", + " msg_repr = message.pretty_repr(html=True)\n", + " if len(msg_repr) > max_length:\n", + " msg_repr = msg_repr[:max_length] + \" ... (truncated)\"\n", + " print(msg_repr)\n", + " _printed.add(message.id)" + ] }, { "cell_type": "code", @@ -154,7 +393,31 @@ "id": "2dff2209-44c7-4e2c-b607-ba6675f9e45f", "metadata": {}, "outputs": [], - "source": ["from langgraph.checkpoint.memory import InMemorySaver\nfrom langgraph.graph import END, StateGraph, START\n\nbuilder = StateGraph(GraphState)\n\n# Define the nodes\nbuilder.add_node(\"generate\", generate) # generation solution\nbuilder.add_node(\"check_code\", code_check) # check code\n\n# Build graph\nbuilder.add_edge(START, \"generate\")\nbuilder.add_edge(\"generate\", \"check_code\")\nbuilder.add_conditional_edges(\n \"check_code\",\n decide_to_finish,\n {\n \"end\": END,\n \"generate\": \"generate\",\n },\n)\n\nmemory = InMemorySaver()\ngraph = builder.compile(checkpointer=memory)"] + "source": [ + "from langgraph.checkpoint.memory import InMemorySaver\n", + "from langgraph.graph import END, StateGraph, START\n", + "\n", + "builder = StateGraph(GraphState)\n", + "\n", + "# Define the nodes\n", + "builder.add_node(\"generate\", generate) # generation solution\n", + "builder.add_node(\"check_code\", code_check) # check code\n", + "\n", + "# Build graph\n", + "builder.add_edge(START, \"generate\")\n", + "builder.add_edge(\"generate\", \"check_code\")\n", + "builder.add_conditional_edges(\n", + " \"check_code\",\n", + " decide_to_finish,\n", + " {\n", + " \"end\": END,\n", + " \"generate\": \"generate\",\n", + " },\n", + ")\n", + "\n", + "memory = InMemorySaver()\n", + "graph = builder.compile(checkpointer=memory)" + ] }, { "cell_type": "code", @@ -173,7 +436,15 @@ "output_type": "display_data" } ], - "source": ["from IPython.display import Image, display\n\ntry:\n display(Image(graph.get_graph(xray=True).draw_mermaid_png()))\nexcept Exception:\n # This requires some extra dependencies and is optional\n pass"] + "source": [ + "from IPython.display import Image, display\n", + "\n", + "try:\n", + " display(Image(graph.get_graph(xray=True).draw_mermaid_png()))\n", + "except Exception:\n", + " # This requires some extra dependencies and is optional\n", + " pass" + ] }, { "cell_type": "code", @@ -181,7 +452,23 @@ "id": "242aa2f0-2c31-462f-a958-ff9ae0cf7c62", "metadata": {}, "outputs": [], - "source": ["_printed = set()\nthread_id = str(uuid.uuid4())\nconfig = {\n \"configurable\": {\n # Checkpoints are accessed by thread_id\n \"thread_id\": thread_id,\n }\n}\n\nquestion = \"Write a Python program that prints 'Hello, World!' to the console.\"\nevents = graph.stream(\n {\"messages\": [(\"user\", question)], \"iterations\": 0}, config, stream_mode=\"values\"\n)\nfor event in events:\n _print_event(event, _printed)"] + "source": [ + "_printed = set()\n", + "thread_id = str(uuid.uuid4())\n", + "config = {\n", + " \"configurable\": {\n", + " # Checkpoints are accessed by thread_id\n", + " \"thread_id\": thread_id,\n", + " }\n", + "}\n", + "\n", + "question = \"Write a Python program that prints 'Hello, World!' to the console.\"\n", + "events = graph.stream(\n", + " {\"messages\": [(\"user\", question)], \"iterations\": 0}, config, stream_mode=\"values\"\n", + ")\n", + "for event in events:\n", + " _print_event(event, _printed)" + ] }, { "cell_type": "markdown", @@ -199,7 +486,31 @@ "id": "390b2768-f395-4aea-8b0e-9d36212a31ac", "metadata": {}, "outputs": [], - "source": ["_printed = set()\nthread_id = str(uuid.uuid4())\nconfig = {\n \"configurable\": {\n # Checkpoints are accessed by thread_id\n \"thread_id\": thread_id,\n }\n}\n\nquestion = \"\"\"Create a Python program that checks if a given string is a palindrome. A palindrome is a word, phrase, number, or other sequence of characters that reads the same forward and backward (ignoring spaces, punctuation, and capitalization).\n\nRequirements:\nThe program should define a function is_palindrome(s) that takes a string s as input.\nThe function should return True if the string is a palindrome and False otherwise.\nIgnore spaces, punctuation, and case differences when checking for palindromes.\n\nGive an example of it working on an example input word.\"\"\"\n\nevents = graph.stream(\n {\"messages\": [(\"user\", question)], \"iterations\": 0}, config, stream_mode=\"values\"\n)\nfor event in events:\n _print_event(event, _printed)"] + "source": [ + "_printed = set()\n", + "thread_id = str(uuid.uuid4())\n", + "config = {\n", + " \"configurable\": {\n", + " # Checkpoints are accessed by thread_id\n", + " \"thread_id\": thread_id,\n", + " }\n", + "}\n", + "\n", + "question = \"\"\"Create a Python program that checks if a given string is a palindrome. A palindrome is a word, phrase, number, or other sequence of characters that reads the same forward and backward (ignoring spaces, punctuation, and capitalization).\n", + "\n", + "Requirements:\n", + "The program should define a function is_palindrome(s) that takes a string s as input.\n", + "The function should return True if the string is a palindrome and False otherwise.\n", + "Ignore spaces, punctuation, and case differences when checking for palindromes.\n", + "\n", + "Give an example of it working on an example input word.\"\"\"\n", + "\n", + "events = graph.stream(\n", + " {\"messages\": [(\"user\", question)], \"iterations\": 0}, config, stream_mode=\"values\"\n", + ")\n", + "for event in events:\n", + " _print_event(event, _printed)" + ] }, { "cell_type": "markdown", @@ -217,7 +528,26 @@ "id": "0a3f946b-e2f2-44d9-905b-09f36980cf9f", "metadata": {}, "outputs": [], - "source": ["_printed = set()\nthread_id = str(uuid.uuid4())\nconfig = {\n \"configurable\": {\n # Checkpoints are accessed by thread_id\n \"thread_id\": thread_id,\n }\n}\n\nquestion = \"\"\"Write a program that prints the numbers from 1 to 100. \nBut for multiples of three, print \"Fizz\" instead of the number, and for the multiples of five, print \"Buzz\". \nFor numbers which are multiples of both three and five, print \"FizzBuzz\".\"\"\"\n\nevents = graph.stream(\n {\"messages\": [(\"user\", question)], \"iterations\": 0}, config, stream_mode=\"values\"\n)\nfor event in events:\n _print_event(event, _printed)"] + "source": [ + "_printed = set()\n", + "thread_id = str(uuid.uuid4())\n", + "config = {\n", + " \"configurable\": {\n", + " # Checkpoints are accessed by thread_id\n", + " \"thread_id\": thread_id,\n", + " }\n", + "}\n", + "\n", + "question = \"\"\"Write a program that prints the numbers from 1 to 100. \n", + "But for multiples of three, print \"Fizz\" instead of the number, and for the multiples of five, print \"Buzz\". \n", + "For numbers which are multiples of both three and five, print \"FizzBuzz\".\"\"\"\n", + "\n", + "events = graph.stream(\n", + " {\"messages\": [(\"user\", question)], \"iterations\": 0}, config, stream_mode=\"values\"\n", + ")\n", + "for event in events:\n", + " _print_event(event, _printed)" + ] }, { "cell_type": "markdown", @@ -235,7 +565,37 @@ "id": "2bb883df-540b-46ab-9415-fe27db68456f", "metadata": {}, "outputs": [], - "source": ["import uuid\n\n_printed = set()\nthread_id = str(uuid.uuid4())\nconfig = {\n \"configurable\": {\n # Checkpoints are accessed by thread_id\n \"thread_id\": thread_id,\n }\n}\n\nquestion = \"\"\"I want to vectorize a function\n\n frame = np.zeros((out_h, out_w, 3), dtype=np.uint8)\n for i, val1 in enumerate(rows):\n for j, val2 in enumerate(cols):\n for j, val3 in enumerate(ch):\n # Assuming you want to store the pair as tuples in the matrix\n frame[i, j, k] = image[val1, val2, val3]\n\n out.write(np.array(frame))\n\nwith a simple numpy function that does something like this what is it called. Show me a test case with this working.\"\"\"\n\nevents = graph.stream(\n {\"messages\": [(\"user\", question)], \"iterations\": 0}, config, stream_mode=\"values\"\n)\nfor event in events:\n _print_event(event, _printed)"] + "source": [ + "import uuid\n", + "\n", + "_printed = set()\n", + "thread_id = str(uuid.uuid4())\n", + "config = {\n", + " \"configurable\": {\n", + " # Checkpoints are accessed by thread_id\n", + " \"thread_id\": thread_id,\n", + " }\n", + "}\n", + "\n", + "question = \"\"\"I want to vectorize a function\n", + "\n", + " frame = np.zeros((out_h, out_w, 3), dtype=np.uint8)\n", + " for i, val1 in enumerate(rows):\n", + " for j, val2 in enumerate(cols):\n", + " for j, val3 in enumerate(ch):\n", + " # Assuming you want to store the pair as tuples in the matrix\n", + " frame[i, j, k] = image[val1, val2, val3]\n", + "\n", + " out.write(np.array(frame))\n", + "\n", + "with a simple numpy function that does something like this what is it called. Show me a test case with this working.\"\"\"\n", + "\n", + "events = graph.stream(\n", + " {\"messages\": [(\"user\", question)], \"iterations\": 0}, config, stream_mode=\"values\"\n", + ")\n", + "for event in events:\n", + " _print_event(event, _printed)" + ] }, { "cell_type": "markdown", @@ -253,7 +613,34 @@ "id": "ee05da1f-c272-405d-8a7b-552cfc3106e1", "metadata": {}, "outputs": [], - "source": ["_printed = set()\nthread_id = str(uuid.uuid4())\nconfig = {\n \"configurable\": {\n # Checkpoints are accessed by thread_id\n \"thread_id\": thread_id,\n }\n}\n\nquestion = \"\"\"Create a Python program that allows two players to play a game of Tic-Tac-Toe. The game should be played on a 3x3 grid. The program should:\n\n- Allow players to take turns to input their moves.\n- Check for invalid moves (e.g., placing a marker on an already occupied space).\n- Determine and announce the winner or if the game ends in a draw.\n\nRequirements:\n- Use a 2D list to represent the Tic-Tac-Toe board.\n- Use functions to modularize the code.\n- Validate player input.\n- Check for win conditions and draw conditions after each move.\"\"\"\n\nevents = graph.stream(\n {\"messages\": [(\"user\", question)], \"iterations\": 0}, config, stream_mode=\"values\"\n)\nfor event in events:\n _print_event(event, _printed)"] + "source": [ + "_printed = set()\n", + "thread_id = str(uuid.uuid4())\n", + "config = {\n", + " \"configurable\": {\n", + " # Checkpoints are accessed by thread_id\n", + " \"thread_id\": thread_id,\n", + " }\n", + "}\n", + "\n", + "question = \"\"\"Create a Python program that allows two players to play a game of Tic-Tac-Toe. The game should be played on a 3x3 grid. The program should:\n", + "\n", + "- Allow players to take turns to input their moves.\n", + "- Check for invalid moves (e.g., placing a marker on an already occupied space).\n", + "- Determine and announce the winner or if the game ends in a draw.\n", + "\n", + "Requirements:\n", + "- Use a 2D list to represent the Tic-Tac-Toe board.\n", + "- Use functions to modularize the code.\n", + "- Validate player input.\n", + "- Check for win conditions and draw conditions after each move.\"\"\"\n", + "\n", + "events = graph.stream(\n", + " {\"messages\": [(\"user\", question)], \"iterations\": 0}, config, stream_mode=\"values\"\n", + ")\n", + "for event in events:\n", + " _print_event(event, _printed)" + ] }, { "cell_type": "markdown", @@ -271,7 +658,7 @@ "id": "814fc2a4-8e5b-4faa-8f52-3977226bd09a", "metadata": {}, "outputs": [], - "source": [""] + "source": [] } ], "metadata": { diff --git a/examples/configuration.ipynb b/examples/configuration.ipynb deleted file mode 100644 index 93eaf3426..000000000 --- a/examples/configuration.ipynb +++ /dev/null @@ -1,33 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "e9a58c69", - "metadata": {}, - "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/how-tos/configuration.ipynb" - ] - } - ], - "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.9" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/examples/create-react-agent-hitl.ipynb b/examples/create-react-agent-hitl.ipynb deleted file mode 100644 index 113b087ec..000000000 --- a/examples/create-react-agent-hitl.ipynb +++ /dev/null @@ -1,33 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "a1e6efeb", - "metadata": {}, - "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/how-tos/create-react-agent-hitl.ipynb" - ] - } - ], - "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.9" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/examples/create-react-agent-memory.ipynb b/examples/create-react-agent-memory.ipynb deleted file mode 100644 index 621374ca0..000000000 --- a/examples/create-react-agent-memory.ipynb +++ /dev/null @@ -1,33 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "1ef41a89", - "metadata": {}, - "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/how-tos/create-react-agent-memory.ipynb" - ] - } - ], - "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.1" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/examples/create-react-agent-system-prompt.ipynb b/examples/create-react-agent-system-prompt.ipynb deleted file mode 100644 index 12bade9a4..000000000 --- a/examples/create-react-agent-system-prompt.ipynb +++ /dev/null @@ -1,33 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "9e2f7902", - "metadata": {}, - "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/how-tos/create-react-agent-system-prompt.ipynb" - ] - } - ], - "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.1" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/examples/create-react-agent.ipynb b/examples/create-react-agent.ipynb deleted file mode 100644 index 336fbb581..000000000 --- a/examples/create-react-agent.ipynb +++ /dev/null @@ -1,33 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "eb07372e", - "metadata": {}, - "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/how-tos/create-react-agent.ipynb" - ] - } - ], - "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.1" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/examples/customer-support/customer-support.ipynb b/examples/customer-support/customer-support.ipynb index e9d4245cc..449e1180d 100644 --- a/examples/customer-support/customer-support.ipynb +++ b/examples/customer-support/customer-support.ipynb @@ -5,7 +5,15 @@ "id": "a8232bc9", "metadata": {}, "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/tutorials/customer-support/customer-support.ipynb" + "[This file has been moved](https://github.com/langchain-ai/langgraph/blob/23961cff61a42b52525f3b20b4094d8d2fba1744/docs/docs/tutorials/customer-support/customer-support.ipynb)" + ] + }, + { + "cell_type": "markdown", + "id": "63da8671", + "metadata": {}, + "source": [ + "This directory is retained purely for archival purposes and is no longer updated. The examples previously found here have been moved to the newly [consolidated LangChain documentation](https://docs.langchain.com/oss/python/langgraph/overview)." ] } ], diff --git a/examples/extraction/retries.ipynb b/examples/extraction/retries.ipynb index 3c6d92333..7d70839c5 100644 --- a/examples/extraction/retries.ipynb +++ b/examples/extraction/retries.ipynb @@ -5,7 +5,15 @@ "id": "8dbdba5b", "metadata": {}, "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/tutorials/extraction/retries.ipynb" + "[This file has been moved](https://github.com/langchain-ai/langgraph/blob/23961cff61a42b52525f3b20b4094d8d2fba1744/docs/docs/tutorials/extraction/retries.ipynb)" + ] + }, + { + "cell_type": "markdown", + "id": "1d444b7f", + "metadata": {}, + "source": [ + "This directory is retained purely for archival purposes and is no longer updated. The examples previously found here have been moved to the newly [consolidated LangChain documentation](https://docs.langchain.com/oss/python/langgraph/overview)." ] } ], diff --git a/examples/human_in_the_loop/wait-user-input.ipynb b/examples/human_in_the_loop/wait-user-input.ipynb index 5cc0539f6..cac624b23 100644 --- a/examples/human_in_the_loop/wait-user-input.ipynb +++ b/examples/human_in_the_loop/wait-user-input.ipynb @@ -5,7 +5,15 @@ "id": "3ecab357", "metadata": {}, "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/how-tos/human_in_the_loop/wait-user-input.ipynb" + "[This file has been moved](https://github.com/langchain-ai/langgraph/blob/23961cff61a42b52525f3b20b4094d8d2fba1744/docs/docs/how-tos/human_in_the_loop/wait-user-input.ipynb)" + ] + }, + { + "cell_type": "markdown", + "id": "3f2866bd", + "metadata": {}, + "source": [ + "This directory is retained purely for archival purposes and is no longer updated. The examples previously found here have been moved to the newly [consolidated LangChain documentation](https://docs.langchain.com/oss/python/langgraph/overview)." ] } ], diff --git a/examples/input_output_schema.ipynb b/examples/input_output_schema.ipynb deleted file mode 100644 index 31977d817..000000000 --- a/examples/input_output_schema.ipynb +++ /dev/null @@ -1,33 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "fc0793cb", - "metadata": {}, - "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/how-tos/input_output_schema.ipynb" - ] - } - ], - "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.1" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/examples/lats/lats.ipynb b/examples/lats/lats.ipynb index 0ba9dea76..e3b7c93ab 100644 --- a/examples/lats/lats.ipynb +++ b/examples/lats/lats.ipynb @@ -5,7 +5,15 @@ "id": "09038b53", "metadata": {}, "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/tutorials/lats/lats.ipynb" + "[This file has been moved](https://github.com/langchain-ai/langgraph/blob/23961cff61a42b52525f3b20b4094d8d2fba1744/docs/docs/tutorials/lats/lats.ipynb)" + ] + }, + { + "cell_type": "markdown", + "id": "b1669748", + "metadata": {}, + "source": [ + "This directory is retained purely for archival purposes and is no longer updated. The examples previously found here have been moved to the newly [consolidated LangChain documentation](https://docs.langchain.com/oss/python/langgraph/overview)." ] } ], diff --git a/examples/llm-compiler/LLMCompiler.ipynb b/examples/llm-compiler/LLMCompiler.ipynb index 100de4f66..d31905ddf 100644 --- a/examples/llm-compiler/LLMCompiler.ipynb +++ b/examples/llm-compiler/LLMCompiler.ipynb @@ -5,7 +5,15 @@ "id": "85205e97", "metadata": {}, "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/tutorials/llm-compiler/LLMCompiler.ipynb" + "[This file has been moved](https://github.com/langchain-ai/langgraph/blob/23961cff61a42b52525f3b20b4094d8d2fba1744/docs/docs/tutorials/llm-compiler/LLMCompiler.ipynb)" + ] + }, + { + "cell_type": "markdown", + "id": "2fdab366", + "metadata": {}, + "source": [ + "This directory is retained purely for archival purposes and is no longer updated. The examples previously found here have been moved to the newly [consolidated LangChain documentation](https://docs.langchain.com/oss/python/langgraph/overview)." ] } ], diff --git a/examples/map-reduce.ipynb b/examples/map-reduce.ipynb deleted file mode 100644 index 60202320a..000000000 --- a/examples/map-reduce.ipynb +++ /dev/null @@ -1,33 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "42abb708", - "metadata": {}, - "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/how-tos/map-reduce.ipynb" - ] - } - ], - "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.9" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/examples/memory/add-summary-conversation-history.ipynb b/examples/memory/add-summary-conversation-history.ipynb deleted file mode 100644 index 4b95ed59e..000000000 --- a/examples/memory/add-summary-conversation-history.ipynb +++ /dev/null @@ -1,33 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "298784f6", - "metadata": {}, - "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/how-tos/memory/add-summary-conversation-history.ipynb" - ] - } - ], - "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.1" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/examples/memory/delete-messages.ipynb b/examples/memory/delete-messages.ipynb deleted file mode 100644 index 2c8dc13ff..000000000 --- a/examples/memory/delete-messages.ipynb +++ /dev/null @@ -1,33 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "3f4370fd", - "metadata": {}, - "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/how-tos/memory/delete-messages.ipynb" - ] - } - ], - "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.9" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/examples/memory/manage-conversation-history.ipynb b/examples/memory/manage-conversation-history.ipynb deleted file mode 100644 index 94535ad6b..000000000 --- a/examples/memory/manage-conversation-history.ipynb +++ /dev/null @@ -1,33 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "6ec7cb13", - "metadata": {}, - "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/how-tos/memory/manage-conversation-history.ipynb" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "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.9" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/examples/multi_agent/hierarchical_agent_teams.ipynb b/examples/multi_agent/hierarchical_agent_teams.ipynb index 3da01d221..f4754a06f 100644 --- a/examples/multi_agent/hierarchical_agent_teams.ipynb +++ b/examples/multi_agent/hierarchical_agent_teams.ipynb @@ -5,7 +5,15 @@ "id": "5cc8a2ad", "metadata": {}, "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/tutorials/multi_agent/hierarchical_agent_teams.ipynb" + "[This file has been moved](https://github.com/langchain-ai/langgraph/blob/23961cff61a42b52525f3b20b4094d8d2fba1744/docs/docs/tutorials/multi_agent/hierarchical_agent_teams.ipynb)" + ] + }, + { + "cell_type": "markdown", + "id": "b9f3508a", + "metadata": {}, + "source": [ + "This directory is retained purely for archival purposes and is no longer updated. The examples previously found here have been moved to the newly [consolidated LangChain documentation](https://docs.langchain.com/oss/python/langgraph/overview)." ] } ], diff --git a/examples/multi_agent/multi-agent-collaboration.ipynb b/examples/multi_agent/multi-agent-collaboration.ipynb index d718f53d5..3da5c9484 100644 --- a/examples/multi_agent/multi-agent-collaboration.ipynb +++ b/examples/multi_agent/multi-agent-collaboration.ipynb @@ -5,7 +5,15 @@ "id": "d2b507b9", "metadata": {}, "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/tutorials/multi_agent/multi-agent-collaboration.ipynb" + "[This file has been moved](https://github.com/langchain-ai/langgraph/blob/23961cff61a42b52525f3b20b4094d8d2fba1744/docs/docs/tutorials/multi_agent/multi-agent-collaboration.ipynb)" + ] + }, + { + "cell_type": "markdown", + "id": "41a8f10a", + "metadata": {}, + "source": [ + "This directory is retained purely for archival purposes and is no longer updated. The examples previously found here have been moved to the newly [consolidated LangChain documentation](https://docs.langchain.com/oss/python/langgraph/overview)." ] } ], diff --git a/examples/node-retries.ipynb b/examples/node-retries.ipynb deleted file mode 100644 index 65dedb2d4..000000000 --- a/examples/node-retries.ipynb +++ /dev/null @@ -1,33 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "017a01f4", - "metadata": {}, - "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/how-tos/node-retries.ipynb" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "env", - "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.9" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/examples/pass-config-to-tools.ipynb b/examples/pass-config-to-tools.ipynb deleted file mode 100644 index 540f0815c..000000000 --- a/examples/pass-config-to-tools.ipynb +++ /dev/null @@ -1,33 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "05f6ad0a", - "metadata": {}, - "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/how-tos/pass-config-to-tools.ipynb" - ] - } - ], - "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.9" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/examples/pass-run-time-values-to-tools.ipynb b/examples/pass-run-time-values-to-tools.ipynb deleted file mode 100644 index 728c5b9e6..000000000 --- a/examples/pass-run-time-values-to-tools.ipynb +++ /dev/null @@ -1,33 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "8f38bec5", - "metadata": {}, - "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/how-tos/pass-run-time-values-to-tools.ipynb" - ] - } - ], - "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.9" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/examples/pass_private_state.ipynb b/examples/pass_private_state.ipynb deleted file mode 100644 index 9c6cf8929..000000000 --- a/examples/pass_private_state.ipynb +++ /dev/null @@ -1,33 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "4da17088", - "metadata": {}, - "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/how-tos/pass_private_state.ipynb" - ] - } - ], - "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.1" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/examples/persistence.ipynb b/examples/persistence.ipynb deleted file mode 100644 index a7a0e08b0..000000000 --- a/examples/persistence.ipynb +++ /dev/null @@ -1,33 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d16e8b9c", - "metadata": {}, - "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/how-tos/memory/add-memory.md." - ] - } - ], - "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.12.2" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/examples/persistence_mongodb.ipynb b/examples/persistence_mongodb.ipynb deleted file mode 100644 index 7bf76036e..000000000 --- a/examples/persistence_mongodb.ipynb +++ /dev/null @@ -1,33 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "78217098", - "metadata": {}, - "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/how-tos/persistence_mongodb.ipynb" - ] - } - ], - "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.9" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/examples/persistence_postgres.ipynb b/examples/persistence_postgres.ipynb deleted file mode 100644 index 7081e2ef3..000000000 --- a/examples/persistence_postgres.ipynb +++ /dev/null @@ -1,33 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "18526f23", - "metadata": {}, - "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/how-tos/memory/add-memory.md" - ] - } - ], - "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.9" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/examples/persistence_redis.ipynb b/examples/persistence_redis.ipynb deleted file mode 100644 index 20eaf89c2..000000000 --- a/examples/persistence_redis.ipynb +++ /dev/null @@ -1,33 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "eee6ecdd", - "metadata": {}, - "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/how-tos/persistence_redis.ipynb" - ] - } - ], - "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.9" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/examples/plan-and-execute/plan-and-execute.ipynb b/examples/plan-and-execute/plan-and-execute.ipynb index 0f1811417..d529446be 100644 --- a/examples/plan-and-execute/plan-and-execute.ipynb +++ b/examples/plan-and-execute/plan-and-execute.ipynb @@ -5,7 +5,15 @@ "id": "9138f92e", "metadata": {}, "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/tutorials/plan-and-execute/plan-and-execute.ipynb" + "[This file has been moved](https://github.com/langchain-ai/langgraph/blob/23961cff61a42b52525f3b20b4094d8d2fba1744/docs/docs/tutorials/plan-and-execute/plan-and-execute.ipynb)" + ] + }, + { + "cell_type": "markdown", + "id": "093678ba", + "metadata": {}, + "source": [ + "This directory is retained purely for archival purposes and is no longer updated. The examples previously found here have been moved to the newly [consolidated LangChain documentation](https://docs.langchain.com/oss/python/langgraph/overview)." ] } ], diff --git a/examples/rag/langgraph_adaptive_rag.ipynb b/examples/rag/langgraph_adaptive_rag.ipynb index 8d9d26420..d118d5884 100644 --- a/examples/rag/langgraph_adaptive_rag.ipynb +++ b/examples/rag/langgraph_adaptive_rag.ipynb @@ -1,5 +1,13 @@ { "cells": [ + { + "cell_type": "markdown", + "id": "fedd6d23", + "metadata": {}, + "source": [ + "This directory is retained purely for archival purposes and is no longer updated. Please see the newly [consolidated LangChain documentation](https://docs.langchain.com/oss/python/langgraph/overview) for the most current information and resources." + ] + }, { "attachments": { "36fa621a-9d3d-4860-a17c-5d20e6987481.png": { diff --git a/examples/rag/langgraph_adaptive_rag_cohere.ipynb b/examples/rag/langgraph_adaptive_rag_cohere.ipynb index dbc957f91..e3732931b 100644 --- a/examples/rag/langgraph_adaptive_rag_cohere.ipynb +++ b/examples/rag/langgraph_adaptive_rag_cohere.ipynb @@ -1,5 +1,13 @@ { "cells": [ + { + "cell_type": "markdown", + "id": "ba8a450f", + "metadata": {}, + "source": [ + "This directory is retained purely for archival purposes and is no longer updated. Please see the newly [consolidated LangChain documentation](https://docs.langchain.com/oss/python/langgraph/overview) for the most current information and resources." + ] + }, { "attachments": { "2a4ecdd2-280d-4311-a2cd-cd6138090be9.png": { @@ -66,7 +74,10 @@ }, "outputs": [], "source": [ - "### LLMs\nimport os\n\nos.environ[\"COHERE_API_KEY\"] = \"\"" + "### LLMs\n", + "import os\n", + "\n", + "os.environ[\"COHERE_API_KEY\"] = \"\"" ] }, { @@ -78,7 +89,10 @@ }, "outputs": [], "source": [ - "# ### Tracing (optional)\n# os.environ['LANGCHAIN_TRACING_V2'] = 'true'\n# os.environ['LANGCHAIN_ENDPOINT'] = 'https://api.smith.langchain.com'\n# os.environ['LANGCHAIN_API_KEY'] =''" + "# ### Tracing (optional)\n", + "# os.environ['LANGCHAIN_TRACING_V2'] = 'true'\n", + "# os.environ['LANGCHAIN_ENDPOINT'] = 'https://api.smith.langchain.com'\n", + "# os.environ['LANGCHAIN_API_KEY'] =''" ] }, { @@ -100,7 +114,40 @@ }, "outputs": [], "source": [ - "### Build Index\n\nfrom langchain.text_splitter import RecursiveCharacterTextSplitter\nfrom langchain_cohere import CohereEmbeddings\nfrom langchain_community.document_loaders import WebBaseLoader\nfrom langchain_community.vectorstores import Chroma\n\n# Set embeddings\nembd = CohereEmbeddings()\n\n# Docs to index\nurls = [\n \"https://lilianweng.github.io/posts/2023-06-23-agent/\",\n \"https://lilianweng.github.io/posts/2023-03-15-prompt-engineering/\",\n \"https://lilianweng.github.io/posts/2023-10-25-adv-attack-llm/\",\n]\n\n# Load\ndocs = [WebBaseLoader(url).load() for url in urls]\ndocs_list = [item for sublist in docs for item in sublist]\n\n# Split\ntext_splitter = RecursiveCharacterTextSplitter.from_tiktoken_encoder(\n chunk_size=512, chunk_overlap=0\n)\ndoc_splits = text_splitter.split_documents(docs_list)\n\n# Add to vectorstore\nvectorstore = Chroma.from_documents(\n documents=doc_splits,\n embedding=embd,\n)\n\nretriever = vectorstore.as_retriever()" + "### Build Index\n", + "\n", + "from langchain.text_splitter import RecursiveCharacterTextSplitter\n", + "from langchain_cohere import CohereEmbeddings\n", + "from langchain_community.document_loaders import WebBaseLoader\n", + "from langchain_community.vectorstores import Chroma\n", + "\n", + "# Set embeddings\n", + "embd = CohereEmbeddings()\n", + "\n", + "# Docs to index\n", + "urls = [\n", + " \"https://lilianweng.github.io/posts/2023-06-23-agent/\",\n", + " \"https://lilianweng.github.io/posts/2023-03-15-prompt-engineering/\",\n", + " \"https://lilianweng.github.io/posts/2023-10-25-adv-attack-llm/\",\n", + "]\n", + "\n", + "# Load\n", + "docs = [WebBaseLoader(url).load() for url in urls]\n", + "docs_list = [item for sublist in docs for item in sublist]\n", + "\n", + "# Split\n", + "text_splitter = RecursiveCharacterTextSplitter.from_tiktoken_encoder(\n", + " chunk_size=512, chunk_overlap=0\n", + ")\n", + "doc_splits = text_splitter.split_documents(docs_list)\n", + "\n", + "# Add to vectorstore\n", + "vectorstore = Chroma.from_documents(\n", + " documents=doc_splits,\n", + " embedding=embd,\n", + ")\n", + "\n", + "retriever = vectorstore.as_retriever()" ] }, { @@ -148,7 +195,57 @@ } ], "source": [ - "### Router\n\nfrom langchain_cohere import ChatCohere\nfrom langchain_core.prompts import ChatPromptTemplate\nfrom langchain_core.pydantic_v1 import BaseModel, Field\n\n\n# Data model\nclass web_search(BaseModel):\n \"\"\"\n The internet. Use web_search for questions that are related to anything else than agents, prompt engineering, and adversarial attacks.\n \"\"\"\n\n query: str = Field(description=\"The query to use when searching the internet.\")\n\n\nclass vectorstore(BaseModel):\n \"\"\"\n A vectorstore containing documents related to agents, prompt engineering, and adversarial attacks. Use the vectorstore for questions on these topics.\n \"\"\"\n\n query: str = Field(description=\"The query to use when searching the vectorstore.\")\n\n\n# Preamble\npreamble = \"\"\"You are an expert at routing a user question to a vectorstore or web search.\nThe vectorstore contains documents related to agents, prompt engineering, and adversarial attacks.\nUse the vectorstore for questions on these topics. Otherwise, use web-search.\"\"\"\n\n# LLM with tool use and preamble\nllm = ChatCohere(model=\"command-r\", temperature=0)\nstructured_llm_router = llm.bind_tools(\n tools=[web_search, vectorstore], preamble=preamble\n)\n\n# Prompt\nroute_prompt = ChatPromptTemplate.from_messages(\n [\n (\"human\", \"{question}\"),\n ]\n)\n\nquestion_router = route_prompt | structured_llm_router\nresponse = question_router.invoke(\n {\"question\": \"Who will the Bears draft first in the NFL draft?\"}\n)\nprint(response.response_metadata[\"tool_calls\"])\nresponse = question_router.invoke({\"question\": \"What are the types of agent memory?\"})\nprint(response.response_metadata[\"tool_calls\"])\nresponse = question_router.invoke({\"question\": \"Hi how are you?\"})\nprint(\"tool_calls\" in response.response_metadata)" + "### Router\n", + "\n", + "from langchain_cohere import ChatCohere\n", + "from langchain_core.prompts import ChatPromptTemplate\n", + "from langchain_core.pydantic_v1 import BaseModel, Field\n", + "\n", + "\n", + "# Data model\n", + "class web_search(BaseModel):\n", + " \"\"\"\n", + " The internet. Use web_search for questions that are related to anything else than agents, prompt engineering, and adversarial attacks.\n", + " \"\"\"\n", + "\n", + " query: str = Field(description=\"The query to use when searching the internet.\")\n", + "\n", + "\n", + "class vectorstore(BaseModel):\n", + " \"\"\"\n", + " A vectorstore containing documents related to agents, prompt engineering, and adversarial attacks. Use the vectorstore for questions on these topics.\n", + " \"\"\"\n", + "\n", + " query: str = Field(description=\"The query to use when searching the vectorstore.\")\n", + "\n", + "\n", + "# Preamble\n", + "preamble = \"\"\"You are an expert at routing a user question to a vectorstore or web search.\n", + "The vectorstore contains documents related to agents, prompt engineering, and adversarial attacks.\n", + "Use the vectorstore for questions on these topics. Otherwise, use web-search.\"\"\"\n", + "\n", + "# LLM with tool use and preamble\n", + "llm = ChatCohere(model=\"command-r\", temperature=0)\n", + "structured_llm_router = llm.bind_tools(\n", + " tools=[web_search, vectorstore], preamble=preamble\n", + ")\n", + "\n", + "# Prompt\n", + "route_prompt = ChatPromptTemplate.from_messages(\n", + " [\n", + " (\"human\", \"{question}\"),\n", + " ]\n", + ")\n", + "\n", + "question_router = route_prompt | structured_llm_router\n", + "response = question_router.invoke(\n", + " {\"question\": \"Who will the Bears draft first in the NFL draft?\"}\n", + ")\n", + "print(response.response_metadata[\"tool_calls\"])\n", + "response = question_router.invoke({\"question\": \"What are the types of agent memory?\"})\n", + "print(response.response_metadata[\"tool_calls\"])\n", + "response = question_router.invoke({\"question\": \"Hi how are you?\"})\n", + "print(\"tool_calls\" in response.response_metadata)" ] }, { @@ -172,7 +269,39 @@ } ], "source": [ - "### Retrieval Grader\n\n\n# Data model\nclass GradeDocuments(BaseModel):\n \"\"\"Binary score for relevance check on retrieved documents.\"\"\"\n\n binary_score: str = Field(\n description=\"Documents are relevant to the question, 'yes' or 'no'\"\n )\n\n\n# Prompt\npreamble = \"\"\"You are a grader assessing relevance of a retrieved document to a user question. \\n\nIf the document contains keyword(s) or semantic meaning related to the user question, grade it as relevant. \\n\nGive a binary score 'yes' or 'no' score to indicate whether the document is relevant to the question.\"\"\"\n\n# LLM with function call\nllm = ChatCohere(model=\"command-r\", temperature=0)\nstructured_llm_grader = llm.with_structured_output(GradeDocuments, preamble=preamble)\n\ngrade_prompt = ChatPromptTemplate.from_messages(\n [\n (\"human\", \"Retrieved document: \\n\\n {document} \\n\\n User question: {question}\"),\n ]\n)\n\nretrieval_grader = grade_prompt | structured_llm_grader\nquestion = \"types of agent memory\"\ndocs = retriever.invoke(question)\ndoc_txt = docs[1].page_content\nresponse = retrieval_grader.invoke({\"question\": question, \"document\": doc_txt})\nprint(response)" + "### Retrieval Grader\n", + "\n", + "\n", + "# Data model\n", + "class GradeDocuments(BaseModel):\n", + " \"\"\"Binary score for relevance check on retrieved documents.\"\"\"\n", + "\n", + " binary_score: str = Field(\n", + " description=\"Documents are relevant to the question, 'yes' or 'no'\"\n", + " )\n", + "\n", + "\n", + "# Prompt\n", + "preamble = \"\"\"You are a grader assessing relevance of a retrieved document to a user question. \\n\n", + "If the document contains keyword(s) or semantic meaning related to the user question, grade it as relevant. \\n\n", + "Give a binary score 'yes' or 'no' score to indicate whether the document is relevant to the question.\"\"\"\n", + "\n", + "# LLM with function call\n", + "llm = ChatCohere(model=\"command-r\", temperature=0)\n", + "structured_llm_grader = llm.with_structured_output(GradeDocuments, preamble=preamble)\n", + "\n", + "grade_prompt = ChatPromptTemplate.from_messages(\n", + " [\n", + " (\"human\", \"Retrieved document: \\n\\n {document} \\n\\n User question: {question}\"),\n", + " ]\n", + ")\n", + "\n", + "retrieval_grader = grade_prompt | structured_llm_grader\n", + "question = \"types of agent memory\"\n", + "docs = retriever.invoke(question)\n", + "doc_txt = docs[1].page_content\n", + "response = retrieval_grader.invoke({\"question\": question, \"document\": doc_txt})\n", + "print(response)" ] }, { @@ -206,7 +335,36 @@ } ], "source": [ - "### Generate\n\nfrom langchain_core.messages import HumanMessage\nfrom langchain_core.output_parsers import StrOutputParser\n\n# Preamble\npreamble = \"\"\"You are an assistant for question-answering tasks. Use the following pieces of retrieved context to answer the question. If you don't know the answer, just say that you don't know. Use three sentences maximum and keep the answer concise.\"\"\"\n\n# LLM\nllm = ChatCohere(model_name=\"command-r\", temperature=0).bind(preamble=preamble)\n\n\n# Prompt\ndef prompt(x):\n return ChatPromptTemplate.from_messages(\n [\n HumanMessage(\n f\"Question: {x['question']} \\nAnswer: \",\n additional_kwargs={\"documents\": x[\"documents\"]},\n )\n ]\n )\n\n\n# Chain\nrag_chain = prompt | llm | StrOutputParser()\n\n# Run\ngeneration = rag_chain.invoke({\"documents\": docs, \"question\": question})\nprint(generation)" + "### Generate\n", + "\n", + "from langchain_core.messages import HumanMessage\n", + "from langchain_core.output_parsers import StrOutputParser\n", + "\n", + "# Preamble\n", + "preamble = \"\"\"You are an assistant for question-answering tasks. Use the following pieces of retrieved context to answer the question. If you don't know the answer, just say that you don't know. Use three sentences maximum and keep the answer concise.\"\"\"\n", + "\n", + "# LLM\n", + "llm = ChatCohere(model_name=\"command-r\", temperature=0).bind(preamble=preamble)\n", + "\n", + "\n", + "# Prompt\n", + "def prompt(x):\n", + " return ChatPromptTemplate.from_messages(\n", + " [\n", + " HumanMessage(\n", + " f\"Question: {x['question']} \\nAnswer: \",\n", + " additional_kwargs={\"documents\": x[\"documents\"]},\n", + " )\n", + " ]\n", + " )\n", + "\n", + "\n", + "# Chain\n", + "rag_chain = prompt | llm | StrOutputParser()\n", + "\n", + "# Run\n", + "generation = rag_chain.invoke({\"documents\": docs, \"question\": question})\n", + "print(generation)" ] }, { @@ -224,7 +382,31 @@ } ], "source": [ - "### LLM fallback\n\nfrom langchain_core.output_parsers import StrOutputParser\n\n# Preamble\npreamble = \"\"\"You are an assistant for question-answering tasks. Answer the question based upon your knowledge. Use three sentences maximum and keep the answer concise.\"\"\"\n\n# LLM\nllm = ChatCohere(model_name=\"command-r\", temperature=0).bind(preamble=preamble)\n\n\n# Prompt\ndef prompt(x):\n return ChatPromptTemplate.from_messages(\n [HumanMessage(f\"Question: {x['question']} \\nAnswer: \")]\n )\n\n\n# Chain\nllm_chain = prompt | llm | StrOutputParser()\n\n# Run\nquestion = \"Hi how are you?\"\ngeneration = llm_chain.invoke({\"question\": question})\nprint(generation)" + "### LLM fallback\n", + "\n", + "from langchain_core.output_parsers import StrOutputParser\n", + "\n", + "# Preamble\n", + "preamble = \"\"\"You are an assistant for question-answering tasks. Answer the question based upon your knowledge. Use three sentences maximum and keep the answer concise.\"\"\"\n", + "\n", + "# LLM\n", + "llm = ChatCohere(model_name=\"command-r\", temperature=0).bind(preamble=preamble)\n", + "\n", + "\n", + "# Prompt\n", + "def prompt(x):\n", + " return ChatPromptTemplate.from_messages(\n", + " [HumanMessage(f\"Question: {x['question']} \\nAnswer: \")]\n", + " )\n", + "\n", + "\n", + "# Chain\n", + "llm_chain = prompt | llm | StrOutputParser()\n", + "\n", + "# Run\n", + "question = \"Hi how are you?\"\n", + "generation = llm_chain.invoke({\"question\": question})\n", + "print(generation)" ] }, { @@ -251,7 +433,38 @@ } ], "source": [ - "### Hallucination Grader\n\n\n# Data model\nclass GradeHallucinations(BaseModel):\n \"\"\"Binary score for hallucination present in generation answer.\"\"\"\n\n binary_score: str = Field(\n description=\"Answer is grounded in the facts, 'yes' or 'no'\"\n )\n\n\n# Preamble\npreamble = \"\"\"You are a grader assessing whether an LLM generation is grounded in / supported by a set of retrieved facts. \\n\nGive a binary score 'yes' or 'no'. 'Yes' means that the answer is grounded in / supported by the set of facts.\"\"\"\n\n# LLM with function call\nllm = ChatCohere(model=\"command-r\", temperature=0)\nstructured_llm_grader = llm.with_structured_output(\n GradeHallucinations, preamble=preamble\n)\n\n# Prompt\nhallucination_prompt = ChatPromptTemplate.from_messages(\n [\n # (\"system\", system),\n (\"human\", \"Set of facts: \\n\\n {documents} \\n\\n LLM generation: {generation}\"),\n ]\n)\n\nhallucination_grader = hallucination_prompt | structured_llm_grader\nhallucination_grader.invoke({\"documents\": docs, \"generation\": generation})" + "### Hallucination Grader\n", + "\n", + "\n", + "# Data model\n", + "class GradeHallucinations(BaseModel):\n", + " \"\"\"Binary score for hallucination present in generation answer.\"\"\"\n", + "\n", + " binary_score: str = Field(\n", + " description=\"Answer is grounded in the facts, 'yes' or 'no'\"\n", + " )\n", + "\n", + "\n", + "# Preamble\n", + "preamble = \"\"\"You are a grader assessing whether an LLM generation is grounded in / supported by a set of retrieved facts. \\n\n", + "Give a binary score 'yes' or 'no'. 'Yes' means that the answer is grounded in / supported by the set of facts.\"\"\"\n", + "\n", + "# LLM with function call\n", + "llm = ChatCohere(model=\"command-r\", temperature=0)\n", + "structured_llm_grader = llm.with_structured_output(\n", + " GradeHallucinations, preamble=preamble\n", + ")\n", + "\n", + "# Prompt\n", + "hallucination_prompt = ChatPromptTemplate.from_messages(\n", + " [\n", + " # (\"system\", system),\n", + " (\"human\", \"Set of facts: \\n\\n {documents} \\n\\n LLM generation: {generation}\"),\n", + " ]\n", + ")\n", + "\n", + "hallucination_grader = hallucination_prompt | structured_llm_grader\n", + "hallucination_grader.invoke({\"documents\": docs, \"generation\": generation})" ] }, { @@ -278,7 +491,35 @@ } ], "source": [ - "### Answer Grader\n\n\n# Data model\nclass GradeAnswer(BaseModel):\n \"\"\"Binary score to assess answer addresses question.\"\"\"\n\n binary_score: str = Field(\n description=\"Answer addresses the question, 'yes' or 'no'\"\n )\n\n\n# Preamble\npreamble = \"\"\"You are a grader assessing whether an answer addresses / resolves a question \\n\nGive a binary score 'yes' or 'no'. Yes' means that the answer resolves the question.\"\"\"\n\n# LLM with function call\nllm = ChatCohere(model=\"command-r\", temperature=0)\nstructured_llm_grader = llm.with_structured_output(GradeAnswer, preamble=preamble)\n\n# Prompt\nanswer_prompt = ChatPromptTemplate.from_messages(\n [\n (\"human\", \"User question: \\n\\n {question} \\n\\n LLM generation: {generation}\"),\n ]\n)\n\nanswer_grader = answer_prompt | structured_llm_grader\nanswer_grader.invoke({\"question\": question, \"generation\": generation})" + "### Answer Grader\n", + "\n", + "\n", + "# Data model\n", + "class GradeAnswer(BaseModel):\n", + " \"\"\"Binary score to assess answer addresses question.\"\"\"\n", + "\n", + " binary_score: str = Field(\n", + " description=\"Answer addresses the question, 'yes' or 'no'\"\n", + " )\n", + "\n", + "\n", + "# Preamble\n", + "preamble = \"\"\"You are a grader assessing whether an answer addresses / resolves a question \\n\n", + "Give a binary score 'yes' or 'no'. Yes' means that the answer resolves the question.\"\"\"\n", + "\n", + "# LLM with function call\n", + "llm = ChatCohere(model=\"command-r\", temperature=0)\n", + "structured_llm_grader = llm.with_structured_output(GradeAnswer, preamble=preamble)\n", + "\n", + "# Prompt\n", + "answer_prompt = ChatPromptTemplate.from_messages(\n", + " [\n", + " (\"human\", \"User question: \\n\\n {question} \\n\\n LLM generation: {generation}\"),\n", + " ]\n", + ")\n", + "\n", + "answer_grader = answer_prompt | structured_llm_grader\n", + "answer_grader.invoke({\"question\": question, \"generation\": generation})" ] }, { @@ -300,7 +541,12 @@ }, "outputs": [], "source": [ - "### Search\n# os.environ['TAVILY_API_KEY'] =''\n\nfrom langchain_community.tools.tavily_search import TavilySearchResults\n\nweb_search_tool = TavilySearchResults()" + "### Search\n", + "# os.environ['TAVILY_API_KEY'] =''\n", + "\n", + "from langchain_community.tools.tavily_search import TavilySearchResults\n", + "\n", + "web_search_tool = TavilySearchResults()" ] }, { @@ -326,7 +572,24 @@ }, "outputs": [], "source": [ - "from typing import List\n\nfrom typing_extensions import TypedDict\n\n\nclass GraphState(TypedDict):\n \"\"\"|\n Represents the state of our graph.\n\n Attributes:\n question: question\n generation: LLM generation\n documents: list of documents\n \"\"\"\n\n question: str\n generation: str\n documents: List[str]" + "from typing import List\n", + "\n", + "from typing_extensions import TypedDict\n", + "\n", + "\n", + "class GraphState(TypedDict):\n", + " \"\"\"|\n", + " Represents the state of our graph.\n", + "\n", + " Attributes:\n", + " question: question\n", + " generation: LLM generation\n", + " documents: list of documents\n", + " \"\"\"\n", + "\n", + " question: str\n", + " generation: str\n", + " documents: List[str]" ] }, { @@ -348,7 +611,218 @@ }, "outputs": [], "source": [ - "from langchain.schema import Document\n\n\ndef retrieve(state):\n \"\"\"\n Retrieve documents\n\n Args:\n state (dict): The current graph state\n\n Returns:\n state (dict): New key added to state, documents, that contains retrieved documents\n \"\"\"\n print(\"---RETRIEVE---\")\n question = state[\"question\"]\n\n # Retrieval\n documents = retriever.invoke(question)\n return {\"documents\": documents, \"question\": question}\n\n\ndef llm_fallback(state):\n \"\"\"\n Generate answer using the LLM w/o vectorstore\n\n Args:\n state (dict): The current graph state\n\n Returns:\n state (dict): New key added to state, generation, that contains LLM generation\n \"\"\"\n print(\"---LLM Fallback---\")\n question = state[\"question\"]\n generation = llm_chain.invoke({\"question\": question})\n return {\"question\": question, \"generation\": generation}\n\n\ndef generate(state):\n \"\"\"\n Generate answer using the vectorstore\n\n Args:\n state (dict): The current graph state\n\n Returns:\n state (dict): New key added to state, generation, that contains LLM generation\n \"\"\"\n print(\"---GENERATE---\")\n question = state[\"question\"]\n documents = state[\"documents\"]\n if not isinstance(documents, list):\n documents = [documents]\n\n # RAG generation\n generation = rag_chain.invoke({\"documents\": documents, \"question\": question})\n return {\"documents\": documents, \"question\": question, \"generation\": generation}\n\n\ndef grade_documents(state):\n \"\"\"\n Determines whether the retrieved documents are relevant to the question.\n\n Args:\n state (dict): The current graph state\n\n Returns:\n state (dict): Updates documents key with only filtered relevant documents\n \"\"\"\n\n print(\"---CHECK DOCUMENT RELEVANCE TO QUESTION---\")\n question = state[\"question\"]\n documents = state[\"documents\"]\n\n # Score each doc\n filtered_docs = []\n for d in documents:\n score = retrieval_grader.invoke(\n {\"question\": question, \"document\": d.page_content}\n )\n grade = score.binary_score\n if grade == \"yes\":\n print(\"---GRADE: DOCUMENT RELEVANT---\")\n filtered_docs.append(d)\n else:\n print(\"---GRADE: DOCUMENT NOT RELEVANT---\")\n continue\n return {\"documents\": filtered_docs, \"question\": question}\n\n\ndef web_search(state):\n \"\"\"\n Web search based on the re-phrased question.\n\n Args:\n state (dict): The current graph state\n\n Returns:\n state (dict): Updates documents key with appended web results\n \"\"\"\n\n print(\"---WEB SEARCH---\")\n question = state[\"question\"]\n\n # Web search\n docs = web_search_tool.invoke({\"query\": question})\n web_results = \"\\n\".join([d[\"content\"] for d in docs])\n web_results = Document(page_content=web_results)\n\n return {\"documents\": web_results, \"question\": question}\n\n\n### Edges ###\n\n\ndef route_question(state):\n \"\"\"\n Route question to web search or RAG.\n\n Args:\n state (dict): The current graph state\n\n Returns:\n str: Next node to call\n \"\"\"\n\n print(\"---ROUTE QUESTION---\")\n question = state[\"question\"]\n source = question_router.invoke({\"question\": question})\n\n # Fallback to LLM or raise error if no decision\n if \"tool_calls\" not in source.additional_kwargs:\n print(\"---ROUTE QUESTION TO LLM---\")\n return \"llm_fallback\"\n if len(source.additional_kwargs[\"tool_calls\"]) == 0:\n raise \"Router could not decide source\"\n\n # Choose datasource\n datasource = source.additional_kwargs[\"tool_calls\"][0][\"function\"][\"name\"]\n if datasource == \"web_search\":\n print(\"---ROUTE QUESTION TO WEB SEARCH---\")\n return \"web_search\"\n elif datasource == \"vectorstore\":\n print(\"---ROUTE QUESTION TO RAG---\")\n return \"vectorstore\"\n else:\n print(\"---ROUTE QUESTION TO LLM---\")\n return \"vectorstore\"\n\n\ndef decide_to_generate(state):\n \"\"\"\n Determines whether to generate an answer, or re-generate a question.\n\n Args:\n state (dict): The current graph state\n\n Returns:\n str: Binary decision for next node to call\n \"\"\"\n\n print(\"---ASSESS GRADED DOCUMENTS---\")\n state[\"question\"]\n filtered_documents = state[\"documents\"]\n\n if not filtered_documents:\n # All documents have been filtered check_relevance\n # We will re-generate a new query\n print(\"---DECISION: ALL DOCUMENTS ARE NOT RELEVANT TO QUESTION, WEB SEARCH---\")\n return \"web_search\"\n else:\n # We have relevant documents, so generate answer\n print(\"---DECISION: GENERATE---\")\n return \"generate\"\n\n\ndef grade_generation_v_documents_and_question(state):\n \"\"\"\n Determines whether the generation is grounded in the document and answers question.\n\n Args:\n state (dict): The current graph state\n\n Returns:\n str: Decision for next node to call\n \"\"\"\n\n print(\"---CHECK HALLUCINATIONS---\")\n question = state[\"question\"]\n documents = state[\"documents\"]\n generation = state[\"generation\"]\n\n score = hallucination_grader.invoke(\n {\"documents\": documents, \"generation\": generation}\n )\n grade = score.binary_score\n\n # Check hallucination\n if grade == \"yes\":\n print(\"---DECISION: GENERATION IS GROUNDED IN DOCUMENTS---\")\n # Check question-answering\n print(\"---GRADE GENERATION vs QUESTION---\")\n score = answer_grader.invoke({\"question\": question, \"generation\": generation})\n grade = score.binary_score\n if grade == \"yes\":\n print(\"---DECISION: GENERATION ADDRESSES QUESTION---\")\n return \"useful\"\n else:\n print(\"---DECISION: GENERATION DOES NOT ADDRESS QUESTION---\")\n return \"not useful\"\n else:\n pprint(\"---DECISION: GENERATION IS NOT GROUNDED IN DOCUMENTS, RE-TRY---\")\n return \"not supported\"" + "from langchain.schema import Document\n", + "\n", + "\n", + "def retrieve(state):\n", + " \"\"\"\n", + " Retrieve documents\n", + "\n", + " Args:\n", + " state (dict): The current graph state\n", + "\n", + " Returns:\n", + " state (dict): New key added to state, documents, that contains retrieved documents\n", + " \"\"\"\n", + " print(\"---RETRIEVE---\")\n", + " question = state[\"question\"]\n", + "\n", + " # Retrieval\n", + " documents = retriever.invoke(question)\n", + " return {\"documents\": documents, \"question\": question}\n", + "\n", + "\n", + "def llm_fallback(state):\n", + " \"\"\"\n", + " Generate answer using the LLM w/o vectorstore\n", + "\n", + " Args:\n", + " state (dict): The current graph state\n", + "\n", + " Returns:\n", + " state (dict): New key added to state, generation, that contains LLM generation\n", + " \"\"\"\n", + " print(\"---LLM Fallback---\")\n", + " question = state[\"question\"]\n", + " generation = llm_chain.invoke({\"question\": question})\n", + " return {\"question\": question, \"generation\": generation}\n", + "\n", + "\n", + "def generate(state):\n", + " \"\"\"\n", + " Generate answer using the vectorstore\n", + "\n", + " Args:\n", + " state (dict): The current graph state\n", + "\n", + " Returns:\n", + " state (dict): New key added to state, generation, that contains LLM generation\n", + " \"\"\"\n", + " print(\"---GENERATE---\")\n", + " question = state[\"question\"]\n", + " documents = state[\"documents\"]\n", + " if not isinstance(documents, list):\n", + " documents = [documents]\n", + "\n", + " # RAG generation\n", + " generation = rag_chain.invoke({\"documents\": documents, \"question\": question})\n", + " return {\"documents\": documents, \"question\": question, \"generation\": generation}\n", + "\n", + "\n", + "def grade_documents(state):\n", + " \"\"\"\n", + " Determines whether the retrieved documents are relevant to the question.\n", + "\n", + " Args:\n", + " state (dict): The current graph state\n", + "\n", + " Returns:\n", + " state (dict): Updates documents key with only filtered relevant documents\n", + " \"\"\"\n", + "\n", + " print(\"---CHECK DOCUMENT RELEVANCE TO QUESTION---\")\n", + " question = state[\"question\"]\n", + " documents = state[\"documents\"]\n", + "\n", + " # Score each doc\n", + " filtered_docs = []\n", + " for d in documents:\n", + " score = retrieval_grader.invoke(\n", + " {\"question\": question, \"document\": d.page_content}\n", + " )\n", + " grade = score.binary_score\n", + " if grade == \"yes\":\n", + " print(\"---GRADE: DOCUMENT RELEVANT---\")\n", + " filtered_docs.append(d)\n", + " else:\n", + " print(\"---GRADE: DOCUMENT NOT RELEVANT---\")\n", + " continue\n", + " return {\"documents\": filtered_docs, \"question\": question}\n", + "\n", + "\n", + "def web_search(state):\n", + " \"\"\"\n", + " Web search based on the re-phrased question.\n", + "\n", + " Args:\n", + " state (dict): The current graph state\n", + "\n", + " Returns:\n", + " state (dict): Updates documents key with appended web results\n", + " \"\"\"\n", + "\n", + " print(\"---WEB SEARCH---\")\n", + " question = state[\"question\"]\n", + "\n", + " # Web search\n", + " docs = web_search_tool.invoke({\"query\": question})\n", + " web_results = \"\\n\".join([d[\"content\"] for d in docs])\n", + " web_results = Document(page_content=web_results)\n", + "\n", + " return {\"documents\": web_results, \"question\": question}\n", + "\n", + "\n", + "### Edges ###\n", + "\n", + "\n", + "def route_question(state):\n", + " \"\"\"\n", + " Route question to web search or RAG.\n", + "\n", + " Args:\n", + " state (dict): The current graph state\n", + "\n", + " Returns:\n", + " str: Next node to call\n", + " \"\"\"\n", + "\n", + " print(\"---ROUTE QUESTION---\")\n", + " question = state[\"question\"]\n", + " source = question_router.invoke({\"question\": question})\n", + "\n", + " # Fallback to LLM or raise error if no decision\n", + " if \"tool_calls\" not in source.additional_kwargs:\n", + " print(\"---ROUTE QUESTION TO LLM---\")\n", + " return \"llm_fallback\"\n", + " if len(source.additional_kwargs[\"tool_calls\"]) == 0:\n", + " raise \"Router could not decide source\"\n", + "\n", + " # Choose datasource\n", + " datasource = source.additional_kwargs[\"tool_calls\"][0][\"function\"][\"name\"]\n", + " if datasource == \"web_search\":\n", + " print(\"---ROUTE QUESTION TO WEB SEARCH---\")\n", + " return \"web_search\"\n", + " elif datasource == \"vectorstore\":\n", + " print(\"---ROUTE QUESTION TO RAG---\")\n", + " return \"vectorstore\"\n", + " else:\n", + " print(\"---ROUTE QUESTION TO LLM---\")\n", + " return \"vectorstore\"\n", + "\n", + "\n", + "def decide_to_generate(state):\n", + " \"\"\"\n", + " Determines whether to generate an answer, or re-generate a question.\n", + "\n", + " Args:\n", + " state (dict): The current graph state\n", + "\n", + " Returns:\n", + " str: Binary decision for next node to call\n", + " \"\"\"\n", + "\n", + " print(\"---ASSESS GRADED DOCUMENTS---\")\n", + " state[\"question\"]\n", + " filtered_documents = state[\"documents\"]\n", + "\n", + " if not filtered_documents:\n", + " # All documents have been filtered check_relevance\n", + " # We will re-generate a new query\n", + " print(\"---DECISION: ALL DOCUMENTS ARE NOT RELEVANT TO QUESTION, WEB SEARCH---\")\n", + " return \"web_search\"\n", + " else:\n", + " # We have relevant documents, so generate answer\n", + " print(\"---DECISION: GENERATE---\")\n", + " return \"generate\"\n", + "\n", + "\n", + "def grade_generation_v_documents_and_question(state):\n", + " \"\"\"\n", + " Determines whether the generation is grounded in the document and answers question.\n", + "\n", + " Args:\n", + " state (dict): The current graph state\n", + "\n", + " Returns:\n", + " str: Decision for next node to call\n", + " \"\"\"\n", + "\n", + " print(\"---CHECK HALLUCINATIONS---\")\n", + " question = state[\"question\"]\n", + " documents = state[\"documents\"]\n", + " generation = state[\"generation\"]\n", + "\n", + " score = hallucination_grader.invoke(\n", + " {\"documents\": documents, \"generation\": generation}\n", + " )\n", + " grade = score.binary_score\n", + "\n", + " # Check hallucination\n", + " if grade == \"yes\":\n", + " print(\"---DECISION: GENERATION IS GROUNDED IN DOCUMENTS---\")\n", + " # Check question-answering\n", + " print(\"---GRADE GENERATION vs QUESTION---\")\n", + " score = answer_grader.invoke({\"question\": question, \"generation\": generation})\n", + " grade = score.binary_score\n", + " if grade == \"yes\":\n", + " print(\"---DECISION: GENERATION ADDRESSES QUESTION---\")\n", + " return \"useful\"\n", + " else:\n", + " print(\"---DECISION: GENERATION DOES NOT ADDRESS QUESTION---\")\n", + " return \"not useful\"\n", + " else:\n", + " pprint(\"---DECISION: GENERATION IS NOT GROUNDED IN DOCUMENTS, RE-TRY---\")\n", + " return \"not supported\"" ] }, { @@ -451,7 +925,19 @@ } ], "source": [ - "# Run\ninputs = {\n \"question\": \"What player are the Bears expected to draft first in the 2024 NFL draft?\"\n}\nfor output in app.stream(inputs):\n for key, value in output.items():\n # Node\n pprint.pprint(f\"Node '{key}':\")\n # Optional: print full state at each node\n pprint.pprint(\"\\n---\\n\")\n\n# Final generation\npprint.pprint(value[\"generation\"])" + "# Run\n", + "inputs = {\n", + " \"question\": \"What player are the Bears expected to draft first in the 2024 NFL draft?\"\n", + "}\n", + "for output in app.stream(inputs):\n", + " for key, value in output.items():\n", + " # Node\n", + " pprint.pprint(f\"Node '{key}':\")\n", + " # Optional: print full state at each node\n", + " pprint.pprint(\"\\n---\\n\")\n", + "\n", + "# Final generation\n", + "pprint.pprint(value[\"generation\"])" ] }, { @@ -508,7 +994,18 @@ } ], "source": [ - "# Run\ninputs = {\"question\": \"What are the types of agent memory?\"}\nfor output in app.stream(inputs):\n for key, value in output.items():\n # Node\n pprint.pprint(f\"Node '{key}':\")\n # Optional: print full state at each node\n # pprint.pprint(value[\"keys\"], indent=2, width=80, depth=None)\n pprint.pprint(\"\\n---\\n\")\n\n# Final generation\npprint.pprint(value[\"generation\"])" + "# Run\n", + "inputs = {\"question\": \"What are the types of agent memory?\"}\n", + "for output in app.stream(inputs):\n", + " for key, value in output.items():\n", + " # Node\n", + " pprint.pprint(f\"Node '{key}':\")\n", + " # Optional: print full state at each node\n", + " # pprint.pprint(value[\"keys\"], indent=2, width=80, depth=None)\n", + " pprint.pprint(\"\\n---\\n\")\n", + "\n", + "# Final generation\n", + "pprint.pprint(value[\"generation\"])" ] }, { @@ -546,7 +1043,18 @@ } ], "source": [ - "# Run\ninputs = {\"question\": \"Hello, how are you today?\"}\nfor output in app.stream(inputs):\n for key, value in output.items():\n # Node\n pprint.pprint(f\"Node '{key}':\")\n # Optional: print full state at each node\n # pprint.pprint(value[\"keys\"], indent=2, width=80, depth=None)\n pprint.pprint(\"\\n---\\n\")\n\n# Final generation\npprint.pprint(value[\"generation\"])" + "# Run\n", + "inputs = {\"question\": \"Hello, how are you today?\"}\n", + "for output in app.stream(inputs):\n", + " for key, value in output.items():\n", + " # Node\n", + " pprint.pprint(f\"Node '{key}':\")\n", + " # Optional: print full state at each node\n", + " # pprint.pprint(value[\"keys\"], indent=2, width=80, depth=None)\n", + " pprint.pprint(\"\\n---\\n\")\n", + "\n", + "# Final generation\n", + "pprint.pprint(value[\"generation\"])" ] }, { @@ -565,9 +1073,7 @@ "id": "ce3cda0a-c4bd-41ea-830b-d992f27fde15", "metadata": {}, "outputs": [], - "source": [ - "" - ] + "source": [] } ], "metadata": { diff --git a/examples/rag/langgraph_adaptive_rag_local.ipynb b/examples/rag/langgraph_adaptive_rag_local.ipynb index 4a0435e38..0b289636b 100644 --- a/examples/rag/langgraph_adaptive_rag_local.ipynb +++ b/examples/rag/langgraph_adaptive_rag_local.ipynb @@ -1,5 +1,13 @@ { "cells": [ + { + "cell_type": "markdown", + "id": "39b26b09", + "metadata": {}, + "source": [ + "This directory is retained purely for archival purposes and is no longer updated. Please see the newly [consolidated LangChain documentation](https://docs.langchain.com/oss/python/langgraph/overview) for the most current information and resources." + ] + }, { "attachments": { "3755396d-c4a8-45bd-87d4-00cb56339fe5.png": { diff --git a/examples/rag/langgraph_agentic_rag.ipynb b/examples/rag/langgraph_agentic_rag.ipynb index 27e957b6c..268914f51 100644 --- a/examples/rag/langgraph_agentic_rag.ipynb +++ b/examples/rag/langgraph_agentic_rag.ipynb @@ -1,5 +1,13 @@ { "cells": [ + { + "cell_type": "markdown", + "id": "47e3b43b", + "metadata": {}, + "source": [ + "This directory is retained purely for archival purposes and is no longer updated. Please see the newly [consolidated LangChain documentation](https://docs.langchain.com/oss/python/langgraph/overview) for the most current information and resources." + ] + }, { "cell_type": "markdown", "id": "425fb020-e864-40ce-a31f-8da40c73d14b", @@ -200,11 +208,11 @@ "output_type": "stream", "text": [ "********************Prompt[rlm/rag-prompt]********************\n", - "================================\u001B[1m Human Message \u001B[0m=================================\n", + "================================\u001b[1m Human Message \u001b[0m=================================\n", "\n", "You are an assistant for question-answering tasks. Use the following pieces of retrieved context to answer the question. If you don't know the answer, just say that you don't know. Use three sentences maximum and keep the answer concise.\n", - "Question: \u001B[33;1m\u001B[1;3m{question}\u001B[0m \n", - "Context: \u001B[33;1m\u001B[1;3m{context}\u001B[0m \n", + "Question: \u001b[33;1m\u001b[1;3m{question}\u001b[0m \n", + "Context: \u001b[33;1m\u001b[1;3m{context}\u001b[0m \n", "Answer:\n" ] } diff --git a/examples/rag/langgraph_crag.ipynb b/examples/rag/langgraph_crag.ipynb index 009ad25ff..e039ffa31 100644 --- a/examples/rag/langgraph_crag.ipynb +++ b/examples/rag/langgraph_crag.ipynb @@ -1,5 +1,13 @@ { "cells": [ + { + "cell_type": "markdown", + "id": "c71da2ea", + "metadata": {}, + "source": [ + "This directory is retained purely for archival purposes and is no longer updated. Please see the newly [consolidated LangChain documentation](https://docs.langchain.com/oss/python/langgraph/overview) for the most current information and resources." + ] + }, { "attachments": { "683fae34-980f-43f0-a9c2-9894bebd9157.png": { diff --git a/examples/rag/langgraph_crag_local.ipynb b/examples/rag/langgraph_crag_local.ipynb index c454127f2..9ace47871 100644 --- a/examples/rag/langgraph_crag_local.ipynb +++ b/examples/rag/langgraph_crag_local.ipynb @@ -1,5 +1,13 @@ { "cells": [ + { + "cell_type": "markdown", + "id": "ac7db067", + "metadata": {}, + "source": [ + "This directory is retained purely for archival purposes and is no longer updated. Please see the newly [consolidated LangChain documentation](https://docs.langchain.com/oss/python/langgraph/overview) for the most current information and resources." + ] + }, { "attachments": { "b77a7d3b-b28a-4dcf-9f1a-861f2f2c5f6c.png": { diff --git a/examples/rag/langgraph_self_rag.ipynb b/examples/rag/langgraph_self_rag.ipynb index 4aedf620d..23751308c 100644 --- a/examples/rag/langgraph_self_rag.ipynb +++ b/examples/rag/langgraph_self_rag.ipynb @@ -1,5 +1,13 @@ { "cells": [ + { + "cell_type": "markdown", + "id": "b3d959ff", + "metadata": {}, + "source": [ + "This directory is retained purely for archival purposes and is no longer updated. Please see the newly [consolidated LangChain documentation](https://docs.langchain.com/oss/python/langgraph/overview) for the most current information and resources." + ] + }, { "attachments": { "15cba0ab-a549-4909-8373-fb761e384eff.png": { diff --git a/examples/rag/langgraph_self_rag_local.ipynb b/examples/rag/langgraph_self_rag_local.ipynb index 22e84d79a..b7b729bdd 100644 --- a/examples/rag/langgraph_self_rag_local.ipynb +++ b/examples/rag/langgraph_self_rag_local.ipynb @@ -1,5 +1,13 @@ { "cells": [ + { + "cell_type": "markdown", + "id": "345488d8", + "metadata": {}, + "source": [ + "This directory is retained purely for archival purposes and is no longer updated. Please see the newly [consolidated LangChain documentation](https://docs.langchain.com/oss/python/langgraph/overview) for the most current information and resources." + ] + }, { "attachments": { "5fca0a3e-d13d-4bfa-95ea-58203640cc7a.png": { diff --git a/examples/rag/langgraph_self_rag_pinecone_movies.ipynb b/examples/rag/langgraph_self_rag_pinecone_movies.ipynb index bdcc129c4..cb6dd761f 100644 --- a/examples/rag/langgraph_self_rag_pinecone_movies.ipynb +++ b/examples/rag/langgraph_self_rag_pinecone_movies.ipynb @@ -1,5 +1,13 @@ { "cells": [ + { + "cell_type": "markdown", + "id": "403aeb6e", + "metadata": {}, + "source": [ + "This directory is retained purely for archival purposes and is no longer updated. Please see the newly [consolidated LangChain documentation](https://docs.langchain.com/oss/python/langgraph/overview) for the most current information and resources." + ] + }, { "attachments": { "15cba0ab-a549-4909-8373-fb761e384eff.png": { @@ -54,7 +62,11 @@ "metadata": {}, "outputs": [], "source": [ - "import os\n\nos.environ[\"LANGCHAIN_TRACING_V2\"] = \"true\"\nos.environ[\"LANGCHAIN_ENDPOINT\"] = \"https://api.smith.langchain.com\"\nos.environ[\"LANGCHAIN_API_KEY\"] = \"\"" + "import os\n", + "\n", + "os.environ[\"LANGCHAIN_TRACING_V2\"] = \"true\"\n", + "os.environ[\"LANGCHAIN_ENDPOINT\"] = \"https://api.smith.langchain.com\"\n", + "os.environ[\"LANGCHAIN_API_KEY\"] = \"\"" ] }, { @@ -64,7 +76,9 @@ "metadata": {}, "outputs": [], "source": [ - "import os\n\nos.environ[\"LANGCHAIN_PROJECT\"] = \"pinecone-devconnect\"" + "import os\n", + "\n", + "os.environ[\"LANGCHAIN_PROJECT\"] = \"pinecone-devconnect\"" ] }, { @@ -84,7 +98,18 @@ "metadata": {}, "outputs": [], "source": [ - "from langchain_openai import OpenAIEmbeddings\nfrom langchain_pinecone import PineconeVectorStore\n\n# use pinecone movies database\n\n# Add to vectorDB\nvectorstore = PineconeVectorStore(\n embedding=OpenAIEmbeddings(),\n index_name=\"sample-movies\",\n text_key=\"summary\",\n)\nretriever = vectorstore.as_retriever()" + "from langchain_openai import OpenAIEmbeddings\n", + "from langchain_pinecone import PineconeVectorStore\n", + "\n", + "# use pinecone movies database\n", + "\n", + "# Add to vectorDB\n", + "vectorstore = PineconeVectorStore(\n", + " embedding=OpenAIEmbeddings(),\n", + " index_name=\"sample-movies\",\n", + " text_key=\"summary\",\n", + ")\n", + "retriever = vectorstore.as_retriever()" ] }, { @@ -113,7 +138,11 @@ } ], "source": [ - "docs = retriever.invoke(\"James Cameron\")\nfor doc in docs:\n print(\"# \" + doc.metadata[\"title\"])\n print(doc.page_content)\n print()" + "docs = retriever.invoke(\"James Cameron\")\n", + "for doc in docs:\n", + " print(\"# \" + doc.metadata[\"title\"])\n", + " print(doc.page_content)\n", + " print()" ] }, { @@ -173,7 +202,12 @@ } ], "source": [ - "# Test the retrieval grader\nquestion = \"movies starring jason momoa\"\ndocs = retriever.invoke(question)\ndoc_txt = docs[0].page_content\nprint(doc_txt)\nprint(retrieval_grader.invoke({\"question\": question, \"document\": doc_txt}))" + "# Test the retrieval grader\n", + "question = \"movies starring jason momoa\"\n", + "docs = retriever.invoke(question)\n", + "doc_txt = docs[0].page_content\n", + "print(doc_txt)\n", + "print(retrieval_grader.invoke({\"question\": question, \"document\": doc_txt}))" ] }, { @@ -201,7 +235,23 @@ } ], "source": [ - "### Generate\n\nfrom langchain import hub\nfrom langchain_core.output_parsers import StrOutputParser\n\n# Prompt\nprompt = hub.pull(\"rlm/rag-prompt\")\n\n# LLM\nllm = ChatOpenAI(model_name=\"gpt-3.5-turbo\", temperature=0)\n\n# Chain\nrag_chain = prompt | llm | StrOutputParser()\n\n# Run\ngeneration = rag_chain.invoke({\"context\": docs, \"question\": question})\nprint(generation)" + "### Generate\n", + "\n", + "from langchain import hub\n", + "from langchain_core.output_parsers import StrOutputParser\n", + "\n", + "# Prompt\n", + "prompt = hub.pull(\"rlm/rag-prompt\")\n", + "\n", + "# LLM\n", + "llm = ChatOpenAI(model_name=\"gpt-3.5-turbo\", temperature=0)\n", + "\n", + "# Chain\n", + "rag_chain = prompt | llm | StrOutputParser()\n", + "\n", + "# Run\n", + "generation = rag_chain.invoke({\"context\": docs, \"question\": question})\n", + "print(generation)" ] }, { @@ -329,7 +379,17 @@ } ], "source": [ - "### Question Re-writer\n\n# LLM\nllm = ChatOpenAI(model=\"gpt-3.5-turbo-0125\", temperature=0)\n\n# Prompt\nre_write_prompt = hub.pull(\"efriis/self-rag-question-rewriter\")\n\nquestion_rewriter = re_write_prompt | llm | StrOutputParser()\nprint(question)\nquestion_rewriter.invoke({\"question\": question})" + "### Question Re-writer\n", + "\n", + "# LLM\n", + "llm = ChatOpenAI(model=\"gpt-3.5-turbo-0125\", temperature=0)\n", + "\n", + "# Prompt\n", + "re_write_prompt = hub.pull(\"efriis/self-rag-question-rewriter\")\n", + "\n", + "question_rewriter = re_write_prompt | llm | StrOutputParser()\n", + "print(question)\n", + "question_rewriter.invoke({\"question\": question})" ] }, { @@ -351,7 +411,24 @@ "metadata": {}, "outputs": [], "source": [ - "from typing import List\n\nfrom typing_extensions import TypedDict\n\n\nclass GraphState(TypedDict):\n \"\"\"\n Represents the state of our graph.\n\n Attributes:\n question: question\n generation: LLM generation\n documents: list of documents\n \"\"\"\n\n question: str\n generation: str\n documents: List[str]" + "from typing import List\n", + "\n", + "from typing_extensions import TypedDict\n", + "\n", + "\n", + "class GraphState(TypedDict):\n", + " \"\"\"\n", + " Represents the state of our graph.\n", + "\n", + " Attributes:\n", + " question: question\n", + " generation: LLM generation\n", + " documents: list of documents\n", + " \"\"\"\n", + "\n", + " question: str\n", + " generation: str\n", + " documents: List[str]" ] }, { @@ -361,7 +438,95 @@ "metadata": {}, "outputs": [], "source": [ - "### Nodes\n\n\ndef retrieve(state):\n \"\"\"\n Retrieve documents\n\n Args:\n state (dict): The current graph state\n\n Returns:\n state (dict): New key added to state, documents, that contains retrieved documents\n \"\"\"\n print(\"---RETRIEVE---\")\n question = state[\"question\"]\n\n # Retrieval\n documents = retriever.invoke(question)\n return {\"documents\": documents, \"question\": question}\n\n\ndef generate(state):\n \"\"\"\n Generate answer\n\n Args:\n state (dict): The current graph state\n\n Returns:\n state (dict): New key added to state, generation, that contains LLM generation\n \"\"\"\n print(\"---GENERATE---\")\n question = state[\"question\"]\n documents = state[\"documents\"]\n\n # RAG generation\n generation = rag_chain.invoke({\"context\": documents, \"question\": question})\n return {\"documents\": documents, \"question\": question, \"generation\": generation}\n\n\ndef grade_documents(state):\n \"\"\"\n Determines whether the retrieved documents are relevant to the question.\n\n Args:\n state (dict): The current graph state\n\n Returns:\n state (dict): Updates documents key with only filtered relevant documents\n \"\"\"\n\n print(\"---CHECK DOCUMENT RELEVANCE TO QUESTION---\")\n question = state[\"question\"]\n documents = state[\"documents\"]\n\n # Score each doc\n filtered_docs = []\n for d in documents:\n score = retrieval_grader.invoke(\n {\"question\": question, \"document\": d.page_content}\n )\n grade = score.binary_score\n if grade == \"yes\":\n print(\"---GRADE: DOCUMENT RELEVANT---\")\n filtered_docs.append(d)\n else:\n print(\"---GRADE: DOCUMENT NOT RELEVANT---\")\n continue\n return {\"documents\": filtered_docs, \"question\": question}\n\n\ndef transform_query(state):\n \"\"\"\n Transform the query to produce a better question.\n\n Args:\n state (dict): The current graph state\n\n Returns:\n state (dict): Updates question key with a re-phrased question\n \"\"\"\n\n print(\"---TRANSFORM QUERY---\")\n question = state[\"question\"]\n documents = state[\"documents\"]\n\n # Re-write question\n better_question = question_rewriter.invoke({\"question\": question})\n return {\"documents\": documents, \"question\": better_question}" + "### Nodes\n", + "\n", + "\n", + "def retrieve(state):\n", + " \"\"\"\n", + " Retrieve documents\n", + "\n", + " Args:\n", + " state (dict): The current graph state\n", + "\n", + " Returns:\n", + " state (dict): New key added to state, documents, that contains retrieved documents\n", + " \"\"\"\n", + " print(\"---RETRIEVE---\")\n", + " question = state[\"question\"]\n", + "\n", + " # Retrieval\n", + " documents = retriever.invoke(question)\n", + " return {\"documents\": documents, \"question\": question}\n", + "\n", + "\n", + "def generate(state):\n", + " \"\"\"\n", + " Generate answer\n", + "\n", + " Args:\n", + " state (dict): The current graph state\n", + "\n", + " Returns:\n", + " state (dict): New key added to state, generation, that contains LLM generation\n", + " \"\"\"\n", + " print(\"---GENERATE---\")\n", + " question = state[\"question\"]\n", + " documents = state[\"documents\"]\n", + "\n", + " # RAG generation\n", + " generation = rag_chain.invoke({\"context\": documents, \"question\": question})\n", + " return {\"documents\": documents, \"question\": question, \"generation\": generation}\n", + "\n", + "\n", + "def grade_documents(state):\n", + " \"\"\"\n", + " Determines whether the retrieved documents are relevant to the question.\n", + "\n", + " Args:\n", + " state (dict): The current graph state\n", + "\n", + " Returns:\n", + " state (dict): Updates documents key with only filtered relevant documents\n", + " \"\"\"\n", + "\n", + " print(\"---CHECK DOCUMENT RELEVANCE TO QUESTION---\")\n", + " question = state[\"question\"]\n", + " documents = state[\"documents\"]\n", + "\n", + " # Score each doc\n", + " filtered_docs = []\n", + " for d in documents:\n", + " score = retrieval_grader.invoke(\n", + " {\"question\": question, \"document\": d.page_content}\n", + " )\n", + " grade = score.binary_score\n", + " if grade == \"yes\":\n", + " print(\"---GRADE: DOCUMENT RELEVANT---\")\n", + " filtered_docs.append(d)\n", + " else:\n", + " print(\"---GRADE: DOCUMENT NOT RELEVANT---\")\n", + " continue\n", + " return {\"documents\": filtered_docs, \"question\": question}\n", + "\n", + "\n", + "def transform_query(state):\n", + " \"\"\"\n", + " Transform the query to produce a better question.\n", + "\n", + " Args:\n", + " state (dict): The current graph state\n", + "\n", + " Returns:\n", + " state (dict): Updates question key with a re-phrased question\n", + " \"\"\"\n", + "\n", + " print(\"---TRANSFORM QUERY---\")\n", + " question = state[\"question\"]\n", + " documents = state[\"documents\"]\n", + "\n", + " # Re-write question\n", + " better_question = question_rewriter.invoke({\"question\": question})\n", + " return {\"documents\": documents, \"question\": better_question}" ] }, { @@ -371,7 +536,74 @@ "metadata": {}, "outputs": [], "source": [ - "### Edges\n\n\ndef decide_to_generate(state):\n \"\"\"\n Determines whether to generate an answer, or re-generate a question.\n\n Args:\n state (dict): The current graph state\n\n Returns:\n str: Binary decision for next node to call\n \"\"\"\n\n print(\"---ASSESS GRADED DOCUMENTS---\")\n state[\"question\"]\n filtered_documents = state[\"documents\"]\n\n if not filtered_documents:\n # All documents have been filtered check_relevance\n # We will re-generate a new query\n print(\n \"---DECISION: ALL DOCUMENTS ARE NOT RELEVANT TO QUESTION, TRANSFORM QUERY---\"\n )\n return \"transform_query\"\n else:\n # We have relevant documents, so generate answer\n print(\"---DECISION: GENERATE---\")\n return \"generate\"\n\n\ndef grade_generation_v_documents_and_question(state):\n \"\"\"\n Determines whether the generation is grounded in the document and answers question.\n\n Args:\n state (dict): The current graph state\n\n Returns:\n str: Decision for next node to call\n \"\"\"\n\n print(\"---CHECK HALLUCINATIONS---\")\n question = state[\"question\"]\n documents = state[\"documents\"]\n generation = state[\"generation\"]\n\n score = hallucination_grader.invoke(\n {\"documents\": documents, \"generation\": generation}\n )\n grade = score.binary_score\n\n # Check hallucination\n if grade == \"yes\":\n print(\"---DECISION: GENERATION IS GROUNDED IN DOCUMENTS---\")\n # Check question-answering\n print(\"---GRADE GENERATION vs QUESTION---\")\n score = answer_grader.invoke({\"question\": question, \"generation\": generation})\n grade = score.binary_score\n if grade == \"yes\":\n print(\"---DECISION: GENERATION ADDRESSES QUESTION---\")\n return \"useful\"\n else:\n print(\"---DECISION: GENERATION DOES NOT ADDRESS QUESTION---\")\n return \"not useful\"\n else:\n pprint(\"---DECISION: GENERATION IS NOT GROUNDED IN DOCUMENTS, RE-TRY---\")\n return \"not supported\"" + "### Edges\n", + "\n", + "\n", + "def decide_to_generate(state):\n", + " \"\"\"\n", + " Determines whether to generate an answer, or re-generate a question.\n", + "\n", + " Args:\n", + " state (dict): The current graph state\n", + "\n", + " Returns:\n", + " str: Binary decision for next node to call\n", + " \"\"\"\n", + "\n", + " print(\"---ASSESS GRADED DOCUMENTS---\")\n", + " state[\"question\"]\n", + " filtered_documents = state[\"documents\"]\n", + "\n", + " if not filtered_documents:\n", + " # All documents have been filtered check_relevance\n", + " # We will re-generate a new query\n", + " print(\n", + " \"---DECISION: ALL DOCUMENTS ARE NOT RELEVANT TO QUESTION, TRANSFORM QUERY---\"\n", + " )\n", + " return \"transform_query\"\n", + " else:\n", + " # We have relevant documents, so generate answer\n", + " print(\"---DECISION: GENERATE---\")\n", + " return \"generate\"\n", + "\n", + "\n", + "def grade_generation_v_documents_and_question(state):\n", + " \"\"\"\n", + " Determines whether the generation is grounded in the document and answers question.\n", + "\n", + " Args:\n", + " state (dict): The current graph state\n", + "\n", + " Returns:\n", + " str: Decision for next node to call\n", + " \"\"\"\n", + "\n", + " print(\"---CHECK HALLUCINATIONS---\")\n", + " question = state[\"question\"]\n", + " documents = state[\"documents\"]\n", + " generation = state[\"generation\"]\n", + "\n", + " score = hallucination_grader.invoke(\n", + " {\"documents\": documents, \"generation\": generation}\n", + " )\n", + " grade = score.binary_score\n", + "\n", + " # Check hallucination\n", + " if grade == \"yes\":\n", + " print(\"---DECISION: GENERATION IS GROUNDED IN DOCUMENTS---\")\n", + " # Check question-answering\n", + " print(\"---GRADE GENERATION vs QUESTION---\")\n", + " score = answer_grader.invoke({\"question\": question, \"generation\": generation})\n", + " grade = score.binary_score\n", + " if grade == \"yes\":\n", + " print(\"---DECISION: GENERATION ADDRESSES QUESTION---\")\n", + " return \"useful\"\n", + " else:\n", + " print(\"---DECISION: GENERATION DOES NOT ADDRESS QUESTION---\")\n", + " return \"not useful\"\n", + " else:\n", + " pprint(\"---DECISION: GENERATION IS NOT GROUNDED IN DOCUMENTS, RE-TRY---\")\n", + " return \"not supported\"" ] }, { @@ -390,7 +622,42 @@ "id": "0e09ca9f-e36d-4ef4-a0d5-79fdbada9fe0", "metadata": {}, "outputs": [], - "source": ["from langgraph.graph import END, StateGraph, START\n\nworkflow = StateGraph(GraphState)\n\n# Define the nodes\nworkflow.add_node(\"retrieve\", retrieve) # retrieve\nworkflow.add_node(\"grade_documents\", grade_documents) # grade documents\nworkflow.add_node(\"generate\", generate) # generate\nworkflow.add_node(\"transform_query\", transform_query) # transform_query\n\n# Build graph\nworkflow.add_edge(START, \"retrieve\")\nworkflow.add_edge(\"retrieve\", \"grade_documents\")\nworkflow.add_conditional_edges(\n \"grade_documents\",\n decide_to_generate,\n {\n \"transform_query\": \"transform_query\",\n \"generate\": \"generate\",\n },\n)\nworkflow.add_edge(\"transform_query\", \"retrieve\")\nworkflow.add_conditional_edges(\n \"generate\",\n grade_generation_v_documents_and_question,\n {\n \"not supported\": \"generate\",\n \"useful\": END,\n \"not useful\": \"transform_query\",\n },\n)\n\n# Compile\napp = workflow.compile()"] + "source": [ + "from langgraph.graph import END, StateGraph, START\n", + "\n", + "workflow = StateGraph(GraphState)\n", + "\n", + "# Define the nodes\n", + "workflow.add_node(\"retrieve\", retrieve) # retrieve\n", + "workflow.add_node(\"grade_documents\", grade_documents) # grade documents\n", + "workflow.add_node(\"generate\", generate) # generate\n", + "workflow.add_node(\"transform_query\", transform_query) # transform_query\n", + "\n", + "# Build graph\n", + "workflow.add_edge(START, \"retrieve\")\n", + "workflow.add_edge(\"retrieve\", \"grade_documents\")\n", + "workflow.add_conditional_edges(\n", + " \"grade_documents\",\n", + " decide_to_generate,\n", + " {\n", + " \"transform_query\": \"transform_query\",\n", + " \"generate\": \"generate\",\n", + " },\n", + ")\n", + "workflow.add_edge(\"transform_query\", \"retrieve\")\n", + "workflow.add_conditional_edges(\n", + " \"generate\",\n", + " grade_generation_v_documents_and_question,\n", + " {\n", + " \"not supported\": \"generate\",\n", + " \"useful\": END,\n", + " \"not useful\": \"transform_query\",\n", + " },\n", + ")\n", + "\n", + "# Compile\n", + "app = workflow.compile()" + ] }, { "cell_type": "code", @@ -426,7 +693,18 @@ } ], "source": [ - "from pprint import pprint\n\n# Run\ninputs = {\"question\": \"Movies that star Daniel Craig\"}\nfor output in app.stream(inputs):\n for key, value in output.items():\n # Node\n pprint(f\"Node '{key}':\")\n pprint(\"\\n---\\n\")\n\n# Final generation\npprint(value[\"generation\"])" + "from pprint import pprint\n", + "\n", + "# Run\n", + "inputs = {\"question\": \"Movies that star Daniel Craig\"}\n", + "for output in app.stream(inputs):\n", + " for key, value in output.items():\n", + " # Node\n", + " pprint(f\"Node '{key}':\")\n", + " pprint(\"\\n---\\n\")\n", + "\n", + "# Final generation\n", + "pprint(value[\"generation\"])" ] }, { @@ -436,7 +714,15 @@ "metadata": {}, "outputs": [], "source": [ - "inputs = {\"question\": \"Which movies are about aliens?\"}\nfor output in app.stream(inputs):\n for key, value in output.items():\n # Node\n pprint(f\"Node '{key}':\")\n pprint(\"\\n---\\n\")\n\n# Final generation\npprint(value[\"generation\"])" + "inputs = {\"question\": \"Which movies are about aliens?\"}\n", + "for output in app.stream(inputs):\n", + " for key, value in output.items():\n", + " # Node\n", + " pprint(f\"Node '{key}':\")\n", + " pprint(\"\\n---\\n\")\n", + "\n", + "# Final generation\n", + "pprint(value[\"generation\"])" ] }, { @@ -445,9 +731,7 @@ "id": "42369ab8-322d-434a-b5dd-2266e4cb2903", "metadata": {}, "outputs": [], - "source": [ - "" - ] + "source": [] } ], "metadata": { diff --git a/examples/react-agent-from-scratch.ipynb b/examples/react-agent-from-scratch.ipynb index 98514b13c..37e605cee 100644 --- a/examples/react-agent-from-scratch.ipynb +++ b/examples/react-agent-from-scratch.ipynb @@ -5,7 +5,14 @@ "id": "294995c4", "metadata": {}, "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/how-tos/react-agent-from-scratch.ipynb" + "[This file has been moved](https://github.com/langchain-ai/langgraph/blob/23961cff61a42b52525f3b20b4094d8d2fba1744/docs/docs/how-tos/react-agent-from-scratch.ipynb)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This directory is retained purely for archival purposes and is no longer updated. The examples previously found here have been moved to the newly [consolidated LangChain documentation](https://docs.langchain.com/oss/python/langgraph/overview)." ] } ], diff --git a/examples/react-agent-structured-output.ipynb b/examples/react-agent-structured-output.ipynb index 180becb37..8a4bd9b7f 100644 --- a/examples/react-agent-structured-output.ipynb +++ b/examples/react-agent-structured-output.ipynb @@ -5,7 +5,14 @@ "id": "40f0d107", "metadata": {}, "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/how-tos/react-agent-structured-output.ipynb" + "[This file has been moved](https://github.com/langchain-ai/langgraph/blob/23961cff61a42b52525f3b20b4094d8d2fba1744/docs/docs/how-tos/react-agent-structured-output.ipynb)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This directory is retained purely for archival purposes and is no longer updated. The examples previously found here have been moved to the newly [consolidated LangChain documentation](https://docs.langchain.com/oss/python/langgraph/overview)." ] } ], diff --git a/examples/recursion-limit.ipynb b/examples/recursion-limit.ipynb deleted file mode 100644 index 7d383f967..000000000 --- a/examples/recursion-limit.ipynb +++ /dev/null @@ -1,33 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "fa3f7c50", - "metadata": {}, - "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/how-tos/recursion-limit.ipynb" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "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.9" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/examples/reflection/reflection.ipynb b/examples/reflection/reflection.ipynb index 4facaf3b4..63fea05d0 100644 --- a/examples/reflection/reflection.ipynb +++ b/examples/reflection/reflection.ipynb @@ -5,7 +5,15 @@ "id": "658773a2", "metadata": {}, "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/tutorials/reflection/reflection.ipynb" + "[This file has been moved](https://github.com/langchain-ai/langgraph/blob/23961cff61a42b52525f3b20b4094d8d2fba1744/docs/docs/tutorials/reflection/reflection.ipynb)" + ] + }, + { + "cell_type": "markdown", + "id": "1cb60657", + "metadata": {}, + "source": [ + "This directory is retained purely for archival purposes and is no longer updated. The examples previously found here have been moved to the newly [consolidated LangChain documentation](https://docs.langchain.com/oss/python/langgraph/overview)." ] } ], diff --git a/examples/reflexion/reflexion.ipynb b/examples/reflexion/reflexion.ipynb index 71c21c5ff..481395dd9 100644 --- a/examples/reflexion/reflexion.ipynb +++ b/examples/reflexion/reflexion.ipynb @@ -5,7 +5,15 @@ "id": "caf07859", "metadata": {}, "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/tutorials/reflexion/reflexion.ipynb" + "[This file has been moved](https://github.com/langchain-ai/langgraph/blob/23961cff61a42b52525f3b20b4094d8d2fba1744/docs/docs/tutorials/reflexion/reflexion.ipynb)" + ] + }, + { + "cell_type": "markdown", + "id": "cd1df0e0", + "metadata": {}, + "source": [ + "This directory is retained purely for archival purposes and is no longer updated. The examples previously found here have been moved to the newly [consolidated LangChain documentation](https://docs.langchain.com/oss/python/langgraph/overview)." ] } ], diff --git a/examples/rewoo/rewoo.ipynb b/examples/rewoo/rewoo.ipynb index b5df4d0c6..add5406e2 100644 --- a/examples/rewoo/rewoo.ipynb +++ b/examples/rewoo/rewoo.ipynb @@ -5,7 +5,15 @@ "id": "961f43ec", "metadata": {}, "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/tutorials/rewoo/rewoo.ipynb" + "[This file has been moved](https://github.com/langchain-ai/langgraph/blob/23961cff61a42b52525f3b20b4094d8d2fba1744/docs/docs/tutorials/rewoo/rewoo.ipynb)" + ] + }, + { + "cell_type": "markdown", + "id": "7f00c427", + "metadata": {}, + "source": [ + "This directory is retained purely for archival purposes and is no longer updated. The examples previously found here have been moved to the newly [consolidated LangChain documentation](https://docs.langchain.com/oss/python/langgraph/overview)." ] } ], diff --git a/examples/run-id-langsmith.ipynb b/examples/run-id-langsmith.ipynb index 257c70c31..19f46a167 100644 --- a/examples/run-id-langsmith.ipynb +++ b/examples/run-id-langsmith.ipynb @@ -5,7 +5,14 @@ "id": "bbd6e9b8", "metadata": {}, "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/how-tos/run-id-langsmith.ipynb" + "[This file has been moved](https://github.com/langchain-ai/langgraph/blob/23961cff61a42b52525f3b20b4094d8d2fba1744/docs/docs/how-tos/run-id-langsmith.md)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This directory is retained purely for archival purposes and is no longer updated. The examples previously found here have been moved to the newly [consolidated LangChain documentation](https://docs.langchain.com/oss/python/langgraph/overview)." ] } ], diff --git a/examples/self-discover/self-discover.ipynb b/examples/self-discover/self-discover.ipynb index 0f0d6ad20..ccdf3b722 100644 --- a/examples/self-discover/self-discover.ipynb +++ b/examples/self-discover/self-discover.ipynb @@ -5,7 +5,15 @@ "id": "f6db1873", "metadata": {}, "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/tutorials/self-discover/self-discover.ipynb" + "[This file has been moved](https://github.com/langchain-ai/langgraph/blob/23961cff61a42b52525f3b20b4094d8d2fba1744/docs/docs/tutorials/self-discover/self-discover.ipynb)" + ] + }, + { + "cell_type": "markdown", + "id": "219a78f9", + "metadata": {}, + "source": [ + "This directory is retained purely for archival purposes and is no longer updated. The examples previously found here have been moved to the newly [consolidated LangChain documentation](https://docs.langchain.com/oss/python/langgraph/overview)." ] } ], diff --git a/examples/state-model.ipynb b/examples/state-model.ipynb deleted file mode 100644 index 7c6b27782..000000000 --- a/examples/state-model.ipynb +++ /dev/null @@ -1,33 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "4149ffcc", - "metadata": {}, - "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/how-tos/state-model.ipynb" - ] - } - ], - "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.9" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/examples/storm/storm.ipynb b/examples/storm/storm.ipynb deleted file mode 100644 index fc5088867..000000000 --- a/examples/storm/storm.ipynb +++ /dev/null @@ -1,33 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "3e05d7f9", - "metadata": {}, - "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/tutorials/storm/storm.ipynb" - ] - } - ], - "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.12.2" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/examples/stream-multiple.ipynb b/examples/stream-multiple.ipynb deleted file mode 100644 index d55e6d6bb..000000000 --- a/examples/stream-multiple.ipynb +++ /dev/null @@ -1,33 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "e663f597", - "metadata": {}, - "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/how-tos/stream-multiple.ipynb" - ] - } - ], - "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.9" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/examples/stream-updates.ipynb b/examples/stream-updates.ipynb deleted file mode 100644 index d7b86fc8c..000000000 --- a/examples/stream-updates.ipynb +++ /dev/null @@ -1,33 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "e6829c80", - "metadata": {}, - "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/how-tos/stream-updates.ipynb" - ] - } - ], - "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.9" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/examples/stream-values.ipynb b/examples/stream-values.ipynb deleted file mode 100644 index c98939826..000000000 --- a/examples/stream-values.ipynb +++ /dev/null @@ -1,33 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "5ec11895", - "metadata": {}, - "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/how-tos/stream-values.ipynb" - ] - } - ], - "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.9" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/examples/streaming-content.ipynb b/examples/streaming-content.ipynb deleted file mode 100644 index 5135bccd1..000000000 --- a/examples/streaming-content.ipynb +++ /dev/null @@ -1,33 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "6619387c", - "metadata": {}, - "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/how-tos/streaming-content.ipynb" - ] - } - ], - "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.9" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/examples/streaming-events-from-within-tools-without-langchain.ipynb b/examples/streaming-events-from-within-tools-without-langchain.ipynb deleted file mode 100644 index ce53577ce..000000000 --- a/examples/streaming-events-from-within-tools-without-langchain.ipynb +++ /dev/null @@ -1,33 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "57b7e303", - "metadata": {}, - "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/how-tos/streaming-events-from-within-tools-without-langchain.ipynb" - ] - } - ], - "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.9" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/examples/streaming-events-from-within-tools.ipynb b/examples/streaming-events-from-within-tools.ipynb deleted file mode 100644 index 66060a4fb..000000000 --- a/examples/streaming-events-from-within-tools.ipynb +++ /dev/null @@ -1,33 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "8e71a0c8", - "metadata": {}, - "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/how-tos/streaming-events-from-within-tools.ipynb" - ] - } - ], - "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.9" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/examples/streaming-from-final-node.ipynb b/examples/streaming-from-final-node.ipynb deleted file mode 100644 index 2f1142f30..000000000 --- a/examples/streaming-from-final-node.ipynb +++ /dev/null @@ -1,33 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "756e4554", - "metadata": {}, - "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/how-tos/streaming-from-final-node.ipynb" - ] - } - ], - "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.9" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/examples/streaming-subgraphs.ipynb b/examples/streaming-subgraphs.ipynb deleted file mode 100644 index 83d94ba98..000000000 --- a/examples/streaming-subgraphs.ipynb +++ /dev/null @@ -1,33 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "47164a72", - "metadata": {}, - "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/how-tos/streaming-subgraphs.ipynb" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "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.9" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/examples/streaming-tokens-without-langchain.ipynb b/examples/streaming-tokens-without-langchain.ipynb deleted file mode 100644 index b16de62c6..000000000 --- a/examples/streaming-tokens-without-langchain.ipynb +++ /dev/null @@ -1,33 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "218dfbcb", - "metadata": {}, - "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/how-tos/streaming-tokens-without-langchain.ipynb" - ] - } - ], - "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.9" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/examples/streaming-tokens.ipynb b/examples/streaming-tokens.ipynb deleted file mode 100644 index 46dd92dec..000000000 --- a/examples/streaming-tokens.ipynb +++ /dev/null @@ -1,33 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "99eb887e", - "metadata": {}, - "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/how-tos/streaming-tokens.ipynb" - ] - } - ], - "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.9" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/examples/subgraph-transform-state.ipynb b/examples/subgraph-transform-state.ipynb deleted file mode 100644 index 62e8d3781..000000000 --- a/examples/subgraph-transform-state.ipynb +++ /dev/null @@ -1,33 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "0de7689f", - "metadata": {}, - "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/how-tos/subgraph-transform-state.ipynb" - ] - } - ], - "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.9" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/examples/subgraph.ipynb b/examples/subgraph.ipynb index 7b3a31f55..d9822a8bf 100644 --- a/examples/subgraph.ipynb +++ b/examples/subgraph.ipynb @@ -5,7 +5,14 @@ "id": "f49876e1", "metadata": {}, "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/how-tos/subgraph.ipynb" + "[This file has been moved](https://github.com/langchain-ai/langgraph/blob/23961cff61a42b52525f3b20b4094d8d2fba1744/docs/docs/how-tos/subgraph.md)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This directory is retained purely for archival purposes and is no longer updated. The examples previously found here have been moved to the newly [consolidated LangChain documentation](https://docs.langchain.com/oss/python/langgraph/overview)." ] } ], diff --git a/examples/subgraphs-manage-state.ipynb b/examples/subgraphs-manage-state.ipynb deleted file mode 100644 index 113953122..000000000 --- a/examples/subgraphs-manage-state.ipynb +++ /dev/null @@ -1,33 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "5106959e", - "metadata": {}, - "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/how-tos/subgraphs-manage-state.ipynb" - ] - } - ], - "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.9" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/examples/tool-calling-errors.ipynb b/examples/tool-calling-errors.ipynb deleted file mode 100644 index 68628f21e..000000000 --- a/examples/tool-calling-errors.ipynb +++ /dev/null @@ -1,33 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "dc21501d", - "metadata": {}, - "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/how-tos/tool-calling-errors.ipynb" - ] - } - ], - "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.9" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/examples/tool-calling.ipynb b/examples/tool-calling.ipynb index 882b45640..ccec5fec4 100644 --- a/examples/tool-calling.ipynb +++ b/examples/tool-calling.ipynb @@ -5,7 +5,14 @@ "id": "7fd8bd65", "metadata": {}, "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/how-tos/tool-calling.ipynb" + "[This file has been moved](https://github.com/langchain-ai/langgraph/blob/23961cff61a42b52525f3b20b4094d8d2fba1744/docs/docs/how-tos/tool-calling.md)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This directory is retained purely for archival purposes and is no longer updated. The examples previously found here have been moved to the newly [consolidated LangChain documentation](https://docs.langchain.com/oss/python/langgraph/overview)." ] } ], diff --git a/examples/tutorials/sql-agent.ipynb b/examples/tutorials/sql-agent.ipynb index 5227230c0..b8ce442f7 100644 --- a/examples/tutorials/sql-agent.ipynb +++ b/examples/tutorials/sql-agent.ipynb @@ -5,7 +5,15 @@ "id": "83c2223f", "metadata": {}, "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/tutorials/sql-agent.ipynb" + "[This file has been moved](https://github.com/langchain-ai/langgraph/blob/23961cff61a42b52525f3b20b4094d8d2fba1744/docs/docs/tutorials/sql/sql-agent.md)" + ] + }, + { + "cell_type": "markdown", + "id": "57f924b1", + "metadata": {}, + "source": [ + "This directory is retained purely for archival purposes and is no longer updated. The examples previously found here have been moved to the newly [consolidated LangChain documentation](https://docs.langchain.com/oss/python/langgraph/overview)." ] } ], diff --git a/examples/tutorials/tnt-llm/tnt-llm.ipynb b/examples/tutorials/tnt-llm/tnt-llm.ipynb index 3c8421c29..5c562ac10 100644 --- a/examples/tutorials/tnt-llm/tnt-llm.ipynb +++ b/examples/tutorials/tnt-llm/tnt-llm.ipynb @@ -5,7 +5,15 @@ "id": "11140167", "metadata": {}, "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/tutorials/tnt-llm/tnt-llm.ipynb" + "[This file has been moved](https://github.com/langchain-ai/langgraph/blob/23961cff61a42b52525f3b20b4094d8d2fba1744/docs/docs/tutorials/tnt-llm/tnt-llm.ipynb)" + ] + }, + { + "cell_type": "markdown", + "id": "1a2ba3e6", + "metadata": {}, + "source": [ + "This directory is retained purely for archival purposes and is no longer updated. The examples previously found here have been moved to the newly [consolidated LangChain documentation](https://docs.langchain.com/oss/python/langgraph/overview)." ] } ], diff --git a/examples/usaco/usaco.ipynb b/examples/usaco/usaco.ipynb index 7b83b7926..f4667a77c 100644 --- a/examples/usaco/usaco.ipynb +++ b/examples/usaco/usaco.ipynb @@ -5,7 +5,15 @@ "id": "9dffdb54", "metadata": {}, "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/tutorials/usaco/usaco.ipynb" + "[This file has been moved](https://github.com/langchain-ai/langgraph/blob/23961cff61a42b52525f3b20b4094d8d2fba1744/docs/docs/tutorials/usaco/usaco.ipynb)" + ] + }, + { + "cell_type": "markdown", + "id": "579c9959", + "metadata": {}, + "source": [ + "This directory is retained purely for archival purposes and is no longer updated. The examples previously found here have been moved to the newly [consolidated LangChain documentation](https://docs.langchain.com/oss/python/langgraph/overview)." ] } ], diff --git a/examples/visualization.ipynb b/examples/visualization.ipynb deleted file mode 100644 index d4b383edc..000000000 --- a/examples/visualization.ipynb +++ /dev/null @@ -1,33 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "9c9cb15a", - "metadata": {}, - "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/how-tos/visualization.ipynb" - ] - } - ], - "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.9" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/examples/web-navigation/web_voyager.ipynb b/examples/web-navigation/web_voyager.ipynb index 2c1abdc0c..28990d51c 100644 --- a/examples/web-navigation/web_voyager.ipynb +++ b/examples/web-navigation/web_voyager.ipynb @@ -5,7 +5,15 @@ "id": "007ea2e9", "metadata": {}, "source": [ - "This file has been moved to https://github.com/langchain-ai/langgraph/blob/main/docs/docs/tutorials/web-navigation/web_voyager.ipynb" + "[This file has been moved](https://github.com/langchain-ai/langgraph/blob/23961cff61a42b52525f3b20b4094d8d2fba1744/docs/docs/tutorials/web-navigation/web_voyager.ipynb)" + ] + }, + { + "cell_type": "markdown", + "id": "f0d7b895", + "metadata": {}, + "source": [ + "This directory is retained purely for archival purposes and is no longer updated. The examples previously found here have been moved to the newly [consolidated LangChain documentation](https://docs.langchain.com/oss/python/langgraph/overview)." ] } ], diff --git a/libs/langgraph/langgraph/types.py b/libs/langgraph/langgraph/types.py index c8a798a38..3f95deb97 100644 --- a/libs/langgraph/langgraph/types.py +++ b/libs/langgraph/langgraph/types.py @@ -61,18 +61,22 @@ __all__ = ( Durability = Literal["sync", "async", "exit"] """Durability mode for the graph execution. -- `"sync"`: Changes are persisted synchronously before the next step starts. -- `"async"`: Changes are persisted asynchronously while the next step executes. -- `"exit"`: Changes are persisted only when the graph exits.""" + +- `'sync'`: Changes are persisted synchronously before the next step starts. +- `'async'`: Changes are persisted asynchronously while the next step executes. +- `'exit'`: Changes are persisted only when the graph exits. +""" All = Literal["*"] """Special value to indicate that graph should interrupt on all nodes.""" Checkpointer = None | bool | BaseCheckpointSaver """Type of the checkpointer to use for a subgraph. -- True enables persistent checkpointing for this subgraph. -- False disables checkpointing, even if the parent graph has a checkpointer. -- None inherits checkpointer from the parent graph.""" + +- `True` enables persistent checkpointing for this subgraph. +- `False` disables checkpointing, even if the parent graph has a checkpointer. +- `None` inherits checkpointer from the parent graph. +""" def ensure_valid_checkpointer(checkpointer: Checkpointer) -> Checkpointer: