Skip to content

Commit f6fbf97

Browse files
committed
Add LangChain recipies
1 parent 14e4b05 commit f6fbf97

File tree

5 files changed

+2683
-0
lines changed

5 files changed

+2683
-0
lines changed

recipes/use_cases/langchain/README.md

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# LangChain <> Llama3 Cookbooks
2+
3+
LLM agents use [planning, memory, and tools](https://lilianweng.github.io/posts/2023-06-23-agent/) to accomplish tasks.
4+
5+
LangChain offers several different ways to implement agents.
6+
7+
(1) Use [agent executor](https://python.langchain.com/docs/modules/agents/quick_start/) with [tool-calling](https://python.langchain.com/docs/integrations/chat/) versions of llama3.
8+
9+
(2) Use [LangGraph](https://python.langchain.com/docs/langgraph), a library from LangChain that can be used to build reliable agents.
10+
11+
---
12+
13+
### Agent Executor
14+
15+
Our first notebook, `tool-calling-agent`, shows how to build a [tool calling agent](https://python.langchain.com/docs/modules/agents/agent_types/tool_calling/) with agent executor.
16+
17+
This show how to build an agent that uses web search and retrieval tools.
18+
19+
---
20+
21+
### LangGraph
22+
23+
[LangGraph](https://python.langchain.com/docs/langgraph) is a library from LangChain that can be used to build reliable agents.
24+
25+
LangGraph can be used to build agents with a few pieces:
26+
- **Planning:** Define a control flow of steps that you want the agent to take (a graph)
27+
- **Memory:** Persist information (graph state) across these steps
28+
- **Tool use:** Tools can be used at any step to modify state
29+
30+
Our second notebook, `langgraph-agent`, shows how to build an agent that uses web search and retrieval tool in LangGraph.
31+
32+
It discusses some of the trade-offs between agent executor and LangGraph.
33+
34+
Our third notebook, `langgraph-rag-agent`, shows how to apply LangGraph to build advanced RAG agents that use ideas from 3 papers:
35+
36+
* Corrective-RAG (CRAG) [paper](https://arxiv.org/pdf/2401.15884.pdf) uses self-grading on retrieved documents and web-search fallback if documents are not relevant.
37+
* Self-RAG [paper](https://arxiv.org/abs/2310.11511) adds self-grading on generations for hallucinations and for ability to answer the question.
38+
* Adaptive RAG [paper](https://arxiv.org/abs/2403.14403) routes queries between different RAG approaches based on their complexity.
39+
40+
We implement each approach as a control flow in LangGraph:
41+
- **Planning:** The sequence of RAG steps (e.g., retrieval, grading, generation) that we want the agent to take
42+
- **Memory:** All the RAG-related information (input question, retrieved documents, etc) that we want to pass between steps
43+
- **Tool use:** All the tools needed for RAG (e.g., decide web search or vectorstore retrieval based on the question)
44+
45+
We will build from CRAG (blue, below) to Self-RAG (green) and finally to Adaptive RAG (red):
46+
47+
![RAG](./img/langgraph_adaptive_rag.png "RAG control flow")
48+
49+
Our fouth notebook, `langgraph-rag-agent-local`, shows how to apply LangGraph to build advanced RAG agents that run locally and reliable.
50+
51+
See this [video overview](https://www.youtube.com/watch?v=sgnrL7yo1TE) for more detail.

recipes/use_cases/langchain/langgraph-agent.ipynb

Lines changed: 762 additions & 0 deletions
Large diffs are not rendered by default.

recipes/use_cases/langchain/langgraph-rag-agent-local.ipynb

Lines changed: 803 additions & 0 deletions
Large diffs are not rendered by default.

recipes/use_cases/langchain/langgraph-rag-agent.ipynb

Lines changed: 724 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 343 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,343 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "code",
5+
"execution_count": null,
6+
"id": "2f35e5e7-e3b2-4321-bb43-886575533d3d",
7+
"metadata": {},
8+
"outputs": [],
9+
"source": [
10+
"! pip install -U langchain_groq langchain langchain_community langchain_openai tavily-python tiktoken langchainhub chromadb"
11+
]
12+
},
13+
{
14+
"cell_type": "markdown",
15+
"id": "745f7d9f-15c4-41c8-94f8-09e1426581cc",
16+
"metadata": {},
17+
"source": [
18+
"# Tool calling agent with LLaMA3\n",
19+
"\n",
20+
"[Tool calling](https://python.langchain.com/docs/modules/agents/agent_types/tool_calling/) allows an LLM to detect when one or more tools should be called.\n",
21+
"\n",
22+
"It will then respond with the inputs that should be passed to those tools. \n",
23+
"\n",
24+
"LangChain has a general agent that works with tool-calling LLMs.\n",
25+
"\n",
26+
"### Tools \n",
27+
"\n",
28+
"Let's define a few tools.\n",
29+
"\n",
30+
"`Retriever`"
31+
]
32+
},
33+
{
34+
"cell_type": "code",
35+
"execution_count": 4,
36+
"id": "6debf81d-84d1-4645-aa25-07d24cdcbc2c",
37+
"metadata": {},
38+
"outputs": [],
39+
"source": [
40+
"from langchain_community.document_loaders import WebBaseLoader\n",
41+
"from langchain_community.vectorstores import Chroma\n",
42+
"from langchain_openai import OpenAIEmbeddings\n",
43+
"from langchain_text_splitters import RecursiveCharacterTextSplitter\n",
44+
"\n",
45+
"loader = WebBaseLoader(\"https://docs.smith.langchain.com/overview\")\n",
46+
"docs = loader.load()\n",
47+
"documents = RecursiveCharacterTextSplitter(\n",
48+
" chunk_size=1000, chunk_overlap=200\n",
49+
").split_documents(docs)\n",
50+
"vector = Chroma.from_documents(documents, OpenAIEmbeddings())\n",
51+
"retriever = vector.as_retriever()\n",
52+
"\n",
53+
"from langchain.tools.retriever import create_retriever_tool\n",
54+
"retriever_tool = create_retriever_tool(\n",
55+
" retriever,\n",
56+
" \"langsmith_search\",\n",
57+
" \"Search for information about LangSmith. For any questions about LangSmith, you must use this tool!\",\n",
58+
")"
59+
]
60+
},
61+
{
62+
"cell_type": "markdown",
63+
"id": "8454286f-f6d3-4ac0-a583-16315189d151",
64+
"metadata": {},
65+
"source": [
66+
"`Web search`"
67+
]
68+
},
69+
{
70+
"cell_type": "code",
71+
"execution_count": 5,
72+
"id": "8a4d9feb-80b7-4355-9cba-34e816400aa5",
73+
"metadata": {},
74+
"outputs": [],
75+
"source": [
76+
"from langchain_community.tools.tavily_search import TavilySearchResults\n",
77+
"search = TavilySearchResults()"
78+
]
79+
},
80+
{
81+
"cell_type": "markdown",
82+
"id": "42215e7b-3170-4311-8438-5a7b385ebb64",
83+
"metadata": {},
84+
"source": [
85+
"`Custom`"
86+
]
87+
},
88+
{
89+
"cell_type": "code",
90+
"execution_count": 6,
91+
"id": "c130481d-dc6f-48e0-b795-7e3a4438fb6a",
92+
"metadata": {},
93+
"outputs": [],
94+
"source": [
95+
"from langchain.agents import tool\n",
96+
"\n",
97+
"@tool\n",
98+
"def magic_function(input: int) -> int:\n",
99+
" \"\"\"Applies a magic function to an input.\"\"\"\n",
100+
" return input + 2"
101+
]
102+
},
103+
{
104+
"cell_type": "code",
105+
"execution_count": 8,
106+
"id": "bfc0cfbe-d5ce-4c26-859f-5d29be121bef",
107+
"metadata": {},
108+
"outputs": [],
109+
"source": [
110+
"tools = [magic_function, search, retriever_tool] "
111+
]
112+
},
113+
{
114+
"cell_type": "markdown",
115+
"id": "e88c2e1d-1503-4659-be4d-98900a69253f",
116+
"metadata": {},
117+
"source": [
118+
"### LLM\n",
119+
"\n",
120+
"Here, we need a llama model that support tool use.\n",
121+
"\n",
122+
"This can be accomplished via prompt engineering (e.g., see [here](https://replicate.com/hamelsmu/llama-3-70b-instruct-awq-with-tools)) or fine-tuning (e.g., see [here](https://huggingface.co/mzbac/llama-3-8B-Instruct-function-calling) and [here](https://huggingface.co/mzbac/llama-3-8B-Instruct-function-calling)).\n",
123+
"\n",
124+
"We can review LLMs that support tool calling [here](https://python.langchain.com/docs/integrations/chat/) and Groq is included.\n",
125+
"\n",
126+
"[Here](https://github.com/groq/groq-api-cookbook/blob/main/llama3-stock-market-function-calling/llama3-stock-market-function-calling.ipynb) is a reference for Groq + tool use."
127+
]
128+
},
129+
{
130+
"cell_type": "code",
131+
"execution_count": 10,
132+
"id": "99c919d2-198d-4c3b-85ba-0772bf7db383",
133+
"metadata": {},
134+
"outputs": [],
135+
"source": [
136+
"from langchain_groq import ChatGroq\n",
137+
"llm = ChatGroq(temperature=0, model=\"llama3-70b-8192\")"
138+
]
139+
},
140+
{
141+
"cell_type": "markdown",
142+
"id": "695ffb74-c278-4420-b10b-b18210d824eb",
143+
"metadata": {},
144+
"source": [
145+
"### Agent\n",
146+
"\n",
147+
"We use LangChain [tool calling agent](https://python.langchain.com/docs/modules/agents/agent_types/tool_calling/). "
148+
]
149+
},
150+
{
151+
"cell_type": "code",
152+
"execution_count": 11,
153+
"id": "fae083a8-864c-4394-93e5-36d22aaa5fe3",
154+
"metadata": {},
155+
"outputs": [],
156+
"source": [
157+
"# Prompt \n",
158+
"from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder\n",
159+
"prompt = ChatPromptTemplate.from_messages(\n",
160+
" [\n",
161+
" (\"system\", \"You are a helpful assistant\"),\n",
162+
" (\"human\", \"{input}\"),\n",
163+
" MessagesPlaceholder(\"agent_scratchpad\"),\n",
164+
" ]\n",
165+
")"
166+
]
167+
},
168+
{
169+
"cell_type": "code",
170+
"execution_count": 12,
171+
"id": "421f9565-bc1a-4141-aae7-c6bcae2c63fc",
172+
"metadata": {},
173+
"outputs": [],
174+
"source": [
175+
"### Run\n",
176+
"from langchain.agents import AgentExecutor, create_tool_calling_agent, tool\n",
177+
"agent = create_tool_calling_agent(llm, tools, prompt)\n",
178+
"agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)"
179+
]
180+
},
181+
{
182+
"cell_type": "code",
183+
"execution_count": 13,
184+
"id": "229372f4-abb3-4418-9444-cadc548a8155",
185+
"metadata": {},
186+
"outputs": [
187+
{
188+
"name": "stdout",
189+
"output_type": "stream",
190+
"text": [
191+
"\n",
192+
"\n",
193+
"\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
194+
"\u001b[32;1m\u001b[1;3m\n",
195+
"Invoking: `magic_function` with `{'input': 3}`\n",
196+
"\n",
197+
"\n",
198+
"\u001b[0m\u001b[36;1m\u001b[1;3m5\u001b[0m\u001b[32;1m\u001b[1;3mThe result of `magic_function(3)` is indeed 5.\u001b[0m\n",
199+
"\n",
200+
"\u001b[1m> Finished chain.\u001b[0m\n"
201+
]
202+
},
203+
{
204+
"data": {
205+
"text/plain": [
206+
"{'input': 'what is the value of magic_function(3)?',\n",
207+
" 'output': 'The result of `magic_function(3)` is indeed 5.'}"
208+
]
209+
},
210+
"execution_count": 13,
211+
"metadata": {},
212+
"output_type": "execute_result"
213+
}
214+
],
215+
"source": [
216+
"agent_executor.invoke({\"input\": \"what is the value of magic_function(3)?\"})"
217+
]
218+
},
219+
{
220+
"cell_type": "markdown",
221+
"id": "016b447f-d374-4fc7-a1fe-0ce56856a763",
222+
"metadata": {},
223+
"source": [
224+
"Trace: \n",
225+
"\n",
226+
"https://smith.langchain.com/public/adf06494-94d6-4e93-98f3-60e65d2f2c19/r"
227+
]
228+
},
229+
{
230+
"cell_type": "code",
231+
"execution_count": 14,
232+
"id": "6914b16c-be7a-4838-b080-b6af6b6e1417",
233+
"metadata": {},
234+
"outputs": [
235+
{
236+
"name": "stdout",
237+
"output_type": "stream",
238+
"text": [
239+
"\n",
240+
"\n",
241+
"\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
242+
"\u001b[32;1m\u001b[1;3m\n",
243+
"Invoking: `tavily_search_results_json` with `{'query': 'current weather in san francisco'}`\n",
244+
"\n",
245+
"\n",
246+
"\u001b[0m\u001b[33;1m\u001b[1;3m[{'url': 'https://www.weatherapi.com/', 'content': \"{'location': {'name': 'San Francisco', 'region': 'California', 'country': 'United States of America', 'lat': 37.78, 'lon': -122.42, 'tz_id': 'America/Los_Angeles', 'localtime_epoch': 1714766520, 'localtime': '2024-05-03 13:02'}, 'current': {'last_updated_epoch': 1714766400, 'last_updated': '2024-05-03 13:00', 'temp_c': 17.8, 'temp_f': 64.0, 'is_day': 1, 'condition': {'text': 'Partly cloudy', 'icon': '//cdn.weatherapi.com/weather/64x64/day/116.png', 'code': 1003}, 'wind_mph': 6.9, 'wind_kph': 11.2, 'wind_degree': 250, 'wind_dir': 'WSW', 'pressure_mb': 1014.0, 'pressure_in': 29.95, 'precip_mm': 0.0, 'precip_in': 0.0, 'humidity': 54, 'cloud': 25, 'feelslike_c': 17.8, 'feelslike_f': 64.0, 'vis_km': 16.0, 'vis_miles': 9.0, 'uv': 5.0, 'gust_mph': 17.0, 'gust_kph': 27.4}}\"}, {'url': 'https://www.wunderground.com/hourly/us/ca/san-francisco/94134/date/2024-05-03', 'content': 'San Francisco Weather Forecasts. Weather Underground provides local & long-range weather forecasts, weatherreports, maps & tropical weather conditions for the San Francisco area. ... Friday 05/03 ...'}, {'url': 'https://www.accuweather.com/en/us/san-francisco/94103/weather-forecast/347629', 'content': 'San Francisco, CA Weather Forecast, with current conditions, wind, air quality, and what to expect for the next 3 days.'}, {'url': 'https://forecast.weather.gov/zipcity.php?inputstring=San francisco,CA', 'content': 'San Francisco CA 37.77°N 122.41°W (Elev. 131 ft) Last Update: 1:25 am PDT May 2, 2024. Forecast Valid: 4am PDT May 2, 2024-6pm PDT May 8, 2024 . Forecast Discussion . Additional Resources. Radar & Satellite Image. Hourly Weather Forecast. ... Severe Weather ; Current Outlook Maps ; Drought ; Fire Weather ; Fronts/Precipitation Maps ; Current ...'}, {'url': 'https://www.timeanddate.com/weather/usa/san-francisco/hourly', 'content': 'Hour-by-Hour Forecast for San Francisco, California, USA. Weather Today Weather Hourly 14 Day Forecast Yesterday/Past Weather Climate (Averages) Currently: 51 °F. Clear. (Weather station: San Francisco International Airport, USA). See more current weather.'}]\u001b[0m\u001b[32;1m\u001b[1;3mThe current weather in San Francisco is partly cloudy with a temperature of 64°F (17.8°C) and humidity of 54%. The wind is blowing at 6.9 mph (11.2 km/h) from the west-southwest direction.\u001b[0m\n",
247+
"\n",
248+
"\u001b[1m> Finished chain.\u001b[0m\n"
249+
]
250+
},
251+
{
252+
"data": {
253+
"text/plain": [
254+
"{'input': 'whats the weather in sf?',\n",
255+
" 'output': 'The current weather in San Francisco is partly cloudy with a temperature of 64°F (17.8°C) and humidity of 54%. The wind is blowing at 6.9 mph (11.2 km/h) from the west-southwest direction.'}"
256+
]
257+
},
258+
"execution_count": 14,
259+
"metadata": {},
260+
"output_type": "execute_result"
261+
}
262+
],
263+
"source": [
264+
"agent_executor.invoke({\"input\": \"whats the weather in sf?\"})"
265+
]
266+
},
267+
{
268+
"cell_type": "markdown",
269+
"id": "9e363535-29b8-45d8-85b6-10d2e21f93bc",
270+
"metadata": {},
271+
"source": [
272+
"Trace: \n",
273+
"\n",
274+
"https://smith.langchain.com/public/64a62781-7e3c-4acf-ae72-ce49ccb82960/r"
275+
]
276+
},
277+
{
278+
"cell_type": "code",
279+
"execution_count": null,
280+
"id": "8ce1b38c-a22a-4035-a9a1-2ea0da419ade",
281+
"metadata": {},
282+
"outputs": [],
283+
"source": [
284+
"agent_executor.invoke({\"input\": \"how can langsmith help with testing?\"})"
285+
]
286+
},
287+
{
288+
"cell_type": "markdown",
289+
"id": "e28cc79b-f6de-45fb-b7e5-84c119ba57da",
290+
"metadata": {},
291+
"source": [
292+
"This last question failed to run. \n",
293+
"\n",
294+
"Trace:\n",
295+
"\n",
296+
"https://smith.langchain.com/public/960a40e9-24f1-42a0-859d-2e0a30018d1c/r\n",
297+
"\n",
298+
"We can see that the agent correctly decides to query the vectorstore for a question about LangSmith.\n",
299+
"\n",
300+
"But it then inexplicably attempts web search. \n",
301+
"\n",
302+
"And it appears to get stuck in a loop of calling various tools before crashing.\n",
303+
"\n",
304+
"Of course, this is using a non-fine-tuned (only prompting) version of llama3 for tool-use.\n",
305+
"\n",
306+
"But, it illustates the reliability challenge with using Agent Executor. \n",
307+
"\n",
308+
"It is sensitive to the LLMs capacity for tool-use! \n",
309+
"\n",
310+
"In the next notebook, we will show an alternative way to implement this agent using LangGraph."
311+
]
312+
},
313+
{
314+
"cell_type": "code",
315+
"execution_count": null,
316+
"id": "55e7518c-e7d8-4ce7-9a4a-7909fb3a8b88",
317+
"metadata": {},
318+
"outputs": [],
319+
"source": []
320+
}
321+
],
322+
"metadata": {
323+
"kernelspec": {
324+
"display_name": "Python 3 (ipykernel)",
325+
"language": "python",
326+
"name": "python3"
327+
},
328+
"language_info": {
329+
"codemirror_mode": {
330+
"name": "ipython",
331+
"version": 3
332+
},
333+
"file_extension": ".py",
334+
"mimetype": "text/x-python",
335+
"name": "python",
336+
"nbconvert_exporter": "python",
337+
"pygments_lexer": "ipython3",
338+
"version": "3.11.9"
339+
}
340+
},
341+
"nbformat": 4,
342+
"nbformat_minor": 5
343+
}

0 commit comments

Comments
 (0)