<b>Let's have a look at output parsers. </b> <b>Output parsers is one of those topics</b> <b>that seem to get overlooked in Lang chain</b> <b>and Flowwise tutorials. </b> <b>And in my opinion, it's probably one of</b> <b>the most important features to learn.
</b> <b>We will use output parsers in some more</b> <b>complex scenarios throughout the series,</b> <b>but in this video, I do want</b> <b>to show you the fundamentals. </b> <b>So to get us started, I've created a very</b> <b>simple flow that contains an LLM chain,</b> <b>the OpenAI node with the GPT 3. 5 Turbo</b> <b>instruct model, as well as</b> <b>a simple prompt template.
</b> <b>So far, this is nothing new. </b> <b>Let's go ahead and set</b> <b>up our prompt template. </b> <b>So let's expand this, and for the prompt</b> <b>template, let's type something like</b> <b>"Determine if the following</b> <b>sentence is true or false",</b> <b>and let's add a</b> <b>placeholder called "sentence".
</b> <b>Let's save this. </b> <b>So let's save this chat flow, then let's</b> <b>test this out, and let's enter something</b> <b>like "The sky is green". </b> <b>And we get this text back</b> <b>with the value of "false".
</b> <b>But take note that this is simply a</b> <b>string value from the model,</b> <b>and this could be uppercase false,</b> <b>lowercase false, there could be quotes,</b> <b>it could even be an entire sentence. </b> <b>So we can actually use an output parser</b> <b>to ensure that we receive the</b> <b>response in a specific format. </b> <b>And you will see later on in this video,</b> <b>how we can then use that value to</b> <b>implement some very cool logic.
</b> <b>So let's close this, and</b> <b>let's click on "Add nodes",</b> <b>then let's open up output parsers, and</b> <b>let's add a structured output parser. </b> <b>Then let's connect this structured output</b> <b>parser to the output</b> <b>parser input on the chain. </b> <b>Then within the structured output parser,</b> <b>click on additional parameters.
</b> <b>We can go ahead and delete</b> <b>these two sample properties. </b> <b>Let's add a new item, we can give it a</b> <b>name by double clicking</b> <b>on this property value. </b> <b>I'll give it a name, I'll</b> <b>just call it "sentiment".
</b> <b>For the type, we have the options of</b> <b>setting a string, a number, or a boolean. </b> <b>And what we want is a boolean value,</b> <b>which can only be true or false,</b> <b>and not a string and a</b> <b>whole bunch of other things. </b> <b>And in the description, we can enter</b> <b>something like</b> <b>"sentence is true or false".
</b> <b>Let's click off this popup to close it. </b> <b>Let's save this, and in the chat, I'm</b> <b>actually going to clear the chat history. </b> <b>And in the chat, let's type something</b> <b>like "1 plus 1 equals 3".
</b> <b>And you will now notice that instead of</b> <b>receiving a string response, we now</b> <b>receive a JSON object. </b> <b>And within this object, we can see that</b> <b>property "sentiment"</b> <b>with a value of "false". </b> <b>Now, this might seem a little bit</b> <b>technical if you're</b> <b>not familiar with JSON,</b> <b>but don't worry, I will show you exactly</b> <b>how we can use this in a very</b> <b>simple way within this flow.
</b> <b>But for those of you with JSON experience</b> <b>or coding experience,</b> <b>you can probably already</b> <b>see the benefit of this. </b> <b>For example, let's say we call our</b> <b>Flow-wise application</b> <b>through an API endpoint,</b> <b>and we expect to receive</b> <b>a JSON value coming back. </b> <b>So in our code, it's very</b> <b>easy to use this response.
</b> <b>If that didn't make sense</b> <b>to you, please don't worry,</b> <b>it will all make sense as we</b> <b>start using this in the series. </b> <b>Let's have a look at another</b> <b>interesting use case of this. </b> <b>Let's change this prompt.
</b> <b>So let's remove this first</b> <b>part, and let's simply say</b> <b>"extract information from the following</b> <b>sentence", and let's save this. </b> <b>And let's click on</b> <b>"format prompt values",</b> <b>and let's ensure that sentence is indeed</b> <b>mapped to the question from the chat box. </b> <b>Now, let's say we've got an example where</b> <b>we pause in a sentence like</b> <b>"Max is 30 years old</b> <b>and married to Angie",</b> <b>and let's say that we want the model to</b> <b>extract the name "age"</b> <b>and the spouse's name</b> <b>from any given sentence, and it should</b> <b>then return that information</b> <b>in a very specific structure.
</b> <b>So let's remove that sentence from the</b> <b>prompt, let's save our Flow,</b> <b>let's update our output parser by</b> <b>clicking on additional parameters,</b> <b>let's remove the sentiment, and let's add</b> <b>an item called "name",</b> <b>which is of type "string",</b> <b>and in the description, let's enter</b> <b>something like the name of the person,</b> <b>then let's add another</b> <b>property called "age". </b> <b>For age, let's return a number with a</b> <b>description of the age of the person,</b> <b>and these descriptions are important as</b> <b>this will tell the model</b> <b>how to extract this information and which</b> <b>property to map that information to. </b> <b>Lastly, let's set another property called</b> <b>"spouse", which is of type "string",</b> <b>and for the description, I'll</b> <b>enter the name of the spouse.
</b> <b>Let's close this, let's save the chat</b> <b>flow, and let's test</b> <b>this out in the chat. </b> <b>Let's enter "Max is 30 years old and</b> <b>married to Angie", and let's send this. </b> <b>And I think it took less than a second</b> <b>for that response to come back,</b> <b>and we can see that our application was</b> <b>able to successfully</b> <b>extract the name "the age"</b> <b>as well as the name of the spouse.
</b> <b>Now imagine using this</b> <b>in an actual application. </b> <b>The user can pass in</b> <b>pretty much any sentence,</b> <b>and this flow will extract all the</b> <b>relevant information</b> <b>and return it in a format</b> <b>that we can use downstream. </b> <b>Let's have another look at</b> <b>where this can be useful,</b> <b>and then I'll show you how we can</b> <b>conditionally call</b> <b>chains using an output parser.
</b> <b>First, let's change this</b> <b>prompt template to something like</b> <b>"provide a comma separated list of</b> <b>synonyms for the word word". </b> <b>Let's save this, then in the format</b> <b>prompt values, let's delete "sentence". </b> <b>Let's add a new value called "word",</b> <b>because this is what we call the</b> <b>placeholder in the prompt template.
</b> <b>Let's click on "edit", and let's select</b> <b>the value from the chat box. </b> <b>Let's also go ahead and delete this</b> <b>structured output parser,</b> <b>then let's save this chat</b> <b>flow, and let's run chat. </b> <b>Let's clear this, and in the chat, let's</b> <b>enter a word like "happy".
</b> <b>We now receive a list of</b> <b>comma separated words like so,</b> <b>but again, this is simply a string,</b> <b>and there's no guarantee that the model</b> <b>will always respond with</b> <b>this specific structure. </b> <b>We can force this into a JSON list by</b> <b>adding an output parser. </b> <b>In "add nodes", let's</b> <b>go to "output parsers",</b> <b>and let's select</b> <b>"custom list output parser".
</b> <b>Of course, let's</b> <b>connect this to our chain. </b> <b>For this list output parser, we can</b> <b>specify the separator,</b> <b>which will be a comma in this instance,</b> <b>and we can simply leave length blank. </b> <b>Now, watch what happens when</b> <b>we run the same chat again.
</b> <b>Let's parse in "happy" again, and this</b> <b>time, we receive a JSON</b> <b>list of string values. </b> <b>So again, if we are using</b> <b>this flow in an application,</b> <b>we can simply use this as an array and</b> <b>loop through the values. </b> <b>Now, let me show you another powerful use</b> <b>case of using output parsers,</b> <b>and that is to conditionally call</b> <b>different chains based on a value.
</b> <b>Let's delete this output parser for now,</b> <b>and let's change this</b> <b>prompt template to something like</b> <b>"determine if the</b> <b>following review is positive",</b> <b>and let's add a</b> <b>placeholder called "review". </b> <b>Let's save this. </b> <b>Then let's open format prompt values.
</b> <b>Let's delete "word". </b> <b>Let's add a new value. </b> <b>Let's call it "review",</b> <b>and let's click on "edit",</b> <b>and let's select the</b> <b>value from the chat box.
</b> <b>Now, before we add an output parser,</b> <b>let's simply save this. </b> <b>Let's run this in the chat, and actually,</b> <b>let's clear the chat history,</b> <b>and let's write something like "the</b> <b>service was terrible",</b> <b>and this tells us that</b> <b>this was a negative review,</b> <b>or what about "the food was</b> <b>great", and this is positive. </b> <b>So let's say we want to</b> <b>call a different chain,</b> <b>depending on whether the review was</b> <b>positive or negative.
</b> <b>So let's actually add two</b> <b>more chains to this flow. </b> <b>So I'll add a chain over here, and let's</b> <b>say this is the positive chain,</b> <b>and this chain will</b> <b>specialize in positive reviews. </b> <b>For example, we might want this chain to</b> <b>thank the user for their positive review,</b> <b>and then ask the user if they would like</b> <b>to post a review on our website.
</b> <b>And let's add another chain that will</b> <b>specialize in dealing</b> <b>with negative reviews. </b> <b>I'll actually call it "negative", and</b> <b>this chain could, as an example,</b> <b>ask the user if they would</b> <b>like to log a support ticket,</b> <b>and apologize for the bad experience. </b> <b>So we've learned in the previous videos</b> <b>that for these LLM chains,</b> <b>we need to add a</b> <b>model as well as a prompt.
</b> <b>Let's start by adding a</b> <b>model, and for the model,</b> <b>I'm actually going to use a chat model,</b> <b>and specifically the chat OpenAI model. </b> <b>And that is simply because</b> <b>we've seen in the previous video,</b> <b>these chat models produce way better</b> <b>output than the instruct models. </b> <b>Let's go ahead and</b> <b>select our credentials.
</b> <b>I'll leave the model as 3. 5 turbo, and</b> <b>I'll set the temperature to 0. 7.
</b> <b>Let's also add a prompt template. </b> <b>So under prompts, let's</b> <b>select a prompt template,</b> <b>and let's connect this</b> <b>prompt template to the chain. </b> <b>Then let's set our</b> <b>template by clicking on "expand",</b> <b>and let's enter something like "You are a</b> <b>customer support assistant".
</b> <b>First, thank the client for the review,</b> <b>and then ask if they would like to post a</b> <b>review to our website. </b> <b>Also summarize the review, and let's add</b> <b>a placeholder called</b> <b>"review", and let's save this. </b> <b>Now let's do the same</b> <b>thing for the negative chain.
</b> <b>First, let's add a model. </b> <b>Again, I'll add a chat model, and I'll</b> <b>add the chat OpenAI model. </b> <b>Then let's connect this model to the</b> <b>chain, let's select our credentials.
</b> <b>I'll leave it as "gpt 3. 5 turbo", and</b> <b>let's set the temperature to 0. 7.
</b> <b>Now for the prompt, let's go to prompts,</b> <b>and let's add a prompt template. </b> <b>Let's connect the prompt template to the</b> <b>chain, and let's give this a value,</b> <b>and let's enter something like "You are a</b> <b>customer support assistant"</b> <b>that deals with negative reviews. </b> <b>Write an apology for</b> <b>the following review,</b> <b>and ask the user if they would like to be</b> <b>contacted by a customer service rep,</b> <b>and it's also adding our review, and it's</b> <b>prefix this as well with review, like so.
</b> <b>So if you wanted to, you could try and</b> <b>cram all of this into a single prompt,</b> <b>but in real world applications, these</b> <b>chains might use different models</b> <b>based on what we want them to do. </b> <b>And once we have a look at agents, you</b> <b>might want to hand this output over</b> <b>to a chain in one instance,</b> <b>or in another to an agent. </b> <b>But this example is good enough to</b> <b>demonstrate the point.
</b> <b>Now let's have a look at how we can</b> <b>conditionally call these chains</b> <b>based on the output of this chain. </b> <b>At the moment, this chain will tell us if</b> <b>the review is positive or negative,</b> <b>but this is simply a</b> <b>string value, like so,</b> <b>and there's no guarantee that this</b> <b>response will always</b> <b>follow this convention,</b> <b>and the model could even return an entire</b> <b>sentence if it wanted to. </b> <b>So let's use an output parser to force</b> <b>the response to be a boolean value.
</b> <b>So under nodes, let's</b> <b>go to output parsers,</b> <b>let's add this structured output parser,</b> <b>and let's connect this to this chain. </b> <b>Let's actually call this</b> <b>the sentiment chain as well. </b> <b>For the output parser, let's click on</b> <b>additional parameters.
</b> <b>Let's delete these sample properties. </b> <b>And for the value,</b> <b>let's call it positive. </b> <b>For the type, let's set it to boolean.
</b> <b>And for the description,</b> <b>let's say the review is positive. </b> <b>So if the review is positive, this value</b> <b>will be set to true. </b> <b>Otherwise, it will be set to false.
</b> <b>So now we know we will</b> <b>always receive a JSON object</b> <b>with the property positive, and that</b> <b>value can either be true or false. </b> <b>Now, in order to</b> <b>conditionally call these chains,</b> <b>I'm just going to make some space by</b> <b>moving these chains over a bit, like so. </b> <b>And now we can conditionally call these</b> <b>chains by adding a</b> <b>utility called if-else.
</b> <b>So under add nodes, let's go to</b> <b>utilities, and let's</b> <b>add this if-else function. </b> <b>We can now use this if-else function to</b> <b>conditionally call chains</b> <b>based on the input that it receives. </b> <b>So let's pass the output of this chain</b> <b>into the if-else function.
</b> <b>First, let's change the</b> <b>output to output prediction,</b> <b>and then let's attach</b> <b>this to the if-else function. </b> <b>We now need to give</b> <b>this input a variable name. </b> <b>So let's click on add, and</b> <b>let's call this sentiment.
</b> <b>We can now assign a value to</b> <b>sentiment by clicking on edit. </b> <b>Let's click on this input box, and let's</b> <b>select a value from the</b> <b>sentiment chain, like so. </b> <b>So we know from the output parser that</b> <b>this response will return</b> <b>one property called positive,</b> <b>and this can either be true or false.
</b> <b>So we can now reference</b> <b>that value in this function,</b> <b>and this might seem a little bit</b> <b>intimidating if you're</b> <b>not familiar with coding,</b> <b>but don't worry, this is not too</b> <b>difficult to understand. </b> <b>And this is the few times in Flow-wise</b> <b>where you might have to</b> <b>write very simple code. </b> <b>Just follow along in this if-function</b> <b>block, pick on expand,</b> <b>and what we want to do is reference that</b> <b>sentiment variable,</b> <b>which is called sentiment,</b> <b>and in order to tell this that we are</b> <b>referring to the variable,</b> <b>we simply have to add a</b> <b>dollar sign in front of it.
</b> <b>And within sentiment, we have one</b> <b>property called positive,</b> <b>and what we want to do is if this value</b> <b>is true, remember, it can</b> <b>only be either true or false,</b> <b>then we will return the value of true. </b> <b>Let's click on save, and for the else</b> <b>function, we don't</b> <b>have to change anything. </b> <b>So how this works is this if-else node</b> <b>has two outputs, a true</b> <b>output and a false output.
</b> <b>So if the condition in</b> <b>this first block is true,</b> <b>then whatever chain is connected to this</b> <b>true output will be called. </b> <b>Otherwise, whatever is connected to this</b> <b>false output will be called. </b> <b>So if the sentiment is positive, then we</b> <b>want to call this positive chain.
</b> <b>So we can do that by connecting this true</b> <b>output to the prompt</b> <b>value of the positive chain,</b> <b>and we can connect the negative chain by</b> <b>connecting this false output</b> <b>to the prompt value</b> <b>of the negative chain. </b> <b>And now you should be left with a flow</b> <b>that looks something like this. </b> <b>So in a nutshell, the first chain will</b> <b>return a structured</b> <b>output with a property called</b> <b>positive, which is either true or false.
</b> <b>That value is then passed</b> <b>into the if-else function,</b> <b>and if sentiment. positive equals true,</b> <b>then we call the positive chain. </b> <b>Else, if the sentiment was negative, we</b> <b>will call the negative chain.
</b> <b>Now let's test this</b> <b>out by saving the flow. </b> <b>Let's click on chat, and let's type</b> <b>something like "the food was awesome". </b> <b>And now we are receiving a response from</b> <b>the positive chain,</b> <b>saying "Dear valued customer,</b> <b>thank you so much for taking the time to</b> <b>share your feedback.
</b> <b>We truly appreciate it. "</b> <b>In order to showcase your review on our</b> <b>website and to let others</b> <b>know about your experience,</b> <b>we would like to ask your</b> <b>permission to post it. Fantastic.
</b> <b>And in the series, we will have a look at</b> <b>adding tools to these applications</b> <b>that will actually</b> <b>make updates to databases. </b> <b>Let's try a negative use case, something</b> <b>like "the waiter was rude"</b> <b>and "the food was called". </b> <b>And this time, based on the prompt</b> <b>template, we expect the model to</b> <b>apologize and ask if</b> <b>a customer support rep should contact the</b> <b>customer.
So let's</b> <b>see if that is the case. </b> <b>Firstly, it is apologizing to the</b> <b>customer, and indeed we</b> <b>can see a message saying,</b> <b>"A customer support representative would</b> <b>be more than happy to reach out to you</b> <b>and personally address</b> <b>any concerns you may have. "</b> <b>So there are plenty of use</b> <b>cases for output parsers,</b> <b>and I hope you do see the value of</b> <b>learning this important tool.