Posey's Tips & Tricks

Do-It-Yourself AI, Part 3: Filtering Results

Next up in our series, I'll show you how to cut through reasoning text to receive the answer to your AI query.

In the previous blog post in this series, I showed you how to get DeepSeek-R1 up and running so that you can perform large language model queries directly on your own hardware, for free, and independently of any cloud services. As I pointed out at the beginning of this series however, DeepSeek-R1 is a reasoning model, meaning that it has to "think about" your question before it can come up with an answer. Unfortunately, the models can produce a large amount of reasoning text before giving you an answer. In this article, I want to show you how you can use PowerShell to filter out the reasoning text so that all you see is the answer to your question.

[Click on image for larger view.] Figure 1. DeepSeek-R1 produces large amounts of reasoning text before giving you an answer.

Using PowerShell to filter DeepSeek-R1 responses essentially involves two things. These include using PowerShell variables to get data into and out of DeepSeek-R1 and using string manipulation to get rid of the unwanted text.

Every DeepSeek-R1 conversation begins with asking a question. We need to give PowerShell a way of passing the query to DeepSeek-R1. I like to use a command like this one:

$Query = Read-Host "Enter your query."

This command prompts the user to enter a query and then stores the query text in a variable named $Query.

The next step in the process is to send the query to DeepSeek-R1 and store the query results in a variable. Here is the command that I use:

$Response = & ollama run deepseek-r1 $Query

The ampersand (&) sign in this command is what's known as a call operator. It tells PowerShell that we want to run a command (ollama run deepseek-r1 $query) and then store the result in the assigned variable ($Result). Keep in mind that this line of code references the default model. If you want to use an alternative model, you will need to modify this command accordingly.

At this point, DeepSeek-R1's response should be stored in the $Response variable. However, the data is not quite ready to use. As I was developing my script, I found that the string manipulations that I attempted against the response did not work the way that they should. I soon realized that my problems were being caused by the fact that the data within the $Response variable was being stored as an object, not as a string. In fact, you can confirm the data type by using this command:

$Response.GetType().Name
[Click on image for larger view.] Figure 2. The data is being stored as an object.

Being that the response is indeed an object, we need to convert it to a string. The way that I do this is by using this command:

$ResponseString = $Response -Join "`n"

In case you are wondering, `n is the PowerShell string operator that forces a line break. I also occasionally use `r`n in situations where `n alone doesn't give me the desired result. Omitting this portion of the command results in all of the filtered output being presented as a single line of text. If you look at Figure 3, you can see that the $ResponseString variable is a string as opposed to an object.

[Click on image for larger view.] Figure 3. The $ResponseString variable contains DeepSeek-R1's response, stored in string format.

Now that the response is stored in the correct format, we can filter it. The way that I like to handle the filtering process is by storing the filter in a variable that I can reference during the filtering process. Here is the variable assignment:

$Filter =  "(?s)<think>.*?</think>\r?\n?"

The basic idea behind this filter is that DeepSeek-R1 places the <think> tag ahead of its reasoning text. It then adds the </think> tag to the output as a way of indicating that the reasoning process is done. Everything that comes after the </think> tag is a part of the answer. This filter is designed to strip away the <think> and the </think> tags, and everything in between. The \r?\n? portion of the filter are designed to get rid of the blank line that DeepSeek-R1 inserts just above the answer portion of its output.

The last step in the process is to create a variable that will store the filtered output. Here is the command that I am using:

$FilteredText = [regex]::Replace($ResponseString, $Filter,  "")

The $FilteredText variable uses a regular expression to replace any text within the response string matching the filter with an empty string. You can see the final results by outputting the contents of the $FilteredText variable. As you can see in Figure 4, I have stripped away all of the reasoning text, leaving only the answer to the query.

[Click on image for larger view.] Figure 4. The reasoning text has been filtered out, leaving only the answer to the prompt!

Now that I have shown you how to filter the output, I want to conclude this series in Part 4 by showing you how to build a full-blown AI chatbot based on DeepSeek-R1.

About the Author

Brien Posey is a 22-time Microsoft MVP with decades of IT experience. As a freelance writer, Posey has written thousands of articles and contributed to several dozen books on a wide variety of IT topics. Prior to going freelance, Posey was a CIO for a national chain of hospitals and health care facilities. He has also served as a network administrator for some of the country's largest insurance companies and for the Department of Defense at Fort Knox. In addition to his continued work in IT, Posey has spent the last several years actively training as a commercial scientist-astronaut candidate in preparation to fly on a mission to study polar mesospheric clouds from space. You can follow his spaceflight training on his Web site.

Featured

comments powered by Disqus

Subscribe on YouTube