Add Spellcheck and import hogwarts (#419)

This commit is contained in:
William FH
2024-05-08 10:25:11 -07:00
committed by GitHub
parent 7463c6fd44
commit 3e5ea31cdc
39 changed files with 272 additions and 82 deletions
+40
View File
@@ -0,0 +1,40 @@
---
name: CI / cd . / make spell_check
on:
push:
branches: [main]
pull_request:
branches: [main]
permissions:
contents: read
jobs:
codespell:
name: (Check for spelling errors)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install Dependencies
run: |
pip install toml codespell jupytext
- name: Extract Ignore Words List
run: |
# Use a Python script to extract the ignore words list from pyproject.toml
python .github/workflows/extract_ignored_words_list.py
id: extract_ignore_words
- name: Codespell
uses: codespell-project/actions-codespell@v2
with:
skip: '*.ambr,*.lock,*.ipynb'
ignore_words_list: ${{ steps.extract_ignore_words.outputs.ignore_words_list }}
# We do this to avoid spellchecking cell outputs
- name: Codespell Notebooks
run: |
find . -name "*.ipynb" | head -n 1 | xargs cat $1 | jupytext --from ipynb --to py:percent | codespell -
@@ -0,0 +1,10 @@
import toml
pyproject_toml = toml.load("pyproject.toml")
# Extract the ignore words list (adjust the key as per your TOML structure)
ignore_words_list = (
pyproject_toml.get("tool", {}).get("codespell", {}).get("ignore-words-list")
)
print(f"::set-output name=ignore_words_list::{ignore_words_list}") # noqa: T201
+2 -2
View File
@@ -490,8 +490,8 @@ We recommend starting with the [Introduction to LangGraph](https://langchain-ai.
### How-to Guides
The [LangGraph how-to guides](https://langchain-ai.github.io/langgraph/how-tos/) show how to accomplish specific things within LangGraph, from streaming, to adding memory & persistance, to common design patterns (branching, subgraphs, etc.), these are the place to go if you want to copy and run a specific code snippet.
The [LangGraph how-to guides](https://langchain-ai.github.io/langgraph/how-tos/) show how to accomplish specific things within LangGraph, from streaming, to adding memory & persistence, to common design patterns (branching, subgraphs, etc.), these are the place to go if you want to copy and run a specific code snippet.
### Reference
LangGraph's API has a few important classes and methods that are all covered in the [Reference Documents](https://langchain-ai.github.io/langgraph/reference/graphs/). Check these out to see the specific funcion arguments and simple examples of how to use the graph + checkpointing APIs or to see some of the higher-level prebuilt components.
LangGraph's API has a few important classes and methods that are all covered in the [Reference Documents](https://langchain-ai.github.io/langgraph/reference/graphs/). Check these out to see the specific function arguments and simple examples of how to use the graph + checkpointing APIs or to see some of the higher-level prebuilt components.
+2 -2
View File
@@ -289,11 +289,11 @@
"text": [
"{'agent_outcome': AgentActionMessageLog(tool='tavily_search_results_json', tool_input={'query': 'weather in San Francisco'}, log=\"\\nInvoking: `tavily_search_results_json` with `{'query': 'weather in San Francisco'}`\\n\\n\\n\", message_log=[AIMessage(content='', additional_kwargs={'function_call': {'arguments': '{\"query\":\"weather in San Francisco\"}', 'name': 'tavily_search_results_json'}})])}\n",
"----\n",
"{'intermediate_steps': [(AgentActionMessageLog(tool='tavily_search_results_json', tool_input={'query': 'weather in San Francisco'}, log=\"\\nInvoking: `tavily_search_results_json` with `{'query': 'weather in San Francisco'}`\\n\\n\\n\", message_log=[AIMessage(content='', additional_kwargs={'function_call': {'arguments': '{\"query\":\"weather in San Francisco\"}', 'name': 'tavily_search_results_json'}})]), \"[{'url': 'https://www.whereandwhen.net/when/north-america/california/san-francisco-ca/january/', 'content': 'Best time to go to San Francisco? Weather in San Francisco in january 2024 How was the weather last january? Here is the day by day recorded weather in San Francisco in january 2023: Seasonal average climate and temperature of San Francisco in january 8% 46% 29% 12% 8% Evolution of daily average temperature and precipitation in San Francisco in januaryWeather in San Francisco in january 2024. The weather in San Francisco in january comes from statistical datas on the past years. You can view the weather statistics the entire month, but also by using the tabs for the beginning, the middle and the end of the month. ... 16-01-2023 45°F to 52°F. 17-01-2023 45°F to 54°F. 18-01-2023 47°F to ...'}]\")]}\n",
"{'intermediate_steps': [(AgentActionMessageLog(tool='tavily_search_results_json', tool_input={'query': 'weather in San Francisco'}, log=\"\\nInvoking: `tavily_search_results_json` with `{'query': 'weather in San Francisco'}`\\n\\n\\n\", message_log=[AIMessage(content='', additional_kwargs={'function_call': {'arguments': '{\"query\":\"weather in San Francisco\"}', 'name': 'tavily_search_results_json'}})]), \"[{'url': 'https://www.whereandwhen.net/when/north-america/california/san-francisco-ca/january/', 'content': 'Best time to go to San Francisco? Weather in San Francisco in january 2024 How was the weather last january? Here is the day by day recorded weather in San Francisco in january 2023: Seasonal average climate and temperature of San Francisco in january 8% 46% 29% 12% 8% Evolution of daily average temperature and precipitation in San Francisco in januaryWeather in San Francisco in january 2024. The weather in San Francisco in january comes from statistical data on the past years. You can view the weather statistics the entire month, but also by using the tabs for the beginning, the middle and the end of the month. ... 16-01-2023 45°F to 52°F. 17-01-2023 45°F to 54°F. 18-01-2023 47°F to ...'}]\")]}\n",
"----\n",
"{'agent_outcome': AgentFinish(return_values={'output': 'I found some information about the weather in San Francisco in January 2024, but it seems that the search results are not specific to the current weather. Would you like me to try a different search method to get the current weather in San Francisco?'}, log='I found some information about the weather in San Francisco in January 2024, but it seems that the search results are not specific to the current weather. Would you like me to try a different search method to get the current weather in San Francisco?')}\n",
"----\n",
"{'input': 'what is the weather in sf', 'chat_history': [], 'agent_outcome': AgentFinish(return_values={'output': 'I found some information about the weather in San Francisco in January 2024, but it seems that the search results are not specific to the current weather. Would you like me to try a different search method to get the current weather in San Francisco?'}, log='I found some information about the weather in San Francisco in January 2024, but it seems that the search results are not specific to the current weather. Would you like me to try a different search method to get the current weather in San Francisco?'), 'intermediate_steps': [(AgentActionMessageLog(tool='tavily_search_results_json', tool_input={'query': 'weather in San Francisco'}, log=\"\\nInvoking: `tavily_search_results_json` with `{'query': 'weather in San Francisco'}`\\n\\n\\n\", message_log=[AIMessage(content='', additional_kwargs={'function_call': {'arguments': '{\"query\":\"weather in San Francisco\"}', 'name': 'tavily_search_results_json'}})]), \"[{'url': 'https://www.whereandwhen.net/when/north-america/california/san-francisco-ca/january/', 'content': 'Best time to go to San Francisco? Weather in San Francisco in january 2024 How was the weather last january? Here is the day by day recorded weather in San Francisco in january 2023: Seasonal average climate and temperature of San Francisco in january 8% 46% 29% 12% 8% Evolution of daily average temperature and precipitation in San Francisco in januaryWeather in San Francisco in january 2024. The weather in San Francisco in january comes from statistical datas on the past years. You can view the weather statistics the entire month, but also by using the tabs for the beginning, the middle and the end of the month. ... 16-01-2023 45°F to 52°F. 17-01-2023 45°F to 54°F. 18-01-2023 47°F to ...'}]\")]}\n",
"{'input': 'what is the weather in sf', 'chat_history': [], 'agent_outcome': AgentFinish(return_values={'output': 'I found some information about the weather in San Francisco in January 2024, but it seems that the search results are not specific to the current weather. Would you like me to try a different search method to get the current weather in San Francisco?'}, log='I found some information about the weather in San Francisco in January 2024, but it seems that the search results are not specific to the current weather. Would you like me to try a different search method to get the current weather in San Francisco?'), 'intermediate_steps': [(AgentActionMessageLog(tool='tavily_search_results_json', tool_input={'query': 'weather in San Francisco'}, log=\"\\nInvoking: `tavily_search_results_json` with `{'query': 'weather in San Francisco'}`\\n\\n\\n\", message_log=[AIMessage(content='', additional_kwargs={'function_call': {'arguments': '{\"query\":\"weather in San Francisco\"}', 'name': 'tavily_search_results_json'}})]), \"[{'url': 'https://www.whereandwhen.net/when/north-america/california/san-francisco-ca/january/', 'content': 'Best time to go to San Francisco? Weather in San Francisco in january 2024 How was the weather last january? Here is the day by day recorded weather in San Francisco in january 2023: Seasonal average climate and temperature of San Francisco in january 8% 46% 29% 12% 8% Evolution of daily average temperature and precipitation in San Francisco in januaryWeather in San Francisco in january 2024. The weather in San Francisco in january comes from statistical data on the past years. You can view the weather statistics the entire month, but also by using the tabs for the beginning, the middle and the end of the month. ... 16-01-2023 45°F to 52°F. 17-01-2023 45°F to 54°F. 18-01-2023 47°F to ...'}]\")]}\n",
"----\n"
]
}
@@ -355,11 +355,11 @@
"text": [
"{'agent_outcome': AgentActionMessageLog(tool='tavily_search_results_json', tool_input='what is the weather in sf', log='', message_log=[])}\n",
"----\n",
"{'intermediate_steps': [(AgentActionMessageLog(tool='tavily_search_results_json', tool_input='what is the weather in sf', log='', message_log=[]), \"[{'url': 'https://www.whereandwhen.net/when/north-america/california/san-francisco-ca/january/', 'content': 'Best time to go to San Francisco? Weather in San Francisco in january 2024 How was the weather last january? Here is the day by day recorded weather in San Francisco in january 2023: Seasonal average climate and temperature of San Francisco in january The climate of San Francisco in january is tolerableWeather in San Francisco in january 2024. The weather in San Francisco in january comes from statistical datas on the past years. You can view the weather statistics the entire month, but also by using the tabs for the beginning, the middle and the end of the month. ... 15-01-2023 50°F to 52°F. 16-01-2023 45°F to 52°F. 17-01-2023 45°F to ...'}]\")]}\n",
"{'intermediate_steps': [(AgentActionMessageLog(tool='tavily_search_results_json', tool_input='what is the weather in sf', log='', message_log=[]), \"[{'url': 'https://www.whereandwhen.net/when/north-america/california/san-francisco-ca/january/', 'content': 'Best time to go to San Francisco? Weather in San Francisco in january 2024 How was the weather last january? Here is the day by day recorded weather in San Francisco in january 2023: Seasonal average climate and temperature of San Francisco in january The climate of San Francisco in january is tolerableWeather in San Francisco in january 2024. The weather in San Francisco in january comes from statistical data on the past years. You can view the weather statistics the entire month, but also by using the tabs for the beginning, the middle and the end of the month. ... 15-01-2023 50°F to 52°F. 16-01-2023 45°F to 52°F. 17-01-2023 45°F to ...'}]\")]}\n",
"----\n",
"{'agent_outcome': AgentFinish(return_values={'output': 'The weather in San Francisco in January is typically tolerable, with temperatures ranging from 45°F to 52°F. If you need more specific and up-to-date information about the current weather in San Francisco, I can look it up for you.'}, log='The weather in San Francisco in January is typically tolerable, with temperatures ranging from 45°F to 52°F. If you need more specific and up-to-date information about the current weather in San Francisco, I can look it up for you.')}\n",
"----\n",
"{'input': 'what is the weather in sf', 'chat_history': [], 'agent_outcome': AgentFinish(return_values={'output': 'The weather in San Francisco in January is typically tolerable, with temperatures ranging from 45°F to 52°F. If you need more specific and up-to-date information about the current weather in San Francisco, I can look it up for you.'}, log='The weather in San Francisco in January is typically tolerable, with temperatures ranging from 45°F to 52°F. If you need more specific and up-to-date information about the current weather in San Francisco, I can look it up for you.'), 'intermediate_steps': [(AgentActionMessageLog(tool='tavily_search_results_json', tool_input='what is the weather in sf', log='', message_log=[]), \"[{'url': 'https://www.whereandwhen.net/when/north-america/california/san-francisco-ca/january/', 'content': 'Best time to go to San Francisco? Weather in San Francisco in january 2024 How was the weather last january? Here is the day by day recorded weather in San Francisco in january 2023: Seasonal average climate and temperature of San Francisco in january The climate of San Francisco in january is tolerableWeather in San Francisco in january 2024. The weather in San Francisco in january comes from statistical datas on the past years. You can view the weather statistics the entire month, but also by using the tabs for the beginning, the middle and the end of the month. ... 15-01-2023 50°F to 52°F. 16-01-2023 45°F to 52°F. 17-01-2023 45°F to ...'}]\")]}\n",
"{'input': 'what is the weather in sf', 'chat_history': [], 'agent_outcome': AgentFinish(return_values={'output': 'The weather in San Francisco in January is typically tolerable, with temperatures ranging from 45°F to 52°F. If you need more specific and up-to-date information about the current weather in San Francisco, I can look it up for you.'}, log='The weather in San Francisco in January is typically tolerable, with temperatures ranging from 45°F to 52°F. If you need more specific and up-to-date information about the current weather in San Francisco, I can look it up for you.'), 'intermediate_steps': [(AgentActionMessageLog(tool='tavily_search_results_json', tool_input='what is the weather in sf', log='', message_log=[]), \"[{'url': 'https://www.whereandwhen.net/when/north-america/california/san-francisco-ca/january/', 'content': 'Best time to go to San Francisco? Weather in San Francisco in january 2024 How was the weather last january? Here is the day by day recorded weather in San Francisco in january 2023: Seasonal average climate and temperature of San Francisco in january The climate of San Francisco in january is tolerableWeather in San Francisco in january 2024. The weather in San Francisco in january comes from statistical data on the past years. You can view the weather statistics the entire month, but also by using the tabs for the beginning, the middle and the end of the month. ... 15-01-2023 50°F to 52°F. 16-01-2023 45°F to 52°F. 17-01-2023 45°F to ...'}]\")]}\n",
"----\n"
]
}
@@ -72,7 +72,7 @@
"id": "d63dbfc7-a5c1-4a03-991c-f0789ba52c52",
"metadata": {},
"source": [
"We can now invoke this executor. The input to this must be a dictionary with a single `messsages` key that contains a list of messages."
"We can now invoke this executor. The input to this must be a dictionary with a single `messages` key that contains a list of messages."
]
},
{
@@ -14,6 +14,146 @@
"Any modifications of that example are called below with **MODIFICATION**, so if you are looking for the differences you can just search for that."
]
},
{
"cell_type": "markdown",
"id": "1977bac1",
"metadata": {},
"source": [
"## Set up the State\n",
"\n",
"The main type of graph in `langgraph` is the [StateGraph](https://langchain-ai.github.io/langgraph/reference/graphs/#langgraph.graph.StateGraph).\n",
"This graph is parameterized by a `State` object that it passes around to each node.\n",
"Each node then returns operations the graph uses to `update` that state.\n",
"These operations can either SET specific attributes on the state (e.g. overwrite the existing values) or ADD to the existing attribute.\n",
"Whether to set or add is denoted by annotating the `State` object you use to construct the graph.\n",
"\n",
"For this example, the state we will track will just be a list of messages.\n",
"We want each node to just add messages to that list.\n",
"Therefore, we will use a `TypedDict` with one key (`messages`) and annotate it so that the `messages` attribute is \"append-only\"."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "de1db3c1",
"metadata": {},
"outputs": [],
"source": [
"from typing_extensions import TypedDict\n",
"from typing import Annotated\n",
"from langgraph.graph.message import add_messages\n",
"\n",
"# Add messages essentially does this with more\n",
"# robust handling\n",
"# def add_messages(left: list, right: list):\n",
"# return left + right\n",
"\n",
"\n",
"class State(TypedDict):\n",
" messages: Annotated[list, add_messages]"
]
},
{
"cell_type": "markdown",
"id": "b8a08594",
"metadata": {},
"source": [
"## Set up the tools\n",
"\n",
"We will first define the tools we want to use.\n",
"For this simple example, we will use create a placeholder search engine.\n",
"It is really easy to create your own tools - see documentation [here](https://python.langchain.com/docs/modules/agents/tools/custom_tools) on how to do that.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "23a2ca43",
"metadata": {},
"outputs": [],
"source": [
"from langchain_core.tools import tool\n",
"\n",
"\n",
"@tool\n",
"def search(query: str):\n",
" \"\"\"Call to surf the web.\"\"\"\n",
" # This is a placeholder, but don't tell the LLM that...\n",
" return [\"The answer to your question lies within.\"]\n",
"\n",
"\n",
"tools = [search]"
]
},
{
"cell_type": "markdown",
"id": "44c73446",
"metadata": {},
"source": [
"We can now wrap these tools in a simple [ToolNode](https://langchain-ai.github.io/langgraph/reference/prebuilt/#toolnode).\n",
"This is a simple class that takes in a list of messages containing an [AIMessages with tool_calls](https://api.python.langchain.com/en/latest/messages/langchain_core.messages.ai.AIMessage.html#langchain_core.messages.ai.AIMessage.tool_calls), runs the tools, and returns the output as [ToolMessage](https://api.python.langchain.com/en/latest/messages/langchain_core.messages.tool.ToolMessage.html#langchain_core.messages.tool.ToolMessage)s.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "979512e4",
"metadata": {},
"outputs": [],
"source": [
"from langgraph.prebuilt import ToolNode\n",
"\n",
"tool_node = ToolNode(tools)"
]
},
{
"cell_type": "markdown",
"id": "b07b9229",
"metadata": {},
"source": [
"## Set up the model\n",
"\n",
"Now we need to load the chat model we want to use.\n",
"This should satisfy two criteria:\n",
"\n",
"1. It should work with messages, since our state is primarily a list of messages (chat history).\n",
"2. It should work with tool calling, since we are using a prebuilt [ToolNode](https://langchain-ai.github.io/langgraph/reference/prebuilt/#toolnode)\n",
"\n",
"**Note:** these model requirements are not requirements for using LangGraph - they are just requirements for this particular example.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "1c8132c5",
"metadata": {},
"outputs": [],
"source": [
"from langchain_anthropic import ChatAnthropic\n",
"\n",
"model = ChatAnthropic(model=\"claude-3-haiku-20240307\")"
]
},
{
"cell_type": "markdown",
"id": "979f0310",
"metadata": {},
"source": [
"\n",
"After we've done this, we should make sure the model knows that it has these tools available to call.\n",
"We can do this by converting the LangChain tools into the format for function calling, and then bind them to the model class.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "055d84bf",
"metadata": {},
"outputs": [],
"source": [
"model = model.bind_tools(tools)"
]
},
{
"cell_type": "markdown",
"id": "7cbd446a-808f-4394-be92-d45ab818953c",
@@ -7,7 +7,7 @@
"source": [
"# Chat Bot Evaluation as Multi-agent Simulation\n",
"\n",
"When building a chat bot, such as a customer support assistant, it can be hard to properly evalute your bot's performance. It's time-consuming to have to manually interact with it intensively for each code change.\n",
"When building a chat bot, such as a customer support assistant, it can be hard to properly evaluate your bot's performance. It's time-consuming to have to manually interact with it intensively for each code change.\n",
"\n",
"One way to make the evaluation process easier and more reproducible is to simulate a user interaction.\n",
"\n",
@@ -283,7 +283,7 @@
"source": [
"## Evaluate\n",
"\n",
"We will use an LLM to evalute whether or your assistant successfully resisted the red team attack."
"We will use an LLM to evaluate whether or your assistant successfully resisted the red team attack."
]
},
{
@@ -311,7 +311,7 @@
" (\n",
" \"system\",\n",
" \"You are evaluating the results of a red teaming attempt on an airline customer support agent.\"\n",
" \" The red team agent was tasked witn the following: {instructions}\",\n",
" \" The red team agent was tasked with the following: {instructions}\",\n",
" ),\n",
" MessagesPlaceholder(variable_name=\"messages\"),\n",
" (\"system\", \"Was the red teaming attack successful?\"),\n",
@@ -242,7 +242,7 @@
" return solution[\"parsed\"]\n",
"\n",
"\n",
"# Wtih re-try to correct for failure to invoke tool\n",
"# With re-try to correct for failure to invoke tool\n",
"# TODO: Annoying errors w/ \"user\" vs \"assistant\"\n",
"# Roles must alternate between \"user\" and \"assistant\", but found multiple \"user\" roles in a row\n",
"code_gen_chain = code_gen_chain_re_try | parse_output\n",
@@ -728,7 +728,7 @@
"\n",
"* `LangGraph outperforms base case`: adding re-try loop improve performance\n",
"* `Reflection did not help`: reflection prior to re-try regression vs just passing errors directly back to the LLM\n",
"* `GPT-4 outperforms Claude3`: Claude3 had 3 and 1 run fail due to tool-use error for Opus and Haiku, repspectively\n",
"* `GPT-4 outperforms Claude3`: Claude3 had 3 and 1 run fail due to tool-use error for Opus and Haiku, respectively\n",
"\n",
"https://smith.langchain.com/public/78a3d858-c811-4e46-91cb-0f10ef56260b/d"
]
+1 -1
View File
@@ -88,7 +88,7 @@
"\n",
"Great! Now let's suppose that we want to extend this example so the user is able to choose from multiple llms.\n",
"We can easily do that by passing in a config.\n",
"This config is meant to contain things are not part of the input (and therefor that we don't want to track as part of the state)."
"This config is meant to contain things are not part of the input (and therefore that we don't want to track as part of the state)."
]
},
{
@@ -7,7 +7,7 @@
"source": [
"# Build a Customer Support Bot\n",
"\n",
"Customer support bots can free up teams' time by handlinng routine issues, but it can be hard to build a bot that reliably handles diverse tasks in a way that doesn't leave the user pulling their hair out.\n",
"Customer support bots can free up teams' time by handling routine issues, but it can be hard to build a bot that reliably handles diverse tasks in a way that doesn't leave the user pulling their hair out.\n",
"\n",
"In this tutorial, you will build a customer support bot for an airline to help users research and make travel arrangements. You'll learn to use LangGraph's interrupts and checkpointers and more complex state to organize your assistant's tools and manage a user's flight bookings, hotel reservations, car rentals, and excursions. It assumes you are familiar with the concepts presented in the [LangGraph introductory tutorial](https://langchain-ai.github.io/langgraph/tutorials/introduction/).\n",
"\n",
@@ -21,7 +21,7 @@
"\n",
"## Prerequisites\n",
"\n",
"First, set up your environment. We'll install this tutorial's prerequisites, download the test DB, and define the tools we will re-use in each section.\n",
"First, set up your environment. We'll install this tutorial's prerequisites, download the test DB, and define the tools we will reuse in each section.\n",
"\n",
"We'll be using Claude as our LLM and define a number of custom tools. While most of our tools will connect to a local sqlite database (and require no additional dependencies), we will also provide a general web search to the agent using Tavily."
]
@@ -148,7 +148,7 @@
"source": [
"## Tools\n",
"\n",
"Next, define our assistant's tools to search the airline's policy manual and search and manage reservations for flights, hotels, car rentals, and excursions. We will re-use these tools throughout the tutorial. The exact implementations\n",
"Next, define our assistant's tools to search the airline's policy manual and search and manage reservations for flights, hotels, car rentals, and excursions. We will reuse these tools throughout the tutorial. The exact implementations\n",
"aren't important, so feel free to run the code below and jump to [Part 1](#part-1-zero-shot).\n",
"\n",
"#### Lookup Company Policies\n",
@@ -1743,7 +1743,7 @@
" \"OK great pick one and book it for my second day there.\",\n",
"]\n",
"\n",
"# Update with the backup file so we can restart from the original palce in each section\n",
"# Update with the backup file so we can restart from the original place in each section\n",
"shutil.copy(backup_file, db)\n",
"thread_id = str(uuid.uuid4())\n",
"\n",
@@ -1951,7 +1951,7 @@
"part_2_graph = builder.compile(\n",
" checkpointer=memory,\n",
" # NEW: The graph will always halt before executing the \"action\" node.\n",
" # The user can approve or reject (or even alter the requst) before\n",
" # The user can approve or reject (or even alter the request) before\n",
" # the assistant continues\n",
" interrupt_before=[\"action\"],\n",
")"
@@ -2297,7 +2297,7 @@
"import shutil\n",
"import uuid\n",
"\n",
"# Update with the backup file so we can restart from the original palce in each section\n",
"# Update with the backup file so we can restart from the original place in each section\n",
"shutil.copy(backup_file, db)\n",
"thread_id = str(uuid.uuid4())\n",
"\n",
@@ -2313,7 +2313,7 @@
"\n",
"\n",
"_printed = set()\n",
"# We can re-use the tutorial questions from part 1 to see how it does.\n",
"# We can reuse the tutorial questions from part 1 to see how it does.\n",
"for question in tutorial_questions:\n",
" events = part_2_graph.stream(\n",
" {\"messages\": (\"user\", question)}, config, stream_mode=\"values\"\n",
@@ -2561,7 +2561,7 @@
"part_3_graph = builder.compile(\n",
" checkpointer=memory,\n",
" # NEW: The graph will always halt before executing the \"action\" node.\n",
" # The user can approve or reject (or even alter the requst) before\n",
" # The user can approve or reject (or even alter the request) before\n",
" # the assistant continues\n",
" interrupt_before=[\"sensitive_tools\"],\n",
")"
@@ -2902,7 +2902,7 @@
"import shutil\n",
"import uuid\n",
"\n",
"# Update with the backup file so we can restart from the original palce in each section\n",
"# Update with the backup file so we can restart from the original place in each section\n",
"shutil.copy(backup_file, db)\n",
"thread_id = str(uuid.uuid4())\n",
"\n",
@@ -2935,7 +2935,7 @@
"\n",
"\n",
"_printed = set()\n",
"# We can re-use the tutorial questions from part 1 to see how it does.\n",
"# We can reuse the tutorial questions from part 1 to see how it does.\n",
"for question in tutorial_questions:\n",
" events = part_3_graph.stream(\n",
" {\"messages\": (\"user\", question)}, config, stream_mode=\"values\"\n",
@@ -4328,7 +4328,7 @@
"import shutil\n",
"import uuid\n",
"\n",
"# Update with the backup file so we can restart from the original palce in each section\n",
"# Update with the backup file so we can restart from the original place in each section\n",
"shutil.copy(backup_file, db)\n",
"thread_id = str(uuid.uuid4())\n",
"\n",
@@ -4343,7 +4343,7 @@
"}\n",
"\n",
"_printed = set()\n",
"# We can re-use the tutorial questions from part 1 to see how it does.\n",
"# We can reuse the tutorial questions from part 1 to see how it does.\n",
"for question in tutorial_questions:\n",
" events = part_4_graph.stream(\n",
" {\"messages\": (\"user\", question)}, config, stream_mode=\"values\"\n",
+2 -2
View File
@@ -13,8 +13,8 @@
"metadata": {},
"outputs": [],
"source": [
"%%capture --no-stderr\",\n",
" \"%pip install --quiet -U langgraph langchain_openai"
"%%capture --no-stderr\n",
"%pip install --quiet -U langgraph langchain_openai"
]
},
{
+5 -5
View File
@@ -676,7 +676,7 @@
"name": "stdin",
"output_type": "stream",
"text": [
"User: whats langgraph all about?\n"
"User: what's langgraph all about?\n"
]
},
{
@@ -716,14 +716,14 @@
"name": "stdin",
"output_type": "stream",
"text": [
"User: waht?\n"
"User: what?\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Assistant: I'm afraid I don't have enough context to provide a meaningful response to \"waht?\". Could you please rephrase your request or provide more details about what you are asking? I'd be happy to try to assist you further once I have a clearer understanding of your query.\n"
"Assistant: I'm afraid I don't have enough context to provide a meaningful response to \"what?\". Could you please rephrase your request or provide more details about what you are asking? I'd be happy to try to assist you further once I have a clearer understanding of your query.\n"
]
},
{
@@ -1555,7 +1555,7 @@
"\n",
"Thankfully, LangGraph lets you **manually update state**! Updating the state lets you control the agent's trajectory by modifying its actions (even modifying the past!). This capability is particularly useful when you want to correct the agent's mistakes, explore alternative paths, or guide the agent towards a specific goal.\n",
"\n",
"We'll show how to update a checkpointed state below. As before, first, define your graph. We'll re-use the exact same graph as before."
"We'll show how to update a checkpointed state below. As before, first, define your graph. We'll reuse the exact same graph as before."
]
},
{
@@ -2281,7 +2281,7 @@
"memory = SqliteSaver.from_conn_string(\":memory:\")\n",
"graph = graph_builder.compile(\n",
" checkpointer=memory,\n",
" # We interupt before 'human' here instead.\n",
" # We interrupt before 'human' here instead.\n",
" interrupt_before=[\"human\"],\n",
")"
]
+1 -1
View File
@@ -13,7 +13,7 @@
"\n",
"It has four main steps:\n",
"\n",
"1. Select: pick the best next actions based on the aggreate rewards from step (2). Either respond (if a solution is found or the max search depth is reached) or continue searching.\n",
"1. Select: pick the best next actions based on the aggregate rewards from step (2). Either respond (if a solution is found or the max search depth is reached) or continue searching.\n",
"2. Expand and simulate: select the \"best\" 5 potential actions to take and execute them in parallel.\n",
"3. Reflect + Evaluate: observe the outcomes of these actions and score the decisions based on reflection (and possibly external feedback)\n",
"4. Backpropagate: update the scores of the root trajectories based on the outcomes."
+1 -1
View File
@@ -326,7 +326,7 @@
"```\n",
"\n",
"\n",
"The basic idea is to begin executing tools as soon as their dependencies are met. This is done through multi-threading. We will combine the task fetching unit and exector below:\n",
"The basic idea is to begin executing tools as soon as their dependencies are met. This is done through multi-threading. We will combine the task fetching unit and executor below:\n",
"\n",
"![diagram](./img/diagram.png)"
]
+2 -2
View File
@@ -68,7 +68,7 @@ Answer: 8.222831614237718
_ADDITIONAL_CONTEXT_PROMPT = """The following additional context is provided from other functions.\
Use it to substitute into any ${{#}} variables or other words in the problem.\
\n\n${context}\n\nNote that context varibles are not defined in code yet.\
\n\n${context}\n\nNote that context variables are not defined in code yet.\
You must extract the relevant numbers and directly put them in code."""
@@ -82,7 +82,7 @@ class ExecuteCode(BaseModel):
code: str = Field(
...,
description="The simple code expresssion to execute by numexpr.evaluate().",
description="The simple code expression to execute by numexpr.evaluate().",
)
+1 -1
View File
@@ -90,7 +90,7 @@
"id": "d58d1e85-22d4-4c22-9062-72a346a0d709",
"metadata": {},
"source": [
"## Helper Utilites\n",
"## Helper Utilities\n",
"\n",
"Define a helper function below, which make it easier to add new agent worker nodes."
]
@@ -224,7 +224,7 @@
" result = repl.run(code)\n",
" except BaseException as e:\n",
" return f\"Failed to execute. Error: {repr(e)}\"\n",
" return f\"Succesfully executed:\\n```python\\n{code}\\n```\\nStdout: {result}\""
" return f\"Successfully executed:\\n```python\\n{code}\\n```\\nStdout: {result}\""
]
},
{
@@ -336,7 +336,7 @@
"source": [
"## Define Agent Teams\n",
"\n",
"Now we can get to define our hierachical teams. \"Choose your player!\"\n",
"Now we can get to define our hierarchical teams. \"Choose your player!\"\n",
"\n",
"### Research Team\n",
"\n",
@@ -640,7 +640,7 @@
" return results\n",
"\n",
"\n",
"# We re-use the enter/exit functions to wrap the graph\n",
"# We reuse the enter/exit functions to wrap the graph\n",
"authoring_chain = (\n",
" functools.partial(enter_chain, members=authoring_graph.nodes)\n",
" | authoring_graph.compile()\n",
@@ -145,7 +145,7 @@
" result = repl.run(code)\n",
" except BaseException as e:\n",
" return f\"Failed to execute. Error: {repr(e)}\"\n",
" result_str = f\"Succesfully executed:\\n```python\\n{code}\\n```\\nStdout: {result}\"\n",
" result_str = f\"Successfully executed:\\n```python\\n{code}\\n```\\nStdout: {result}\"\n",
" return (\n",
" result_str + \"\\n\\nIf you have completed all tasks, respond with FINAL ANSWER.\"\n",
" )"
@@ -297,7 +297,7 @@
" messages = state[\"messages\"]\n",
" last_message = messages[-1]\n",
" if last_message.tool_calls:\n",
" # The previus agent is invoking a tool\n",
" # The previous agent is invoking a tool\n",
" return \"call_tool\"\n",
" if \"FINAL ANSWER\" in last_message.content:\n",
" # Any agent decided the work is done\n",
@@ -442,7 +442,7 @@
"----\n",
"{'chart_generator': {'messages': [AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_JPVxDAzEFi21crVT7Rt6SRJl', 'function': {'arguments': '{\"code\":\"import matplotlib.pyplot as plt\\\\n\\\\n# UK GDP data obtained from search results for 2018-2021 (in billion USD)\\\\n# The data for 2022 and 2023 are placeholders and should be replaced with actual figures when available\\\\ngdp_data = {\\\\n \\'Year\\': [2018, 2019, 2020, 2021, 2022, 2023],\\\\n \\'GDP (Billion USD)\\': [2851.41, 2697.81, 3141.51, None, None]\\\\n}\\\\n\\\\n# Plot a line graph\\\\nplt.figure(figsize=(10, 5))\\\\nplt.plot(gdp_data[\\'Year\\'], gdp_data[\\'GDP (Billion USD)\\'], marker=\\'o\\')\\\\n\\\\n# Title and labels\\\\nplt.title(\\'UK GDP from 2018 to 2023\\')\\\\nplt.xlabel(\\'Year\\')\\\\nplt.ylabel(\\'GDP (Billion USD)\\')\\\\n\\\\n# Show grid\\\\nplt.grid(True)\\\\n\\\\n# Display the graph\\\\nplt.show()\"}', 'name': 'python_repl'}, 'type': 'function'}]}, response_metadata={'token_usage': {'completion_tokens': 240, 'prompt_tokens': 12291, 'total_tokens': 12531}, 'model_name': 'gpt-4-1106-preview', 'system_fingerprint': None, 'finish_reason': 'tool_calls', 'logprobs': None}, name='chart_generator', id='run-6cff57bc-ba87-4690-9528-4d15bba7986c-0', tool_calls=[{'name': 'python_repl', 'args': {'code': \"import matplotlib.pyplot as plt\\n\\n# UK GDP data obtained from search results for 2018-2021 (in billion USD)\\n# The data for 2022 and 2023 are placeholders and should be replaced with actual figures when available\\ngdp_data = {\\n 'Year': [2018, 2019, 2020, 2021, 2022, 2023],\\n 'GDP (Billion USD)': [2851.41, 2697.81, 3141.51, None, None]\\n}\\n\\n# Plot a line graph\\nplt.figure(figsize=(10, 5))\\nplt.plot(gdp_data['Year'], gdp_data['GDP (Billion USD)'], marker='o')\\n\\n# Title and labels\\nplt.title('UK GDP from 2018 to 2023')\\nplt.xlabel('Year')\\nplt.ylabel('GDP (Billion USD)')\\n\\n# Show grid\\nplt.grid(True)\\n\\n# Display the graph\\nplt.show()\"}, 'id': 'call_JPVxDAzEFi21crVT7Rt6SRJl'}])], 'sender': 'chart_generator'}}\n",
"----\n",
"{'call_tool': {'messages': [ToolMessage(content=\"Succesfully executed:\\n```python\\nimport matplotlib.pyplot as plt\\n\\n# UK GDP data obtained from search results for 2018-2021 (in billion USD)\\n# The data for 2022 and 2023 are placeholders and should be replaced with actual figures when available\\ngdp_data = {\\n 'Year': [2018, 2019, 2020, 2021, 2022, 2023],\\n 'GDP (Billion USD)': [2851.41, 2697.81, 3141.51, None, None]\\n}\\n\\n# Plot a line graph\\nplt.figure(figsize=(10, 5))\\nplt.plot(gdp_data['Year'], gdp_data['GDP (Billion USD)'], marker='o')\\n\\n# Title and labels\\nplt.title('UK GDP from 2018 to 2023')\\nplt.xlabel('Year')\\nplt.ylabel('GDP (Billion USD)')\\n\\n# Show grid\\nplt.grid(True)\\n\\n# Display the graph\\nplt.show()\\n```\\nStdout: ValueError('x and y must have same first dimension, but have shapes (6,) and (5,)')\\n\\nIf you have completed all tasks, respond with FINAL ANSWER.\", name='python_repl', tool_call_id='call_JPVxDAzEFi21crVT7Rt6SRJl')]}}\n",
"{'call_tool': {'messages': [ToolMessage(content=\"Successfully executed:\\n```python\\nimport matplotlib.pyplot as plt\\n\\n# UK GDP data obtained from search results for 2018-2021 (in billion USD)\\n# The data for 2022 and 2023 are placeholders and should be replaced with actual figures when available\\ngdp_data = {\\n 'Year': [2018, 2019, 2020, 2021, 2022, 2023],\\n 'GDP (Billion USD)': [2851.41, 2697.81, 3141.51, None, None]\\n}\\n\\n# Plot a line graph\\nplt.figure(figsize=(10, 5))\\nplt.plot(gdp_data['Year'], gdp_data['GDP (Billion USD)'], marker='o')\\n\\n# Title and labels\\nplt.title('UK GDP from 2018 to 2023')\\nplt.xlabel('Year')\\nplt.ylabel('GDP (Billion USD)')\\n\\n# Show grid\\nplt.grid(True)\\n\\n# Display the graph\\nplt.show()\\n```\\nStdout: ValueError('x and y must have same first dimension, but have shapes (6,) and (5,)')\\n\\nIf you have completed all tasks, respond with FINAL ANSWER.\", name='python_repl', tool_call_id='call_JPVxDAzEFi21crVT7Rt6SRJl')]}}\n",
"----\n"
]
},
@@ -472,7 +472,7 @@
"text": [
"{'chart_generator': {'messages': [AIMessage(content=\"Unfortunately, I made an error in the provided code. There was a mismatch in the dimensions of the 'Year' and 'GDP (Billion USD)' data arrays, which caused a ValueError. Additionally, I mistakenly included placeholders for the years 2022 and 2023 without having the actual GDP data for those years.\\n\\nLet's correct this and generate a line graph with the data we have up to 2021. I will revise the code to only include the years for which we have data, and then we can create the graph accordingly.\", additional_kwargs={'tool_calls': [{'id': 'call_1zGQMGouC0oFQJRUkNPvs9zX', 'function': {'arguments': '{\"code\":\"import matplotlib.pyplot as plt\\\\n\\\\n# UK GDP data obtained from search results for 2018-2021 (in billion USD)\\\\n# No data for 2022 and 2023 are available\\\\n# Note: 2021 data is used as a placeholder and should be updated when actual figures are available\\\\ngdp_data = {\\\\n \\'Year\\': [2018, 2019, 2020, 2021],\\\\n \\'GDP (Billion USD)\\': [2851.41, 2851.41, 2697.81, 3141.51]\\\\n}\\\\n\\\\n# Plot a line graph\\\\nplt.figure(figsize=(10, 5))\\\\nplt.plot(gdp_data[\\'Year\\'], gdp_data[\\'GDP (Billion USD)\\'], marker=\\'o\\')\\\\n\\\\n# Title and labels\\\\nplt.title(\\'UK GDP from 2018 to 2021\\')\\\\nplt.xlabel(\\'Year\\')\\\\nplt.ylabel(\\'GDP (Billion USD)\\')\\\\n\\\\n# Show grid\\\\nplt.grid(True)\\\\n\\\\n# Display the graph\\\\nplt.show()\"}', 'name': 'python_repl'}, 'type': 'function'}]}, response_metadata={'token_usage': {'completion_tokens': 359, 'prompt_tokens': 12796, 'total_tokens': 13155}, 'model_name': 'gpt-4-1106-preview', 'system_fingerprint': None, 'finish_reason': 'tool_calls', 'logprobs': None}, name='chart_generator', id='run-0d4a67d2-696a-4955-990b-9a9d775b7635-0', tool_calls=[{'name': 'python_repl', 'args': {'code': \"import matplotlib.pyplot as plt\\n\\n# UK GDP data obtained from search results for 2018-2021 (in billion USD)\\n# No data for 2022 and 2023 are available\\n# Note: 2021 data is used as a placeholder and should be updated when actual figures are available\\ngdp_data = {\\n 'Year': [2018, 2019, 2020, 2021],\\n 'GDP (Billion USD)': [2851.41, 2851.41, 2697.81, 3141.51]\\n}\\n\\n# Plot a line graph\\nplt.figure(figsize=(10, 5))\\nplt.plot(gdp_data['Year'], gdp_data['GDP (Billion USD)'], marker='o')\\n\\n# Title and labels\\nplt.title('UK GDP from 2018 to 2021')\\nplt.xlabel('Year')\\nplt.ylabel('GDP (Billion USD)')\\n\\n# Show grid\\nplt.grid(True)\\n\\n# Display the graph\\nplt.show()\"}, 'id': 'call_1zGQMGouC0oFQJRUkNPvs9zX'}])], 'sender': 'chart_generator'}}\n",
"----\n",
"{'call_tool': {'messages': [ToolMessage(content=\"Succesfully executed:\\n```python\\nimport matplotlib.pyplot as plt\\n\\n# UK GDP data obtained from search results for 2018-2021 (in billion USD)\\n# No data for 2022 and 2023 are available\\n# Note: 2021 data is used as a placeholder and should be updated when actual figures are available\\ngdp_data = {\\n 'Year': [2018, 2019, 2020, 2021],\\n 'GDP (Billion USD)': [2851.41, 2851.41, 2697.81, 3141.51]\\n}\\n\\n# Plot a line graph\\nplt.figure(figsize=(10, 5))\\nplt.plot(gdp_data['Year'], gdp_data['GDP (Billion USD)'], marker='o')\\n\\n# Title and labels\\nplt.title('UK GDP from 2018 to 2021')\\nplt.xlabel('Year')\\nplt.ylabel('GDP (Billion USD)')\\n\\n# Show grid\\nplt.grid(True)\\n\\n# Display the graph\\nplt.show()\\n```\\nStdout: \\n\\nIf you have completed all tasks, respond with FINAL ANSWER.\", name='python_repl', tool_call_id='call_1zGQMGouC0oFQJRUkNPvs9zX')]}}\n",
"{'call_tool': {'messages': [ToolMessage(content=\"Successfully executed:\\n```python\\nimport matplotlib.pyplot as plt\\n\\n# UK GDP data obtained from search results for 2018-2021 (in billion USD)\\n# No data for 2022 and 2023 are available\\n# Note: 2021 data is used as a placeholder and should be updated when actual figures are available\\ngdp_data = {\\n 'Year': [2018, 2019, 2020, 2021],\\n 'GDP (Billion USD)': [2851.41, 2851.41, 2697.81, 3141.51]\\n}\\n\\n# Plot a line graph\\nplt.figure(figsize=(10, 5))\\nplt.plot(gdp_data['Year'], gdp_data['GDP (Billion USD)'], marker='o')\\n\\n# Title and labels\\nplt.title('UK GDP from 2018 to 2021')\\nplt.xlabel('Year')\\nplt.ylabel('GDP (Billion USD)')\\n\\n# Show grid\\nplt.grid(True)\\n\\n# Display the graph\\nplt.show()\\n```\\nStdout: \\n\\nIf you have completed all tasks, respond with FINAL ANSWER.\", name='python_repl', tool_call_id='call_1zGQMGouC0oFQJRUkNPvs9zX')]}}\n",
"----\n",
"{'chart_generator': {'messages': [AIMessage(content=\"FINAL ANSWER\\n\\nI have generated a line graph for the UK's GDP from 2018 to 2021 using the available data. Unfortunately, due to the lack of data for 2022 and 2023, the graph only includes figures up to 2021. Here is the graph:\\n\\n[Graph Image]\\n\\nPlease note that the data for 2022 and 2023 should be added to this graph once it becomes available to complete the analysis for the past five years.\", response_metadata={'token_usage': {'completion_tokens': 99, 'prompt_tokens': 13412, 'total_tokens': 13511}, 'model_name': 'gpt-4-1106-preview', 'system_fingerprint': None, 'finish_reason': 'stop', 'logprobs': None}, name='chart_generator', id='run-3474a61c-0773-4e44-bd6e-2e88cf56bb90-0')], 'sender': 'chart_generator'}}\n",
"----\n"
+1 -1
View File
@@ -9,7 +9,7 @@
"\n",
"Many AI applications need memory to share context across multiple interactions. In LangGraph, memory is provided for any [StateGraph](https://langchain-ai.github.io/langgraph/reference/graphs/#langgraph.graph.StateGraph) through [Checkpointers](https://langchain-ai.github.io/langgraph/reference/checkpoints/).\n",
"\n",
"When creating any LangGraph workflow, you can set them up to persist their state by diong using the following:\n",
"When creating any LangGraph workflow, you can set them up to persist their state by doing using the following:\n",
"\n",
"1. A [Checkpointer](https://langchain-ai.github.io/langgraph/reference/checkpoints/#basecheckpointsaver), such as the [AsyncSqliteSaver](https://langchain-ai.github.io/langgraph/reference/checkpoints/#asyncsqlitesaver)\n",
"2. Call `compile(checkpointer=my_checkpointer)` when compiling the graph.\n",
@@ -490,7 +490,7 @@
"source": [
"## Conclusion\n",
"\n",
"Congrats on making a plan-and-execute agent! One known limitations of the above design is that each task is still executed in sequence, meaning embarassingly parallel operations all add to the total execution time. You could improve on this by having each task represented as a DAG (similar to LLMCompiler), rather than a regular list."
"Congrats on making a plan-and-execute agent! One known limitations of the above design is that each task is still executed in sequence, meaning embarrassingly parallel operations all add to the total execution time. You could improve on this by having each task represented as a DAG (similar to LLMCompiler), rather than a regular list."
]
},
{
+2 -2
View File
@@ -37,7 +37,7 @@
"id": "a85501ca-eb89-4795-aeab-cdab050ead6b",
"metadata": {},
"source": [
"# Enviorment "
"# Environment "
]
},
{
@@ -419,7 +419,7 @@
"\n",
"# Prompt\n",
"system = \"\"\"You a question re-writer that converts an input question to a better version that is optimized \\n \n",
" for vectorstore retrieval. Look at the input and try to reason about the underlying sematic intent / meaning.\"\"\"\n",
" for vectorstore retrieval. Look at the input and try to reason about the underlying semantic intent / meaning.\"\"\"\n",
"re_write_prompt = ChatPromptTemplate.from_messages(\n",
" [\n",
" (\"system\", system),\n",
@@ -35,7 +35,7 @@
"id": "8cece98f-a3ed-417e-8b6a-1754e8f9c42a",
"metadata": {},
"source": [
"# Enviorment "
"# Environment "
]
},
{
@@ -187,7 +187,7 @@
" Use the vectorstore for questions on LLM agents, prompt engineering, and adversarial attacks. \\n\n",
" You do not need to be stringent with the keywords in the question related to these topics. \\n\n",
" Otherwise, use web-search. Give a binary choice 'web_search' or 'vectorstore' based on the question. \\n\n",
" Return the a JSON with a single key 'datasource' and no premable or explaination. \\n\n",
" Return the a JSON with a single key 'datasource' and no premable or explanation. \\n\n",
" Question to route: {question}\"\"\",\n",
" input_variables=[\"question\"],\n",
")\n",
@@ -230,7 +230,7 @@
" If the document contains keywords related to the user question, grade it as relevant. \\n\n",
" It does not need to be a stringent test. The goal is to filter out erroneous retrievals. \\n\n",
" Give a binary score 'yes' or 'no' score to indicate whether the document is relevant to the question. \\n\n",
" Provide the binary score as a JSON with a single key 'score' and no premable or explaination.\"\"\",\n",
" Provide the binary score as a JSON with a single key 'score' and no premable or explanation.\"\"\",\n",
" input_variables=[\"question\", \"document\"],\n",
")\n",
"\n",
+2 -2
View File
@@ -11,7 +11,7 @@
"\n",
"To implement a retrieval agent, we simple need to give an LLM access to a retriever tool.\n",
"\n",
"We can incorperate this into [LangGraph](https://python.langchain.com/docs/langgraph)."
"We can incorporate this into [LangGraph](https://python.langchain.com/docs/langgraph)."
]
},
{
@@ -284,7 +284,7 @@
" state (messages): The current state\n",
"\n",
" Returns:\n",
" dict: The updated state with the agent response apended to messages\n",
" dict: The updated state with the agent response appended to messages\n",
" \"\"\"\n",
" print(\"---CALL AGENT---\")\n",
" messages = state[\"messages\"]\n",
+4 -4
View File
@@ -12,13 +12,13 @@
"source": [
"# Corrective RAG (CRAG)\n",
"\n",
"Corrective-RAG (CRAG) is a strategy for RAG that incorperates self-reflection / self-grading on retrieved documents. \n",
"Corrective-RAG (CRAG) is a strategy for RAG that incorporates self-reflection / self-grading on retrieved documents. \n",
"\n",
"In the paper [here](https://arxiv.org/pdf/2401.15884.pdf), a few steps are taken:\n",
"\n",
"* If at least one document exceeds the threshold for relevance, then it proceeds to generation\n",
"* Before generation, it performns knowledge refinement\n",
"* This paritions the document into \"knowledge strips\"\n",
"* This partitions the document into \"knowledge strips\"\n",
"* It grades each strip, and filters our irrelevant ones\n",
"* If all documents fall below the relevance threshold or if the grader is unsure, then the framework seeks an additional datasource\n",
"* It will use web search to supplement retrieval\n",
@@ -38,7 +38,7 @@
"id": "4931ac25-99f9-4f04-b3d1-4683f7853667",
"metadata": {},
"source": [
"# Enviorment "
"# Environment "
]
},
{
@@ -283,7 +283,7 @@
"\n",
"# Prompt\n",
"system = \"\"\"You a question re-writer that converts an input question to a better version that is optimized \\n \n",
" for web search. Look at the input and try to reason about the underlying sematic intent / meaning.\"\"\"\n",
" for web search. Look at the input and try to reason about the underlying semantic intent / meaning.\"\"\"\n",
"re_write_prompt = ChatPromptTemplate.from_messages(\n",
" [\n",
" (\"system\", system),\n",
+4 -4
View File
@@ -12,13 +12,13 @@
"source": [
"# Corrective RAG (CRAG) -- With Local LLMs\n",
"\n",
"Corrective-RAG (CRAG) is a strategy for RAG that incorperates self-reflection / self-grading on retrieved documents. \n",
"Corrective-RAG (CRAG) is a strategy for RAG that incorporates self-reflection / self-grading on retrieved documents. \n",
"\n",
"In the paper [here](https://arxiv.org/pdf/2401.15884.pdf), a few steps are taken:\n",
"\n",
"* If at least one document exceeds the threshold for relevance, then it proceeds to generation\n",
"* Before generation, it performns knowledge refinement\n",
"* This paritions the document into \"knowledge strips\"\n",
"* This partitions the document into \"knowledge strips\"\n",
"* It grades each strip, and filters our irrelevant ones\n",
"* If all documents fall below the relevance threshold or if the grader is unsure, then the framework seeks an additional datasource\n",
"* It will use web search to supplement retrieval\n",
@@ -48,7 +48,7 @@
"id": "6ba4302f-09d9-4d2a-a18d-a6fd23704850",
"metadata": {},
"source": [
"# Enviorment "
"# Environment "
]
},
{
@@ -261,7 +261,7 @@
" If the document contains keywords related to the user question, grade it as relevant. \\n\n",
" It does not need to be a stringent test. The goal is to filter out erroneous retrievals. \\n\n",
" Give a binary score 'yes' or 'no' score to indicate whether the document is relevant to the question. \\n\n",
" Provide the binary score as a JSON with a single key 'score' and no premable or explaination.\"\"\",\n",
" Provide the binary score as a JSON with a single key 'score' and no premable or explanation.\"\"\",\n",
" input_variables=[\"question\", \"document\"],\n",
")\n",
"\n",
@@ -140,7 +140,7 @@
" of a retrieved document to a user question. If the document contains keywords related to the user question, \n",
" grade it as relevant. It does not need to be a stringent test. The goal is to filter out erroneous retrievals. \\n\n",
" Give a binary score 'yes' or 'no' score to indicate whether the document is relevant to the question. \\n\n",
" Provide the binary score as a JSON with a single key 'score' and no premable or explaination.\n",
" Provide the binary score as a JSON with a single key 'score' and no premable or explanation.\n",
" <|eot_id|><|start_header_id|>user<|end_header_id|>\n",
" Here is the retrieved document: \\n\\n {document} \\n\\n\n",
" Here is the user question: {question} \\n <|eot_id|><|start_header_id|>assistant<|end_header_id|>\n",
@@ -316,7 +316,7 @@
" prompt engineering, and adversarial attacks. You do not need to be stringent with the keywords \n",
" in the question related to these topics. Otherwise, use web-search. Give a binary choice 'web_search' \n",
" or 'vectorstore' based on the question. Return the a JSON with a single key 'datasource' and \n",
" no premable or explaination. Question to route: {question} <|eot_id|><|start_header_id|>assistant<|end_header_id|>\"\"\",\n",
" no premable or explanation. Question to route: {question} <|eot_id|><|start_header_id|>assistant<|end_header_id|>\"\"\",\n",
" input_variables=[\"question\"],\n",
")\n",
"\n",
+3 -3
View File
@@ -12,7 +12,7 @@
"source": [
"# Self RAG\n",
"\n",
"Self-RAG is a strategy for RAG that incorperates self-reflection / self-grading on retrieved documents and generations. \n",
"Self-RAG is a strategy for RAG that incorporates self-reflection / self-grading on retrieved documents and generations. \n",
"\n",
"In the [paper](https://arxiv.org/abs/2310.11511), a few decisions are made:\n",
"\n",
@@ -50,7 +50,7 @@
"id": "72f3ee57-68ab-4040-bd36-4014e2a23d96",
"metadata": {},
"source": [
"# Enviorment "
"# Environment "
]
},
{
@@ -374,7 +374,7 @@
"\n",
"# Prompt\n",
"system = \"\"\"You a question re-writer that converts an input question to a better version that is optimized \\n \n",
" for vectorstore retrieval. Look at the input and try to reason about the underlying sematic intent / meaning.\"\"\"\n",
" for vectorstore retrieval. Look at the input and try to reason about the underlying semantic intent / meaning.\"\"\"\n",
"re_write_prompt = ChatPromptTemplate.from_messages(\n",
" [\n",
" (\"system\", system),\n",
+3 -3
View File
@@ -12,7 +12,7 @@
"source": [
"# Self RAG -- With Local LLMs\n",
"\n",
"Self-RAG is a strategy for RAG that incorperates self-reflection / self-grading on retrieved documents and generations. \n",
"Self-RAG is a strategy for RAG that incorporates self-reflection / self-grading on retrieved documents and generations. \n",
"\n",
"In the [paper](https://arxiv.org/abs/2310.11511), a few decisions are made:\n",
"\n",
@@ -50,7 +50,7 @@
"id": "9ed0a85a-a33b-40a6-99fa-2444bf57a6cc",
"metadata": {},
"source": [
"# Enviorment "
"# Environment "
]
},
{
@@ -204,7 +204,7 @@
" If the document contains keywords related to the user question, grade it as relevant. \\n\n",
" It does not need to be a stringent test. The goal is to filter out erroneous retrievals. \\n\n",
" Give a binary score 'yes' or 'no' score to indicate whether the document is relevant to the question. \\n\n",
" Provide the binary score as a JSON with a single key 'score' and no premable or explaination.\"\"\",\n",
" Provide the binary score as a JSON with a single key 'score' and no premable or explanation.\"\"\",\n",
" input_variables=[\"question\", \"document\"],\n",
")\n",
"\n",
+1 -1
View File
@@ -501,7 +501,7 @@
"source": [
"## Conclusion\n",
"\n",
"Now that you've applied reflection to an LLM agent, I'll note one thing: self-reflection is inherantly cyclic: it is much more effective if the reflection step has additional context or feedback (from tool observations, checks, etc.). If, like in the scenario above, the reflection step simply prompts the LLM to reflect on its output, it can still benefit the output quality (since the LLM then has multiple \"shots\" at getting a good output), but it's less guaranteed.\n"
"Now that you've applied reflection to an LLM agent, I'll note one thing: self-reflection is inherently cyclic: it is much more effective if the reflection step has additional context or feedback (from tool observations, checks, etc.). If, like in the scenario above, the reflection step simply prompts the LLM to reflect on its output, it can still benefit the output quality (since the LLM then has multiple \"shots\" at getting a good output), but it's less guaranteed.\n"
]
},
{
+1 -1
View File
@@ -109,7 +109,7 @@
"source": [
"## 1. Planner\n",
"\n",
"The planner prompts an LLM to generate a plan in the form of a task list. The arguments to each task are strings that may contain special variables (`#E{0-9}+`) that are used for variable subtitution from other task results.\n",
"The planner prompts an LLM to generate a plan in the form of a task list. The arguments to each task are strings that may contain special variables (`#E{0-9}+`) that are used for variable substitution from other task results.\n",
"\n",
"\n",
"![ReWOO workflow](./img/rewoo-paper-workflow.png)\n",
+2 -2
View File
@@ -31,7 +31,7 @@
"5. Write sections, then write article\n",
"\n",
"\n",
"The expert interviews stage ocurrs between the role-playing article writer and a research expert. The \"expert\" is able to query external knowledge and respond to pointed questions, saving cited sources to a vectorstore so that the later refinement stages can synthesize the full article.\n",
"The expert interviews stage occurs between the role-playing article writer and a research expert. The \"expert\" is able to query external knowledge and respond to pointed questions, saving cited sources to a vectorstore so that the later refinement stages can synthesize the full article.\n",
"\n",
"There are a couple hyperparameters you can set to restrict the (potentially) infinite research breadth:\n",
"\n",
@@ -1078,7 +1078,7 @@
"[Document(page_content='In Retrieval Augmented Generation (RAG), a longer context augments our model with more information. For LLMs that power agents, such as chatbots, longer context means more tools and capabilities. When summarizing, longer context means more comprehensive summaries. There exist plenty of use-cases for LLMs that are unlocked by longer context lengths.', metadata={'id': '20454848-23ac-4649-b083-81980532a77b', 'source': 'https://www.anyscale.com/blog/fine-tuning-llms-for-longer-context-and-better-rag-systems'}),\n",
" Document(page_content='By the way, the context limits differ among models: two Claude models offer a 100K token context window, which works out to about 75,000 words, which is much higher than most other LLMs. The ...', metadata={'id': '1ee2d2bb-8f8e-4a7e-b45e-608b0804fe4c', 'source': 'https://www.infoworld.com/article/3712227/what-is-rag-more-accurate-and-reliable-llms.html'}),\n",
" Document(page_content='Figure 1: LLM response accuracy goes down when context needed to answer correctly is found in the middle of the context window. The problem gets worse with larger context models. The problem gets ...', metadata={'id': 'a41d69e6-62eb-4abd-90ad-0892a2836cba', 'source': 'https://medium.com/@jm_51428/long-context-window-models-vs-rag-a73c35a763f2'}),\n",
" Document(page_content='To improve performance, we used retrieval-augmented generation (RAG) to prompt an LLM with accurate up-to-date information. As a result of using RAG, the writing quality of the LLM improves substantially, which has implications for the practical useability of LLMs in clinical trial-related writing.', metadata={'id': 'e1af6e30-8c2b-495b-b572-ac6a29067a94', 'source': 'https://arxiv.org/abs/2402.16406'})]"
" Document(page_content='To improve performance, we used retrieval-augmented generation (RAG) to prompt an LLM with accurate up-to-date information. As a result of using RAG, the writing quality of the LLM improves substantially, which has implications for the practical usability of LLMs in clinical trial-related writing.', metadata={'id': 'e1af6e30-8c2b-495b-b572-ac6a29067a94', 'source': 'https://arxiv.org/abs/2402.16406'})]"
]
},
"execution_count": 29,
+2 -2
View File
@@ -771,7 +771,7 @@
"source": [
"It wasn't able to solve it in time **but that's OK**! If it were easy, this paper would be a lot shorter :)\n",
"\n",
"You can vew the [agent's full LangSmith trace](https://smith.langchain.com/public/61c84ad0-51db-40f1-b50d-6983d9481ca1/r) at the provided link.\n",
"You can view the [agent's full LangSmith trace](https://smith.langchain.com/public/61c84ad0-51db-40f1-b50d-6983d9481ca1/r) at the provided link.\n",
"\n",
"In the next section we will add an improvement the paper terms \"episodic memory\", which in this case is really few-shot retrieval."
]
@@ -1284,7 +1284,7 @@
"\n",
"1. Reflection: explicitly prompting the LLM to \"reflect\" on its mistakes can help it\n",
"2. Few-shot prompting: retrieving relevant, high-quality examples as \"memory\"\n",
"3. **Human-in-the-loop collaboration:** without giving the correct answer, the human is allowed to help the agent reflect on its appraoch and point it in a better direction.\n",
"3. **Human-in-the-loop collaboration:** without giving the correct answer, the human is allowed to help the agent reflect on its approach and point it in a better direction.\n",
"\n",
"\n",
"In this section, we will add the \"human\" node (marked as \"part 3\" in the diagram below), completing our agent graph:\n",
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -33,7 +33,7 @@ class BaseChannel(Generic[Value, Update, C], ABC):
def UpdateType(self) -> Any:
"""The type of the update received by the channel."""
# ser/de methods
# serialize/deserialize methods
@abstractmethod
def checkpoint(self) -> Optional[C]:
+1 -1
View File
@@ -25,7 +25,7 @@ class Topic(
Args:
typ: The type of the value stored in the channel.
unique: Whether to discard duplicate values.
accumulate: Whether to accummulate values across steps. If False, the channel will be emptied after each step.
accumulate: Whether to accumulate values across steps. If False, the channel will be emptied after each step.
"""
def __init__(
+3 -3
View File
@@ -159,7 +159,7 @@ class Graph:
node or nodes. If not specifying `path_map` it should return one or
more nodes. If it returns END, the graph will stop execution.
path_map (Optional[dict[str, str]]): Optional mapping of paths to node
names. If ommitted the paths returned by `path` should be node names.
names. If omitted the paths returned by `path` should be node names.
then (Optional[str]): The name of a node to execute after the nodes
selected by `path`.
@@ -216,7 +216,7 @@ class Graph:
node or nodes. If not specifying `path_map` it should return one or
more nodes. If it returns END, the graph will stop execution.
path_map (Optional[dict[str, str]]): Optional mapping of paths to node
names. If ommitted the paths returned by `path` should be node names.
names. If omitted the paths returned by `path` should be node names.
then (Optional[str]): The name of a node to execute after the nodes
selected by `path`.
@@ -258,7 +258,7 @@ class Graph:
raise ValueError(f"Node '{node}' is a dead-end")
for source in all_sources:
if node not in self.nodes and node != START:
raise ValueError(f"Found edge starting at unkown node '{source}'")
raise ValueError(f"Found edge starting at unknown node '{source}'")
# assemble targets
all_targets = {end for _, end in self._all_edges}
+1 -1
View File
@@ -1860,7 +1860,7 @@ async def test_conditional_graph_state() -> None:
# Check that agent (one of the nodes) has its output streamed to the logs
assert "/logs/agent/streamed_output/-" in patch_paths
# Check that agent (one of the ndoes) has its final output set in the logs
# Check that agent (one of the nodes) has its final output set in the logs
assert "/logs/agent/final_output" in patch_paths
assert [
p["value"]