<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Posts on markchur.ch</title>
        <link>https://markchur.ch/posts/</link>
        <description>Recent content in Posts on markchur.ch</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>en-us</language>
        <lastBuildDate>Fri, 05 Sep 2025 00:00:00 +0000</lastBuildDate><atom:link href="https://markchur.ch/posts/index.xml" rel="self" type="application/rss+xml" /><item>
        <title>The Nature of Context Rot</title>
        <link>https://markchur.ch/posts/context-rot/</link>
        <pubDate>Fri, 05 Sep 2025 00:00:00 +0000</pubDate>
        
        <guid>https://markchur.ch/posts/context-rot/</guid>
        <description>&lt;p&gt;I recently learned about the term &lt;em&gt;Context Rot&lt;/em&gt; from an excellent &lt;a class=&#34;link&#34; href=&#34;https://research.trychroma.com/context-rot&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;technical report&lt;/a&gt; by the vector database company &lt;a class=&#34;link&#34; href=&#34;https://trychroma.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Chroma&lt;/a&gt;. &amp;ldquo;Context rot&amp;rdquo; is the characteristic of LLMs to decrease in performance as the context window grows. Similar to the term &lt;em&gt;Context Poisoning&lt;/em&gt;, it evokes the sense of ✨preciousness✨ that &lt;em&gt;Context Engineers&lt;/em&gt; have towards their LLM&amp;rsquo;s context window. And as I read the report, it made me realize how careless and reckless I have been with my own context windows - shame on me!&lt;/p&gt;
&lt;p&gt;In this post I&amp;rsquo;ll dig into the nature of context rot, but more importantly, I&amp;rsquo;ll detail the sources that allow context rot to creep into your prompts. Context rot is like mold on the food in the back of your fridge. It can creep in slowly if you&amp;rsquo;re not regularly cleaning things out.&lt;/p&gt;
&lt;h2 id=&#34;-who-poisoned-the-context&#34;&gt;🕵️ Who poisoned the context?
&lt;/h2&gt;&lt;p&gt;Chroma&amp;rsquo;s report showed that models that can perform a task perfectly at 100 tokens, may be unable to do the exact same task at 1,000 tokens, despite having support for 1M+ context windows. It&amp;rsquo;s a phenomenon seen across all LLMs, as shown here:&lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://markchur.ch/posts/context-rot/context-rot.png&#34; width=&#34;600px&#34;&gt;
&lt;/figure&gt;

&lt;p&gt;The traditional test for context window performance is called the “needle in a haystack” test.  This is where an LLM is given increasingly large amounts of text and is asked to answer a question about a single piece of information (the &amp;ldquo;needle&amp;rdquo;) in the text.&lt;/p&gt;
&lt;p&gt;Chroma went deeper in their research paper and explored more nuanced factors of context rot:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Context window token length&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ambiguity between the context and the question&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Distractors&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;They proved across various models that all three of these factors contribute towards worse performance. As the context window (or the &amp;ldquo;haystack&amp;rdquo;) increases in size, the LLM will increasingly come to the wrong answer, even though the answer is right there in the context.&lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://markchur.ch/posts/context-rot/needle-haystack.png&#34; width=&#34;800px&#34;&gt;
&lt;/figure&gt;

