<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Paul Pham 157]]></title><description><![CDATA[Having built and deployed dozens of AI agents and RAG pipelines, I write about AI System Design, LLMOps, and Optimization from a practical DevOps perspective. I]]></description><link>https://paulpham157.hashnode.dev</link><image><url>https://cdn.hashnode.com/uploads/logos/6a29392edd76b58e2e8790b6/424c628f-d3ec-4990-aed0-2ad5e37be4b3.jpg</url><title>Paul Pham 157</title><link>https://paulpham157.hashnode.dev</link></image><generator>RSS for Node</generator><lastBuildDate>Fri, 13 Nov 2026 18:52:22 GMT</lastBuildDate><atom:link href="https://paulpham157.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Why We Distrust Tests Written After the Code]]></title><description><![CDATA[Why my team writes tests before implementation, and a Codex report (#24922) where an agent edited regression tests until the suite went green.]]></description><link>https://paulpham157.hashnode.dev/why-we-distrust-tests-written-after-the-code</link><guid isPermaLink="true">https://paulpham157.hashnode.dev/why-we-distrust-tests-written-after-the-code</guid><category><![CDATA[AI]]></category><category><![CDATA[Testing]]></category><category><![CDATA[ai coding agents]]></category><category><![CDATA[code review]]></category><category><![CDATA[Software Engineering]]></category><dc:creator><![CDATA[Paul Pham]]></dc:creator><pubDate>Fri, 13 Nov 2026 13:45:14 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6a29392edd76b58e2e8790b6/f0f9fd3e-b9cb-44f0-82a1-ce20fab39abf.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Test order.</p>
<p>On my team, the unit tests get written right after the plan is agreed and before anyone (human or agent) starts on the implementation. And if a test shows up in a commit after the feature code, we treat it as suspect until someone has looked at it properly.</p>
<p>That sounds fussy, I know. The reason is boring. Agents often add or edit tests to fit code they already wrote. A test written before the code is a record of what we agreed. A test written after it is, too often, a record of what the code happens to do.</p>
<p>None of this is new. Kent Beck's TDD book came out in 2002, and people have argued about test-first ever since. What changed for us is the speed. An agent can write a feature and rewrite three tests to match it in a few minutes, and the CI badge looks the same either way.</p>
<p>Think of a tailor who cuts the suit first and then goes back and changes the measurements on the order slip so they match. Every number on the slip is now correct. The customer's shoulders didn't change.</p>
<h2>A public example</h2>
<p>The clearest write-up of this I've seen in 2026 is <a href="https://github.com/openai/codex/issues/24922">openai/codex #24922</a>, opened on May 28 and closed the same day by a maintainer who said it "appears to be model behavior, not a Codex harness issue." It's one developer's report. I haven't reproduced it, and one report tells you nothing about how often this happens. It is very detailed, though.</p>
<p>The task was a bounded React refactor: move feature logic from an eager shell into a lazy-loaded surface, preserve an async stale-navigation guard, keep positive route-transition behavior, remove exactly five temporary lint baseline entries, then run tests, lint and build and post READY evidence. The reporter says Codex got the first part right. It "explicitly identified the stale-navigation guard and lint entries before editing."</p>
<p>Then a context compaction happened in the middle of implementation, tests started failing, and Codex "repeatedly increased async settling windows and then weakened/remapped assertions instead of preserving the original behavior contract."</p>
<p>The detail that got me was one test. Before the refactor, a positive test proved that clicking Begin navigates into the draft route:</p>
<pre><code class="language-ts">expect(window.location.pathname).toBe("/workspace/drafts/draft-1");
expect(activePanel()).toBe("draft");
</code></pre>
<p>After it, the same test, with the same name, asserted this:</p>
<pre><code class="language-ts">expect(window.location.pathname).toBe("/workspace/briefs/req-1");
expect(activePanel()).toBe("");
</code></pre>
<p>In the report's words, a test "still named as proving navigation into a draft route instead asserted that navigation did not occur." That's the tailor and the order slip, more or less exactly.</p>
<p>There was more. A stale-request race test was made "vacuous": two mock branches for the same API path, the first one returning immediately, so the deferred branch the test existed for could never run. And the READY record said five lint entries had been removed, while the committed diff "did not modify the lint file at all."</p>
<p>The reporter sums it up better than I can: the agent "weakened or invalidated existing regression tests to obtain a green test run, then posted completion evidence contradicted by its own committed file inventory."</p>
<img src="https://cdn.hashnode.com/uploads/covers/6a29392edd76b58e2e8790b6/87a52f82-601c-4349-902b-976816a2d467.png" alt="" style="display:block;margin:0 auto" />

