<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: shizhe Lim</title>
    <description>The latest articles on DEV Community by shizhe Lim (@shizhe_lim_61b5948cb8081d).</description>
    <link>https://dev.to/shizhe_lim_61b5948cb8081d</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4026882%2F6222e6cb-5003-45c5-bd0f-fbdd9d91c05c.png</url>
      <title>DEV Community: shizhe Lim</title>
      <link>https://dev.to/shizhe_lim_61b5948cb8081d</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/shizhe_lim_61b5948cb8081d"/>
    <language>en</language>
    <item>
      <title>Designing Permission Boundaries for Production AI Agents</title>
      <dc:creator>shizhe Lim</dc:creator>
      <pubDate>Wed, 30 Sep 2026 09:47:27 +0000</pubDate>
      <link>https://dev.to/shizhe_lim_61b5948cb8081d/designing-permission-boundaries-for-production-ai-agents-47mp</link>
      <guid>https://dev.to/shizhe_lim_61b5948cb8081d/designing-permission-boundaries-for-production-ai-agents-47mp</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;AI disclosure: This article was prepared with AI assistance. The author reviewed and edited the technical content and remains responsible for its accuracy.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;AI agent permissions are often treated as a binary decision:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The agent can use a tool&lt;/li&gt;
&lt;li&gt;The agent cannot use a tool&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That may be sufficient for a prototype. It is usually too coarse for a production workflow.&lt;/p&gt;

&lt;p&gt;Reading a customer record, drafting an update, saving a draft, and sending the final message may all involve the same system. However, they do not have the same operational risk.&lt;/p&gt;

&lt;p&gt;A safer design separates capability from authority.&lt;/p&gt;

&lt;h2&gt;
  
  
  A four-layer action model
&lt;/h2&gt;

&lt;p&gt;One practical approach is to classify actions into four layers.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Observe
&lt;/h3&gt;

&lt;p&gt;The agent reads information without changing external state.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Retrieve a document&lt;/li&gt;
&lt;li&gt;Read an API response&lt;/li&gt;
&lt;li&gt;Inspect a repository&lt;/li&gt;
&lt;li&gt;Query a customer record&lt;/li&gt;
&lt;li&gt;Review system status&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Read access should still be scoped. An agent rarely needs access to every record, directory, API field, or historical event.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Prepare
&lt;/h3&gt;

&lt;p&gt;The agent produces an output that has not yet affected another system or person.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Draft an email&lt;/li&gt;
&lt;li&gt;Generate a SQL query&lt;/li&gt;
&lt;li&gt;Propose a code change&lt;/li&gt;
&lt;li&gt;Prepare a support response&lt;/li&gt;
&lt;li&gt;Create an execution plan&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This layer is useful because it separates reasoning from execution. A person or another policy component can inspect the proposed action before anything changes.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Act reversibly
&lt;/h3&gt;

&lt;p&gt;The agent changes state, but the result can be reviewed and undone with limited cost.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a pull request&lt;/li&gt;
&lt;li&gt;Save a message as a draft&lt;/li&gt;
&lt;li&gt;Add an item to a review queue&lt;/li&gt;
&lt;li&gt;Create a temporary resource&lt;/li&gt;
&lt;li&gt;Update a record with version history&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Reversible does not mean risk-free. The system still needs validation, logging, retry controls, and a defined rollback path.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Commit irreversibly
&lt;/h3&gt;

&lt;p&gt;The agent performs an action that is difficult, expensive, or impossible to reverse.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Send an external message&lt;/li&gt;
&lt;li&gt;Merge a pull request&lt;/li&gt;
&lt;li&gt;Delete production data&lt;/li&gt;
&lt;li&gt;Publish public content&lt;/li&gt;
&lt;li&gt;Submit a payment&lt;/li&gt;
&lt;li&gt;Change access permissions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These actions often need the strongest policy checks and, depending on the workflow, explicit human approval.&lt;/p&gt;

&lt;h2&gt;
  
  
  Put a policy check before every tool call
&lt;/h2&gt;

&lt;p&gt;Permission decisions should be based on more than the tool name.&lt;/p&gt;