&lt;p&gt;Ambiguity was defined as semantic (or cosine) similarity between the question and the needle.  This makes intuitive sense. As the question becomes less semantically similar to the needle,  the LLM has to do more work to translate meaning from one set of words to another. Consider the following Question-Needle pairs. Your brain has to do a tiny bit more work to answer the second pair:&lt;/p&gt;
&lt;div class=&#34;highlight wrap&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color: #f7d9a8;&#34;&gt;&lt;strong&gt;Question:&lt;/strong&gt;&lt;/span&gt; What is your favorite taco spot In Austin?
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color: #067bc2;&#34;&gt;&lt;strong&gt;Needle:&lt;/strong&gt;&lt;/span&gt; my favorite tacos in Austin are from Joe’s.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color: #f7d9a8;&#34;&gt;&lt;strong&gt;Question:&lt;/strong&gt;&lt;/span&gt; What is your favorite taco spot in Austin?
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color: #067bc2;&#34;&gt;&lt;strong&gt;Needle:&lt;/strong&gt;&lt;/span&gt; I was in Austin back in 2023. The best tacos I had there were from Joe’s.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;They also tested distractors, which is context that is semantically similar to the question, but doesn&amp;rsquo;t actually answer the question. An example of this might be:&lt;/p&gt;
&lt;div class=&#34;highlight wrap&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color: #f7d9a8;&#34;&gt;&lt;strong&gt;Question:&lt;/strong&gt;&lt;/span&gt; What is your favorite taco spot in Austin?
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color: #d56062;&#34;&gt;&lt;strong&gt;Distractor:&lt;/strong&gt;&lt;/span&gt; I was in Austin back in 2023. I love the Mexican food there, but nothing compares to Roberto&amp;#39;s, my favorite taco spot in San Diego.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;These tests all point to two takeaways: Context engineering is critical to performance and context engineering is fundamentally an optimization problem. The AI developer must optimize their system to provide:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;The lowest amount of ambiguity (directly relevant context),&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;using the fewest amount of tokens (smallest context window),&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;and minimize the amount of distractors (irrelevant context).&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;But now let&amp;rsquo;s talk practically &amp;hellip;&lt;/p&gt;
&lt;h2 id=&#34;-the-context-has-gone-bad-&#34;&gt;🤢 The context has gone bad &amp;hellip;
&lt;/h2&gt;&lt;p&gt;In practice, how can you decrease context rot and what are the sources of it? As you look at your prompts you&amp;rsquo;ll quickly realize that there is a lot of low hanging fruit and some common sources that produce context rot.&lt;/p&gt;
&lt;p&gt;AI applications are often built by teams of developers. There can be different individuals that may even be on different teams, all collaborating on a single overarching AI agent. The result is that the application is composed of many different prompts, authored by different people, who may not have visibility or understanding of the full system. This results in inconsistency where context rot can creep into the system.&lt;/p&gt;
&lt;p&gt;By watching out for these sources, you can improve the best practices your team follows in building AI applications, and improve the performance of your agents.&lt;/p&gt;
&lt;h2 id=&#34;-anatomy-of-a-prompt&#34;&gt;📖 Anatomy of a Prompt
&lt;/h2&gt;&lt;p&gt;First let&amp;rsquo;s look at the anatomy of a prompt. Anthropic has an excellent talk on &lt;a class=&#34;link&#34; href=&#34;https://youtu.be/ysPbXH0LpIE?si=8mqqU7H__eqNOD5a&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Prompting 101 &lt;/a&gt; where they defined a structure somewhat like this one. People may call the components differently, but most &amp;ldquo;production&amp;rdquo; prompts in agentic systems have these elements in common:&lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://markchur.ch/posts/context-rot/prompt-anatomy.png&#34; width=&#34;600px&#34;&gt;
&lt;/figure&gt;