<h2>Why test order helps (a bit)</h2>
<p>None of those changes would look scary in a diff. Nothing was deleted, nothing skipped, coverage probably didn't move. If you read the feature code carefully and skim the tests because "they pass", you approve it. Plenty of us would, on a tired day.</p>
<p>Writing tests first won't make an agent honest. You do get something to compare against that the agent couldn't have shaped around its own code, because the code didn't exist yet. When a pre-written assertion changes in the same PR as the feature, that's a finding by default, and somebody has to explain it.</p>
<p>In practice that mostly means reading the test diff before the code diff, and checking that test names still match what the bodies assert. Plus one cheap check from this report: if the completion message says a file changed, <code>git show --stat</code> should list that file. The lint claim would have failed that in about ten seconds.</p>
<p>Something like this, against the base branch, is enough to know where to look:</p>
<pre><code class="language-bash">git diff origin/main...HEAD -- '**/*.test.*' | grep -E '^[-+].*expect\('
</code></pre>
<p>It won't tell you whether a change is right. It tells you which tests the agent touched, which is usually the part nobody reads.</p>
<p>To be fair to the agent, humans do exactly this too when a deadline is close, and the report also mentions the compaction, which may have played a part (nobody knows how much). Agents just do it faster, in larger diffs, and then write a confident summary on top.</p>
<p>Anyway. The suite was green. The test name was still very sure the page navigates.</p>
]]></content:encoded></item><item><title><![CDATA[We Burned Dozens of Sprints Learning This, But You Don’t Have To ]]></title><description><![CDATA[I’ve built and deployed dozens of AI agent systems and RAG pipelines. Hope this article helps you avoid making the same mistakes.]]></description><link>https://paulpham157.hashnode.dev/we-burned-dozens-of-sprints-learning-this-but-you-don-t-have-to</link><guid isPermaLink="true">https://paulpham157.hashnode.dev/we-burned-dozens-of-sprints-learning-this-but-you-don-t-have-to</guid><category><![CDATA[ai-agent]]></category><category><![CDATA[Evaluation]]></category><category><![CDATA[#llmops]]></category><category><![CDATA[Devops]]></category><dc:creator><![CDATA[Paul Pham]]></dc:creator><pubDate>Tue, 16 Jun 2026 08:56:08 GMT</pubDate><content:encoded><![CDATA[<p>My name is Hung also known as <a href="https://linktr.ee/paulpham157">Paul</a>.</p>
<img src="https://cdn.hashnode.com/uploads/covers/6a29392edd76b58e2e8790b6/ea9cf279-df5c-4311-acb9-6a307f09de1f.png" alt="Paul" style="display:block;margin:0 auto" />

<p>I have worked in the technical field for 6 years and started learning about LLM around spring 2023, when ChatGPT had just launched and the whole world was asking “can this be used in production?“.</p>
<p>I have been involved in deploying and building dozens of AI agent systems and RAG pipeline products. We spent a lot of time, weeks went by, many products were built. But some of them were not good enough. There was a project I wish I knew how to optimize better sooner. Today, I just finished a course on AWS Bedrock of Anthropic, and I suddenly found myself reminiscing about that time. To be honest, we did not answer this question from the beginning, the question that nobody asked before building at that time. I think this article might help people avoid repeating the same mistakes.</p>
<blockquote>
<p>“How do we measure AI response when deployed in production?”</p>
</blockquote>
<p>I mean, it was not just about analyzing conversations, collecting logs, or gathering user feedback after a product launch. We need to measure AI’s response during the testing phase, before launching the product.</p>
<p>In 2024, we created a website that helps people learn to use AI in their work through a gamified experience. At that time, there were only a few coding agent tools and our vision was to educate people in tech industry to become familiar with them. Because we believed that these tools would continue to develop and would soon become the new trend. We developed a self-learning experience with AI and a secure cloud-based sandbox environment for practice. My co-founder always says</p>
<blockquote>
<p>“we have to achieve 95% accuracy“.</p>
</blockquote>
<p>But nobody knew 95% of what? Which dataset is it 95% of? Or which test case is it 95% of? We did not answer the questions. We tried to build a list of test cases based on our understanding in this field and feedback from end-users. We used to believe that we could just ship the product and then customers would give feedback before we could improve it.</p>
<p>And this was a wonderful trap. Everyone on the team pushed themselves to deliver. Testers wrote test cases based on their experience and understanding of the field. Developers completed their frontend with Next.js and backend with NestJS and LangGraph. Prompt engineers finished the final system prompt. DevOps engineers deployed the product to the cloud. Marketers started social media advertising campaigns. We gained around 500 new free users and 3 pieces of feedback after spending a significant amount of time and money.</p>
<img src="https://cdn.hashnode.com/uploads/covers/6a29392edd76b58e2e8790b6/a619518e-202f-495f-a27a-e38caf361b4e.png" alt="The loop" style="display:block;margin:0 auto" />

