Ausnahme gefangen: SSL certificate problem: certificate is not yet valid 📌 A Gentle Intro to Chaining LLMs, Agents, and utils via LangChain

🏠 Team IT Security News

TSecurity.de ist eine Online-Plattform, die sich auf die Bereitstellung von Informationen,alle 15 Minuten neuste Nachrichten, Bildungsressourcen und Dienstleistungen rund um das Thema IT-Sicherheit spezialisiert hat.
Ob es sich um aktuelle Nachrichten, Fachartikel, Blogbeiträge, Webinare, Tutorials, oder Tipps & Tricks handelt, TSecurity.de bietet seinen Nutzern einen umfassenden Überblick über die wichtigsten Aspekte der IT-Sicherheit in einer sich ständig verändernden digitalen Welt.

16.12.2023 - TIP: Wer den Cookie Consent Banner akzeptiert, kann z.B. von Englisch nach Deutsch übersetzen, erst Englisch auswählen dann wieder Deutsch!

Google Android Playstore Download Button für Team IT Security



📚 A Gentle Intro to Chaining LLMs, Agents, and utils via LangChain


💡 Newskategorie: AI Nachrichten
🔗 Quelle: towardsdatascience.com

#LLM for beginners

Understand the basics of agents, tools, and prompts and some learnings along the way

Audience: For those feeling overwhelmed with the giant (yet brilliant) library…
Image generated by Author using DALL.E 2

Introduction

I’d be lying if I said I have got the entire LangChain library covered — in fact, I am far from it. But the buzz surrounding it was enough to shake me out of my writing hiatus and give it a go 🚀.

The initial motivation was to see what was it that LangChain was adding (on a practical level) that set it apart from the chatbot I built last month using the ChatCompletion.create() function from the openai package. Whilst doing so, I realized I needed to understand the building blocks for LangChain first before moving on to the more complex parts.

This is what this article does. Heads-up though, this will be more parts coming as I am truly fascinated by the library and will continue to explore to see what all can be built through it.

Let’s begin by understanding the fundamental building blocks of LangChain — i.e. Chains. If you’d like to follow along, here’s the GitHub repo.

What are chains in LangChain?

Chains are what you get by connecting one or more large language models (LLMs) in a logical way. (Chains can be built of entities other than LLMs but for now, let’s stick with this definition for simplicity).

OpenAI is a type of LLM (provider) that you can use but there are others like Cohere, Bloom, Huggingface, etc.

Note: Pretty much most of these LLM providers will need you to request an API key in order to use them. So make sure you do that before proceeding with the remainder of this blog. For example:

import os
os.environ["OPENAI_API_KEY"] = "..."

P.S. I am going to use OpenAI for this tutorial because I have a key with credits that expire in a month’s time, but feel free to replace it with any other LLM. The concepts covered here will be useful regardless.

Chains can be simple (i.e. Generic) or specialized (i.e. Utility).

  1. Generic — A single LLM is the simplest chain. It takes an input prompt and the name of the LLM and then uses the LLM for text generation (i.e. output for the prompt). Here’s an example:

Let’s build a basic chain — create a prompt and get a prediction

Prompt creation (using PromptTemplate) is a bit fancy in Lanchain but this is probably because there are quite a few different ways prompts can be created depending on the use case (we will cover AIMessagePromptTemplate,
HumanMessagePromptTemplate etc. in the next blog post). Here’s a simple one for now:

from langchain.prompts import PromptTemplate

prompt = PromptTemplate(
input_variables=["product"],
template="What is a good name for a company that makes {product}?",
)

print(prompt.format(product="podcast player"))

# OUTPUT
# What is a good name for a company that makes podcast player?