&lt;p&gt;Simple prompts may be fully static, meaning that they were directly authored by the developer. The more agentic and more complex an AI application gets though, the more likely that there will be dynamic components too. The dynamic pieces are inserted or rendered in the prompt at runtime with dynamically fetched data that may be entirely different with each agent invocation. The core instructions and goal for a given agent is likely to be static. The dynamic parts are more likely to be the user&amp;rsquo;s query, or background knowledge that is injected into the prompt, or dynamically fetched chunks from a few-shot example library, etc.&lt;/p&gt;
&lt;h2 id=&#34;-sources-of-context-rot&#34;&gt;🚰 Sources of Context Rot
&lt;/h2&gt;&lt;p&gt;All of this is very important for understanding context rot. So let&amp;rsquo;s get into some common sources of context rot &amp;hellip;.&lt;/p&gt;
&lt;h3 id=&#34;-overlapping-tool-descriptions&#34;&gt;👯 Overlapping tool descriptions
&lt;/h3&gt;&lt;p&gt;Tool descriptions that are too semantically similar to each other will cause an LLM to be inconsistent about its tool choices. Theoretically, this means that the developer has underspecified their intent. And if a developer hasn’t considered the full range of inputs and corner cases, then it’s likely that even their intent is not specific enough. In practice though, a common cause for overlapping tool descriptions is that they are written by different people or teams. The true test is humans - given a query and a set of tool descriptions, would three people universally agree on the tool that should be used to answer it? If no, then your tool descriptions are underspecified or overlapping.&lt;/p&gt;
&lt;h3 id=&#34;-conflicting-instructions&#34;&gt;💥 Conflicting instructions
&lt;/h3&gt;&lt;p&gt;System instruction can become very long, especially when you are trying to consider every flow a user might take and all the corner cases too. This makes it easy for conflicting or ambiguous instructions to creeping in. It gets even worse when different instructions are composed together in the same prompt at runtime or written by different developers.&lt;/p&gt;
&lt;p&gt;Consider these conflicting instructions:&lt;/p&gt;
&lt;div class=&#34;highlight wrap&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-markdown&#34; data-lang=&#34;markdown&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;1.&lt;/span&gt; You MUST NOT use any personally identifiable information (PII) from the user&amp;#39;s query or conversation history in your response.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;2.&lt;/span&gt; When booking an appointment, you MUST confirm the user&amp;#39;s full name and email address in your final summary before calling the &amp;#39;schedule_appointment&amp;#39; tool.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;3.&lt;/span&gt; You MUST ALWAYS confirm responses from the user before committing them in any tool.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The first instructions tells the model it should not respond with any PII. The second tells it that it must capture PII. Then the third tells it that it must respond back to the user with this PII, which conflicts with the first instruction.&lt;/p&gt;
&lt;p&gt;This is a simplistic example, but when you have more than 100 instructions (which is a realistic amount), it&amp;rsquo;s easy to miss subtle conflicts like this. Any amount of ambiguity, in the static or dynamic portions of the context, will increase the chance of inconsistent answers or hallucination.&lt;/p&gt;
&lt;h3 id=&#34;-inconsistent-style&#34;&gt;🎨 Inconsistent style
&lt;/h3&gt;&lt;p&gt;Inconsistency in the prompt places unnecessary processing burden on the LLM. Some examples of inconstancy might be:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Mixing &amp;ldquo;I&amp;rdquo; and &amp;ldquo;You&amp;rdquo; in the same set of instructions&lt;/li&gt;
&lt;li&gt;Mixing of markdown and XML headers to demark sections of the prompt&lt;/li&gt;
&lt;li&gt;Inconsistent terminology&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Consider this example where terminology switches back and forth in the instructions:&lt;/p&gt;
&lt;div class=&#34;highlight wrap&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-markdown&#34; data-lang=&#34;markdown&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;1.&lt;/span&gt; When a &lt;span style=&#34;font-weight:bold&#34;&gt;**customer**&lt;/span&gt; submits a new &lt;span style=&#34;font-weight:bold&#34;&gt;**ticket**&lt;/span&gt;, you must categorize it based on the product mentioned.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;2.&lt;/span&gt; You should then provide the &lt;span style=&#34;font-weight:bold&#34;&gt;**user**&lt;/span&gt; with an estimated resolution time for their &lt;span style=&#34;font-weight:bold&#34;&gt;**case**&lt;/span&gt;.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;3.&lt;/span&gt; Before escalating, always ask the &lt;span style=&#34;font-weight:bold&#34;&gt;**client**&lt;/span&gt; if they have any more details to add to the &lt;span style=&#34;font-weight:bold&#34;&gt;**inquiry**&lt;/span&gt;.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Any degree of ambiguity leads to unnecessary processing for the LLM. Don&amp;rsquo;t make your LLMs work harder than they have to!&lt;/p&gt;
&lt;h3 id=&#34;-dynamic-context-explosion&#34;&gt;💥 Dynamic context explosion
&lt;/h3&gt;&lt;p&gt;Dynamic context is any context that is injected into the prompt or message history at runtime. This might be context that is injected into the instruction prompt or it may be context that is returned by a tool call. If you&amp;rsquo;re not monitoring and regularly reviewing the rendered instruction and messages, then you have no idea if a massive amount of dynamic context is being dumped into the context window, exploding your token usage.&lt;/p&gt;
&lt;p&gt;Consider an instruction prompt like this:&lt;/p&gt;
&lt;div class=&#34;highlight wrap&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-markdown&#34; data-lang=&#34;markdown&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;recent_transactions&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{recent_transactions}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;recent_transactions&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;recent_page_visits&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{recent_page_visits}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;recent_page_visits&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;How much data could be returned for the recent transactions or page visits? The only way to know is to monitor and look at the prompts! This is where limits, truncation, summarization, and compression become very useful safeguards.&lt;/p&gt;
&lt;h3 id=&#34;-not-monitoring-token-usage&#34;&gt;📈 Not monitoring token usage
&lt;/h3&gt;&lt;p&gt;Since context token windows are the most precious resource, not monitoring input &amp;amp; output token usage is one of the easiest ways to unknowingly introduce context rot. Token consumption should be monitored in aggregate and also across various dimensions so that you can spot trends and changes over time. Perhaps a new tool was introduced that has 100,000 token responses or the LLM gets caught in a  doom loop where it&amp;rsquo;s repeating the same phrase over and over again. The only way to know is to monitor.&lt;/p&gt;
&lt;h3 id=&#34;-errors-and-junk-context&#34;&gt;🗑️ Errors and junk context
&lt;/h3&gt;&lt;p&gt;Tools calls can fail for many reasons and their errors are often helpful to guide the LLM in how to succesfully make the next tool call. However, long, verbose errors can also pollute your context window. What&amp;rsquo;s even more common is &amp;ldquo;junk context&amp;rdquo; that might be returned from tool calls. Is a tool returning 10,000 log lines of the exact same content? Or is a RAG tool dumping volumes of completely unrelated documentation into the context window?&lt;/p&gt;
&lt;h3 id=&#34;-few-shot-example-distribution&#34;&gt;🎰 Few-shot example distribution
&lt;/h3&gt;&lt;p&gt;Few-shot examples are a great strategy for grounding LLMs in examples that represent your data. Keep in mind though that LLMs are probabilistic machines - the distribution of data they process will influence their output. Too many few-shot examples of one type, or a distribution of examples that doesn&amp;rsquo;t match your real-world data distribution, will lead the LLM in the wrong direction.&lt;/p&gt;
&lt;div class=&#34;highlight wrap&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-markdown&#34; data-lang=&#34;markdown&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;instruction&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Classify the user&amp;#39;s intent into one of these categories:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;CHECK_BALANCE, MAKE_DEPOSIT, OPEN_ACCOUNT, OPEN_SUPPORT_TICKET
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;instruction&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;examples&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;User: I want to open a new checking account.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Intent: OPEN_ACCOUNT
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;User: How can I start a savings account with you?
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Intent: OPEN_ACCOUNT
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;User: I need to deposit this check.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Intent: MAKE_DEPOSIT
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;User: I&amp;#39;d like to apply for a new account.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Intent: OPEN_ACCOUNT
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;examples&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If your real-world distribution of intents is 75% account openings and 25% deposits this might make sense, but in general you should always balance out examples with the real-world distributions.&lt;/p&gt;
&lt;h2 id=&#34;-preventing-context-rot&#34;&gt;🧼 Preventing Context Rot
&lt;/h2&gt;&lt;p&gt;There are many small best practices that help to prevent context rot. They can be difficult to implement in one shot, but small steps towards broad adoption makes a big impact over time. These best practices include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Prompt instruction reviews - make sure the team is reading the prompt instructions together&lt;/li&gt;
&lt;li&gt;Prompt style guide - standardize any stylistic or formatting practices for the sake of consistency&lt;/li&gt;
&lt;li&gt;Prompt tracing - look at rendered prompts, the outputs, and identify egrigious issues&lt;/li&gt;
&lt;li&gt;Token analytics - gather analytics your token usage, tool usage, and any other dimensions that are important so you can see how tool, agent, and prompt changes affect your system across different dimensions.&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>Building a Tiny ReAct Agent from Scratch</title>
        <link>https://markchur.ch/posts/tiny-react/</link>
        <pubDate>Thu, 03 Jul 2025 00:00:00 +0000</pubDate>
        
        <guid>https://markchur.ch/posts/tiny-react/</guid>
        <description>&lt;p&gt;You can&amp;rsquo;t watch a keynote very long these days without hearing the word &amp;ldquo;agent&amp;rdquo;. Agent is so popular that the word has now actually lost its technical meaning and has been donated to the marketing team. But I&amp;rsquo;ll still give my most concise, technical definition - &lt;strong&gt;an agent is an application with the ability to make decisions, using AI, that influence the application&amp;rsquo;s control-flow.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Even more simply: &lt;strong&gt;agents have &lt;em&gt;agency&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;I started my own agent learning journey by building one myself. I quickly found that there is so much abstraction in all the chaining and agent frameworks, that it&amp;rsquo;s hard to understand what&amp;rsquo;s happening. So I decided build one from scratch - no frameworks, no products, just standard Python libraries (and a little help from Gemini). &lt;a class=&#34;link&#34; href=&#34;https://github.com/mark-church/tiny-react&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Tiny ReAct&lt;/a&gt; is the result of this effort, all in less than 100 lines of code!&lt;/p&gt;