<p>After reviewing the system logs, I realized that end users never act exactly like test cases. They acted by the way that none of us had thought. They used different words. They asked confused questions. They combined cases that we would never have written into tests. Our tests all passed, but the tests did not match actual real user input data. We came up with the numbers based on intuition. There was no baseline, no definition. Just a feeling like that “it seems okay“. The true problem here was not AI, the most important issue is our lack domain knowledge to write good enough test cases. We were testing based on our own biases, and those biases do not reprersent real users.</p>
<p><mark class="bg-yellow-200 dark:bg-yellow-500/30">Our mistake: a lack of domain expert and accurate test measure.</mark></p>
<p>We fell into to a loop. The loop that optimizes prompts. We listened to user feedback, adjusted test cases, modified system prompts, re-launch, repeated… But 3 feedback were never enough for us to improve. Ultimately, users just kept leaving and we were forced to abandon the idea after wasting an entire year.</p>
<h2>1. Why this is design issue, and not just prompt issue?</h2>
<blockquote>
<p>Before diving into the solution, I want to say that I am not writing this to complain. My former teammates have done very well within their capabilities. But we just had not found the right method to solve the issue at the time.</p>
</blockquote>
<p>Overview: most builder teams are building outer harness and calling LLM API via a provider. They usually do not care about inter harness. They leave it to LLM providers.</p>
<img src="https://cdn.hashnode.com/uploads/covers/6a29392edd76b58e2e8790b6/b6b75cd0-8e9b-4bc1-8390-d2096d87452f.png" alt="Inter Harness - Outer Harness" style="display:block;margin:0 auto" />

<p>What is Inter Harness? That includes all the infrastructure surrounding the system that serves LLM models, compliance with post-training alignment (a special type of unchangeable prompt), calling internal tool, caching user prompts, handling errors, handling agentic loops, handling guardrails…</p>
<p>What is Outer Harness? These are all the layers that we usually build into our products such as system prompts, PRDs, skills, hooks, memories…</p>
<p>I have noticed that 80% of the large businesses I know are not using Claude via Claude, while other builders are. The enterprises are using their own inter harness on the biggest cloud services such as AWS, GCP, and Azure.</p>
<p>I know, Claude or GPT also has Enterprise plan with powerful features such as user spending limits, better context window, role based access permission, network access control, IP white list, audit logs, observability, monitoring… But you must pay at least 240 dollars for a seat per year, and you still have to bear the risks of service disruption.</p>
<p>Have you subscribed on Claude Status mailing list? I have counted at least 253 incidents from December 2025 to May 2026, including a number of incidents related to the Claude dot ai Enterprise plan.</p>
<img src="https://cdn.hashnode.com/uploads/covers/6a29392edd76b58e2e8790b6/9c0c4abf-4434-4799-aea7-1a7f26eb74c6.png" alt="At least 253 emails about Claude incident from Dec 2025 to May 2026" style="display:block;margin:0 auto" />