Note: If you require multiple input_variables, for instance: input_variables=["product", "audience"] for a template such as “What is a good name for a company that makes {product} for {audience}”, you need to do print(prompt.format(product="podcast player", audience="children”) to get the updated prompt.

Once you have built a prompt, we can call the desired LLM with it. To do so, we create an LLMChain instance (in our case, we use OpenAI's large language model text-davinci-003). To get the prediction (i.e. AI-generated text), we use run function with the name of the product.

from langchain.llms import OpenAI
from langchain.chains import LLMChain

llm = OpenAI(
model_name="text-davinci-003", # default model
temperature=0.9) #temperature dictates how whacky the output should be
llmchain = LLMChain(llm=llm, prompt=prompt)
llmchain.run("podcast player")

# OUTPUT
# PodConneXion

If you had more than one input_variables, then you won’t be able to use run. Instead, you’ll have to pass all the variables as a dict. For example, llmchain({“product”: “podcast player”, “audience”: “children”}).

Note 1: According to OpenAI, davinci text-generation models are 10x more expensive than their chat counterparts i.e gpt-3.5-turbo, so I tried to switch from a text model to a chat model (i.e. from OpenAI to ChatOpenAI) and the results are pretty much the same.

Note 2: You might see some tutorials using OpenAIChatinstead of ChatOpenAI. The former is deprecated and will no longer be supported and we are supposed to use ChatOpenAI.

from langchain.chat_models import ChatOpenAI

chatopenai = ChatOpenAI(
model_name="gpt-3.5-turbo")
llmchain_chat = LLMChain(llm=chatopenai, prompt=prompt)
llmchain_chat.run("podcast player")

# OUTPUT
# PodcastStream

This concludes our section on simple chains. It is important to note that we rarely use generic chains as standalone chains. More often they are used as building blocks for Utility chains (as we will see next).

2. Utility — These are specialized chains, comprised of many LLMs to help solve a specific task. For example, LangChain supports some end-to-end chains (such as AnalyzeDocumentChain for summarization, QnA, etc) and some specific ones (such as GraphQnAChain for creating, querying, and saving graphs). We will look at one specific chain called PalChain in this tutorial for digging deeper.

PAL stands for Programme Aided Language Model. PALChain reads complex math problems (described in natural language) and generates programs (for solving the math problem) as the intermediate reasoning steps, but offloads the solution step to a runtime such as a Python interpreter.

To confirm this is in fact true, we can inspect the _call() in the base code here. Under the hood, we can see this chain:

P.S. It is a good practice to inspect _call() in base.py for any of the chains in LangChain to see how things are working under the hood.

from langchain.chains import PALChain
palchain = PALChain.from_math_prompt(llm=llm, verbose=True)
palchain.run("If my age is half of my dad's age and he is going to be 60 next year, what is my current age?")

# OUTPUT
# > Entering new PALChain chain...
# def solution():
# """If my age is half of my dad's age and he is going to be 60 next year, what is my current age?"""
# dad_age_next_year = 60
# dad_age_now = dad_age_next_year - 1
# my_age_now = dad_age_now / 2
# result = my_age_now
# return result
#
# > Finished chain.
# '29.5'

Note1: verbose can be set to False if you do not need to see the intermediate step.

Now some of you may be wondering — but what about the prompt? We certainly didn’t pass one as we did for the generic llmchain we built. The fact is, it is automatically loaded when using .from_math_prompt(). You can check the default prompt using palchain.prompt.template or you can directly inspect the prompt file here.

print(palchain.prompt.template)
# OUTPUT
# 'Q: Olivia has $23. She bought five bagels for $3 each. How much money does she have left?\n\n# solution in Python:\n\n\ndef solution():\n """Olivia has $23. She bought five bagels for $3 each. How much money does she have left?"""\n money_initial = 23\n bagels = 5\n bagel_cost = 3\n money_spent = bagels * bagel_cost\n money_left = money_initial - money_spent\n result = money_left\n return result\n\n\n\n\n\nQ: Michael had 58 golf balls. On tuesday, he lost 23 golf balls. On wednesday, he lost 2 more. How many golf balls did he have at the end of wednesday?\n\n# solution in Python:\n\n\ndef solution():\n """Michael had 58 golf balls. On tuesday, he lost 23 golf balls. On wednesday, he lost 2 more. How many golf balls did he have at the end of wednesday?"""\n golf_balls_initial = 58\n golf_balls_lost_tuesday = 23\n golf_balls_lost_wednesday = 2\n golf_balls_left = golf_balls_initial - golf_balls_lost_tuesday - golf_balls_lost_wednesday\n result = golf_balls_left\n return result\n\n\n\n\n\nQ: There were nine computers in the server room. Five more computers were installed each day, from monday to thursday. How many computers are now in the server room?\n\n# solution in Python:\n\n\ndef solution():\n """There were nine computers in the server room. Five more computers were installed each day, from monday to thursday. How many computers are now in the server room?"""\n computers_initial = 9\n computers_per_day = 5\n num_days = 4 # 4 days between monday and thursday\n computers_added = computers_per_day * num_days\n computers_total = computers_initial + computers_added\n result = computers_total\n return result\n\n\n\n\n\nQ: Shawn has five toys. For Christmas, he got two toys each from his mom and dad. How many toys does he have now?\n\n# solution in Python:\n\n\ndef solution():\n """Shawn has five toys. For Christmas, he got two toys each from his mom and dad. How many toys does he have now?"""\n toys_initial = 5\n mom_toys = 2\n dad_toys = 2\n total_received = mom_toys + dad_toys\n total_toys = toys_initial + total_received\n result = total_toys\n return result\n\n\n\n\n\nQ: Jason had 20 lollipops. He gave Denny some lollipops. Now Jason has 12 lollipops. How many lollipops did Jason give to Denny?\n\n# solution in Python:\n\n\ndef solution():\n """Jason had 20 lollipops. He gave Denny some lollipops. Now Jason has 12 lollipops. How many lollipops did Jason give to Denny?"""\n jason_lollipops_initial = 20\n jason_lollipops_after = 12\n denny_lollipops = jason_lollipops_initial - jason_lollipops_after\n result = denny_lollipops\n return result\n\n\n\n\n\nQ: Leah had 32 chocolates and her sister had 42. If they ate 35, how many pieces do they have left in total?\n\n# solution in Python:\n\n\ndef solution():\n """Leah had 32 chocolates and her sister had 42. If they ate 35, how many pieces do they have left in total?"""\n leah_chocolates = 32\n sister_chocolates = 42\n total_chocolates = leah_chocolates + sister_chocolates\n chocolates_eaten = 35\n chocolates_left = total_chocolates - chocolates_eaten\n result = chocolates_left\n return result\n\n\n\n\n\nQ: If there are 3 cars in the parking lot and 2 more cars arrive, how many cars are in the parking lot?\n\n# solution in Python:\n\n\ndef solution():\n """If there are 3 cars in the parking lot and 2 more cars arrive, how many cars are in the parking lot?"""\n cars_initial = 3\n cars_arrived = 2\n total_cars = cars_initial + cars_arrived\n result = total_cars\n return result\n\n\n\n\n\nQ: There are 15 trees in the grove. Grove workers will plant trees in the grove today. After they are done, there will be 21 trees. How many trees did the grove workers plant today?\n\n# solution in Python:\n\n\ndef solution():\n """There are 15 trees in the grove. Grove workers will plant trees in the grove today. After they are done, there will be 21 trees. How many trees did the grove workers plant today?"""\n trees_initial = 15\n trees_after = 21\n trees_added = trees_after - trees_initial\n result = trees_added\n return result\n\n\n\n\n\nQ: {question}\n\n# solution in Python:\n\n\n'

Note: Most of the utility chains will have their prompts pre-defined as part of the library (check them out here). They are, at times, quite detailed (read: lots of tokens) so there is definitely a trade-off between cost and the quality of response from the LLM.

Are there any Chains that don’t need LLMs and prompts?

Even though PalChain requires an LLM (and a corresponding prompt) to parse the user’s question written in natural language, there are some chains in LangChain that don’t need one. These are mainly transformation chains that preprocess the prompt, such as removing extra spaces, before inputting it into the LLM. You can see another example here.

Can we get to the good part and start creating chains?

Of course, we can! We have all the basic building blocks we need to start chaining together LLMs logically such that input from one can be fed to the next. To do so, we will use SimpleSequentialChain.

The documentation has some great examples on this, for example, you can see here how to have two chains combined where chain#1 is used to clean the prompt (remove extra whitespaces, shorten prompt, etc) and chain#2 is used to call an LLM with this clean prompt. Here’s another one where chain#1 is used to generate a synopsis for a play and chain#2 is used to write a review based on this synopsis.

While these are excellent examples, I want to focus on something else. If you remember before, I mentioned that chains can be composed of entities other than LLMs. More specifically, I am interested in chaining agents and LLMs together. But first, what are agents?

Using agents for dynamically calling LLMs

It will be much easier to explain what an agent does vs. what it is.

Say, we want to know the weather forecast for tomorrow. If were to use the simple ChatGPT API and give it a prompt Show me the weather for tomorrow in London, it won’t know the answer because it does not have access to real-time data.

Wouldn’t it be useful if we had an arrangement where we could utilize an LLM for understanding our query (i.e prompt) in natural language and then call the weather API on our behalf to fetch the data needed? This is exactly what an agent does (amongst other things, of course).

An agent has access to an LLM and a suite of tools for example Google Search, Python REPL, math calculator, weather APIs, etc.

There are quite a few agents that LangChain supports — see here for the complete list, but quite frankly the most common one I came across in tutorials and YT videos was zero-shot-react-description. This agent uses ReAct (Reason + Act) framework to pick the most usable tool (from a list of tools), based on what the input query is.

P.S.: Here’s a nice article that goes in-depth into the ReAct framework.

Let’s initialize an agent using initialize_agent and pass it the tools and LLM it needs. There’s a long list of tools available here that an agent can use to interact with the outside world. For our example, we are using the same math-solving tool as above, called pal-math. This one requires an LLM at the time of initialization, so we pass to it the same OpenAI LLM instance as before.

from langchain.agents import initialize_agent
from langchain.agents import AgentType
from langchain.agents import load_tools

llm = OpenAI(temperature=0)
tools = load_tools(["pal-math"], llm=llm)

agent = initialize_agent(tools,
llm,
agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
verbose=True)

Let’s test it out on the same example as above:

agent.run("If my age is half of my dad's age and he is going to be 60 next year, what is my current age?")

# OUTPUT
# > Entering new AgentExecutor chain...
# I need to figure out my dad's current age and then divide it by two.
# Action: PAL-MATH
# Action Input: What is my dad's current age if he is going to be 60 next year?
# Observation: 59
# Thought: I now know my dad's current age, so I can divide it by two to get my age.
# Action: Divide 59 by 2
# Action Input: 59/2
# Observation: Divide 59 by 2 is not a valid tool, try another one.
# Thought: I can use PAL-MATH to divide 59 by 2.
# Action: PAL-MATH
# Action Input: Divide 59 by 2
# Observation: 29.5
# Thought: I now know the final answer.
# Final Answer: My current age is 29.5 years old.

# > Finished chain.
# 'My current age is 29.5 years old.'

Note 1: At each step, you’ll notice that an agent does one of three things — it either has an observation, a thought, or it takes an action. This is mainly due to the ReAct framework and the associated prompt that the agent is using:

print(agent.agent.llm_chain.prompt.template)
# OUTPUT
# Answer the following questions as best you can. You have access to the following tools:
# PAL-MATH: A language model that is really good at solving complex word math problems. Input should be a fully worded hard word math problem.

# Use the following format:

# Question: the input question you must answer
# Thought: you should always think about what to do
# Action: the action to take, should be one of [PAL-MATH]
# Action Input: the input to the action
# Observation: the result of the action
# ... (this Thought/Action/Action Input/Observation can repeat N times)
# Thought: I now know the final answer
# Final Answer: the final answer to the original input question
# Begin!
# Question: {input}
# Thought:{agent_scratchpad}

Note2: You might be wondering what’s the point of getting an agent to do the same thing that an LLM can do. Some applications will require not just a predetermined chain of calls to LLMs/other tools, but potentially an unknown chain that depends on the user’s input [Source]. In these types of chains, there is an “agent” which has access to a suite of tools.
For instance,
here’s an example of an agent that can fetch the correct documents (from the vectorstores) for RetrievalQAChain depending on whether the question refers to document A or document B.

For fun, I tried making the input question more complex (using Demi Moore’s age as a placeholder for Dad’s actual age).

agent.run("My age is half of my dad's age. Next year he is going to be same age as Demi Moore. What is my current age?")

Unfortunately, the answer was slightly off as the agent was not using the latest age for Demi Moore (since Open AI models were trained on data until 2020). This can be easily fixed by including another tool —
tools = load_tools([“pal-math”, "serpapi"], llm=llm). serpapi is useful for answering questions about current events.

Note: It is important to add as many tools as you think may be relevant to the user query. The problem with using a single tool is that the agent keeps trying to use the same tool even if it’s not the most relevant for a particular observation/action step.

Here’s another example of a tool you can use — podcast-api. You need to get your own API key and plug it into the code below.


tools = load_tools(["podcast-api"], llm=llm, listen_api_key="...")
agent = initialize_agent(tools,
llm,
agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
verbose=True)

agent.run("Show me episodes for money saving tips.")

# OUTPUT
# > Entering new AgentExecutor chain...
# I should search for podcasts or episodes related to money saving
# Action: Podcast API
# Action Input: Money saving tips
# Observation: The API call returned 3 podcasts related to money saving tips: The Money Nerds, The Rachel Cruze Show, and The Martin Lewis Podcast. These podcasts offer valuable money saving tips and advice to help people take control of their finances and create a life they love.
# Thought: I now have some options to choose from
# Final Answer: The Money Nerds, The Rachel Cruze Show, and The Martin Lewis Podcast are great podcast options for money saving tips.

# > Finished chain.

# 'The Money Nerds, The Rachel Cruze Show, and The Martin Lewis Podcast are great podcast options for money saving tips.'

Note1: There is a known error with using this API where you might see, openai.error.InvalidRequestError: This model’s maximum context length is 4097 tokens, however you requested XXX tokens (XX in your prompt; XX for the completion). Please reduce your prompt; or completion length. This happens when the response returned by the API might be too big. To work around this, the documentation suggests returning fewer search results, for example, by updating the question to "Show me episodes for money saving tips, return only 1 result".

Note2: While tinkering around with this tool, I noticed some inconsistencies. The responses aren’t always complete the first time around, for instance here are the input and responses from two consecutive runs:

Input: “Podcasts for getting better at French”

Response 1: “The best podcast for learning French is the one with the highest review score.”
Response 2: ‘The best podcast for learning French is “FrenchPod101”.

Under the hood, the tool is first using an LLMChain for building the API URL based on our input instructions (something along the lines of https://listen-api.listennotes.com/api/v2/search?q=french&type=podcast&page_size=3) and making the API call. Upon receiving the response, it uses another LLMChain that summarizes the response to get the answer to our original question. You can check out the prompts here for both LLMchains which describe the process in more detail.

I am inclined to guess the inconsistent results seen above are resulting from the summarization step because I have separately debugged and tested the API URL (created by LLMChain#1) via Postman and received the right response. To further confirm my doubts, I also stress-tested the summarization chain as a standalone chain with an empty API URL hoping it would throw an error but got the response “Investing’ podcasts were found, containing 3 results in total.” 🤷‍♀ I’d be curious to see if others had better luck than me with this tool!

Use Case 2: Combine chains to create an age-appropriate gift generator

Let’s put our knowledge of agents and sequential chaining to good use and create our own sequential chain. We will combine:

  • Chain #1 — The agent we just created that can solve age problems in math.
  • Chain #2 — An LLM that takes the age of a person and suggests an appropriate gift for them.
# Chain1 - solve math problem, get the age
chain_one = agent

# Chain2 - suggest age-appropriate gift
template = """You are a gift recommender. Given a person's age,\n
it is your job to suggest an appropriate gift for them.

Person Age:
{age}
Suggest gift:"""
prompt_template = PromptTemplate(input_variables=["age"], template=template)
chain_two = LLMChain(llm=llm, prompt=prompt_template)

Now that we have both chains ready we can combine them using SimpleSequentialChain.

from langchain.chains import SimpleSequentialChain

overall_chain = SimpleSequentialChain(
chains=[chain_one, chain_two],
verbose=True)

A couple of things to note:

  • We need not explicitly pass input_variables and output_variables for SimpleSequentialChain as the underlying assumption is that the output from chain 1 is passed as input to chain 2.

Finally, we can run it with the same math problem as before:

question = "If my age is half of my dad's age and he is going to be 60 next year, what is my current age?"
overall_chain.run(question)

# OUTPUT
# > Entering new SimpleSequentialChain chain...


# > Entering new AgentExecutor chain...
# I need to figure out my dad's current age and then divide it by two.
# Action: PAL-MATH
# Action Input: What is my dad's current age if he is going to be 60 next year?
# Observation: 59
# Thought: I now know my dad's current age, so I can divide it by two to get my age.
# Action: Divide 59 by 2
# Action Input: 59/2
# Observation: Divide 59 by 2 is not a valid tool, try another one.
# Thought: I need to use PAL-MATH to divide 59 by 2.
# Action: PAL-MATH
# Action Input: Divide 59 by 2
# Observation: 29.5
# Thought: I now know the final answer.
# Final Answer: My current age is 29.5 years old.

# > Finished chain.
# My current age is 29.5 years old.

# Given your age, a great gift would be something that you can use and enjoy now like a nice bottle of wine, a luxury watch, a cookbook, or a gift card to a favorite store or restaurant. Or, you could get something that will last for years like a nice piece of jewelry or a quality leather wallet.

# > Finished chain.
# '\nGiven your age, a great gift would be something that you can use and enjoy now like a nice bottle of wine, a luxury watch, a cookbook, or a gift card to a favorite store or restaurant. Or, you could get something that will last for years like a nice piece of jewelry or a quality leather wallet

There might be times when you need to pass along some additional context to the second chain, in addition to what it is receiving from the first chain. For instance, I want to set a budget for the gift, depending on the age of the person that is returned by the first chain. We can do so using SimpleMemory.

First, let’s update the prompt for chain_two and pass to it a second variable called budget inside input_variables.

template = """You are a gift recommender. Given a person's age,\n
it is your job to suggest an appropriate gift for them. If age is under 10,\n
the gift should cost no more than {budget} otherwise it should cost atleast 10 times {budget}.

Person Age:
{output}
Suggest gift:"""
prompt_template = PromptTemplate(input_variables=["output", "budget"], template=template)
chain_two = LLMChain(llm=llm, prompt=prompt_template)

If you compare the template we had for SimpleSequentialChain with the one above, you’ll notice that I have also updated the first input’s variable name from age → output. This is a crucial step, failing which an error would be raised at the time of chain validation — Missing required input keys: {age}, only had {input, output, budget}.
This is because the output from the first entity in the chain (i.e. agent) will be the input for the second entity in the chain (i.e. chain_two) and therefore the variable names must match. Upon inspecting agent’s output keys, we see that the output variable is called output, hence the update.

print(agent.agent.llm_chain.output_keys)

# OUTPUT
["output"]

Next, let’s update the kind of chain we are making. We can no longer work with SimpleSequentialChain because it only works in cases where this is a single input and single output. Since chain_two is now taking two input_variables, we need to use SequentialChain which is tailored to handle multiple inputs and outputs.

overall_chain = SequentialChain(
input_variables=["input"],
memory=SimpleMemory(memories={"budget": "100 GBP"}),
chains=[agent, chain_two],
verbose=True)

A couple of things to note:

  • Unlike SimpleSequentialChain, passing input_variables parameter is mandatory for SequentialChain. It is a list containing the name of the input variables that the first entity in the chain (i.e. agent in our case) expects.
    Now some of you may be wondering how to know the exact name used in the input prompt that the agent is going to use. We certainly did not write the prompt for this agent (as we did for chain_two)! It's actually pretty straightforward to find it out by inspecting the prompt template of the llm_chain that the agent is made up of.
print(agent.agent.llm_chain.prompt.template)

# OUTPUT
#Answer the following questions as best you can. You have access to the following tools:

#PAL-MATH: A language model that is really good at solving complex word math problems. Input should be a fully worded hard word math problem.

#Use the following format:

#Question: the input question you must answer
#Thought: you should always think about what to do
#Action: the action to take, should be one of [PAL-MATH]
#Action Input: the input to the action
#Observation: the result of the action
#... (this Thought/Action/Action Input/Observation can repeat N times)
#Thought: I now know the final answer
#Final Answer: the final answer to the original input question

#Begin!

#Question: {input}
#Thought:{agent_scratchpad}

As you can see toward the end of the prompt, the questions being asked by the end-user is stored in an input variable by the name input. If for some reason you had to manipulate this name in the prompt, make sure you are also updating the input_variables at the time of the creation of SequentialChain.

Finally, you could have found out the same information without going through the whole prompt:

print(agent.agent.llm_chain.prompt.input_variables)

# OUTPUT
# ['input', 'agent_scratchpad']
  • SimpleMemory is an easy way to store context or other bits of information that shouldn’t ever change between prompts. It requires one parameter at the time of initialization — memories. You can pass elements to it in dict form. For instance, SimpleMemory(memories={“budget”: “100 GBP”}).

Finally, let’s run the new chain with the same prompt as before. You will notice, the final output has some luxury gift recommendations such as weekend getaways in accordance with the higher budget in our updated prompt.

overall_chain.run("If my age is half of my dad's age and he is going to be 60 next year, what is my current age?")

# OUTPUT
#> Entering new SequentialChain chain...


#> Entering new AgentExecutor chain...
# I need to figure out my dad's current age and then divide it by two.
#Action: PAL-MATH
#Action Input: What is my dad's current age if he is going to be 60 next year?
#Observation: 59
#Thought: I now know my dad's current age, so I can divide it by two to get my age.
#Action: Divide 59 by 2
#Action Input: 59/2
#Observation: Divide 59 by 2 is not a valid tool, try another one.
#Thought: I can use PAL-MATH to divide 59 by 2.
#Action: PAL-MATH
#Action Input: Divide 59 by 2
#Observation: 29.5
#Thought: I now know the final answer.
#Final Answer: My current age is 29.5 years old.

#> Finished chain.

# For someone of your age, a good gift would be something that is both practical and meaningful. Consider something like a nice watch, a piece of jewelry, a nice leather bag, or a gift card to a favorite store or restaurant.\nIf you have a larger budget, you could consider something like a weekend getaway, a spa package, or a special experience.'}

#> Finished chain.
For someone of your age, a good gift would be something that is both practical and meaningful. Consider something like a nice watch, a piece of jewelry, a nice leather bag, or a gift card to a favorite store or restaurant.\nIf you have a larger budget, you could consider something like a weekend getaway, a spa package, or a special experience.'}

Conclusion

Hopefully, the learnings I have shared through this post have made you more comfortable in taking a deep dive into the library. This article just scratched the surface, there is so much more to cover. For instance, how to build a QnA chatbot over your own datasets, and how to optimize memory for these chatbots so that you can cherry-pick/summarize conversations to send in the prompt rather than sending all previous chat history as part of the prompt.

As always if there’s an easier way to do/explain some of the things mentioned in this article, do let me know. In general, refrain from unsolicited destructive/trash/hostile comments!

Until next time ✨


A Gentle Intro to Chaining LLMs, Agents, and utils via LangChain was originally published in Towards Data Science on Medium, where people are continuing the conversation by highlighting and responding to this story.

...



📌 A Gentle Intro to Chaining LLMs, Agents, and utils via LangChain


📈 125.61 Punkte

📌 A Gentle Intro to Azure Cosmos DB for the ASP NET and SQL Server Developer


📈 38.75 Punkte

📌 A Gentle Intro to eBPF


📈 36.96 Punkte

📌 Meet the ‘LangChain Financial Agent’: An AI Fintech Project Built on Langchain and FastAPI


📈 36.68 Punkte

📌 How to Combine Agents and Vector Stores in LangChain?


📈 32.87 Punkte

📌 Build generative AI agents with Amazon Bedrock, Amazon DynamoDB, Amazon Kendra, Amazon Lex, and LangChain


📈 32.87 Punkte

📌 Business Analytics with LangChain and LLMs


📈 32.59 Punkte

📌 Building a Chat App with LangChain, LLMs, and Streamlit for Complex SQL Database Interaction


📈 32.59 Punkte

📌 LLMs for Everyone: Running LangChain and a MistralAI 7B Model in Google Colab


📈 32.59 Punkte

📌 LLMs for Everyone: Running the LLaMA-13B model and LangChain in Google Colab


📈 32.59 Punkte

📌 Performing Customer Analytics with LangChain and LLMs


📈 32.59 Punkte

📌 Getting Started With Agents in LangChain?


📈 31.08 Punkte

📌 Generate Music Recommendations Utilizing LangChain Agents


📈 31.08 Punkte

📌 Using LangChain ReAct Agents for Answering Multi-hop Questions in RAG Systems


📈 31.08 Punkte

📌 Leveraging LLMs with LangChain for Supply Chain Analytics — A Control Tower Powered by GPT


📈 30.8 Punkte

📌 Learn LangChain to link LLMs with external data


📈 30.8 Punkte

📌 LangChain Tutorial: Building LLMs for the First Time


📈 30.8 Punkte

📌 How to Use LangChain to Build With LLMs – A Beginner's Guide


📈 30.8 Punkte

📌 What Is LangChain? Unlocking the Potential of LLMs


📈 30.8 Punkte

📌 LangChain in Action: Redefining Customer Experiences Through LLMs


📈 30.8 Punkte

📌 Meet LangGraph: An AI Library for Building Stateful, Multi-Actor Applications with LLMs Built on Top of LangChain


📈 30.8 Punkte

📌 AI and LLMs - Think of the Children | AI, LLMs and Some Hardware Hacking | News - PSW808


📈 30.29 Punkte

📌 Medium CVE-2020-8147: Utils-extend project Utils-extend


📈 28.89 Punkte

📌 Medium CVE-2020-7722: Nodee-utils project Nodee-utils


📈 28.89 Punkte

📌 SaltStack Salt prior 3002.5 API salt/utils/thin.py salt.utils.thin.gen_thin command injection


📈 28.89 Punkte

📌 High CVE-2021-34080: Ssl-utils project Ssl-utils


📈 28.89 Punkte

📌 Introduction to the Developer's Intro to Data Science Video Series (1 of 28) | Dev Intro to Data Science


📈 28.79 Punkte

📌 Prompt Engineering, Agents, and LLMs: Kickstart a New Year of Hands-On Learning about AI


📈 28.78 Punkte

📌 What are LLMs, Local LLMs and RAG?


📈 28.5 Punkte

📌 What are Large Language Models (LLMs)? Applications and Types of LLMs


📈 28.5 Punkte











matomo