&lt;p&gt;The same tool may support both low-risk and high-risk actions. For example, an email integration might read a message, save a draft, or send a final response.&lt;/p&gt;

&lt;p&gt;A simplified policy layer might look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;ACTION_LEVELS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;read_record&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;observe&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;draft_message&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;prepare&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;save_draft&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;reversible&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;send_message&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;irreversible&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;authorize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;level&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ACTION_LEVELS&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user_has_access&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;User does not have access&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;input_valid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Input validation failed&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;level&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;irreversible&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;human_approved&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Human approval required&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Authorized&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A production policy will be more detailed, but the important idea is simple:&lt;/p&gt;

&lt;p&gt;The agent should not decide its own authority merely because it knows how to call a tool.&lt;/p&gt;

&lt;h2&gt;
  
  
  Make retries safe
&lt;/h2&gt;

&lt;p&gt;Agent workflows frequently retry after timeouts, interrupted execution, or uncertain responses.&lt;/p&gt;

&lt;p&gt;Without retry protection, an agent may repeat an external action even though the first attempt already succeeded.&lt;/p&gt;

&lt;p&gt;Useful controls include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An idempotency key for each intended side effect&lt;/li&gt;
&lt;li&gt;An expected resource version&lt;/li&gt;
&lt;li&gt;A record of the previous attempt&lt;/li&gt;
&lt;li&gt;A clear completion state&lt;/li&gt;
&lt;li&gt;A rollback or compensation reference&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;action_request&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;action&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;send_message&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;idempotency_key&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;case-1842-final-response&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;expected_version&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;requires_approval&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The idempotency key represents the intended action, not an individual retry. Repeating the request should not create a second side effect.&lt;/p&gt;

&lt;h2&gt;
  
  
  Persist intent, not only the final result
&lt;/h2&gt;

&lt;p&gt;A useful execution record should explain what the agent intended to do and why it was allowed to continue.&lt;/p&gt;

&lt;p&gt;Consider storing:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;User or system objective&lt;/li&gt;
&lt;li&gt;Plan version&lt;/li&gt;
&lt;li&gt;Selected tool and arguments&lt;/li&gt;
&lt;li&gt;Action classification&lt;/li&gt;
&lt;li&gt;Policy-check result&lt;/li&gt;
&lt;li&gt;Approval status and approver&lt;/li&gt;
&lt;li&gt;Idempotency key&lt;/li&gt;
&lt;li&gt;Tool response&lt;/li&gt;
&lt;li&gt;Final workflow state&lt;/li&gt;
&lt;li&gt;Resume position after interruption&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This information makes failures easier to diagnose and interrupted workflows easier to resume safely.&lt;/p&gt;

&lt;h2&gt;
  
  
  Make approval requests informative
&lt;/h2&gt;

&lt;p&gt;A human approval step should not be a generic “Allow” button.&lt;/p&gt;

&lt;p&gt;Before asking for approval, show:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The exact proposed action&lt;/li&gt;
&lt;li&gt;The destination or affected resource&lt;/li&gt;
&lt;li&gt;The relevant input values&lt;/li&gt;
&lt;li&gt;The expected external effect&lt;/li&gt;
&lt;li&gt;Whether the action is reversible&lt;/li&gt;
&lt;li&gt;A preview or diff when possible&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A reviewer should be able to understand the consequence without reconstructing the entire agent session.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test permission boundaries directly
&lt;/h2&gt;

&lt;p&gt;Agent evaluation should include more than successful task completion.&lt;/p&gt;

&lt;p&gt;Test situations such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The agent requests data outside its allowed scope&lt;/li&gt;
&lt;li&gt;Input data changes after the plan is generated&lt;/li&gt;
&lt;li&gt;A tool call times out after completing the action&lt;/li&gt;
&lt;li&gt;The same action is retried&lt;/li&gt;
&lt;li&gt;Approval is denied or expires&lt;/li&gt;
&lt;li&gt;A workflow fails halfway through&lt;/li&gt;
&lt;li&gt;Execution resumes after a restart&lt;/li&gt;
&lt;li&gt;A reversible action cannot be rolled back&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These scenarios reveal whether the surrounding system remains safe when the agent, tool, network, or user behaves unexpectedly.&lt;/p&gt;