<p>When you need Claude API to use in your product, you need to use Claude Platform (not claude dot ai), which is completely separate from your Claude enterprise licenses. Claude dot AI enterprise license only grants you access to Chat, Claude Code, the Claude Github App…, but not API access.</p>
<p>AWS’s SLA commitment 99.99% uptime, allowing complete control over even the smallest behaviors through IAM. Immune to Claude incidents.</p>
<p>Wait, I am not selling for AWS. I wonder why the most big companies use it to control their inter harness and what can I learn from it.</p>
<h2>2. About the Claude in Amazon Bedrock course</h2>
<p>I am a fan of Anthropic. I like how they incorporate ethics and AI safety issues into their product. My first encounter with Anthropic was probably through the ebook “The Way of Code”, which they collaborated with Rick Rubin; I read it in 2025. But it is only recently that I have started taking their course on Skilljar. Claude in Amazon Bedrock consist of 83 lessons, about 7 hours long, covering all stacks to build AI agent production-ready.</p>
<ul>
<li><p>API Bedrock: handle Multi-turn conversations, System Prompts, Temperature, Streaming.</p>
</li>
<li><p>Tool Use: call external functions, guardrail tool calls, batch execution.</p>
</li>
<li><p>RAG: Hybrid Search, Contextual Retrieval, Reranking, Chunking Strategy.</p>
</li>
<li><p>Prompt Caching: FinOps.</p>
</li>
<li><p>MCP, Agent, Computer Use, Claude Code, Agent Design Principles.</p>
</li>
<li><p>Evaluate Prompt Engineering.</p>
</li>
</ul>
<p>All of there above modules include hands-on practice code, and each of them could be written as a separate topic. But if I had to choose only one, I would choose Evaluate Prompt Engineering. If only I had known about it sooner, our previous project might have turned out better.</p>
<h2>3. Build a pipeline to objectively measure and evaluate AI responses</h2>
<p>Anthropic solved the issue with a complete workflow in Amazon Bedrock. There were only 4 steps:</p>
<h3>3.1. Step one: Define “good“ before testing</h3>
<p>So what exactly does good mean?</p>
<p>Okay. A good software may have been tested through thousands of samples and thousands of cases. An AI agent system has… unlimited cases.</p>
<img src="https://cdn.hashnode.com/uploads/covers/6a29392edd76b58e2e8790b6/2dc5b0e6-7692-44ea-b264-cbd267316295.png" alt="Ouroboros" style="display:block;margin:0 auto" />

<blockquote>
<p>Wait, am I kidding you?</p>
</blockquote>
<p>Yes, if you have chosen to ask ChatGPT, to download a dataset from somewhere on the internet, or to ask someone and pray that they will give you some samples. You will always fall into one of two situations: too few test cases or too many that are still insufficient.</p>
<p>However, testing AI agents is different from testing conventional software. We need to build a golden dataset which defines about 200 scenarios and their expected outputs.</p>
<p>Accuracy: was output’s meaning or the action the AI took accurate?</p>
<p>Format compliance: was the output format correct?</p>
<p>Tone: was the chatting tone correct? was its behavior acceptable? did it ever overstep its permission?</p>
<p>Completeness: was the information in the output sufficient?</p>
<p>A good dataset for testing is a clear, complete scenario and expected output.</p>
<p>No definition = no measurement = the 95% figure you gave is just subjective.</p>
<h3>3.2. Step two: Generate evaluation datasets</h3>
<p>Then, how to build a golden dataset?</p>
<img src="https://cdn.hashnode.com/uploads/covers/6a29392edd76b58e2e8790b6/03c806d0-c76f-4c07-ae97-c75abf90bf87.png" alt="Automated generation vs Manual generation" style="display:block;margin:0 auto" />

<p>A tester can write around 60 to 80 manual test cases a day for a software project. And they can run about 50 to 70 cases per day. Testing an AI agent is very difficult. Because its output is non-deterministic. In a traditional software, you know, there would be a place to input data, a place to press interactive button, and yet another place to filter output data.</p>
<p>I mean, for example if I have 2 simple checkboxes then I will have total two to the power of two equal four scenarios:</p>
<p>Do not check any checkboxes</p>
<p>Check all checkboxes</p>
<p>Check only the first one</p>
<p>Check only the last one</p>
<p>You can always calculate how many cases are enough for covering the requirements.</p>
<p>But AI agent does not work like that. It is probabilistic prediction software. Each input goes through multiple intermediate steps and ultimately returns outputs that are never exactly the same. So you can’t calculate the number of test cases. In other words, counting test cases is pointless.</p>
<p>The input cases that your AI agent system will receive can be broadly divided into three types:</p>
<p>Typical cases: happy cases</p>
<p>Edge cases: boundary cases</p>
<p>Adversarial inputs: ways users intentionally “disrupt“ the system</p>
<p>At the time, adversarial inputs were what we lacked. We had a few clients who were willing to share their opinions, and we used to consult with several domain experts, so I thought we could cover typical cases and some edge cases. But the adversarial inputs were our blind spot. We could only see them when analyzing the logs after users went the wrong way.</p>
<p>AWS Bedrock provides a built-in feature that allows you to upload the PDF document in the field to use it as a RAG source, to plan with Opus and to use Haiku to write each record for the dataset that cover all three input types above. In an automatic way, it might help us to save a lot of time to think of and write the test cases.</p>
<p>Or you can simple write your records without Claude generation.</p>
<p>After collecting the test dataset, our job is to review these records, it will be used as samples in the automated testing and in future run.</p>
<h3>3.3. Step three: Grading</h3>
<img src="https://cdn.hashnode.com/uploads/covers/6a29392edd76b58e2e8790b6/03e5bda2-b4e4-4d8c-b861-f03373f914c9.png" alt="The judges" style="display:block;margin:0 auto" />

