All right. This is your last lesson where you will apply a new function coding skills on a more significant project. Let's take a look. In previous lessons, we looked at using function calling as a way of interfacing with external tools such as APIs and internal Python tools. We also learned that using function calling as a way of doing structured extraction, where we extracted insights about data that was in an unstructured format. In this lesson, we will be combining all of them together into a single lesson and build a dialog processing system as a core project. Specifically, we will be taking transcripts of customer interactions, which are dialog exchanges between a customer service representative and a customer and extracting insights such as the agent name, product ID, and customer information from the dialog data. We will then be storing this into a database using an LLM, and then extracting insights from the database regarding aggregated queries that requires the LLM to generate SQL code. Let's get started. First, we'll take a look at the type of data we're dealing with. What you'll notice is the data is a list of exchanges between an agent and a customer. The customer provides various insights such as their phone number, their email, as well as their overall sentiment embedded in the verbiage that they use. The agent also provides details such as their name. We would want to ideally extract all of this into a structured format and store it into a database. This will allow us to do aggregated insights, such as analyzing how many customers specify agents have pleased, or how many customers specific agents have not been able to address their requirements for. Let's first start by building the tools required to build this system. We'll first define the specific insights that we want to label as important insights we want to extract. We will be using the data class approach because this is a far more complicated extraction task. This approach was discussed in an earlier lesson and we will be using that here. We will specifically be extracting the agent name, the customer email, the customer order, the customer phone number, as well as the customer sentiment. We will be also calling "exec" on this data class, just so that the Python interpreter is able to understand our new format. We will also build the database. The database will essentially just contain a few different columns such as the agent name, the customer, email, and the various attributes that we want to extract. We will store it into a database called extracted.db and named the table "customer_information". This tool just initializes the database. Let's initialize it. Secondarily, we would also need to create tools to populate the database. You will define a tool called Update Knowledge that takes in a list of records. Records being the data class that we added to our interpreter earlier. And you would just iterate over every record in your results list and insert it into your database. You'll give it a try using some dummy data. Here you're just defining a single record object with some dummy data, such as the agent name, a dummy customer order number, as well as a dummy sentiment. Great. You were able to insert the records successfully. Now, you will also need to pull information out from the database. Here you define a tool called execute SQL that dates in a direct sequel string that you will run against your earlier database stored in extracted.db. Specifically, you'll be running your SQL against a customer information table that you created earlier. Let's give this a try. You'll define a SQL string where you pull the agent name, where the customer is happy. From the table that we've been discussing about. Running the SQL gives you the information that you need, such as Agent Smith. This matches what we expect. Great. Now let's start building the pipeline. Let's first delete the sample database we had earlier, and let's reinitialize the database. Next, we will be downloading the customer service chatbot dataset from HuggingFace. This dataset contains a list of traces of dialog between an agent and a customer. We will be using this dataset for this course project. Let's download the dataset. Let's print just one sample of dialog from this dataset. Here we will take the sixth element and print it out. What we notice is that the format of the data has a lot of similarities to the sample data that we saw earlier. It's worthwhile to note that the agent's name here is Alex. The customer's details include an order number pointing to one, two, three, four, five, and the customer seems frustrated. Let's pass this to Raven. You will use the inspect approach that we discussed earlier. You would simply pull the function signature, clean up the function signature to remove some of the extraneous details that inspect might have added. Pull the function dot string and build the Raven prompt. The Raven prompt simply contains your data class that you defined in the first cell, and extraction function, and the entire text from earlier. Let's pass this to Raven. Great. Raven was able to generate the function call where it notes the name being Alex, the order number being one, two, three, four, five, and the customer sentiment being frustrated, which is exactly what we expected. We can run this and insert it into our database. Let's quickly run another example. This time the 10th sample in the data set. And let's also insert this into our database. It's important to note here that the agent name in the sample is John. The order number is BB789012. And the customer sentiment is happy. Suppose we want to pull some insights out of this. We can actually do so using SQL such as selecting the number of customer sentiment details we have that matches the requirements, where the agent name is John and the customer sentiment is happy. This is essentially querying the database to see how many customers John has made happy. Great. We were able to run the query and get back a result, which is one. Which matches. Because this corresponds to the sample we inserted in the previous cell. But this is a bit manual. Can we make this more automatic? Yes, we can pass the execute SQL tool that you defined earlier to Raven to get the output. You will simply write a prompt asking how many customers John has made happy. Use the inspect approach described earlier to pull out the function signature. Pull out the function dot string and provide the SQL schema to your Raven in a Raven prompt. Passing this to Raven, you get back SQL code that you can now execute and get the exact result that you had earlier. Great! You're now ready to run this over the enter dataset. Let's give it a try. Let's first reinitialize the database. Let's iterate over the first ten samples in the dataset, using the same approach detailed earlier. To build the Raven prompt and call Raven. You have now populated the database using ten different samples. You can now try running some aggregated queries here using the Inspect approach, as well as passing the same schema as earlier. You're simply asking how many happy customers are there over those ten samples. Let's feed this to Raven. Raven was able to successfully query and answer your question, which is seven. Next, you can ask to get the names and phone numbers of the customers who are frustrated, as well as their order numbers. Great. And you were able to see Raven generate the SQL code, where it gets the agent name, the customer phone number, and the customer order number from the table where the customer sentiment is frustrated. Here it gives you back the customer items, including the phone numbers if they exist, as well as the order numbers and the associated agent name for customers who are frustrated. Please give this a try by adding in an additional requirement, such as asking for the customer's name. In addition to the agent name, hint, you need to modify the initialization of the database. The insertion into the database and the data class and SQL representations. Please give it a try. In this course, we've touched on so many different things and function calling is very versatile. We hope you had a great time exploring the different applications of function calling.