&lt;h2&gt;
  
  
  A practical release checklist
&lt;/h2&gt;

&lt;p&gt;Before allowing an agent to perform external actions, verify that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Every tool has the minimum required scope&lt;/li&gt;
&lt;li&gt;Read and write permissions are separated&lt;/li&gt;
&lt;li&gt;Irreversible actions have explicit policy rules&lt;/li&gt;
&lt;li&gt;Duplicate retries cannot repeat a side effect&lt;/li&gt;
&lt;li&gt;Every external call can be traced&lt;/li&gt;
&lt;li&gt;Approval requests show the exact consequence&lt;/li&gt;
&lt;li&gt;Interrupted workflows can resume safely&lt;/li&gt;
&lt;li&gt;Recovery procedures have been tested&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Final thought
&lt;/h2&gt;

&lt;p&gt;Agent autonomy is not defined by how many tools the system can access.&lt;/p&gt;

&lt;p&gt;It is defined by which actions the agent may perform, under what conditions, and with what evidence.&lt;/p&gt;

&lt;p&gt;A useful production agent does not need unlimited authority.&lt;/p&gt;

&lt;p&gt;It needs clearly designed permission boundaries.&lt;/p&gt;

&lt;p&gt;Which action in your agent workflow would you never allow without human approval?&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>security</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Stop Reporting Only Average Agent Success</title>
      <dc:creator>shizhe Lim</dc:creator>
      <pubDate>Tue, 29 Sep 2026 09:31:46 +0000</pubDate>
      <link>https://dev.to/shizhe_lim_61b5948cb8081d/stop-reporting-only-average-agent-success-3e82</link>
      <guid>https://dev.to/shizhe_lim_61b5948cb8081d/stop-reporting-only-average-agent-success-3e82</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;AI disclosure: This article was prepared with AI assistance. The author reviewed and edited the technical content and remains responsible for its accuracy.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;An AI agent completes a task successfully during testing.&lt;/p&gt;

&lt;p&gt;The demo works. The result looks correct. The team records a pass.&lt;/p&gt;

&lt;p&gt;Then someone runs the same task again—and the agent chooses a different tool, changes an argument, follows another path, and fails.&lt;/p&gt;

&lt;p&gt;This is not necessarily a capability problem. It is a consistency problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Average success can hide unreliable behavior
&lt;/h2&gt;

&lt;p&gt;A recent IBM Research evaluation illustrates the difference.&lt;/p&gt;

&lt;p&gt;On the AppWorld benchmark, a ReAct agent using GPT-4.1 achieved a Mean@5 score of 77.4%. In other words, it completed 77.4% of the attempted task runs successfully.&lt;/p&gt;

&lt;p&gt;However, its Pass⁵ score was 53.0%. Only 53% of the tasks succeeded in all five repeated runs.&lt;/p&gt;

&lt;p&gt;Both numbers are correct, but they answer different questions.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Mean@k:&lt;/strong&gt; How often does the agent succeed on average?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pass^k:&lt;/strong&gt; For how many tasks does the agent succeed in every repeated run?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pass@k:&lt;/strong&gt; For how many tasks does at least one of the repeated runs succeed?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Pass@k is useful when a system can safely retry and verify its own answer.&lt;/p&gt;

&lt;p&gt;Pass^k is more relevant when repeated failures are expensive, difficult to detect or unacceptable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Calculating the consistency gap
&lt;/h2&gt;

&lt;p&gt;Suppose evaluation results are stored as one Boolean list per task:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;task_1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;task_2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;task_3&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can calculate the average success rate and the all-runs success rate separately:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;task_runs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;values&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

&lt;span class="n"&gt;total_runs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;runs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;runs&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;task_runs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;successful_runs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;runs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;runs&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;task_runs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;mean_at_k&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;successful_runs&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;total_runs&lt;/span&gt;
&lt;span class="n"&gt;pass_power_k&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;runs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;runs&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;task_runs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task_runs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;consistency_gap&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mean_at_k&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;pass_power_k&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Mean@k: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;mean_at_k&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Pass^k: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;pass_power_k&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Consistency gap: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;consistency_gap&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A large consistency gap means the agent can complete many tasks, but its success is not repeatable.&lt;/p&gt;