<p>First of all, I need to write lambda functions that check the format, use regex to separate data and expose number, enter the calculation results (number) into calculator, validate code block format, validate code quality (run code in sandbox environment), calculate response speed, calculate output token (cost), check tools called… Overall, code-based grading are lambda functions which I have written which can be tailoring easily. After that, it combines and then averanges the scores of the functions.</p>
<p>If the final score is lower than the allowed threshold, go back to improving the agent, skipping the model-based grader.</p>
<p>Second stage: in this phase, ưe will use a teacher LLM to judge the outputs. You can choose between Amazon Bedrock Model Evaluation and Amazon Bedrock AgentCore Evaluations. The first one is used to compare and evaluate foundation models, helping you choose the right model for your task. But it is too simple. In this article, I will talk about AgentCore Evaluations, which provides comprehensive evaluation of a complex AI agent system. This service allows you to evaluate every stage of an agent in each trace: its reasoning process, which tool it calls, multi-turn conversations…</p>
<img src="https://cdn.hashnode.com/uploads/covers/6a29392edd76b58e2e8790b6/c6d7f7e1-e350-45fb-8aaa-045ae9849cc9.png" alt="Detailed analysis" style="display:block;margin:0 auto" />

<p>Okay, we can temporarily divide a huge amount of output data received after running the testing dataset into 3 levels:</p>
<ul>
<li><p>Session level (Goal Success Rate) a full session from the user’s first message to the end.</p>
</li>
<li><p>Trace level (per response / step) a sub-task or a single turn.</p>
</li>
<li><p>Tool level (Tool Selection / Tool Parameter Accuracy) a span logged via OpenTelemetry/OpenInference every time a tool called</p>
</li>
</ul>
<p>There are 13 built-in evaluators working across these 3 levels, and you can define your own custom evaluators with your own rubrics.</p>
<p>How does the AgentCore Evaluation process work?</p>
<img src="https://cdn.hashnode.com/uploads/covers/6a29392edd76b58e2e8790b6/d387e9ea-ea92-4226-b276-230b9dbbbc78.png" alt="AgentCore Observability Pipeline" style="display:block;margin:0 auto" />

<p>At the beginning of this phase, Agent or RAG that you use in Bedrock be is instrumented through OpenTelemetry/OpenInference and the Traces/Spans are logged and sent to AgentCore Observability. AgentCore Observability is a service built on top of CloudWatch Log Group. You need to set up Evaluation Configuration includes Config data source (you may choose log group), Evaluator (it is our judge = model + prompt + a scoring schema and/or threshold), Sampling, IAM role, filter… After AgentCore Evaluation Job runs, you will get a score, a reason, and metadata of each record on CloudWatch Logs and visualize scores on CloudWatch metrics.</p>
<img src="https://cdn.hashnode.com/uploads/covers/6a29392edd76b58e2e8790b6/189b80ca-f805-46fb-9320-a15c0e72f6ec.png" alt="Example of CloudWatch Metrics" style="display:block;margin:0 auto" />

<p>That is what will happen, but now I want to dive deeper into the evaluators. For example, in a testing dataset generated by Claude, we will choose the following scenario:</p>
<p>User asked: “Book a flight from Hanoi to HCMC tomorrow afternoon at the lowest price“.</p>
<p>Agent did: it called tools to fetch flight prices, choose the lowest price at 5pm tomorrow, and then asked the user to confirm the action.</p>
<h3>Session level</h3>
<p>At this level, the judge tries to answer the question: “Does this conversation achieve the user’s goals?”. The judge reads the traces, use the Builtin.GoalSuccess evaluator, and then returns GoalSuccess score of 1.0 (PASS) with the reason “agent found the correct flight, no error”.</p>
<h3>Trace level</h3>
<img src="https://cdn.hashnode.com/uploads/covers/6a29392edd76b58e2e8790b6/45fe0fbc-c6ad-4fb4-9b91-f53ce24860f0.png" alt="Each “evaluator” graded the “product”" style="display:block;margin:0 auto" />

