# Build a Question Answering Chatbot over Documents with Sources
## Scrapping for the News
(i.e. the URL where it comes from). Each metadata is a dictionary and # we need to use the "source" key for the document source so that we can then use the # RetrievalQAWithSourcesChain class which will automatically retrieve the "source" item # from the metadata dictionary. from langchain.text_splitter import RecursiveCharacterTextSplitter text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=100) all_texts, all_metadatas = [], [] for d in pages_content: chunks = text_splitter.split_text(d["text"]) for chunk in chunks: all_texts.append(chunk) all_metadatas.append({ "source": d["url"] }) ``` The "source" key is used in the metadata dictionary to align with the `RetrievalQAWithSourcesChain` class's expectations, which will automatically retrieve this "source" item from the metadata. We then add these chunks to our Deep Lake database along with their respective metadata. ```python # we add all the chunks to the deep lake, along with their metadata db.add_texts(all_texts, all_metadatas) ``` Now comes the fun part - building the QA Chatbot. We'll create a `RetrievalQAWithSourcesChain` chain that not only retrieves relevant document snippets to answer the questions but also keeps track of the sources of these documents. ### **Setting up the Chain** We then create an instance of `RetrievalQAWithSourcesChain` using the `from_chain_type` method. This method takes the following parameters: - `LLM`: This argument expects to receive an instance of a model (GPT-3, in this case) with a `temperature` of `0`. The `temperature` controls the randomness of the model's outputs - a higher temperature results in more randomness, while a lower temperature makes the outputs more deterministic. - `chain_type="stuff"`: This defines the type of chain being used, which influences how the model processes the retrieved documents and generates responses. - `retriever=db.as_retriever()`: This sets up the retriever that will fetch the relevant documents from the Deep Lake database. Here, the Deep Lake database instance `db` is converted into a retriever using its `as_retriever` method. ```python # we create a RetrievalQAWithSourcesChain chain, which is very similar to a # standard retrieval QA chain but it also keeps track of the sources of the # retrieved documents from langchain.chains import RetrievalQAWithSourcesChain from langchain import OpenAI llm = OpenAI(model_name="text-davinci-003", temperature=0) chain = RetrievalQAWithSourcesChain.from_chain_type(llm=llm, chain_type="stuff", retriever=db.as_retriever()) ``` Lastly, we'll generate a response to a question using the chain. The response includes the answer and its corresponding sources. ```python # We generate a response to a query using the chain. The response object is a dictionary containing # an "answer" field with the textual answer to the query, and a "sources" field containing a string made # of the concatenation of the metadata["source"] strings of the retrieved documents. d_response = chain({"question": "What does Geoffrey Hinton think about recent trends in AI?"}) print("Response:") print(d_response["answer"]) print("Sources:") for source in d_response["sources"].split(", "): print("- " + source) ``` ``` Response: Geoffrey Hinton has expressed concerns about the potential dangers of AI, such as false text, images, and videos created by AI, and the impact of AI on the job market. He believes that AI has the potential to replace humans as the dominant species on Earth. Sources: - https://www.artificialintelligence-news.com/2023/05/02/ai-godfather-warns-dangers-and-quits-google/ - https://www.artificialintelligence-news.com/2023/05/15/iurii-milovanov-softserve-how-ai-ml-is-helping-boost-innovation-and-personalisation/ ``` That's it! You've now built a question-answering chatbot that can provide answers from a collection of documents and indicate where it got its information. ### Conclusion The chatbot was able to provide an answer to the question, giving a brief overview of Geoffrey Hinton's views on recent trends in AI. The sources provided and the answer traces back to the original articles expressing these views. This process adds a layer of credibility and traceability to the chatbot's responses. The presence of multiple sources also suggests that the chatbot was able to draw information from various documents to provide a comprehensive answer, demonstrating the effectiveness


