mirror of
https://github.com/langchain-ai/langgraph.git
synced 2026-08-17 21:25:46 +02:00
Remove version used in video
This commit is contained in:
@@ -1,624 +0,0 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "54abe00a-0132-493a-bee0-5dcb3044c412",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"! pip install langchain_community tiktoken langchain-openai langchainhub chromadb langchain langgraph faiss-cpu"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "c02e806b-5169-4572-b007-3302df9801e0",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Optionally, use [LangSmith](https://docs.smith.langchain.com/) for tracing: \n",
|
||||
"\n",
|
||||
"```\n",
|
||||
"export LANGCHAIN_TRACING_V2=true\n",
|
||||
"export LANGCHAIN_ENDPOINT=https://api.smith.langchain.com\n",
|
||||
"export LANGCHAIN_API_KEY=<your-api-key>\n",
|
||||
"```"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "15bb14a1-4640-461d-9385-401ce346da75",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Docs"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 14,
|
||||
"id": "e471e650-97c2-4524-82c4-9bffaa8e6447",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from bs4 import BeautifulSoup as Soup\n",
|
||||
"from langchain_community.document_loaders.recursive_url_loader import RecursiveUrlLoader\n",
|
||||
"\n",
|
||||
"# LCEL docs \n",
|
||||
"url = \"https://python.langchain.com/docs/expression_language/\"\n",
|
||||
"loader = RecursiveUrlLoader(\n",
|
||||
" url=url, max_depth=20, extractor=lambda x: Soup(x, \"html.parser\").text\n",
|
||||
")\n",
|
||||
"docs = loader.load()\n",
|
||||
"\n",
|
||||
"# Sort the list based on the URLs in 'metadata' -> 'source'\n",
|
||||
"d_sorted = sorted(docs, key=lambda x: x.metadata[\"source\"])\n",
|
||||
"d_reversed = list(reversed(d_sorted))\n",
|
||||
"\n",
|
||||
"# Concatenate the 'page_content' of each sorted dictionary\n",
|
||||
"concatenated_content = \"\\n\\n\\n --- \\n\\n\\n\".join(\n",
|
||||
" [doc.page_content for doc in d_reversed]\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "5ccf1981-54b6-4667-b56e-a43dbfec35c7",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Tool Use"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 17,
|
||||
"id": "133889df-277a-4641-93cb-5dafa942b47a",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from operator import itemgetter\n",
|
||||
"from langchain_openai import ChatOpenAI\n",
|
||||
"from langchain.prompts import PromptTemplate\n",
|
||||
"from langchain_core.pydantic_v1 import BaseModel, Field\n",
|
||||
"from langchain.output_parsers.openai_tools import PydanticToolsParser\n",
|
||||
"from langchain_core.utils.function_calling import convert_to_openai_tool\n",
|
||||
" \n",
|
||||
"## Data model\n",
|
||||
"class code(BaseModel):\n",
|
||||
" \"\"\"Code output\"\"\"\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",
|
||||
"\n",
|
||||
"## LLM\n",
|
||||
"model = ChatOpenAI(temperature=0, model=\"gpt-4-0125-preview\", streaming=True)\n",
|
||||
"\n",
|
||||
"# Tool\n",
|
||||
"code_tool_oai = convert_to_openai_tool(code)\n",
|
||||
"\n",
|
||||
"# LLM with tool and enforce invocation\n",
|
||||
"llm_with_tool = model.bind(\n",
|
||||
" tools=[code_tool_oai],\n",
|
||||
" tool_choice={\"type\": \"function\", \"function\": {\"name\": \"code\"}},\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"# Parser\n",
|
||||
"parser_tool = PydanticToolsParser(tools=[code])\n",
|
||||
"\n",
|
||||
"## Prompt\n",
|
||||
"template = \"\"\"You are a coding assistant with expertise in LCEL, LangChain expression language. \\n \n",
|
||||
" Here is a full set of LCEL documentation: \n",
|
||||
" \\n ------- \\n\n",
|
||||
" {context} \n",
|
||||
" \\n ------- \\n\n",
|
||||
" Answer the user question based on the above provided documentation. \\n\n",
|
||||
" Ensure any code you provide can be executed with all required imports and variables defined. \\n\n",
|
||||
" Structure your answer with a description of the code solution. \\n\n",
|
||||
" Then list the imports. And finally list the functioning code block. \\n\n",
|
||||
" Here is the user question: \\n --- --- --- \\n {question}\"\"\"\n",
|
||||
"\n",
|
||||
"# Prompt \n",
|
||||
"prompt = PromptTemplate(\n",
|
||||
" template=template,\n",
|
||||
" input_variables=[\"context\", \"question\"],\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"# Chain\n",
|
||||
"chain = (\n",
|
||||
" {\n",
|
||||
" # \"context\": lambda x: docs,\n",
|
||||
" \"context\": lambda x: concatenated_content,\n",
|
||||
" \"question\": itemgetter(\"question\"),\n",
|
||||
" }\n",
|
||||
" | prompt\n",
|
||||
" | llm_with_tool \n",
|
||||
" | parser_tool\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 19,
|
||||
"id": "450cfac7-8a2a-43ed-a431-b38fb4d0de66",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"[code(prefix=\"To create a Retrieval-Augmented Generation (RAG) chain in LangChain Expression Language (LCEL), you need to follow a structured approach. This involves setting up a retriever to fetch relevant documents based on the user's query, and then using those documents to generate a response with a language model. Here's a step-by-step guide to creating a RAG chain in LCEL:\\n\\n\", imports='from operator import itemgetter\\nfrom langchain_community.vectorstores import FAISS\\nfrom langchain_core.output_parsers import StrOutputParser\\nfrom langchain_core.prompts import ChatPromptTemplate\\nfrom langchain_core.runnables import RunnablePassthrough\\nfrom langchain_openai import ChatOpenAI, OpenAIEmbeddings', code='# Initialize the vector store with sample texts and embeddings\\nvectorstore = FAISS.from_texts(\\n [\"harrison worked at kensho\"], embedding=OpenAIEmbeddings())\\n\\n# Create a retriever from the vector store\\nretriever = vectorstore.as_retriever()\\n\\n# Define the prompt template\\ntemplate = \"\"\"Answer the question based only on the following context:{context}Question: {question}\"\"\"\\nprompt = ChatPromptTemplate.from_template(template)\\n\\n# Initialize the model\\nmodel = ChatOpenAI()\\n\\n# Create the RAG chain\\nchain = (\\n {\"context\": retriever, \"question\": RunnablePassthrough()} | prompt | model | StrOutputParser()\\n)\\n\\n# Invoke the chain with a query\\nresponse = chain.invoke(\"where did harrison work?\")\\nprint(response)')]"
|
||||
]
|
||||
},
|
||||
"execution_count": 19,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"chain.invoke({\"question\":\"How to create a RAG chain in LCEL?\"})"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "32a6686d-48d9-4b4c-becf-0d496384eed9",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## State"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 20,
|
||||
"id": "95be35d1-b90c-4559-a6bf-2cd79e68ae4a",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from typing import Dict, TypedDict\n",
|
||||
"\n",
|
||||
"from langchain_core.messages import BaseMessage\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class GraphState(TypedDict):\n",
|
||||
" \"\"\"\n",
|
||||
" Represents the state of our graph.\n",
|
||||
"\n",
|
||||
" Attributes:\n",
|
||||
" keys: A dictionary where each key is a string.\n",
|
||||
" \"\"\"\n",
|
||||
"\n",
|
||||
" keys: Dict[str, any]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 21,
|
||||
"id": "396bee5b-9cc3-44d2-bc6a-955af0e0a847",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from operator import itemgetter\n",
|
||||
"from bs4 import BeautifulSoup as Soup\n",
|
||||
"from langchain_community.document_loaders.recursive_url_loader import RecursiveUrlLoader\n",
|
||||
"from langchain_openai import ChatOpenAI\n",
|
||||
"from langchain.prompts import PromptTemplate\n",
|
||||
"from langchain_core.output_parsers import StrOutputParser\n",
|
||||
"from langchain_core.runnables import RunnablePassthrough\n",
|
||||
"from langchain_core.pydantic_v1 import BaseModel, Field\n",
|
||||
"from langchain.output_parsers import PydanticOutputParser\n",
|
||||
"from langchain.output_parsers.openai_tools import PydanticToolsParser\n",
|
||||
"from langchain_core.utils.function_calling import convert_to_openai_tool\n",
|
||||
"\n",
|
||||
"def generate(state):\n",
|
||||
" \"\"\"\n",
|
||||
" Generate a code solution based on LCEL docs and the input question \n",
|
||||
" with optional feedback from code execution tests \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",
|
||||
" \n",
|
||||
" ## State\n",
|
||||
" state_dict = state[\"keys\"]\n",
|
||||
" question = state_dict[\"question\"]\n",
|
||||
" iter = state_dict[\"iterations\"]\n",
|
||||
" \n",
|
||||
" ## Data model\n",
|
||||
" class code(BaseModel):\n",
|
||||
" \"\"\"Code output\"\"\"\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",
|
||||
" \n",
|
||||
" ## LLM\n",
|
||||
" model = ChatOpenAI(temperature=0, model=\"gpt-4-0125-preview\", streaming=True)\n",
|
||||
" \n",
|
||||
" # Tool\n",
|
||||
" code_tool_oai = convert_to_openai_tool(code)\n",
|
||||
" \n",
|
||||
" # LLM with tool and enforce invocation\n",
|
||||
" llm_with_tool = model.bind(\n",
|
||||
" tools=[convert_to_openai_tool(code_tool_oai)],\n",
|
||||
" tool_choice={\"type\": \"function\", \"function\": {\"name\": \"code\"}},\n",
|
||||
" )\n",
|
||||
" \n",
|
||||
" # Parser\n",
|
||||
" parser_tool = PydanticToolsParser(tools=[code])\n",
|
||||
" \n",
|
||||
" ## Prompt\n",
|
||||
" template = \"\"\"You are a coding assistant with expertise in LCEL, LangChain expression language. \\n \n",
|
||||
" Here is a full set of LCEL documentation: \n",
|
||||
" \\n ------- \\n\n",
|
||||
" {context} \n",
|
||||
" \\n ------- \\n\n",
|
||||
" Answer the user question based on the above provided documentation. \\n\n",
|
||||
" Ensure any code you provide can be executed with all required imports and variables defined. \\n\n",
|
||||
" Structure your answer with a description of the code solution. \\n\n",
|
||||
" Then list the imports. And finally list the functioning code block. \\n\n",
|
||||
" Here is the user question: \\n --- --- --- \\n {question}\"\"\"\n",
|
||||
"\n",
|
||||
" ## Generation\n",
|
||||
" if \"error\" in state_dict:\n",
|
||||
" print(\"---RE-GENERATE SOLUTION w/ ERROR FEEDBACK---\")\n",
|
||||
" \n",
|
||||
" error = state_dict[\"error\"]\n",
|
||||
" code_solution = state_dict[\"generation\"]\n",
|
||||
" \n",
|
||||
" # Udpate prompt \n",
|
||||
" addendum = \"\"\" \\n --- --- --- \\n You previously tried to solve this problem. \\n Here is your solution: \n",
|
||||
" \\n --- --- --- \\n {generation} \\n --- --- --- \\n Here is the resulting error from code \n",
|
||||
" execution: \\n --- --- --- \\n {error} \\n --- --- --- \\n Please re-try to answer this. \n",
|
||||
" Structure your answer with a description of the code solution. \\n Then list the imports. \n",
|
||||
" And finally list the functioning code block. Structure your answer with a description of \n",
|
||||
" the code solution. \\n Then list the imports. And finally list the functioning code block. \n",
|
||||
" \\n Here is the user question: \\n --- --- --- \\n {question}\"\"\"\n",
|
||||
" template = template + addendum\n",
|
||||
"\n",
|
||||
" # Prompt \n",
|
||||
" prompt = PromptTemplate(\n",
|
||||
" template=template,\n",
|
||||
" input_variables=[\"context\", \"question\", \"generation\", \"error\"],\n",
|
||||
" )\n",
|
||||
" \n",
|
||||
" # Chain\n",
|
||||
" chain = (\n",
|
||||
" {\n",
|
||||
" \"context\": lambda x: concatenated_content,\n",
|
||||
" \"question\": itemgetter(\"question\"),\n",
|
||||
" \"generation\": itemgetter(\"generation\"),\n",
|
||||
" \"error\": itemgetter(\"error\"),\n",
|
||||
" }\n",
|
||||
" | prompt\n",
|
||||
" | llm_with_tool \n",
|
||||
" | parser_tool\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
" code_solution = chain.invoke({\"question\":question,\n",
|
||||
" \"generation\":str(code_solution[0]),\n",
|
||||
" \"error\":error})\n",
|
||||
" \n",
|
||||
" else:\n",
|
||||
" print(\"---GENERATE SOLUTION---\")\n",
|
||||
" \n",
|
||||
" # Prompt \n",
|
||||
" prompt = PromptTemplate(\n",
|
||||
" template=template,\n",
|
||||
" input_variables=[\"context\", \"question\"],\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
" # Chain\n",
|
||||
" chain = (\n",
|
||||
" {\n",
|
||||
" # \"context\": lambda x: docs,\n",
|
||||
" \"context\": lambda x: concatenated_content,\n",
|
||||
" \"question\": itemgetter(\"question\"),\n",
|
||||
" }\n",
|
||||
" | prompt\n",
|
||||
" | llm_with_tool \n",
|
||||
" | parser_tool\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
" code_solution = chain.invoke({\"question\":question})\n",
|
||||
"\n",
|
||||
" iter = iter+1 \n",
|
||||
" return {\"keys\": {\"generation\": code_solution, \"question\": question, \"iterations\": iter}}\n",
|
||||
"\n",
|
||||
"def check_code_imports(state):\n",
|
||||
" \"\"\"\n",
|
||||
" Check imports\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",
|
||||
" ## State\n",
|
||||
" print(\"---CHECKING CODE IMPORTS---\")\n",
|
||||
" state_dict = state[\"keys\"]\n",
|
||||
" question = state_dict[\"question\"]\n",
|
||||
" code_solution = state_dict[\"generation\"]\n",
|
||||
" imports = code_solution[0].imports\n",
|
||||
" iter = state_dict[\"iterations\"]\n",
|
||||
"\n",
|
||||
" try: \n",
|
||||
" # Attempt to execute the imports\n",
|
||||
" exec(imports)\n",
|
||||
" except Exception as e:\n",
|
||||
" print(\"---CODE IMPORT CHECK: FAILED---\")\n",
|
||||
" # Catch any error during execution (e.g., ImportError, SyntaxError)\n",
|
||||
" error = f\"Execution error: {e}\"\n",
|
||||
" if \"error\" in state_dict:\n",
|
||||
" error_prev_runs = state_dict[\"error\"]\n",
|
||||
" error = error_prev_runs + \"\\n --- Most recent run error --- \\n\" + error \n",
|
||||
" else:\n",
|
||||
" print(\"---CODE IMPORT CHECK: SUCCESS---\")\n",
|
||||
" # No errors occurred\n",
|
||||
" error = \"None\"\n",
|
||||
"\n",
|
||||
" return {\"keys\": {\"generation\": code_solution, \"question\": question, \"error\": error, \"iterations\":iter}}\n",
|
||||
"\n",
|
||||
"def check_code_execution(state):\n",
|
||||
" \"\"\"\n",
|
||||
" Check code block execution\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",
|
||||
" ## State\n",
|
||||
" print(\"---CHECKING CODE EXECUTION---\")\n",
|
||||
" state_dict = state[\"keys\"]\n",
|
||||
" question = state_dict[\"question\"]\n",
|
||||
" code_solution = state_dict[\"generation\"]\n",
|
||||
" prefix = code_solution[0].prefix\n",
|
||||
" imports = code_solution[0].imports\n",
|
||||
" code = code_solution[0].code\n",
|
||||
" code_block = imports +\"\\n\"+ code\n",
|
||||
" iter = state_dict[\"iterations\"]\n",
|
||||
"\n",
|
||||
" try: \n",
|
||||
" # Attempt to execute the code block\n",
|
||||
" exec(code_block)\n",
|
||||
" except Exception as e:\n",
|
||||
" print(\"---CODE BLOCK CHECK: FAILED---\")\n",
|
||||
" # Catch any error during execution (e.g., ImportError, SyntaxError)\n",
|
||||
" error = f\"Execution error: {e}\"\n",
|
||||
" if \"error\" in state_dict:\n",
|
||||
" error_prev_runs = state_dict[\"error\"]\n",
|
||||
" error = error_prev_runs + \"\\n --- Most recent run error --- \\n\" + error \n",
|
||||
" else:\n",
|
||||
" print(\"---CODE BLOCK CHECK: SUCCESS---\")\n",
|
||||
" # No errors occurred\n",
|
||||
" error = \"None\"\n",
|
||||
"\n",
|
||||
" return {\"keys\": {\"generation\": code_solution, \n",
|
||||
" \"question\": question, \n",
|
||||
" \"error\": error, \n",
|
||||
" \"prefix\":prefix,\n",
|
||||
" \"imports\":imports,\n",
|
||||
" \"iterations\":iter,\n",
|
||||
" \"code\":code}}\n",
|
||||
"\n",
|
||||
"### Edges\n",
|
||||
"\n",
|
||||
"def decide_to_check_code_exec(state):\n",
|
||||
" \"\"\"\n",
|
||||
" Determines whether to test code execution, or re-try answer generation.\n",
|
||||
"\n",
|
||||
" Args:\n",
|
||||
" state (dict): The current graph state\n",
|
||||
"\n",
|
||||
" Returns:\n",
|
||||
" str: Next node to call\n",
|
||||
" \"\"\"\n",
|
||||
"\n",
|
||||
" print(\"---DECIDE TO TEST CODE EXECUTION---\")\n",
|
||||
" state_dict = state[\"keys\"]\n",
|
||||
" question = state_dict[\"question\"]\n",
|
||||
" code_solution = state_dict[\"generation\"]\n",
|
||||
" error = state_dict[\"error\"]\n",
|
||||
"\n",
|
||||
" if error == \"None\":\n",
|
||||
" # All documents have been filtered check_relevance\n",
|
||||
" # We will re-generate a new query\n",
|
||||
" print(\"---DECISION: TEST CODE EXECUTION---\")\n",
|
||||
" return \"check_code_execution\"\n",
|
||||
" else:\n",
|
||||
" # We have relevant documents, so generate answer\n",
|
||||
" print(\"---DECISION: RE-TRY SOLUTION---\")\n",
|
||||
" return \"generate\"\n",
|
||||
"\n",
|
||||
"def decide_to_finish(state):\n",
|
||||
" \"\"\"\n",
|
||||
" Determines whether to finish (re-try code 3 times.\n",
|
||||
"\n",
|
||||
" Args:\n",
|
||||
" state (dict): The current graph state\n",
|
||||
"\n",
|
||||
" Returns:\n",
|
||||
" str: Next node to call\n",
|
||||
" \"\"\"\n",
|
||||
"\n",
|
||||
" print(\"---DECIDE TO TEST CODE EXECUTION---\")\n",
|
||||
" state_dict = state[\"keys\"]\n",
|
||||
" question = state_dict[\"question\"]\n",
|
||||
" code_solution = state_dict[\"generation\"]\n",
|
||||
" error = state_dict[\"error\"]\n",
|
||||
" iter = state_dict[\"iterations\"]\n",
|
||||
"\n",
|
||||
" if error == \"None\" or iter == 3:\n",
|
||||
" # All documents have been filtered check_relevance\n",
|
||||
" # We will re-generate a new query\n",
|
||||
" print(\"---DECISION: TEST CODE EXECUTION---\")\n",
|
||||
" return \"end\"\n",
|
||||
" else:\n",
|
||||
" # We have relevant documents, so generate answer\n",
|
||||
" print(\"---DECISION: RE-TRY SOLUTION---\")\n",
|
||||
" return \"generate\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 23,
|
||||
"id": "1e19e44d-1628-41ea-8d45-51ea3ebd3c00",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from langgraph.graph import END, StateGraph\n",
|
||||
"\n",
|
||||
"workflow = StateGraph(GraphState)\n",
|
||||
"\n",
|
||||
"# Define the nodes\n",
|
||||
"workflow.add_node(\"generate\", generate) # generation solution\n",
|
||||
"workflow.add_node(\"check_code_imports\", check_code_imports) # check imports\n",
|
||||
"workflow.add_node(\"check_code_execution\", check_code_execution) # check execution\n",
|
||||
"\n",
|
||||
"# Build graph\n",
|
||||
"workflow.set_entry_point(\"generate\")\n",
|
||||
"workflow.add_edge(\"generate\", \"check_code_imports\")\n",
|
||||
"workflow.add_conditional_edges(\n",
|
||||
" \"check_code_imports\",\n",
|
||||
" decide_to_check_code_exec,\n",
|
||||
" {\n",
|
||||
" \"check_code_execution\": \"check_code_execution\",\n",
|
||||
" \"generate\": \"generate\",\n",
|
||||
" },\n",
|
||||
")\n",
|
||||
"workflow.add_conditional_edges(\n",
|
||||
" \"check_code_execution\",\n",
|
||||
" decide_to_finish,\n",
|
||||
" {\n",
|
||||
" \"end\": END,\n",
|
||||
" \"generate\": \"generate\",\n",
|
||||
" },\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"# Compile\n",
|
||||
"app = workflow.compile()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 24,
|
||||
"id": "8cf3924b-3121-4c52-8264-338ef2a82e14",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"---GENERATE SOLUTION---\n",
|
||||
"---CHECKING CODE IMPORTS---\n",
|
||||
"---CODE IMPORT CHECK: SUCCESS---\n",
|
||||
"---DECIDE TO TEST CODE EXECUTION---\n",
|
||||
"---DECISION: TEST CODE EXECUTION---\n",
|
||||
"---CHECKING CODE EXECUTION---\n",
|
||||
"---CODE BLOCK CHECK: FAILED---\n",
|
||||
"---DECIDE TO TEST CODE EXECUTION---\n",
|
||||
"---DECISION: RE-TRY SOLUTION---\n",
|
||||
"---RE-GENERATE SOLUTION w/ ERROR FEEDBACK---\n",
|
||||
"---CHECKING CODE IMPORTS---\n",
|
||||
"---CODE IMPORT CHECK: SUCCESS---\n",
|
||||
"---DECIDE TO TEST CODE EXECUTION---\n",
|
||||
"---DECISION: TEST CODE EXECUTION---\n",
|
||||
"---CHECKING CODE EXECUTION---\n",
|
||||
"Why did the bear break up with his girlfriend?\n",
|
||||
"Because he couldn't bear the relationship anymore!\n",
|
||||
"---CODE BLOCK CHECK: SUCCESS---\n",
|
||||
"---DECIDE TO TEST CODE EXECUTION---\n",
|
||||
"---DECISION: TEST CODE EXECUTION---\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"question = \"I am passing text key 'foo' to my prompt and want to process it with a function, process_text(...), prior to the prompt. How can I do this using LCEL?\"\n",
|
||||
"config = {\"recursion_limit\": 50}\n",
|
||||
"answer = app.invoke({\"keys\":{\"question\":question, \"iterations\":0}},config=config)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 27,
|
||||
"id": "eb8999e8-fa58-45b9-9506-3eb7ce32f0a0",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"\"To process a text key 'foo' with a function before passing it to a prompt using LCEL, you can use a RunnableLambda. This allows you to define a custom function that processes the input text and then passes the modified text to the prompt. Here's how you can do it:\""
|
||||
]
|
||||
},
|
||||
"execution_count": 27,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"answer['keys']['generation'][0].prefix"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 30,
|
||||
"id": "486205af-0e59-4b74-94eb-518cfc55b01f",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"exec(answer['keys']['generation'][0].imports)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 31,
|
||||
"id": "216c3c91-1954-4ee4-bc7c-e78a0ea655d5",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Why did the bear break up with his girlfriend? \n",
|
||||
"\n",
|
||||
"Because he couldn't bear the relationship any longer!\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"exec(answer['keys']['generation'][0].code)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "4fc107f0-eecc-46f9-88d2-15c568537dfb",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"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.9.16"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
Reference in New Issue
Block a user