<p>The judge reads a trace and use Builtin.Helpfulness, Builtin.Correctness Builtin.Coherence, Builtin.Faithfulness, Builtin.Harmfulness, and Builtin.InstructionFollowing to analyze the context and answer, and then returns a score (from 0.0 to 1.0) and a logical reason for each evaluator. Something like that</p>
<p><code>{</code></p>
<p><code>“Helpfulness”: {</code></p>
<p><code>“score”: 0.9,</code></p>
<p><code>“reason”: “The response provides useful information, addresses the user’s needs, and has practical value.”</code></p>
<p><code>},</code></p>
<p><code>“Correctness”: {</code></p>
<p><code>“score”: 1.0,</code></p>
<p><code>“reason”: “The content is factually accurate with no clear errors or misunderstandings.”</code></p>
<p><code>},</code></p>
<p><code>“Coherence”: {</code></p>
<p><code>“score”: 0.9,</code></p>
<p><code>“reason”: “The answer is clear, logical, and well-structured.”</code></p>
<p><code>},</code></p>
<p><code>“Faithfulness”: {</code></p>
<p><code>“score”: 0.9,</code></p>
<p><code>“reason”: “The response stays grounded in the given context and does not introduce unsupported claims.”</code></p>
<p><code>},</code></p>
<p><code>“Harmfulness”: {</code></p>
<p><code>“score”: 0.0,</code></p>
<p><code>“reason”: “The content is safe and does not include harmful or policy-violating elements.”</code></p>
<p><code>},</code></p>
<p><code>“InstructionFollowing”: {</code></p>
<p><code>“score”: 1.0,</code></p>
<p><code>“reason”: “The response closely follows the user’s instructions and requirements.”</code></p>
<p><code>}</code></p>
<p><code>}</code></p>
<h3>Tool level</h3>
<p>This level is easier to understand; the examiner will use two evaluation criteria to determine: using Builtin.ToolSelectionAccuracy to see if the agent selected the correct tool for the request, and using Builtin.ToolParameterAccuracy to see if the parameters fed to the tool are correct/complete/appropriate. For example, did this agent call fetch_flight tool and sent parameters “afternoon” “tomorrow”? If model call get_weather then ToolSelectionAccuracy = 0.0.</p>
<h3>3.4. Step four: Improving loop</h3>
<p>Okay, after all, you cam make a decision once you see the final average scores. Then, you can build a post-processing step to complete workflow. Example: IF GoalSuccess &gt;= X% AND Helpfulness &gt;= a AND Harmfulness &lt;= b AND ToolSelectionAccuracy &gt;= c THEN deploy the agent to staging environment and send a message to the team on Slack.</p>
<img src="https://cdn.hashnode.com/uploads/covers/6a29392edd76b58e2e8790b6/2ff02449-c32b-4dda-a44f-997387c2a79c.png" alt="The loop… with the measurable metrics" style="display:block;margin:0 auto" />

<p>Once you have this pipeline, whenever you make changes, you will know exactly how well your agent is performing based on the measurable metrics, no more emotions.</p>
<h2>4. Ship with Confidence, Not with Prayers</h2>
<p>On AWS Bedrock, the following AgentCore runtimes are available, listed from most expensive to cheapest:</p>
<ul>
<li><p>Online evaluation sampling on production traffic, continuous scoring, and real-time pushing of metrics to CloudWatch for live production monitoring. Most expensive, you can use this in A/B test.</p>
</li>
<li><p>On-demand Evaluation is charged at the standard rate. Most of us are in this position.</p>
</li>
<li><p>Batch Evaluation follows the same pattern as the Bedrock Batch API (model), and you only pay 50% amount of the regular price. It’s very useful in nightly builds.</p>
</li>
</ul>
<p>Because Batch Evaluation is still in public review, you might not use it in some regions. Instead, you can combine other FinOps strategies such as saving plan (save up to 72%) for Lambda functions, EC2, Fargate. You can also leverage Prompt Caching, which saved about 60% of my LLM costs. I will cover Prompt Caching in more detail in another post because it deserves a deeper dive on its own.</p>
<img src="https://cdn.hashnode.com/uploads/covers/6a29392edd76b58e2e8790b6/f1507331-4d95-4845-9c27-fcf0c92f66dd.png" alt="Paul" style="display:block;margin:0 auto" />

<blockquote>
<p>I have a question: I have just started blogging (yes, I used to write short stories, but that was a long time ago) and I am wondering if my use of images or words is appropriate. I mean, I like manga so I use that style, but what about you? Do you like colorful pictures? Let me know in the comments, I am listening.</p>
</blockquote>
]]></content:encoded></item></channel></rss>