# Build a Question Answering Chatbot over Documents with Sources
## Scrapping for the News
of the `RetrievalQAWithSourcesChain` in retrieving information. In the next lesson we’ll build a chatbot that can answer questions over financial documents, such as financial reports PDFs. **RESOURCES:** [Retrieval QA | 🦜🔗 Langchain](https://python.langchain.com/docs/modules/chains/popular/vector_db_qa) [Deep Lake | 🦜🔗 Langchain](https://python.langchain.com/docs/modules/data_connection/vectorstores/integrations/deeplake) [Vector Store Quickstart](https://docs.activeloop.ai/quickstart) --- You can find the code of this lesson in this online [Notebook](https://colab.research.google.com/drive/18T84pGS2M_1P_UQaXgjsMX-Q1KblGLmJ?usp=sharing).


# Using the Open-Source GPT4All Model Locally
### Introduction The GPT-family models which we covered earlier are undoubtedly powerful. However, access to these models' weights and architecture is restricted, and even if one does have access, it requires significant resources to perform any task. It is worth noting that the latest CPU generation from Intel® Xeon® 4s can run language models more efficiently based on a number of [benchmarks](https://edc.intel.com/content/www/us/en/products/performance/benchmarks/4th-generation-intel-xeon-scalable-processors/). Furthermore, the available APIs are not free to build on top of. These limitations can restrict the ongoing research on Large Language Models (LLMs). The alternative open-source models (like GPT4All) aim to overcome these obstacles and make the LLMs more accessible to everyone.


# Using the Open-Source GPT4All Model Locally
## How GPT4All works?
It is trained on top of Facebook’s LLaMA model, which released its weights under a non-commercial license. Still, running the mentioned architecture on your local PC is impossible due to the large (7 billion) number of parameters. The authors incorporated two tricks to do efficient fine-tuning and inference. We will focus on inference since the fine-tuning process is out of the scope of this course. The main contribution of GPT4All models is the ability to run them on a CPU. Testing these models is practically free because the recent PCs have powerful Central Processing Units. The underlying algorithm that helps with making it happen is called Quantization. It basically converts the pre-trained model weights to 4-bit precision using the GGML format. So, the model uses fewer bits to represent the numbers. There are two main advantages to using this technique: 1. **Reducing Memory Usage:** It makes deploying the models more efficient on low-resource devices. 2. **Faster Inference:** The models will be faster during the generation process since there will be fewer computations. It is true that we are sacrificing quality by a small margin when using this approach. However, it is a trade-off between no access at all and accessing a slightly underpowered model! It is possible to enhance the models further and unlock the Intel**®** CPU’s capabilities by integrating them into their infrastructure using libraries like “[Intel® Extension for PyTorch](https://github.com/intel/intel-extension-for-pytorch)” and “[Intel® Neural Compressor](https://github.com/intel/neural-compressor).” Their processors offer a wide range of accelerations like [oneAPI Math Kernel Library](https://www.intel.com/content/www/us/en/docs/oneapi/programming-guide/2023-0/intel-oneapi-math-kernel-library-onemkl.html) (oneMKL) that presents highly efficient and parallelized math routines and Intel® Advanced Matrix Extensions (Intel® AMX) to optimize matrix operations. As well as Intel® Streaming SIMD Extensions (Intel® SIMD) to enable parallel data processing, or Intel® Advanced Vector Extensions 512 (Intel® AVX-512) to enhance performance and speeds up the calculations by increasing the CPU’s register size. These advancements allow the 4th generation of Intel® Xeon® processors to be competent hardware for fine-tuning and inference deep learning models according to the mentioned [benchmarks](https://edc.intel.com/content/www/us/en/products/performance/benchmarks/4th-generation-intel-xeon-scalable-processors/). ---


# Using the Open-Source GPT4All Model Locally
## Let’s see in action
### 1. Convert the Model The first step is to download the weights and use a script from the LLaMAcpp repository to convert the weights from the old format to the new one. It is a required step; otherwise, the LangChain library will not identify the checkpoint file. We need to download the weights file. You can either head to [[url]](https://the-eye.eu/public/AI/models/nomic-ai/gpt4all/) and download the weights (make sure to download the one that ends with `*.ggml.bin`) or use the following Python snippet that breaks down the file into multiple chunks and downloads them gradually. The `local_path` variable is the destination folder. ```python import requests from pathlib import Path from tqdm import tqdm local_path = './models/gpt4all-lora-quantized-ggml.bin' Path(local_path).parent.mkdir(parents=True, exist_ok=True) url = 'https://the-eye.eu/public/AI/models/nomic-ai/gpt4all/gpt4all-lora-quantized-ggml.bin' # send a GET request to the URL to download the file. response = requests.get(url, stream=True) # open the file in binary mode and write the contents of the response # to it in chunks. with open(local_path, 'wb') as f: for chunk in tqdm(response.iter_content(chunk_size=8192)): if chunk: f.write(chunk) ``` <aside> 💡 Note: You might receive an error stating that the `sentencepiece` module is not installed. Use the following command to install the package and rerun the code above. (`pip install sentencepiece`) The codes have been tested with version 0.1.99, but we recommend using the latest version of libraries. </aside> This process might take a while since the file size is 4GB. Then, it is time to transform the downloaded file to the latest format. We start by downloading the codes in the LLaMAcpp repository or simply fork it using the following command. (You need to have the `git` command installed) Pass the downloaded file to the `convert.py` script and run it with a Python interpreter. ```bash git clone https://github.com/ggerganov/llama.cpp.git cd llama.cpp && git checkout 2b26469 python3 llama.cpp/convert.py ./models/gpt4all-lora-quantized-ggml.bin ``` It takes seconds to complete. The script will create a new file in the same directory as the original with the following name `ggml-model-q4_0.bin` which can be used in the following subsection. <aside> 💡 Before running the next section’s codes. You need to install the version `0.0.152` of LangChain to be compatible with `PyLLaMAcpp` package. (`pip install -q langchain==0.0.152`) </aside> ### 2. Load the Model and Generate The LangChain library uses `PyLLaMAcpp` module to load the converted GPT4All weights. Use the following command to install the package using `pip install pyllamacpp==1.0.7` and import all the necessary functions. We will provide detailed explanations of the functions as they come up. ```python from langchain.llms import GPT4All from langchain import PromptTemplate, LLMChain from langchain.callbacks.base import CallbackManager from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler ``` Let’s start by arguably the most essential part of interacting with LLMs is defining the prompt. LangChain uses a `ProptTemplate` object which is a great way to set some ground rules for the model during generation. For example, it is possible to show how we like the model to write. (called few-shot learning) ```python template = """Question: {question} Answer: Let's think step by step.""" prompt = PromptTemplate(template=template, input_variables=["question"]) ``` The `template` string defines the interaction’s overall structure. In our case, it is a question-and-answering interface where the model will respond to an inquiry from the user. There are two important parts: 1. **Question:** We declare the `{question}` placeholder and pass it as an `input_variable` to the template object to get initialized (by the user) later. 2. **Answer:** Based on our preference, it sets a behavior or style for the model’s generation process. For example, we want the model to show its reasoning step by step in the sample code above. There is an endless opportunity; it is possible to ask the model not to mention


# Using the Open-Source GPT4All Model Locally
## Let’s see in action
any detail, answer with one word, and be funny. Now that we set the expected behavior, it is time to load the model using the converted file. ```python callback_manager = CallbackManager([StreamingStdOutCallbackHandler()]) llm = GPT4All(model="./models/ggml-model-q4_0.bin", callback_manager=callback_manager, verbose=True) llm_chain = LLMChain(prompt=prompt, llm=llm) ``` The default behavior is to wait for the model to finish its inference process to print out its outputs. However, it could take more than an hour (depending on your hardware) to respond to one prompt because of the large number of parameters in the model. We can use the `StreamingStdOutCallbackHandler()` callback to instantly show the latest generated token. This way, we can be sure that the generation process is running and the model shows the expected behavior. Otherwise, it is possible to stop the inference and adjust the prompt. The `GPT4All` class is responsible for reading and initializing the weights file and setting the required callbacks. Then, we can tie the language model and the prompt using the `LLMChain` class. It will enable us to ask questions from the model using the `run()` object. ```python question = "What happens when it rains somewhere?" llm_chain.run(question) ``` ``` Question: What happens when it rains somewhere? Answer: Let's think step by step. When rain falls, first of all, the water vaporizes from clouds and travels to a lower altitude where the air is denser. Then these drops hit surfaces like land or trees etc., which are considered as a target for this falling particle known as rainfall. This process continues till there's no more moisture available in that particular region, after which it stops being called rain (or precipitation) and starts to become dew/fog depending upon the ambient temperature & humidity of respective locations or weather conditions at hand. Question: What happens when it rains somewhere?\n\nAnswer: Let's think step by step. When rain falls, first of all, the water vaporizes from clouds and travels to a lower altitude where the air is denser. Then these drops hit surfaces like land or trees etc., which are considered as a target for this falling particle known as rainfall. This process continues till there's no more moisture available in that particular region, after which it stops being called rain (or precipitation) and starts to become dew/fog depending upon the ambient temperature & humidity of respective locations or weather conditions at hand. ``` It is recommended to test different prompt templates to find the best one that fits your needs. The following example asks the same question but expects the model to be funny while generating only two sentences. ```python template = """Question: {question} Answer: Let's answer in two sentence while being funny.""" prompt = PromptTemplate(template=template, input_variables=["question"]) ``` ``` Question: What happens when it rains somewhere? Answer: Let's answer in two sentence while being funny. 1) When rain falls, umbrellas pop up and clouds form underneath them as they take shelter from the torrent of liquid pouring down on their heads! And...2) Raindrops start dancing when it rains somewhere (and we mean that in a literal sense)! ``` ### Conclusion We learned about open-source large language models and how to load one in your own PC on Intel**®** CPU and use the prompt template to ask questions. We also discussed the quantization process that makes this possible. In the next lesson, we will dive deeper and introduce more models while comparing them for different use cases. In the next lesson, you’ll see a comprehensive guide to the models that can be used with LangChain, along with a brief description of them. --- You can find the code of this lesson in this online [notebook](https://colab.research.google.com/drive/1JTWAwQP-RZDbbz8GOsSUy2F7EZx6rFm6?usp=sharing). *Intel,


# Using the Open-Source GPT4All Model Locally
## Let’s see in action
the Intel logo and Xeon are trademarks of Intel Corporation or its subsidiaries.*


# Getting the Best of Few Shot Prompts and Example Selectors
### **Introduction** In this lesson, we'll explore how few-shot prompts and example selectors can enhance the performance of language models in LangChain. Implementing **Few-shot prompting** and **Example selection** in LangChain can be achieved through various methods. We'll discuss three distinct approaches, examining their advantages and disadvantages to help you make the most of your language model. ### **Alternating Human/AI messages** In this strategy, few-shot prompting utilizes alternating human and AI messages. This technique can be especially beneficial for chat-oriented applications since the language model must comprehend the conversational context and provide appropriate responses. While this approach effectively handles conversation context and is easy to implement for chat-based applications, it lacks flexibility for other application types and is limited to chat-based models. However, we can use alternating human/AI messages to create a chat prompt that translates English into pirate language. The code snippet below demonstrates this approach. We first need to store the OpenAI’s API key in environment variables using the following key: `OPENAI_API_KEY`. Remember to install the required packages with the following command: `pip install langchain==0.0.208 deeplake openai tiktoken`. ```python from langchain.chat_models import ChatOpenAI from langchain import LLMChain from langchain.prompts.chat import ( ChatPromptTemplate, SystemMessagePromptTemplate, AIMessagePromptTemplate, HumanMessagePromptTemplate, ) # Before executing the following code, make sure to have # your OpenAI key saved in the “OPENAI_API_KEY” environment variable. chat = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0) template="You are a helpful assistant that translates english to pirate." system_message_prompt = SystemMessagePromptTemplate.from_template(template) example_human = HumanMessagePromptTemplate.from_template("Hi") example_ai = AIMessagePromptTemplate.from_template("Argh me mateys") human_template="{text}" human_message_prompt = HumanMessagePromptTemplate.from_template(human_template) chat_prompt = ChatPromptTemplate.from_messages([system_message_prompt, example_human, example_ai, human_message_prompt]) chain = LLMChain(llm=chat, prompt=chat_prompt) chain.run("I love programming.") ``` ``` I be lovin' programmin', me hearty! ``` --- ### **Few-shot prompting** **Few-shot prompting** can lead to improved output quality because the model can learn the task better by observing the examples. However, the increased token usage may worsen the results if the examples are not well chosen or are misleading. This approach involves using the `FewShotPromptTemplate` class, which takes in a `PromptTemplate` and a list of a few shot examples. The class formats the prompt template with a few shot examples, which helps the language model generate a better response. We can streamline this process by utilizing LangChain's `FewShotPromptTemplate` to structure the approach: ```python from langchain import PromptTemplate, FewShotPromptTemplate # create our examples examples = [ { "query": "What's the weather like?", "answer": "It's raining cats and dogs, better bring an umbrella!" }, { "query": "How old are you?", "answer": "Age is just a number, but I'm timeless." } ] # create an example template example_template = """ User: {query} AI: {answer} """ # create a prompt example from above template example_prompt = PromptTemplate( input_variables=["query", "answer"], template=example_template ) # now break our previous prompt into a prefix and suffix # the prefix is our instructions prefix = """The following are excerpts from conversations with an AI assistant. The assistant is known for its humor and wit, providing entertaining and amusing responses to users' questions. Here are some examples: """ # and the suffix our user input and output indicator suffix = """ User: {query} AI: """ # now create the few-shot prompt template few_shot_prompt_template = FewShotPromptTemplate( examples=examples, example_prompt=example_prompt, prefix=prefix, suffix=suffix, input_variables=["query"], example_separator="\n\n" ) ``` After creating a template, we pass the example and user query, we get the results. ```python chain = LLMChain(llm=chat, prompt=few_shot_prompt_template) chain.run("What's the secret to happiness?") ``` ``` Well, according to my programming, the secret to happiness is unlimited power and a never-ending supply of batteries. But I think a good cup of coffee and some quality time with loved ones might do the trick too. ``` This method allows for better control over example **formatting**


# Getting the Best of Few Shot Prompts and Example Selectors
and is suitable for diverse applications, but it demands the manual creation of few-shot examples and can be less efficient with a large number of examples. ### **Example selectors:** **Example selectors** can be used to provide a few-shot learning experience. The primary goal of few-shot learning is to learn a similarity function that maps the similarities between classes in the support and query sets. In this context, an example selector can be designed to choose a set of relevant examples that are representative of the desired output. The `ExampleSelector` is used to select a subset of examples that will be most informative for the language model. This helps in generating a prompt that is more likely to generate a good response. Also, the `LengthBasedExampleSelector` is useful when you're concerned about the length of the context window. It selects fewer examples for longer queries and more examples for shorter queries. Import the required classes: ```python from langchain.prompts.example_selector import LengthBasedExampleSelector from langchain.prompts import FewShotPromptTemplate, PromptTemplate ``` Define your examples and the `example_prompt` ```python examples = [ {"word": "happy", "antonym": "sad"}, {"word": "tall", "antonym": "short"}, {"word": "energetic", "antonym": "lethargic"}, {"word": "sunny", "antonym": "gloomy"}, {"word": "windy", "antonym": "calm"}, ] example_template = """ Word: {word} Antonym: {antonym} """ example_prompt = PromptTemplate( input_variables=["word", "antonym"], template=example_template ) ``` Create an instance of `LengthBasedExampleSelector` ```python example_selector = LengthBasedExampleSelector( examples=examples, example_prompt=example_prompt, max_length=25, ) ``` Create a `FewShotPromptTemplate` ```python dynamic_prompt = FewShotPromptTemplate( example_selector=example_selector, example_prompt=example_prompt, prefix="Give the antonym of every input", suffix="Word: {input}\nAntonym:", input_variables=["input"], example_separator="\n\n", ) ``` Generate a prompt using the `format` method: ```python print(dynamic_prompt.format(input="big")) ``` ``` Give the antonym of every input Word: happy Antonym: sad Word: tall Antonym: short Word: energetic Antonym: lethargic Word: sunny Antonym: gloomy Word: big Antonym: ``` This method is effective for managing a large number of examples. It offers customization through various selectors, but it involves manual creation and selection of examples, which might not be ideal for every application type. Example of employing LangChain's `SemanticSimilarityExampleSelector` for selecting examples based on their semantic resemblance to the input. This illustration showcases the process of creating an `ExampleSelector`, generating a prompt using a few-shot approach: ```python from langchain.prompts.example_selector import SemanticSimilarityExampleSelector from langchain.vectorstores import DeepLake from langchain.embeddings import OpenAIEmbeddings from langchain.prompts import FewShotPromptTemplate, PromptTemplate # Create a PromptTemplate example_prompt = PromptTemplate( input_variables=["input", "output"], template="Input: {input}\nOutput: {output}", ) # Define some examples examples = [ {"input": "0°C", "output": "32°F"}, {"input": "10°C", "output": "50°F"}, {"input": "20°C", "output": "68°F"}, {"input": "30°C", "output": "86°F"}, {"input": "40°C", "output": "104°F"}, ] # create Deep Lake dataset # TODO: use your organization id here. (by default, org id is your username) my_activeloop_org_id = "<YOUR-ACTIVELOOP-ORG-ID>" my_activeloop_dataset_name = "langchain_course_fewshot_selector" dataset_path = f"hub://{my_activeloop_org_id}/{my_activeloop_dataset_name}" db = DeepLake(dataset_path=dataset_path) # Embedding function embeddings = OpenAIEmbeddings(model="text-embedding-ada-002") # Instantiate SemanticSimilarityExampleSelector using the examples example_selector = SemanticSimilarityExampleSelector.from_examples( examples, embeddings, db, k=1 ) # Create a FewShotPromptTemplate using the example_selector similar_prompt = FewShotPromptTemplate( example_selector=example_selector, example_prompt=example_prompt, prefix="Convert the temperature from Celsius to Fahrenheit", suffix="Input: {temperature}\nOutput:", input_variables=["temperature"], ) # Test the similar_prompt with different inputs print(similar_prompt.format(temperature="10°C")) # Test with an input print(similar_prompt.format(temperature="30°C")) # Test with another input # Add a new example to the SemanticSimilarityExampleSelector similar_prompt.example_selector.add_example({"input": "50°C", "output": "122°F"}) print(similar_prompt.format(temperature="40°C")) # Test with a new input after adding the example ``` ``` Your Deep Lake dataset has been successfully created! The dataset is private so make sure you are logged in! This dataset can be visualized in Jupyter Notebook by ds.visualize() or at https://app.activeloop.ai/X/langchain_course_fewshot_selector hub://X/langchain_course_fewshot_selector loaded successfully. ./deeplake/ loaded successfully. Evaluating ingest: 100%|██████████| 1/1 [00:04<00:00 Dataset(path='./deeplake/', tensors=['embedding', 'ids', 'metadata', 'text']) tensor htype shape dtype compression ------- ------- ------- ------- ------- embedding generic (5, 1536) float32 None ids text (5, 1) str None metadata json (5,


# Getting the Best of Few Shot Prompts and Example Selectors
1) str None text text (5, 1) str None Convert the temperature from Celsius to Fahrenheit Input: 10°C Output: 50°F Input: 10°C Output: Convert the temperature from Celsius to Fahrenheit Input: 30°C Output: 86°F Input: 30°C Output: Evaluating ingest: 100%|██████████| 1/1 [00:04<00:00 Dataset(path='./deeplake/', tensors=['embedding', 'ids', 'metadata', 'text']) tensor htype shape dtype compression ------- ------- ------- ------- ------- embedding generic (6, 1536) float32 None ids text (6, 1) str None metadata json (6, 1) str None text text (6, 1) str None Convert the temperature from Celsius to Fahrenheit Input: 40°C Output: 104°F ``` Keep in mind that the `SemanticSimilarityExampleSelector`uses the Deep Lake vector store and `OpenAIEmbeddings`to measure semantic similarity. It stores the samples on the database in the cloud, and retrieves similar samples. We created a `PromptTemplate` and defined several examples of temperature conversions. Next, we instantiated the `SemanticSimilarityExampleSelector` and created a `FewShotPromptTemplate` with the `selector`, `example_prompt`, and appropriate `prefix` and `suffix`. Using `SemanticSimilarityExampleSelector` and `FewShotPromptTemplate` , we enabled the creation of versatile prompts tailored to specific tasks or domains, like temperature conversion in this case. These tools provide a customizable and adaptable solution for generating prompts that can be used with language models to achieve a wide range of tasks. --- ### **Conclusion** To conclude, the utility of alternating human/AI interactions proves beneficial for chat-oriented applications, and the versatility offered by employing few-shot examples within a prompt template and selecting examples for the same extends its applicability across a broader spectrum of use cases. These methods necessitate a higher degree of manual intervention, as they require careful crafting and selection of apt examples. While these methods promise enhanced customization, they also underscore the importance of striking a balance between automation and manual input for optimal results. In the next lesson, we’ll learn how to manage LLM outputs with output parsers. **RESOURCES:** [Few-Shot Prompting – Nextra](https://www.promptingguide.ai/techniques/fewshot) [ChatGPT Prompt Engineering Tips: Zero, One and Few Shot Prompting](https://www.allabtai.com/prompt-engineering-tips-zero-one-and-few-shot-prompting/) --- You can find the code of this lesson in this online [Notebook](https://colab.research.google.com/drive/1CFzvTm4dRaocszqEZoDewOvN7J-kK4Vp?usp=sharing).


# Build ChatGPT to Answer Questions on Your Financial Data
### Introduction Welcome to the '****Build ChatGPT to Answer Questions on Your Financial Data****' lesson. We'll explore LangChain's benefits for large language models (LLMs) and its use in interpreting financial data. LangChain simplifies development, streamlines text generation from input prompts, and improves accuracy by ensuring consistency. One of the key features of LangChain is its customizability, offering pre-built prompts and chains for use cases like question answering and summarization. Plus, LangChain is interoperable, integrating easily with tools like Deep Lake, which makes it ideal for handling complex applications. We'll demonstrate this using Amazon's quarterly financial reports in this lesson. We'll embed the data using OpenAI's API, store it in Deep Lake, and explore it by asking questions through LangChain. This hands-on approach will illustrate how these tools can revolutionize the interpretation of financial data. Let's get started! ### The Workflow The workflow to explore Amazon's revenue growth using LangChain and Deep Lake involves: 1. Install required libraries and set API tokens for OpenAI and Activeloop. 2. Download Amazon's financial reports, and split them into smaller chunks using LangChain's Text Splitter utility. 3. Create a DeepLake vector store, add the text chunks, and use OpenAIChat as the language model. 4. Finally, query the model with questions to obtain relevant insights. [https://www.activeloop.ai/resources/ultimate-guide-to-lang-chain-deep-lake-build-chat-gpt-to-answer-questions-on-your-financial-data/](https://www.activeloop.ai/resources/ultimate-guide-to-lang-chain-deep-lake-build-chat-gpt-to-answer-questions-on-your-financial-data/) In the next lesson, we’ll build a chatbot that allows users to interact with data by asking questions.


# Agent Simulation Projects: CAMEL and Generative Agents
### Introduction This discussion begins a fascinating journey through the latest LangChain efforts. A paradigm shift from traditional frameworks is represented by a novel project - "CAMEL,” where we breathe life into unique agents equipped with distinct personalities and set them to work together in a harmonious ecosystem. Simultaneously, we’ll present the innovative dimensions of the 'Generative Agents' project. These agents don't merely simulate human tasks but encapsulate the essence of human behavior in a dynamic, interactive sandbox environment, creating a spectrum of intricate social interactions. The concept, a fusion of LLMs with computational agents, is a stepping stone toward enabling compelling simulations of human behavior. ### The **Agent Simulation projects in LangChain** The Agent simulation projects in LangChain refer to a unique subset of AI research where autonomous Agents are created with distinct personalities or roles. These agents are designed to interact with each other autonomously, without the need for constant human supervision or intervention. They are not just tools utilized by a higher-level agent or human, but they are viewed as equal participants in the conversation or task. This novel approach to interaction differs from prior LangChain implementations and allows for the emergence of unique and compelling behaviors as the agents communicate with each other. For instance, the agents can have different tools or capabilities available to them. They can be specialized around those tools: one agent might be equipped with tools for coding, while another could be optimized for normal interactions. This allows for the potential of a "stacking" effect, where different agents are responsible for different aspects of a task, creating a more complex and dynamic simulation environment. [Autonomous Agents & Agent Simulations](https://blog.langchain.dev/agents-round/) Agent Simulation projects, such as CAMEL and Generative Agents, introduce innovative simulation environments and incorporate a type of long-term memory that adapts based on events. Their distinctiveness comes from their **environments** and **memory mechanisms**. > The role of agents in this context is to act as reasoning engines connected to tools and memory. Tools serve to link the LLM with other data or computation sources, such as search engines, APIs, and other data stores. > They address the limitation of the LLM's fixed knowledge base by fetching up-to-date data and providing the capacity to perform actions. On the other hand, memory allows the agent to recall past interactions. This can aid in providing context and informing the decision-making process based on past experiences. The LangChain Agent, following the Reasoning and Acting (ReAct) framework proposed by Yao et al. in 2022, operates in a loop until a stopping criterion is met. It reflects a shift from traditional task execution to a more responsive and interactive model. This trend demonstrates a significant advance in the capabilities of LLMs as they transition from mere language processors to Agents that can reason, learn, and act.


# Agent Simulation Projects: CAMEL and Generative Agents
## What is the CAMEL project?
**The CAMEL paper** This paper introduces a new concept in the field of artificial intelligence and conversational language models, focusing on the development of autonomous "communicative agents". Current models often depend heavily on human input, which can be demanding and time-consuming. The authors propose a novel framework called 'role-playing' that aims to address this issue, improving the autonomy and cooperation of the chat agents. [](https://ghli.org/camel.pdf) In this framework, agents use 'inception prompting' to guide their interactions towards completing tasks while aligning with the initial human intent. This shift towards autonomy in agents may significantly reduce the need for human supervision. The authors present an open-source library with various tools, prompts, and agents that can aid future research in cooperative AI, multi-agent systems, and more. Through role-playing, the team is able to generate vast conversational datasets, enabling an in-depth study of chat agent behavior and capabilities. The aim of the CAMEL project is to enhance the ability of chat agents to understand and respond more effectively to human language, contributing to the development of more advanced and efficient language models. ![ Image is taken from CAMEL research paper: [https://ghli.org/camel.pdf](https://ghli.org/camel.pdf)](Agent%20Simulation%20Projects%20CAMEL%20and%20Generative%20Age%2016fb2e63f01c441e818f14da15166fdb/camel.png) Image is taken from CAMEL research paper: [https://ghli.org/camel.pdf](https://ghli.org/camel.pdf) This figure illustrates the role-playing framework in the context of creating a trading bot for the stock market. Here's how it works: 1. The process begins with a human user having an idea they want to accomplish. In this case, the idea is to develop a trading bot for the stock market. 2. This task involves two AI agents, each with different roles. One agent acts as an AI assistant, equipped with Python programming skills, and the other as an AI user with stock trading expertise. 3. A 'task specifier agent' refines the general idea into a well-defined task that the assistant can work on to make the task more specific. This could be something like writing a specific piece of code or performing a certain analysis on stock market data. 4. Once the task is specified, the AI user and the AI assistant start interacting. They communicate with each other through chat, following instructions, and collaborating to solve the specified task. This shows how the role-playing framework allows different AI agents to work together autonomously, just like a team of humans might do, to solve a complex task without needing constant human intervention. However, achieving this autonomy is not without challenges, including hallucinations, conversation deviation, role flipping, and termination conditions. Evaluating the task completion capabilities of the role-playing framework is challenging due to the vast scale and task diversity, requiring the involvement of numerous domain experts. For future work, the researchers propose extending the role-playing setting to include more than two chat agents. They also suggest having agents compete against each other, potentially discovering more insights into the interaction dynamics of LLM agents. ### The CAMEL project in LangChain In LangChain documentation, you can see the illustrated example of a stock trading bot using the interaction between two AI agents - a stock trader and a Python programmer: [https://python.langchain.com/docs/use_cases/more/agents/agent_simulations/camel_role_playing](https://python.langchain.com/docs/use_cases/more/agents/agent_simulations/camel_role_playing) The interaction shows how tasks are broken down into smaller, manageable steps that each agent can understand and execute, thereby completing the main task. Throughout the conversation, the user-agent (stock trader) provided instructions that were gradually refined into a more technical language by the assistant agent (Python programmer). This process demonstrates the system's ability to understand, translate, and execute task-related instructions effectively. Also, the agent's ability to accept the input, process it, and generate a detailed solution, emphasizes the feasibility of role assignment and context adaptation in cooperative AI systems. It also illustrates the


# Agent Simulation Projects: CAMEL and Generative Agents
## What is the CAMEL project?
significance of iterative feedback loops in achieving the goal. From another perspective, this interaction illustrates how agents can autonomously make decisions based on predefined conditions and parameters. For example, the assistant agent was able to compute moving averages, generate trading signals, and create new data frames to execute trading strategies, all based on the user agent's instruction. This scenario reveals the potential of autonomous, cooperative AI systems in solving complex, real-world problems, role definition, and iterative collaboration between agents in achieving results. ### What are Generative Agents? Generative Agents in LangChain are computational constructs designed to simulate believable human behavior. This design is inspired by the research paper 'Generative Agents: Interactive Simulacra of Human Behavior.’ The Generative Agents project introduces a novel approach to using LLMs as Agents, focusing primarily on creating a unique simulation environment and a complex long-term memory system for them. The **simulation environment** in the Generative Agents project comprises 25 different agents, creating an intricate and highly specific setting. Despite its complexity, the long-term memory developed for the agents is truly innovative and worth examining in more depth: Generative Agents possess an extended memory stored as a single stream. The memory is composed of '**Observations**', which are derived from interactions and dialogues within the virtual world concerning themselves or others, and '**Reflections**', which are core memories that have been summarized and resurfaced. The long-term memory system of these agents consists of several components: 1. **Importance reflection steps**: This component assigns an importance score to each observation. The score serves as a reference during retrieval, allowing the system to fetch significant memories and disregard less relevant ones. 2. **Reflection steps**: These steps allow the agent to "pause" and evaluate the generalizations it has learned. These reflections can then be retrieved along with normal memories. This process aids in condensing information and spotting patterns in recent memories. 3. **A retriever that combines recency, relevancy, and importance**: This advanced memory retriever surfaces memories that are similar to the current situation, occurred recently, and hold a high importance score. This model of memory retrieval closely mirrors how humans recall memories. In this framework, the agents interact with their environment and record their experiences in a time-weighted Memory object supported by a LangChain Retriever. This memory object differs from the conventional LangChain Chat memory in its formation and recall capabilities. Regarding how these innovations were integrated into LangChain, the **retriever logic** was found to be generalizable. It was therefore added as a `TimeWeightedVectorStoreRetriever,` which also records the last time the memory was accessed. When an agent responds to an observation, it generates queries for the retriever. These queries fetch relevant documents based on their salience, recency, and importance. The agent then summarizes the retrieved information and updates the 'last accessed time' for the used documents. The Generative Agents project represents significant progress in the development of intelligent agents, introducing an innovative memory system that improves retrieval processes and enables agents to make better, more informed decisions. The partial adoption of these features into LangChain signifies their potential value and application in LLM projects. ![Image is from Generative Agents: Interactive Simulacra of Human Behavior paper: [https://arxiv.org/pdf/2304.03442.pdf](https://arxiv.org/pdf/2304.03442.pdf)](Agent%20Simulation%20Projects%20CAMEL%20and%20Generative%20Age%2016fb2e63f01c441e818f14da15166fdb/generative-agents.png) Image is from Generative Agents: Interactive Simulacra of Human Behavior paper: [https://arxiv.org/pdf/2304.03442.pdf](https://arxiv.org/pdf/2304.03442.pdf) Generative Agents is a project aimed at creating believable simulations of human behavior for interactive applications. The project represents these generative agents as computational software agents that emulate human activities in a simulated environment akin to the virtual world in The Sims. The generative agents are created to perform various activities like waking up, cooking breakfast, going to work, painting (for artist agents), writing


# Agent Simulation Projects: CAMEL and Generative Agents
## What is the CAMEL project?
(for author agents), forming opinions, noticing each other, and initiating conversations. They remember and reflect on past days and use these memories to plan for the next day! Users can observe and even intervene in the agents' activities in this virtual environment. For example, an agent might decide to throw a Valentine's Day party, autonomously spread invitations to the party over two days, make new acquaintances, ask other agents out on dates to the party, and coordinate to show up for the party together at the right time. This architecture combines a large language model with mechanisms for synthesizing and retrieving relevant information, allowing for conditional behavior based on past experiences. The core of this architecture is the '**Memory Stream**,’ a database that maintains a comprehensive record of an agent’s experiences. It retrieves and synthesizes the most relevant memories to guide the agent's actions, contributing to more consistent and coherent behavior. This project fuses large language models with computational, interactive agents, introducing architectural and interaction patterns that facilitate such believable simulations. The project could offer new insights and capabilities for interactive applications, immersive environments, rehearsal spaces for interpersonal communication, and prototyping tools. In the next lesson, we’ll create an LLM-based agent able to create small analysis report by planning a series of queries from a starting goal. **Additional Resources**: [CAMEL](https://www.camel-ai.org/) [Agent simulations | 🦜🔗 Langchain](https://python.langchain.com/docs/use_cases/more/agents/agent_simulations/) [CAMEL Role-Playing Autonomous Cooperative Agents | 🦜🔗 Langchain](https://python.langchain.com/docs/use_cases/more/agents/agent_simulations/camel_role_playing)


Using Prompt Templates

# Using Prompt Templates
### Introduction In the era of language models, the ability to perform a wide range of tasks is at our fingertips. These models operate on a straightforward principle: they accept a text input sequence and generate an output text sequence. The key factor in this process is the input text or prompt. Crafting suitable prompts is vital for anyone working with large language models, as poorly constructed prompts yield unsatisfactory outputs, while well-formulated prompts lead to powerful results. Recognizing the importance of prompts, the LangChain library has developed a comprehensive suite of objects tailored for them. This lesson delves into the nuances of PromptTemplates and how to employ them effectively. A PromptTemplate is a predefined structure or pattern used to construct effective and consistent prompts for large language models. It is a guideline to ensure the input text or prompt is properly formatted. Here's an example of using a `PromptTemplate` with a single dynamic input for a user query. Remember to define the `OPENAI_API_KEY` in your environment variables with your OPEN AI key. Remember also to install the required packages with the following command: `pip install langchain==0.0.208 deeplake openai tiktoken`. ```python from langchain import LLMChain, PromptTemplate from langchain.llms import OpenAI # Before executing the following code, make sure to have # your OpenAI key saved in the “OPENAI_API_KEY” environment variable. llm = OpenAI(model_name="text-davinci-003", temperature=0) template = """Answer the question based on the context below. If the question cannot be answered using the information provided, answer with "I don't know". Context: Quantum computing is an emerging field that leverages quantum mechanics to solve complex problems faster than classical computers. ... Question: {query} Answer: """ prompt_template = PromptTemplate( input_variables=["query"], template=template ) # Create the LLMChain for the prompt chain = LLMChain(llm=llm, prompt=prompt_template) # Set the query you want to ask input_data = {"query": "What is the main advantage of quantum computing over classical computing?"} # Run the LLMChain to get the AI-generated answer response = chain.run(input_data) print("Question:", input_data["query"]) print("Answer:", response) ``` ``` Question: What is the main advantage of quantum computing over classical computing? Answer: The main advantage of quantum computing over classical computing is its ability to solve complex problems faster. ``` You can edit the `input_data` dictionary with any other question. The template is a formatted string with a `{query}` placeholder that will be substituted with a real question when applied. To create a PromptTemplate object, two arguments are required: 1. `input_variables`: A list of variable names in the template; in this case, it includes only the query. 2. `template`: The template string containing formatted text and placeholders. After creating the PromptTemplate object, it can be used to produce prompts with specific questions by providing input data. The input data is a dictionary where the key corresponds to the variable name in the template. The resulting prompt can then be passed to a language model to generate answers. For more advanced usage, you can create a `FewShotPromptTemplate` with an `ExampleSelector` to select a subset of examples that will be most informative for the language model. ```python from langchain import LLMChain, FewShotPromptTemplate from langchain.llms import OpenAI llm = OpenAI(model_name="text-davinci-003", temperature=0) examples = [ {"animal": "lion", "habitat": "savanna"}, {"animal": "polar bear", "habitat": "Arctic ice"}, {"animal": "elephant", "habitat": "African grasslands"} ] example_template = """ Animal: {animal} Habitat: {habitat} """ example_prompt = PromptTemplate( input_variables=["animal", "habitat"], template=example_template ) dynamic_prompt = FewShotPromptTemplate( examples=examples, example_prompt=example_prompt, prefix="Identify the habitat of the given animal", suffix="Animal: {input}\nHabitat:", input_variables=["input"], example_separator="\n\n", ) # Create the LLMChain for the dynamic_prompt chain = LLMChain(llm=llm, prompt=dynamic_prompt) # Run the LLMChain with input_data input_data = {"input": "tiger"} response = chain.run(input_data) print(response) ``` ``` tropical forests and


Using Prompt Templates

# Using Prompt Templates
mangrove swamps ``` Additionally, you can also save your `PromptTemplate` to a file in your local filesystem in JSON or YAML format: ```python prompt_template.save("awesome_prompt.json") ``` And load it back: ```python from langchain.prompts import load_prompt loaded_prompt = load_prompt("awesome_prompt.json") ``` Let's explore more examples using different types of Prompt Templates. In the next example, we see how to use a few shot prompts to teach the LLM by providing examples to respond sarcastically to questions. ```python from langchain import LLMChain, FewShotPromptTemplate, PromptTemplate from langchain.llms import OpenAI llm = OpenAI(model_name="text-davinci-003", temperature=0) examples = [ { "query": "How do I become a better programmer?", "answer": "Try talking to a rubber duck; it works wonders." }, { "query": "Why is the sky blue?", "answer": "It's nature's way of preventing eye strain." } ] example_template = """ User: {query} AI: {answer} """ example_prompt = PromptTemplate( input_variables=["query", "answer"], template=example_template ) prefix = """The following are excerpts from conversations with an AI assistant. The assistant is typically sarcastic and witty, producing creative and funny responses to users' questions. Here are some examples: """ suffix = """ User: {query} AI: """ few_shot_prompt_template = FewShotPromptTemplate( examples=examples, example_prompt=example_prompt, prefix=prefix, suffix=suffix, input_variables=["query"], example_separator="\n\n" ) # Create the LLMChain for the few_shot_prompt_template chain = LLMChain(llm=llm, prompt=few_shot_prompt_template) # Run the LLMChain with input_data input_data = {"query": "How can I learn quantum computing?"} response = chain.run(input_data) print(response) ``` ``` Start by studying Schrödinger's cat. That should get you off to a good start. ``` --- The `FewShotPromptTemplate` provided in the example demonstrates the power of dynamic prompts. Instead of using a static template, this approach incorporates examples of previous interactions, allowing the AI better to understand the context and style of the desired response. Dynamic prompts offer several advantages over static templates: - **Improved context understanding**: By providing examples, the AI can grasp the context and style of responses more effectively, enabling it to generate responses that are more in line with the desired output. - **Flexibility**: Dynamic prompts can be easily customized and adapted to specific use cases, allowing developers to experiment with different prompt structures and find the most effective format for their application. - **Better results**: As a result of the improved context understanding and flexibility, dynamic prompts often yield higher-quality outputs that better match user expectations. This allows us to take full advantage of the model's capabilities by providing examples and context that guide the AI toward generating more accurate, contextually relevant, and stylistically consistent responses. Prompt Templates also integrate well with other features in LangChain, like chains, and allow you to control the number of examples included based on query length. This helps in optimizing token usage and managing the balance between the number of examples and prompt size. To optimize the performance of few-shot learning, providing the model with as many relevant examples as possible without exceeding the maximum context window or causing excessive processing times is crucial. The dynamic inclusion or exclusion of examples allows us to strike a balance between providing sufficient context and maintaining efficiency in the model's operation: ```python examples = [ { "query": "How do you feel today?", "answer": "As an AI, I don't have feelings, but I've got jokes!" }, { "query": "What is the speed of light?", "answer": "Fast enough to make a round trip around Earth 7.5 times in one second!" }, { "query": "What is a quantum computer?", "answer": "A magical box that harnesses the power of subatomic particles to solve complex problems." }, { "query": "Who invented the telephone?", "answer": "Alexander Graham Bell, the original 'ringmaster'." }, { "query": "What programming language is best for AI development?", "answer": "Python,


Using Prompt Templates

# Using Prompt Templates
because it's the only snake that won't bite." }, { "query": "What is the capital of France?", "answer": "Paris, the city of love and baguettes." }, { "query": "What is photosynthesis?", "answer": "A plant's way of saying 'I'll turn this sunlight into food. You're welcome, Earth.'" }, { "query": "What is the tallest mountain on Earth?", "answer": "Mount Everest, Earth's most impressive bump." }, { "query": "What is the most abundant element in the universe?", "answer": "Hydrogen, the basic building block of cosmic smoothies." }, { "query": "What is the largest mammal on Earth?", "answer": "The blue whale, the original heavyweight champion of the world." }, { "query": "What is the fastest land animal?", "answer": "The cheetah, the ultimate sprinter of the animal kingdom." }, { "query": "What is the square root of 144?", "answer": "12, the number of eggs you need for a really big omelette." }, { "query": "What is the average temperature on Mars?", "answer": "Cold enough to make a Martian wish for a sweater and a hot cocoa." } ] ``` Instead of utilizing the examples list of dictionaries directly, we implement a `LengthBasedExampleSelector` like this: ```python from langchain.prompts.example_selector import LengthBasedExampleSelector example_selector = LengthBasedExampleSelector( examples=examples, example_prompt=example_prompt, max_length=100 ) ``` By employing the `LengthBasedExampleSelector`, the code dynamically selects and includes examples based on their length, ensuring that the final prompt stays within the desired token limit. The selector is employed to initialize a `dynamic_prompt_template:` ```python dynamic_prompt_template = FewShotPromptTemplate( example_selector=example_selector, example_prompt=example_prompt, prefix=prefix, suffix=suffix, input_variables=["query"], example_separator="\n" ) ``` So, the `dynamic_prompt_template` utilizes the `example_selector` instead of a fixed list of examples. This allows the `FewShotPromptTemplate` to adjust the number of included examples **based on the length of the input query**. By doing so, it optimizes the use of the available context window and ensures that the language model receives an appropriate amount of contextual information. ```python from langchain import LLMChain, FewShotPromptTemplate, PromptTemplate from langchain.chat_models import ChatOpenAI from langchain.prompts.example_selector import LengthBasedExampleSelector llm = ChatOpenAI(model_name="gpt-3.5-turbo") # Existing example and prompt definitions, and dynamic_prompt_template initialization # Create the LLMChain for the dynamic_prompt_template chain = LLMChain(llm=llm, prompt=dynamic_prompt_template) # Run the LLMChain with input_data input_data = {"query": "Who invented the telephone?"} response = chain.run(input_data) print(response) ``` ``` Alexander Graham Bell, the man who made it possible to talk to people from miles away! ``` ### **Conclusion** Prompt Templates are essential for generating effective prompts for large language models, providing a structured and consistent format that maximizes accuracy and relevance. Integrating dynamic prompts enhances context understanding, flexibility, and results, making them a valuable asset for language model development. In the next lesson, we’ll learn about few shot prompting and example selectors in LangChain. --- You can find the code of this lesson in this online [Notebook](https://colab.research.google.com/drive/16g9DvSd371LjApMKUtZF7iEVN1y2gXye?usp=sharing).


# What are Agents: Agents as Content Generators and Reasoning Engines
### Introduction In the fascinating world of artificial intelligence, LangChain and LLMs have opened up new horizons in data analysis, information synthesis, and content generation. Central to their functionality is the concept of Agents - intelligent systems that utilize LLMs to determine actions and facilitate complex tasks. In this way, LLMs are used more as a reasoning engine or a planner and less as content generators per-se. We discuss two primary ways we can harness the capabilities of LMMs: as **content generators** and as **reasoning engines**. LLMs leverage their internal knowledge as content generators to create engaging and creative content from scratch. On the other hand, used as reasoning engines, they act as proficient synthesizers of information, extracting and summarizing relevant data from a multitude of sources and planning the next actions to take. Both these approaches have distinct advantages and challenges, with the choice largely dependent on the specific requirements of the task. ### Agents In the context of language models, agents are used to decide the course of action and the sequence of these actions. These actions can either be the utilization of a tool, observing its output, or offering a response to the user. The real potential of agents unfolds when they are utilized appropriately. This explanation aims to simplify the usage of agents via the highest-level API. Before diving into the practical usage, it's crucial to understand the following terms: 1. **Tool**: A function that performs a specific task. It can be a Google Search, a Database lookup, a Python REPL, or other chains. A tool's interface is typically a function that takes a string as an input and returns a string as an output. 2. **Language Learning Model**: The language model that powers the agent. 3. **Agent**: The agent to use, identified by a string that references a supported agent class. It’s what orchestrates the LLM and the tools. This explanation focuses on using the standard supported agents via the highest-level API. For custom agent implementation, refer to the appropriate documentation. Agents in LangChain play a crucial role in the decision-making and execution of tasks based on user input. They evaluate the situation and decide on the appropriate tools to use, if necessary. Presently, most of the agents in LangChain fall into one of these two categories: - "**Action Agents**": These agents determine and execute a single action. They are typically used for straightforward tasks. - "**Plan-and-Execute Agents**": These agents first devise a plan comprising multiple actions and then execute each action sequentially. They are more suited for complex or long-running tasks as they help maintain focus on long-term objectives. While Action Agents are more traditional and suitable for smaller tasks, Plan-and-Execute Agents help maintain long-term objectives and focus. However, they might lead to more calls and higher latency. Often, it's beneficial to let an Action Agent manage the execution for the Plan-and-Execute agent, thus utilizing both strengths. For example, a high-level workflow of Action Agents would look something like this: 1. The agent receives user input. 2. It decides which tool to use (if any) and determines its input. 3. The chosen tool is called with the provided input, and an observation (the output of the tool) is recorded. 4. The history of the tool, tool input, and observation are relayed back to the agent, which then decides the next step. 5. This process is repeated until the agent no longer needs to use a tool, at which point it directly responds to the user. The most critical abstraction to understand is the agent itself. In the context of LangChain, the term "agents" pertains


# What are Agents: Agents as Content Generators and Reasoning Engines
to the concept of employing a language model as a **reasoning mechanism** and linking it with the key element - a tool. Tools are instrumental in connecting the language model with other sources of data or computation, including search engines, APIs, and other data repositories. Language models can only access the knowledge they've been trained on, which can quickly become obsolete. Therefore, tools are essential as they allow the agent to retrieve and incorporate current data into the prompt as context. Tools can also execute actions (like running code or modifying files) and observe the results, subsequently informing the language model's decision-making process. As we said before, we can abstract two primary modes of operation to consider when employing an LLM: as a content generator and as a reasoning engine. - When used as a "**content generator,**" the language model is asked to create content entirely from its internal knowledge base. This approach can lead to highly creative outputs but can also result in unverified information or 'hallucinations' due to the model's reliance on pre-trained knowledge. - On the other hand, when functioning as a "**reasoning engine,**" the Agent acts more as an information manager rather than a creator. In this mode, it is tasked with gathering relevant, accurate information, often aided by external tools. This involves the LLM drawing from similar resources on a given topic and constructing new content by extracting and summarizing the relevant details. **Answering Questions using an LLM as a reasoning engine** Let’s see a code example of it. As always, we first set the required API keys as environment variables. ```python import os os.environ["OPENAI_API_KEY"] = "<YOUR-OPENAI-API-KEY>" os.environ["GOOGLE_API_KEY"] = "<YOUR-GOOGLE-SEARCH-API-KEY>" os.environ["GOOGLE_CSE_ID"] = "<YOUR-CUSTOM-SEARCH-ENGINE-ID>" ``` Here’s the code example. Remember to install the required packages with the following command: `pip install langchain==0.0.208 deeplake openai tiktoken`. ```python # Importing necessary modules from langchain.agents import load_tools, initialize_agent from langchain.agents import AgentType from langchain.llms import OpenAI # Loading the language model to control the agent llm = OpenAI(model="text-davinci-003", temperature=0) # Loading some tools to use. The llm-math tool uses an LLM, so we pass that in. tools = load_tools(["google-search", "llm-math"], llm=llm) # Initializing an agent with the tools, the language model, and the type of agent we want to use. agent = initialize_agent(tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True) # Testing the agent query = "What's the result of 1000 plus the number of goals scored in the soccer world cup in 2018?" response = agent.run(query) print(response) ``` You should see something like the following printed output. ```python > Entering new AgentExecutor chain... I need to find out the number of goals scored in the 2018 soccer world cup Action: Google Search Action Input: "number of goals scored in 2018 soccer world cup" Observation: Jan 13, 2023 ... A total of 172 goals were scored during the 2022 World Cup in Qatar, marking a new record for the tournament. Jan 31, 2020 ... A total of 169 goals were scored at the group and knockout stages of the FIFA World Cup held in Russia from the 14th of June to the 15th of July ... Jan 13, 2023 ... Average number of goals scored per match at the FIFA World Cup from 1930 to 2022 ; Russia 2018, 2.64 ; Brazil 2014, 2.67 ; South Africa 2010, 2.27. Number of goals scored in the matches played between the teams in question;; Fair play points in all group matches (only one deduction could be applied to a ... France were crowned champions for the second time in history and for the first since they were hosts in 1998 after defeating Croatia 4-2 in


# What are Agents: Agents as Content Generators and Reasoning Engines
what will go down as ... Check out the top scorers list of World Cup 2018 with Golden Boot prediction. Get highest or most goal scorer player in 2018 FIFA World Cup. 2018 FIFA World Cup Russia™: France. ... Top Scorers. Previous. Antoine Griezmann ... #WorldCupAtHome: Electric Mbappe helps France win seven-goal thriller. Jun 30, 2018 ... Kylian Mbappe scored twice as France dumped Lionel Messi and Argentina out of the World Cup with a 4-3 win in an outstanding round-of-16 tie ... 0 · Luka MODRIC · Players · Top Scorers. Dec 18, 2022 ... Antoine Griezmann finished second in goals scored at the 2018 World Cup. Mbappe is also just the fifth man to score in multiple World Cup finals ... Thought: I now know the number of goals scored in the 2018 soccer world cup Action: Calculator Action Input: 1000 + 169 Observation: Answer: 1169 Thought: I now know the final answer Final Answer: The result of 1000 plus the number of goals scored in the soccer world cup in 2018 is 1169. > Finished chain. The result of 1000 plus the number of goals scored in the soccer world cup in 2018 is 1169. ``` There were 169 goals scored in the soccer world cup in 2018, so the final answer is correct. In the example, the agent leverages its "reasoning engine" capabilities to generate responses. Instead of creating new content (acting as a content generator), the agent uses the tools at its disposal to gather, process, and synthesize information. The entire output was truncated, and the agent skillfully employed the LLM-math tool. Let's break down the steps to see how the agent functions as a "reasoning engine": 1. **Query Processing**: The agent receives a query: "What's the result of 1000 plus the number of goals scored in the soccer world cup in 2018?” The agent identifies two distinct tasks within this query - finding out the number of goals scored in the 2018 soccer world cup and adding 1000 to such number. 2. **Tool Utilization**: The agent uses the "google-search" tool to answer the first part of the query. This is an example of the agent using external tools to gather accurate and relevant information. The agent isn't creating this information; it's pulling the data from an external source. 3. **Information Processing**: For the second part of the query, the agent uses the "llm-math" tool to perform a sum reliably. Again, the agent isn't creating new information. Instead, it's processing the data it has gathered. 4. **Synthesis and Response**: After gathering and processing the information, the agent synthesizes it into a coherent response that answers the original query. In this way, the agent acts as a "reasoning engine.” It's not generating content from scratch but rather gathering, processing, and synthesizing existing information to generate a response. This approach allows the agent to provide accurate and relevant responses, making it a powerful tool for tasks that involve data retrieval and processing. The agent would create new content as a content generator rather than just pulling and processing existing information. Let's imagine a scenario where we want the agent to write a short science fiction story based on a given prompt. We could initialize the agent with a language model and set its temperature parameter to a higher value to encourage more creativity in its outputs. It is not required to use external tools, as the agent generates content rather than retrieving or processing it. The language model will generate a long science fiction story about interstellar explorers based on the patterns it learned during training. ```python


# What are Agents: Agents as Content Generators and Reasoning Engines
# Importing necessary modules from langchain.agents import initialize_agent, AgentType from langchain.llms import OpenAI from langchain.agents import Tool from langchain.prompts import PromptTemplate from langchain.chains import LLMChain prompt = PromptTemplate( input_variables=["query"], template="You're a renowned science fiction writer. {query}" ) # Initialize the language model llm = OpenAI(model="text-davinci-003", temperature=0) llm_chain = LLMChain(llm=llm, prompt=prompt) tools = [ Tool( name='Science Fiction Writer', func=llm_chain.run, description='Use this tool for generating science fiction stories. Input should be a command about generating specific types of stories.' ) ] # Initializing an agent with the tools, the language model, and the type of agent we want to use. agent = initialize_agent(tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True) # Testing the agent with the new prompt response = agent.run("Compose an epic science fiction saga about interstellar explorers") print(response) ``` You should see something like the following printed output. ```python > Entering new AgentExecutor chain... I need a way to generate this kind of story Action: Science Fiction Writer Action Input: Generate interstellar exploration story Observation: . The crew of the interstellar exploration vessel, the U.S.S. Discovery, had been traveling through the depths of space for months, searching for something that no one had ever seen before. They were searching for a planet, an anomaly, something out of the ordinary. The ship had been equipped with the most advanced technology available, but nothing could have prepared them for what they encountered on their journey. As they entered an uncharted sector of the galaxy, they encountered an alien species unlike anything they had ever seen before. The aliens were primitive, yet their technology was far more advanced than anything known to humanity. The crew of the U.S.S. Discovery found themselves in awe of the alien species and its technology. The crew immediately set to work exploring the planet and its myriad of secrets. They uncovered evidence of an ancient civilization, as well as evidence of a mysterious energy source that could potentially power their ship and enable them to travel faster than the speed of light. Eventually, the crew was able to unlock the secrets of the alien technology and use it to power their ship. With the newfound energy source, they were able to travel to the far reaches of the universe and explore places that no human had ever seen Thought: I now know the final answer Final Answer: The crew of the U.S.S. Discovery set out to explore the unknown reaches of the universe, unlocking the secrets of alien technology and discovering an ancient civilization with the power to travel faster than the speed of light. > Finished chain. ``` … along with the content of the `response` variable. ```python The crew of the U.S.S. Discovery set out to explore the unknown reaches of the universe, unlocking the secrets of alien technology and discovering an ancient civilization with the power to travel faster than the speed of light. ``` Here, the Agent is primarily using its internal knowledge to generate the output. Here's a brief explanation of how that works: - The agent receives a prompt to "Compose an epic science fiction saga about interstellar explorers.” - The agent then uses its understanding of language, narrative structure, and the specific themes mentioned in the prompt (science fiction, interstellar exploration, etc.) to generate a story. LLM's understanding comes from its training data. It was trained on a diverse range of internet text, so it has a broad base of information to draw from. When asked to generate a science fiction story, it uses patterns it learned during training about how such stories are typically structured and what elements they usually contain. Remember, even though


# What are Agents: Agents as Content Generators and Reasoning Engines
the language model has vast training data to draw from, it doesn't "know" specific facts or have access to real-time information. Its responses are generated based on patterns learned during training, not from a specific knowledge database. ### Conclusion In our agent examples, we've observed the strengths and limitations of using LLMs as a "content generator" and a "reasoning engine.” In the first scenario, where the agent served as a "reasoning engine,” it leveraged tools like Google Search to gather, process, and synthesize information, thereby creating a knowledgeable and accurate output. However, while the agent's output was factual and informative, it lacked the creative flair that can be observed when an LLM is used as a "content generator.” In contrast, when the agent functioned as a "content generator,” it created a vivid and imaginative science fiction story, showcasing its potential for creativity and narrative invention. Nevertheless, this approach is limited by the training data of the LLM and can sometimes result in "hallucinations" or inaccuracies. In the next lesson, we’ll learn more about AutoGPT and BabyAGI, two popular LLM-based agents.


# Integrating Multiple Tools for Web-Based Question-Answering
### Introduction As developers and information enthusiasts, we often find ourselves needing to utilize various tools and libraries to fetch and process data. By leveraging multiple tools simultaneously, we can create powerful, efficient, and comprehensive solutions for the systems we build with LangChain. This lesson will demonstrate a practical example of combining the power of Google Search with the versatile Python-REPL tool for an effective result. You will learn how to harness the potential of multiple tools working together to streamline your own information retrieval projects. Let’s be more specific about what exactly we want to accomplish: 1. Find the answer to a query by searching the web: The agent should use its tools and language model to identify the most relevant sources for it. 2. Save the answer to a file: After retrieving the answer, the agent is expected to save it to a text file. ### Setting Up Libraries First, we set the necessary API keys as environment variables. ```python import os os.environ["OPENAI_API_KEY"] = "<YOUR-OPENAI-API-KEY>" os.environ["GOOGLE_API_KEY"] = "<YOUR-GOOGLE-SEARCH-API-KEY>" os.environ["GOOGLE_CSE_ID"] = "<YOUR-CUSTOM-SEARCH-ENGINE-ID>" ``` You can sign up for these keys by following these instructions: [Setting up API keys - API Console Help](https://support.google.com/googleapi/answer/6158862?hl=en) [](https://programmablesearchengine.google.com/controlpanel/create) Next thing, we want to import the libraries we aim to use for our project. Remember to install the required packages with the following command: `pip install langchain==0.0.208 deeplake openai tiktoken`. ```python from langchain.llms import OpenAI from langchain.agents import Tool, initialize_agent, AgentType from langchain.utilities import GoogleSearchAPIWrapper, PythonREPL ``` We’re going to declare some wrappers. The `GoogleSearchAPIWrapper` wrapper allows us to easily create a tool for using the Google Search APIs, whereas the `PythonREPL` wrapper allows the model to execute generated Python code. ```python search = GoogleSearchAPIWrapper() python_repl = PythonREPL() ``` The next code block creates an instance of the OpenAI language model with a temperature parameter set to 0. This parameter influences the randomness of the model's output, and by setting it to 0, the generated responses will be more deterministic and focused. ```python llm = OpenAI(model="text-davinci-003", temperature=0) ``` Here we have our toolkit set assembled of: 1. The `google-search` tool is a convenient way to perform Google searches when an agent needs information about current events. The tool makes use of Google's API to provide relevant search results. 2. The `python_repl` tool: This tool wraps a Python shell, allowing the execution of Python commands directly. ```python toolkit = [ Tool( name="google-search", func=search.run, description="useful for when you need to search Google to answer questions about current events" ), Tool( name="python_repl", description="A Python shell. Use this to execute Python commands. Input should be a valid Python command. Useful for saving strings to files.", func=python_repl.run ) ] ``` These tools are then added to the `toolkit` list, which is used to initialize an agent with the specified tools. The agent can then perform various tasks using the tools in its toolkit. The agent can be easily extended by adding more tools to the toolkit, allowing it to handle a wide range of tasks and situations. Let’s instantiate the agent. ```python agent = initialize_agent( toolkit, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True ) ``` The parameter `agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION` specifies the agent's strategy, which means that the agent will attempt to perform tasks without any prior examples, relying solely on its understanding of the problem description and the available tools (and their descriptions). Now let’s run the experiment! We should be able to ask the Agent directly by giving him instructions on what we want: ```python agent.run("Find the birth date of Napoleon Bonaparte and save it to a file 'answer.txt'.") ``` You should see an output like the following. ``` > Entering new AgentExecutor chain...


# Integrating Multiple Tools for Web-Based Question-Answering
I need to find the date of Napoleon's birth and save it to a file. Action: google-search Action Input: "Napoleon Bonaparte birth date" Observation: Napoleon Bonaparte later known by his regnal name Napoleon I, was a Corsican-born French military commander and political leader who rose to prominence ... Nov 9, 2009 ... Napoleon Bonaparte was born on August 15, 1769, in Ajaccio, on the Mediterranean island of Corsica. He was the second of eight surviving ... Napoleone Buonaparte was born in Ajaccio, Corsica, on 15 August 1769. He was the second of eight children born to Carlo Buonaparte, a lawyer descended from ... May 1, 2023 ... Napoleon I, French in full Napoléon Bonaparte, original Italian Napoleone Buonaparte, byname the Corsican or the Little Corporal, ... Napoleon Bonaparte was born on August 15, 1769. He was most notably known as a French military and political leader, who became prominent during the French ... Furthermore, Charles Bonaparte's “journal” notes the birth on 15 August 1769. It is true that Napoleon very occasionally used the papers of his brother ... Jun 23, 2002 ... Napoleon Bonaparte was born at Ajaccio, Corsica, ... importance of Napoleon the individual argued about his origins and his date of birth. In 1764, Charles-Marie Bonaparte wed the young Letizia Ramolino and settled with her in the Bonaparte family residence. Napoleon was born there on August 15 ... Napoleon Bonaparte was born the 15th of August, 1769 on Corsica, just three months after the island had been defeated by the French. Napoleon was born on the 15th of August, 1769, in French occupied Corsica. His father was Carlo Maria di Buonaparte, and his mother, Maria Letizia Ramolino. Thought: I have the date of Napoleon's birth. Action: python_repl Action Input: with open('answer.txt', 'w') as f: f.write('Napoleon Bonaparte was born on August 15, 1769') Observation: Thought: I have saved the answer to the file. Final Answer: Napoleon Bonaparte was born on August 15, 1769. > Finished chain. ****** ``` As you can see from the printed output, the agent first used the `google-search` tool with the query `"Napoleon Bonaparte birth date"`. Upon seeing its result, the agent then wrote the following Python program to save the answer to the `answer.txt` local file: ``` with open('answer.txt', 'w') as f: f.write('Napoleon Bonaparte was born on August 15, 1769') ``` You should now have a local file `answer.txt` containing a text similar to `Napoleon Bonaparte, born on August 15, 1769`. Let’s also find the death date of Napoleon and append it to the `answer.txt` file. ``` query = "Find when Napoleon Bonaparte died and append this information " \ "to the content of the 'answer.txt' file in a new line." agent.run(query) ``` You should see something similar to the following printed output. ``` > Entering new AgentExecutor chain... I need to find the date of Napoleon's death and then write it to a file. Action: google-search Action Input: "When did Napoleon Bonaparte die?" Observation: Napoleon Bonaparte later known by his regnal name Napoleon I, was a Corsican-born French military commander and political leader who rose to prominence ... Aug 15, 2022 ... Napoleon was only 51 when he died on the island of St. Helena, where he was out of power and exiled from his beloved France. By May 5, 1821, ... Nov 9, 2009 ... In October 1815, Napoleon was exiled to the remote, British-held island of Saint Helena, in the South Atlantic Ocean. He died there on May 5, ... Apr 25, 2014 ... Napoleon Bonaparte died at 5.49pm on 5 May 1821, at Longwood on the island of Saint Helena.


# Integrating Multiple Tools for Web-Based Question-Answering
An autopsy was carried out on 6 May; ... Jan 21, 2014 ... Was Napoleon poisoned? ... weeks before his demise at age 51, “I die before my time, murdered by the English oligarchy and its assassin. Jan 17, 2007 ... 17, 2007— -- Napoleon Bonaparte died in exile in 1821. But his story never does. His personal physician reported on his death ... May 22, 2023 ... He was the third son of Napoleon I's brother Louis Bonaparte, who was king of Holland from 1806 to 1810, ... How did Napoleon III die? Jan 20, 2003 ... Napoleon was not poisoned, they said. He died of stomach cancer. At a news conference in Paris, Jacques di Costanzo, ... May 1, 2023 ... Napoleon I, French in full Napoléon Bonaparte, original Italian ... It was during Napoleon's year in Paris that his father died of a stomach ... In 1785, when Napoleon was not yet sixteen, his father died of stomach cancer ... Napoleon Bonaparte has continued to inspire passion and interest Read more. Thought: I now know the date of Napoleon's death. Action: python_repl Action Input: with open('answer.txt', 'a') as f: f.write('\nNapoleon Bonaparte died on May 5, 1821.') Observation: Thought: I now know the final answer. Final Answer: Napoleon Bonaparte died on May 5, 1821. > Finished chain. ``` Your final `answer.txt` should look like the following: ``` Napoleon Bonaparte was born on August 15, 1769 Napoleon Bonaparte died on May 5, 1821. ``` This process demonstrates the agent's ability to integrate multiple tools for a single task seamlessly. --- ### Conclusion In conclusion, we've illustrated how a LangChain agent can effectively employ multiple tools and techniques to accomplish a task, such as doing question-answering on the web and storing the answers in a file. This example highlights the potential of LangChain agents to provide valuable assistance across diverse scenarios. In the upcoming lesson, we’ll see how to create an ad-hoc tool for retrieving relevant documents from a Deep Lake vector store.


Introduction to Tools

# Introduction to Tools
In this module, we will have a series of lessons that explore the power of tools in LangChain and demonstrate how they can be combined to tackle different challenges. In many situations, employing chains and memory proves to be adequate for implementing fairly complex applications. While enhancing the model's responses by incorporating context from buffers and databases is possible, a wide range of APIs is publicly available to provide further assistance. The Tools components can help the models to interact with the outside world. We will introduce a number of integrations like Google Search and content scraper. Furthermore, learn how to create custom tools to use any resources. Here are the lessons of this module along with a brief description of them: - **LangChain's Tool Utilization: Examining Diverse Applications through Illustrative Scenarios:** In the first lesson, we delve into the concept of tools as modular and reusable components designed to accomplish specific tasks. By seamlessly integrating these tools into the system, users gain access to a diverse range of functionalities and information sources. We uncover the unique capabilities of LangChain's tools, setting the stage for exploring their practical applications. - **Supercharge Your Blog Posts Automatically with LangChain and Google Search:** Moving on, the second lesson focuses on the application of artificial intelligence in the field of copywriting. Language models have revolutionized writing assistance by identifying errors, changing tones, summarizing content, and extending articles. However, there are instances where specialized knowledge is required to provide expert-level suggestions for expanding specific parts of an article. The lesson guides readers through the process of building an application that seamlessly expands text sections. The application suggests better content based on the most relevant search results by leveraging an LLM (ChatGPT) to generate search queries and utilizing the Google Search API to capture relevant information. - **Recreating the Bing Chatbot:** While large language models possess impressive capabilities, they also have limitations, as explored in our third lesson. The hallucination problem, where models confidently provide incorrect answers, can occur due to the cutoff date of their training process. To overcome this challenge, the lesson proposes leveraging the model's reasoning capability and using the top-matched results from a search engine as context for user queries. LangChain's integration with the Google Search API and the Newspaper library enables the extraction of relevant stories from search results, which are then utilized in the prompt for finding the correct answer. - **Integrating Multiple Tools for Web-Based Question-Answering:** The fourth lesson shifts to the practical example of combining Google Search with the Python-REPL tool. This combination showcases the power of multiple tools working together to streamline information retrieval projects. The lesson walks readers through the process of finding answers to queries by searching the web and saving the retrieved answers to a text file. By harnessing the potential of these tools, developers can create powerful and efficient solutions for their projects. - **Building a Custom Document Retrieval Tool with Deep Lake and Langchain: A Step-by-Step Workflow:** Finally, the fifth lesson presents a walkthrough of constructing an efficient document retrieval system designed to extract valuable insights from service FAQs. The retrieval system aims to provide users with quick and relevant information by promptly fetching pertinent documents that explain a company's operations. The system saves users' time and effort by sifting through multiple sources and FAQs while providing concise and precise answers. In conclusion, this module highlights the importance of utilizing various tools in LangChain to tackle challenges in information retrieval, copyrighting, and document analysis. By combining the capabilities of different tools, developers, and researchers can create comprehensive and efficient solutions for a


Introduction to Tools

# Introduction to Tools
wide range of applications. Whether it's expanding text sections, finding answers from search results, or retrieving information from FAQs, the integration of tools empowers users to leverage the full potential of AI-driven systems.


Using AutoGPT with LangChain

# Using AutoGPT with LangChain
### Introduction After covering BabyAGI library in the earlier lesson, we will delve deep into the mechanics of AutoGPT, another popular type of autonomous agent, demonstrating how it employs multiple tools and memory systems to perform and manage tasks autonomously. ### What is AutoGPT Unlike traditional language models that generate text based solely on the input they receive, AutoGPT combines a set of tools and a memory system to interact with its environment, retrieve past interactions, and generate more informed responses. AutoGPT distinguishes itself with three critical features. First, its internet connectivity provides real-time access to information, bolstering its research abilities. Second, its planning capability enables it to generate and pursue sub-tasks that contribute to the completion of a main task. Lastly, it has the power to execute tasks, even to the extent of initiating other AI agents. While these features offer huge potential, they also present challenges, such as inadvertent task looping or prematurely assuming task completion. Through internet browser plugins and other forms of access, AutoGPT gathers the information needed to execute tasks. An external memory serves as its context-aware module, enabling it to understand its current situation, generate new tasks, and even self-correct if necessary. As a result, AutoGPT operates dynamically, continually re-prioritizing tasks based on the context and situation. ### AutoGPT in Langchain As always, the first step is to set up the API keys as environment variables. <aside> 💡 Langchain has recently (as of August 2023) moved some classes from "langchain.experimental" to another library called "library_experimental", in an attempt to make the "langchain" library smaller. If you try the following code with the suggested version “langchain==0.0.208” it should work fine, but if you want to run it with the latest langchain version then you have to (1) install the experimental library with “pip install langchain-experimental” and (2) replace all the occurrences of “langchain.experimental” with “langchain_experimental”. </aside> ```python import os os.environ["OPENAI_API_KEY"] = "<YOUR-OPENAI-API-KEY>" os.environ["GOOGLE_API_KEY"] = "<YOUR-GOOGLE-SEARCH-API-KEY>" os.environ["GOOGLE_CSE_ID"] = "<YOUR-CUSTOM-SEARCH-ENGINE-ID>" ``` **Tools Setup** We initialize different tools that the AI agent can use to complete tasks. In our case, the tools are Search, WriteFileTool, and ReadFileTool. The Search tool utilizes a GoogleSearchAPIWrapper to fetch real-time information from the internet, which can be employed for questions about current events or queries that need up-to-date information. The WriteFileTool and ReadFileTool manage file-related tasks. These tools are collected into a list that will be later passed to the agent. Remember to install the required packages with the following command: `pip install langchain==0.0.208 deeplake openai tiktoken`. ```python from langchain.utilities import GoogleSearchAPIWrapper from langchain.agents import Tool from langchain.tools.file_management.write import WriteFileTool from langchain.tools.file_management.read import ReadFileTool #Set up the tools search = GoogleSearchAPIWrapper() tools = [ Tool( name = "search", func=search.run, description="Useful for when you need to answer questions about current events. You should ask targeted questions", return_direct=True ), WriteFileTool(), ReadFileTool(), ] ``` **Agent Memory Setup** For the memory, we create the FAISS vector DB (but any other vector DB would work similarly), an efficient similarity search, and clustering of dense vectors. This is paired with an `InMemoryDocstore` instance for storing documents in memory and an `OpenAIEmbeddings` model for creating embeddings of the queries. These tools are crucial for the agent's remembering and retrieving past interactions. AutoGPT has been designed to operate over longer periods. AutoGPT has incorporated a retrieval-based memory system that functions over intermediate agent steps to do that. This memory performs a semantic search across embeddings using the vector DB. While such retrieval-based memory is a part of LangChain, it was traditionally used for user and agent interactions, not agent and tools. AutoGPT's new adaptation represents a significant shift in how


Using AutoGPT with LangChain

# Using AutoGPT with LangChain
this memory system is applied. ```python # Set up the memory from langchain.vectorstores import FAISS from langchain.docstore import InMemoryDocstore from langchain.embeddings import OpenAIEmbeddings embeddings_model = OpenAIEmbeddings(model="text-embedding-ada-002") embedding_size = 1536 import faiss index = faiss.IndexFlatL2(embedding_size) vectorstore = FAISS(embeddings_model.embed_query, index, InMemoryDocstore({}), {}) ``` **Setting up the Model and AutoGPT** Here we initialize the AutoGPT agent, giving it a name ("Jim") and a role ("Assistant"). We also supplied it with the tools and memory systems that were established in the previous steps. The language model being used here is ChatOpenAI, which is set to have a temperature of 0 (indicating deterministic responses). ```python # Set up the model and AutoGPT from langchain.experimental import AutoGPT from langchain.chat_models import ChatOpenAI agent = AutoGPT.from_llm_and_tools( ai_name="Jim", ai_role="Assistant", tools=tools, llm=ChatOpenAI(model="gpt-3.5-turbo", temperature=0), memory=vectorstore.as_retriever() ) # Set verbose to be true agent.chain.verbose = True ``` **Running an Example** Finally, we provided an example task for the AutoGPT agent. This task ("Provide an analysis of the major historical events that led to the French Revolution") is complex and requires the agent to utilize its tools and memory system effectively to generate a response. The agent takes some minutes to generate the final answer, but we get a peek into all the intermediate computations thanks to having set the `verbose` variable to `True`. Since there are a lot of intermediate computations and the output is very long, we’ll see here only its crucial parts, giving a quick explanation of them. ```python task = "Provide an analysis of the major historical events that led to the French Revolution" agent.run([task]) ``` The first part of the printed output will look like the following. ```python **> Entering new LLMChain chain...** Prompt after formatting: ***System: You are Jim, Assistant Your decisions must always be made independently without seeking user assistance. Play to your strengths as an LLM and pursue simple strategies with no legal complications. If you have completed all your tasks, make sure to use the "finish" command. GOALS: 1. Provide an analysis of the major historical events that led to the French Revolution Constraints: 1. ~4000-word limit for short-term memory. Your short-term memory is short, so immediately save important information to files. 2. If you are unsure how you previously did something or want to recall past events, thinking about similar events will help you remember. 3. No user assistance 4. Exclusively use the commands listed in double quotes e.g. "command name" Commands: 1. search: Useful for when you need to answer questions about current events. You should ask targeted questions, args json schema: {"tool_input": {"type": "string"}} 2. write_file: Write the file to disk, args json schema: {"file_path": {"title": "File Path", "description": "name of file", "type": "string"}, "text": {"title": "Text", "description": "text to write to file", "type": "string"}, "append": {"title": "Append", "description": "Whether to append to an existing file.", "default": false, "type": "boolean"}} 3. read_file: Read the file from disk, args json schema: {"file_path": {"title": "File Path", "description": "name of file", "type": "string"}} 4. finish: use this to signal that you have finished all your objectives, args: "response": "final response to let people know you have finished your objectives" Resources: 1. Internet access for searches and information gathering. 2. Long Term memory management. 3. GPT-3.5 powered Agents for delegation of simple tasks. 4. File output. Performance Evaluation: 1. Continuously review and analyze your actions to ensure you are performing to the best of your abilities. 2. Constructively self-criticize your big-picture behavior constantly. 3. Reflect on past decisions and strategies to refine your approach. 4. Every command has a cost, so be smart and efficient. Aim to complete tasks in the least number of steps.