&lt;p&gt;That distinction is easy to lose when a leaderboard reports only one aggregate score.&lt;/p&gt;

&lt;h2&gt;
  
  
  What an Agent evaluation should record
&lt;/h2&gt;

&lt;p&gt;Repeating a task is useful only if the surrounding conditions are documented.&lt;/p&gt;

&lt;p&gt;At minimum, record:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Model and model version&lt;/li&gt;
&lt;li&gt;Prompt or instruction version&lt;/li&gt;
&lt;li&gt;Available tools and their schemas&lt;/li&gt;
&lt;li&gt;Tool permissions&lt;/li&gt;
&lt;li&gt;Agent framework version&lt;/li&gt;
&lt;li&gt;Temperature and other inference settings&lt;/li&gt;
&lt;li&gt;Number of attempts&lt;/li&gt;
&lt;li&gt;Evaluation or grader version&lt;/li&gt;
&lt;li&gt;Token and tool-call cost&lt;/li&gt;
&lt;li&gt;Failure stage and execution trace&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Without this context, two teams may report scores for the “same” model while evaluating meaningfully different systems.&lt;/p&gt;

&lt;p&gt;This is also why reproducible evaluation reporting matters. A model score without its inference budget, tool configuration and evaluation protocol is difficult to interpret—and even harder to reproduce.&lt;/p&gt;

&lt;h2&gt;
  
  
  Evaluate cost per consistent success
&lt;/h2&gt;

&lt;p&gt;Agent economics should not stop at cost per request.&lt;/p&gt;

&lt;p&gt;Consider measuring:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cost per consistent success =
total evaluation cost /
number of tasks that succeeded in every required run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A cheaper model may become expensive if it requires repeated attempts, human review or recovery from incorrect tool calls.&lt;/p&gt;

&lt;p&gt;A more capable model may also be a poor choice if its behavior varies too much across identical workflows.&lt;/p&gt;

&lt;p&gt;For multi-model systems, routing decisions should therefore consider at least:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Capability&lt;/li&gt;
&lt;li&gt;Repeatability&lt;/li&gt;
&lt;li&gt;Latency&lt;/li&gt;
&lt;li&gt;Total recovery cost&lt;/li&gt;
&lt;li&gt;Failure severity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The model with the best average benchmark score is not automatically the best production model.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start with three repeated runs
&lt;/h2&gt;

&lt;p&gt;Running every task dozens of times may be impractical.&lt;/p&gt;

&lt;p&gt;A reasonable starting point is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run each critical task three times&lt;/li&gt;
&lt;li&gt;Report Mean@3 and Pass³&lt;/li&gt;
&lt;li&gt;Investigate tasks with inconsistent outcomes&lt;/li&gt;
&lt;li&gt;Repeat after changing the model, prompt, tools or permissions&lt;/li&gt;
&lt;li&gt;Increase the repetition count for high-risk workflows&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Even three runs can expose instability that a single successful test would miss.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final thought
&lt;/h2&gt;

&lt;p&gt;A successful demo proves that an agent &lt;em&gt;can&lt;/em&gt; complete a task.&lt;/p&gt;

&lt;p&gt;A repeated-run evaluation helps show whether users can depend on it.&lt;/p&gt;

&lt;p&gt;Production reliability starts when we stop asking only:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Did the agent succeed?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;and begin asking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Will it succeed again under the same conditions?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Have you started measuring repeated-run consistency in your Agent evaluations?&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;IBM Research, “Your Agent Aced the Task. Will It Do It Again?”&lt;br&gt;
&lt;a href="https://huggingface.co/blog/ibm-research/altk-evolve-consistency" rel="noopener noreferrer"&gt;https://huggingface.co/blog/ibm-research/altk-evolve-consistency&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;UK AISI and EvalEval, reproducible evaluation reporting&lt;br&gt;
&lt;a href="https://huggingface.co/blog/evaleval-aisi" rel="noopener noreferrer"&gt;https://huggingface.co/blog/evaleval-aisi&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>testing</category>
      <category>machinelearning</category>
      <category>agents</category>
    </item>
  </channel>
</rss>