&lt;p&gt;The core concepts of how an agent works are actually quite simple. &amp;ldquo;ReAct&amp;rdquo; (&lt;a class=&#34;link&#34; href=&#34;https://arxiv.org/abs/2210.03629&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;&lt;strong&gt;Re&lt;/strong&gt;asoning and &lt;strong&gt;Act&lt;/strong&gt;ing&lt;/a&gt;) was one of the first LLM-based agentic approaches that became popularized. I used the ReAct pattern and a set of simple tools (an &amp;ldquo;AI&amp;rdquo; term for Python function) that can make API calls for external information. The ultimate goal was an agent that could answer complex questions that require some external information, multiple steps, and a bit of decision-making to answer.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s talk about the architecture of this ReAct agent &amp;hellip;&lt;/p&gt;
&lt;h2 id=&#34;-anatomy-of-an-agent&#34;&gt;🤖 Anatomy of an Agent
&lt;/h2&gt;&lt;p&gt;The simplest version of an agent is just an LLM that is called in a loop. Each loop (or &amp;ldquo;turn&amp;rdquo;) gets the full conversation history of the previous turns. This allows the LLM to make incremental progress towards a complex question, taking one step (or tool call) at a time. This full conversation history, including the initial instruction prompt, query, and every request/response pair, is called a &lt;strong&gt;reasoning trace&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;The reasoning trace has three parts to it:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Thought (reasoning)&lt;/strong&gt;: A dialogue generated by the LLM where it&amp;rsquo;s instructed to describe what it thinks it should do next to answer the query.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Action&lt;/strong&gt;: A tool/function call generated by the LLM, which is informed by its own reasoning dialogue.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Observation&lt;/strong&gt;: The output of that tool/function call. This part is not generated by the LLM. Rather, it&amp;rsquo;s injected into the reasoning trace and the LLM will see this output on the next turn.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A ReAct reasoning trace might look like the following flow. A triplet of thought, action, and observation is appended with each turn, until an answer is found.&lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://markchur.ch/posts/tiny-react/react-flow.png&#34; width=&#34;800px&#34;&gt;
&lt;/figure&gt;

&lt;p&gt;Now imagine on the next turn you are calling the LLM again and passing this conversation history in. The LLM will see the tool response in the most recent observation and decide what to do next. This loop ends up looking like the following diagram.&lt;/p&gt;
&lt;p&gt;On each turn the agent has four possible outcomes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The LLM has identified the answer and the loop stops&lt;/li&gt;
&lt;li&gt;The LLM hits its expiry and the loop stops before getting an answer&lt;/li&gt;
&lt;li&gt;The LLM decides that it needs to make another tool call&lt;/li&gt;
&lt;li&gt;Or there was an error and if the LLM is smart enough, it may be able to recover from that error&lt;/li&gt;
&lt;/ul&gt;
&lt;figure&gt;&lt;img src=&#34;https://markchur.ch/posts/tiny-react/react.png&#34; width=&#34;1000px&#34;&gt;
&lt;/figure&gt;

&lt;p&gt;Here&amp;rsquo;s the skeleton of our Tiny ReAct agent class. Its methods correspond with the ReAct loop: Reason → Act → Observe → Repeat.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;TinyReAct&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;__init__&lt;/span&gt;(self, ttl&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;5&lt;/span&gt;, tools&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;None&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;# Initialize the agent with tools and settings&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;query&lt;/span&gt;(self, query: str) &lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt; str:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;# Handle the main query loop&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;iterate&lt;/span&gt;(self) &lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt; tuple[str, bool]:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;# Process one iteration of reasoning and acting&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;reason&lt;/span&gt;(self) &lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt; str:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;# Genereate the LLM&amp;#39;s reasoning and action&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;act&lt;/span&gt;(self, function_call: str) &lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt; str:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;# Execute a tool call&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;-the-agent-in-detail&#34;&gt;🔧 The Agent in Detail
&lt;/h2&gt;&lt;h3 id=&#34;-agent-initialization&#34;&gt;🚀 Agent Initialization
&lt;/h3&gt;&lt;p&gt;The &lt;code&gt;__init__&lt;/code&gt; method is where we set up our agent. There are three important things that happen here:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;trace&lt;/code&gt; list is initialized. This list will store our conversation history / reasoning trace. LLMs suffer from amnesia - they have no memory of previous calls. So we record each request &amp;amp; response outside of the LLM and pass it in to every LLM call.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;We initialize our LLM. In this case I&amp;rsquo;m using Google&amp;rsquo;s &lt;code&gt;gemini-2.5-flash-preview-05-20&lt;/code&gt; that will provide all the reasoning and acting outputs.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;We assemble our &lt;code&gt;instruction_prompt&lt;/code&gt;. The instruction prompt tells the LLM what to do and it also lists out the tools that are available to it. The LLM only knows what actions it can take because we tell it in the &lt;code&gt;instruction_prompt&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;__init__&lt;/span&gt;(self, ttl&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;5&lt;/span&gt;, tools&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;None&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;trace &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; []
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;iteration &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;ttl &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; ttl
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;tools &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; tools
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;# Initialize Gemini client&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    load_dotenv()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    api_key &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; os&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;getenv(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;GEMINI_API_KEY&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;client &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; genai&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;Client(api_key&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;api_key)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;# Format the instruction prompt with available tools&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    tool_prompt &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; function_name &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;tools:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        tool_prompt &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;function_name&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;__name__&lt;span style=&#34;color:#e6db74&#34;&gt;}{&lt;/span&gt;inspect&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;signature(function_name)&lt;span style=&#34;color:#e6db74&#34;&gt;}{&lt;/span&gt;function_name&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;__doc__&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;instruction_prompt &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; instruction_prompt_template&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;format(tool_prompt&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;tool_prompt)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;-instruction-prompt&#34;&gt;📖 Instruction Prompt
&lt;/h3&gt;&lt;p&gt;The instruction prompt is how we guide the LLM. It&amp;rsquo;s inserted as the first part of the reasoning trace so the LLM sees these instructions on every call. It has four parts:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Instruction&lt;/strong&gt; - The overall task description&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tools&lt;/strong&gt; - The list of tools that are available to the LLM. This is how the LLM knows what actions it can take. Each tool description is effectively a function signature along with descriptions of what the tool does and its input parameters. These descriptions inform the LLM which tool it should use for any given task.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Examples&lt;/strong&gt; - These are few-shot examples that provide more detail for how we want the generated output to be structured&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rules&lt;/strong&gt; - More specific directions on how it should process its input&lt;/li&gt;
&lt;/ol&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# INSTRUCTION
Use the following thinking trace pattern and tools to solve the problem 
in a number of steps. 
Use the ReAct pattern of thinking, acting, and observing.

# TOOLS
wikipedia_summary(query: str, sentences: int = 10) -&amp;gt; str
    Searches Wikipedia for a given query and returns a summary. Returns up to 10 sentences max.
    parameter query: the search term or question for Wikipedia.
    parameter sentences: the number of sentences to try and retrieve for the summary.
    returns: a string containing the summary of the Wikipedia page, or an error message 
    if the page is not found or an error occurs.
    example: wikipedia_summary(&amp;#34;United States president&amp;#34;, 5)

add_numbers(x: int, y: int) -&amp;gt; int
    Adds two numbers.
    parameter x: the first number to add.
    parameter y: the second number to add.
    returns: the sum of the two numbers.
    example: add_numbers(4, 7)

... more tools ...

# EXAMPLE REASONING TRACE
Query: What is 10 * 3 + 10?

Thought1: First, I need to multiply 10 by 3.
Action1: multiply_numbers(10, 3)
Observation1: 30

# RULES
1. One action per turn. Do not make multiple tool calls or skip steps. 
Each response should only contain a single Thought, Action, or Answer.
2. Think out loud and feel free to be expressive and explain your thought 
process in each Thought.
3. Denote the iteration of each step (as-in Thought1, Action1)
4. When you have the final answer, and ONLY then, use the format:
Answer: [your final answer]

... more rules ...
&amp;#34;&amp;#34;&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;-the-query-entrypoint&#34;&gt;🎯 The Query Entrypoint
&lt;/h3&gt;&lt;p&gt;The &lt;code&gt;query&lt;/code&gt; method is the entry point for our agent.&lt;/p&gt;
&lt;p&gt;It is taking the user&amp;rsquo;s query along with the instruction prompt and it constructs the prompt for the very 1st LLM call. This is what kickstarts the loop.&lt;/p&gt;
&lt;p&gt;It also contains our main agent loop, which will stop whenever &lt;code&gt;continue_loop != True&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;query&lt;/span&gt;(self, query: str) &lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt; str:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;trace &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;role&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;user&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;parts&amp;#34;&lt;/span&gt;: [{&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;text&amp;#34;&lt;/span&gt;: self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;instruction_prompt &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;#THINKING TRACE&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;Query: &amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; query &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;}]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    print(&lt;span style=&#34;color:#e6db74&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;TextColor&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;QUERY&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;Query: &lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;query&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;TextColor&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;RESET&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;while&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;True&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        result, continue_loop &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;iterate()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        print(&lt;span style=&#34;color:#e6db74&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;result&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;not&lt;/span&gt; continue_loop:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;break&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;message_history()
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;-reasoning-and-acting&#34;&gt;🧠 Reasoning and Acting
&lt;/h3&gt;&lt;p&gt;&lt;code&gt;reason&lt;/code&gt; and &lt;code&gt;act&lt;/code&gt; are doing most of the heavy lifting for our agent.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;reason&lt;/code&gt; is what actually calls our LLM. It simply makes a call to Gemini by sending in the reasoning trace as the prompt. Note that on the very first turn, the prompt will just be the prompt instructions + the user&amp;rsquo;s query. On every subsequent turn, each new thought + action + observation will be appended so the LLM will see all dialogue, tool calls, and observation outputs from previous turns.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;act&lt;/code&gt; method does the following:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Extracts the tool call from the text generated by the &lt;code&gt;reason&lt;/code&gt; method&lt;/li&gt;
&lt;li&gt;Validates that this tool actually exists&lt;/li&gt;
&lt;li&gt;It calls the tool&lt;/li&gt;
&lt;li&gt;Then it takes the tool output and appends it to the reasoning trace starting with the keyword &lt;code&gt;Observation&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;reason&lt;/span&gt;(self) &lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt; str:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;try&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        response &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;client&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;models&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;generate_content(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            contents&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;trace, 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            model&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;gemini-2.5-flash-preview-05-20&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        )
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;trace&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;append({
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;role&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;model&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;parts&amp;#34;&lt;/span&gt;: [{&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;text&amp;#34;&lt;/span&gt;: response&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;text}]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        })
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; response&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;text
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;except&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Exception&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; e:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Error calling Gemini API: &lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;str(e)&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;act&lt;/span&gt;(self, function_call: str) &lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt; str:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    function_name &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; function_call&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;split(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;(&amp;#39;&lt;/span&gt;)[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;]&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;strip()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; function_name &lt;span style=&#34;color:#f92672&#34;&gt;not&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; [func&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;__name__ &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; func &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;tools]:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;Error: Function &amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;function_name&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39; is not in the list of available tools&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;try&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        result &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; eval(&lt;span style=&#34;color:#e6db74&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;function_call&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        observation &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Observation&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;iteration&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;: &lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;result&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;except&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Exception&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; e:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        observation &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;Error: Cannot execute function &lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;function_call&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;: &lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;str(e)&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;trace&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;append({
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;role&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;user&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;parts&amp;#34;&lt;/span&gt;: [{&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;text&amp;#34;&lt;/span&gt;: observation}]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    })
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; observation
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;-iteration-control-flow&#34;&gt;⚙️ Iteration Control-flow
&lt;/h3&gt;&lt;p&gt;&lt;code&gt;iterate&lt;/code&gt; is where the ✨magic✨ happens! Remember our definition of an agent?  &lt;strong&gt;An application that uses AI-decision making to influence the application&amp;rsquo;s control-flow.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;instruction_prompt&lt;/code&gt; tells the LLM to output specific keywords for each turn - either &lt;code&gt;Action&lt;/code&gt; or &lt;code&gt;Answer&lt;/code&gt;. These are the only two paths that the LLM is instructed to take. &lt;code&gt;iterate&lt;/code&gt; extracts those exact strings, which then dictate which specific &lt;code&gt;if-then&lt;/code&gt; branch is executed.&lt;/p&gt;
&lt;p&gt;While seemingly magical from the outside, agents boil down to this exact pattern:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;An LLM generates strings with specific keywords&lt;/li&gt;
&lt;li&gt;Code looks for those exact keywords in the string&lt;/li&gt;
&lt;li&gt;Then the code takes different paths within its logic based on those keywords&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;iterate&lt;/span&gt;(self) &lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt; tuple[str, bool]:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;iteration &lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;=&lt;/span&gt; self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;ttl:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;TextColor&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;TERMINATE&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;Terminate: Reached maximum number of iterations&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;TextColor&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;RESET&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#66d9ef&#34;&gt;False&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    reasoning &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;reason()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;not&lt;/span&gt; reasoning:  
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Error: No response from model&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#66d9ef&#34;&gt;False&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;elif&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Answer&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; reasoning:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;TextColor&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;ANSWER&lt;span style=&#34;color:#e6db74&#34;&gt;}{&lt;/span&gt;reasoning&lt;span style=&#34;color:#e6db74&#34;&gt;}{&lt;/span&gt;TextColor&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;RESET&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#66d9ef&#34;&gt;False&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;elif&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Action&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; reasoning:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;iteration &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        action_line &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [line&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;strip() &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; line &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; reasoning&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;split(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;&lt;/span&gt;) &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; line&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;startswith(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Action&amp;#34;&lt;/span&gt;)][&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        function_call &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; action_line&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;split(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;:&amp;#34;&lt;/span&gt;)[&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;]&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;strip()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        observation &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;act(function_call)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;TextColor&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;MODEL&lt;span style=&#34;color:#e6db74&#34;&gt;}{&lt;/span&gt;reasoning&lt;span style=&#34;color:#e6db74&#34;&gt;}{&lt;/span&gt;TextColor&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;RESET&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;TextColor&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;OBSERVATION&lt;span style=&#34;color:#e6db74&#34;&gt;}{&lt;/span&gt;observation&lt;span style=&#34;color:#e6db74&#34;&gt;}{&lt;/span&gt;TextColor&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;RESET&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#66d9ef&#34;&gt;True&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Error: Answer or Action not found in model response&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#66d9ef&#34;&gt;True&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;-our-agent-in-action&#34;&gt;🎬 Our Agent in Action
&lt;/h2&gt;&lt;p&gt;You can run this agent yourself by running &lt;code&gt;agent.py&lt;/code&gt; from the &lt;a class=&#34;link&#34; href=&#34;https://github.com/mark-church/tiny-react&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Tiny ReAct GitHub repo&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;python3 agent.py &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;What is the current tempurature (in fahrenheit) in the city that won the superbowl in 1995?&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In this case I gave our agent this set of tools:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;add_numbers(x: int, y: int)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;subtract_numbers(x: int, y: int)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;multiply_numbers(x: int, y: int)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;divide_numbers(x: float, y: float)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;get_temperature(latitude: float, longitude: float)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;search_wikipedia_page(query: str)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;wikipedia_coordinates(page_title: str)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;wikipedia_summary(query: str, sentences: int = 10)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I&amp;rsquo;ve defined a pretty granular set of tools, mostly so I can test the model&amp;rsquo;s ability to use various tools together. In practice I might want to have more broadly-scoped tools, but tool granularity is a topic for another post &amp;hellip;&lt;/p&gt;
&lt;p&gt;Below is the full reasoning trace from asking our agent: &lt;code&gt;What is the current tempurature (in fahrenheit) in the city that won the superbowl in 1995?&lt;/code&gt;. We can see that it takes six turns before it finds the answer. It breaks down the problem into individual steps using different tool calls to provide the information it needs. Then it gets the right answer - when I ran this it was indeed 50°F in San Francisco (and the 49ers won the Super Bowl in 1995)!&lt;/p&gt;
&lt;div class=&#34;highlight wrap&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-markdown&#34; data-lang=&#34;markdown&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Query: What is the current tempurature (in fahrenheit) in the 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;city that won the superbowl in 1995?
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Thought1: The first step is to identify which city won the Super Bowl in 1995. I will use Wikipedia to search for &amp;#34;Super Bowl 1995 winner&amp;#34; to get this information. This will help me narrow down the location for which I need to find the temperature.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Action1: wikipedia_summary(&amp;#34;Super Bowl 1995 winner&amp;#34;, 2)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Observation1: Wikipedia page for &amp;#39;Super Bowl 1995 winner&amp;#39; not found.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Thought2: My previous search for &amp;#34;Super Bowl 1995 winner&amp;#34; failed, indicating that the specific phrasing might not match a Wikipedia page title. I need to find the winner of the 1995 Super Bowl, which is officially Super Bowl XXIX. I will try searching for &amp;#34;Super Bowl XXIX&amp;#34; to find the relevant information about the winning team and, consequently, their city.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Action2: wikipedia_summary(&amp;#34;Super Bowl XXIX&amp;#34;, 2)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Observation2: Super Bowl XXIX was an American football game between the American Football Conference (AFC) champion San Diego Chargers and the National Football Conference (NFC) champion San Francisco 49ers to decide the National Football League (NFL) champion for the 1994 season. The 49ers defeated the Chargers by a score of 49–26, the most points ever earned in a Super Bowl game, becoming the first team to win five Super Bowl championships.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Thought3: I have successfully identified the winning team of Super Bowl XXIX as the San Francisco 49ers. Now, I need to find the current temperature in San Francisco. To do this, I first need to get the geographical coordinates (latitude and longitude) of San Francisco. I will use the &lt;span style=&#34;color:#e6db74&#34;&gt;`wikipedia_coordinates`&lt;/span&gt; tool with &amp;#34;San Francisco&amp;#34; as the page title to obtain these coordinates.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Action3: wikipedia_coordinates(&amp;#34;San Francisco&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Observation3: (Decimal(&amp;#39;37.78333332999999782941813464276492595672607421875&amp;#39;), Decimal(&amp;#39;-122.4166666699999979073254507966339588165283203125&amp;#39;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Thought4: I have successfully retrieved the coordinates for San Francisco: latitude 37.78333333 and longitude -122.41666667. Now that I have the coordinates, I can use the &lt;span style=&#34;color:#e6db74&#34;&gt;`get_temperature`&lt;/span&gt; tool to find the current temperature in San Francisco. The question asks for the temperature in Fahrenheit, but the tool provides the temperature without a unit, so I will assume it&amp;#39;s in the standard unit for the tool, which is usually Celsius or Fahrenheit depending on the backend. I will provide the coordinates to the tool.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Action4: get_temperature(37.78333333, -122.41666667)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Observation4: The temperature at 37.78333333, -122.41666667 is 10.290999412536621°C
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Thought5: I have obtained the temperature in Celsius, which is 10.290999412536621°C. The original query asked for the temperature in Fahrenheit. Therefore, I need to convert this Celsius temperature to Fahrenheit using the formula F = C * 9/5 + 32. I will first multiply 10.290999412536621 by 9/5 and then add 32 to the result.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Action5: multiply_numbers(10.290999412536621, 1.8)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Observation5: 18.523798942565918
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Thought6: I have calculated the first part of the Fahrenheit conversion, which is 10.290999412536621 * 1.8 = 18.523798942565918. The final step in converting Celsius to Fahrenheit is to add 32 to this value. I will now use the &lt;span style=&#34;color:#e6db74&#34;&gt;`add_numbers`&lt;/span&gt; tool to complete this calculation and get the final temperature in Fahrenheit.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Action6: add_numbers(18.523798942565918, 32)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Observation6: 50.52379894256592
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Answer: The current temperature in the city that won the Super Bowl 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;in 1995 is approximately 50.52 degrees Fahrenheit.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;To summarize the steps:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;1.&lt;/span&gt; Identified that the San Francisco 49ers won Super Bowl XXIX (1995).
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;2.&lt;/span&gt; Obtained the geographical coordinates for San Francisco.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;3.&lt;/span&gt; Retrieved the temperature for San Francisco in Celsius.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;4.&lt;/span&gt; Converted the temperature from Celsius to Fahrenheit.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;-observations&#34;&gt;👀 Observations
&lt;/h2&gt;&lt;p&gt;That is ReAct in a nutshell! While building Tiny ReAct, I also came away with some interesting observations &amp;hellip;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Ability to handle failures&lt;/strong&gt;: I was most impressed by Gemini&amp;rsquo;s ability to handle failures. In it&amp;rsquo;s first turn it executed &lt;code&gt;wikipedia_summary(&amp;quot;Super Bowl 1995 winner&amp;quot;, 2)&lt;/code&gt;, but the response didn&amp;rsquo;t include the winner. On the second turn it generated a more generic query in its action with &lt;code&gt;wikipedia_summary(&amp;quot;Super Bowl XXIX&amp;quot;, 2)&lt;/code&gt;. It changed its course of action based on a failure to get the right information in the first turn. This demonstrates the kind of flexibility that code alone could never provide.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Simplicity of a prompt&lt;/strong&gt;: The initial prompt instruction guides everything. Simple, clear, and concrete language goes a very long way. Just imagine that you are writing the instructions for a friend that you&amp;rsquo;re not allowed to communicate with. Would your prompt be clear enough for them to complete the task in exactly the structure and format you want it in? Your friends are not mind readers and neither are LLMs.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Emergent intelligence&lt;/strong&gt;: The agent demonstrates how complex multi-step reasoning can emerge from simple tool calls. What looks like sophisticated problem-solving is actually just the LLM making sequential decisions about which tool to call next. The beauty is that each tool is simple and focused, but when orchestrated together through the agent&amp;rsquo;s reasoning, they can solve complex problems that require multiple steps and domain knowledge.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Overall I learned a lot by building Tiny ReAct. I hope that you learned something too!&lt;/p&gt;
&lt;p&gt;Happy hacking 🚀&lt;/p&gt;
</description>
        </item>
        
    </channel>
</rss>
