Back to TechSheets
Mastering Agent Experience (AX) Evaluation: Strategies for Testing AI Coding Agents Before Production

Mastering Agent Experience (AX) Evaluation: Strategies for Testing AI Coding Agents Before Production

Thanga MariappanSenior Architect
10 min read
Aug 30, 2026

Mastering Agent Experience (AX) Evaluation: Strategies for Testing AI Coding Agents Before Production

As a Senior Front-End Architect, I've spent years optimizing user experiences and developer workflows. Now, with AI agents like GitHub Copilot becoming indispensable in our daily coding, a new frontier in experience design and validation has emerged: Agent Experience (AX). It's not enough for an AI to merely generate code; its interaction with the developer, its understanding of the environment, and its ability to correctly execute tasks define its true value. Yet, evaluating and refining this Agent Experience before it hits production is proving to be a formidable challenge.

Today, we're diving deep into the emerging discipline of AX evaluation. We'll explore why traditional testing falls short, and more importantly, uncover practical, battle-tested strategies for robustly evaluating your AI coding agents, significantly reducing iteration cycles and deployment risks.

The Elusive Nature of Agent Experience

Why is AX evaluation so uniquely difficult? Unlike a deterministic API endpoint or a UI component with predictable states, AI agents operate in a complex, often non-deterministic landscape:

  1. Non-Determinism: Even with the same prompt, an LLM-powered agent might produce varying outputs. This inherent variability complicates reproducible testing.
  2. Context Sensitivity: Agent behavior is heavily influenced by the surrounding code, documentation, API schemas, and even prior interactions. Changing one variable can have cascading, unpredictable effects.
  3. High-Fidelity Dependencies: Agents often interact with real-world tools, APIs, and file systems. Testing these interactions in a production-like environment is expensive, slow, and risky (e.g., mutating production data).
  4. Cost and Speed: Each interaction with a large language model incurs computational cost and latency. Running extensive evaluation suites against live models can quickly become prohibitive in both time and money.
  5. Subjectivity of "Good": What constitutes a "good" agent experience can be subjective. It often involves not just correctness but also helpfulness, efficiency, and adherence to specific coding styles or architectural patterns.

The challenge, as GitHub has highlighted in their internal findings, is that "Most changes you think will improve AI agent behavior won't." This sobering reality means we need sophisticated, rapid, and cost-effective evaluation mechanisms to iterate effectively.

Beyond Prompt Engineering: The Agent Stack

While prompt engineering is crucial, the agent's actual operational environment—its "stack"—plays an equally vital role in AX. This stack includes:

  • Documentation: Up-to-date SDK docs, internal guidelines, READMEs.
  • APIs & Tooling: The actual HTTP APIs, CLI tools, libraries the agent interacts with.
  • Codebase Structure: File organization, existing patterns, component library usage.
  • Environment Variables & Configuration: Runtime settings, credentials.

When we aim to improve an agent's experience, we're often tweaking one or more of these elements. The critical question then becomes: How do we test the impact of these changes without deploying them or incurring massive costs?

Core Strategy 1: Emulating Reality Locally

The most powerful technique for testing AX changes quickly and affordably is local emulation. This involves creating a simulated environment where you can modify aspects of the agent's stack—documentation, API schemas, environment settings—and observe the agent's behavior as if those changes were live, all without leaving your development machine.

Why Local Emulation?

Imagine you want to test if updating your README.md with new architectural guidance makes your AI agent generate more compliant code. Or perhaps you've modified an internal API specification, and you need to ensure the agent adapts correctly. Shipping these changes to a staging environment and then running costly, full-scale evals is too slow. Local emulation allows for:

  • Rapid Iteration: Test hypothesis in minutes, not hours or days.
  • Cost Savings: Avoids repeated LLM inference costs and deployment overhead.
  • Isolation: Test changes without affecting other developers or live systems.
  • Deep Introspection: Debug agent behavior with local tooling.

How to Implement Local Emulation

Local emulation relies on intercepting the agent's interaction with its environment and serving up mock data or altered configurations. Here are common approaches:

  1. Local File System Overrides: For documentation or configuration files, simply modify the local files the agent would typically read. Many agents can be configured to point to local paths.

    # agent_config.yaml
    documentation_paths:
      - ./local_docs/sdk_v2.md
      - ./project_readme.md
    
  2. Proxy Servers for Documentation: For web-hosted documentation (e.g., your internal Confluence or Notion), you can run a local proxy server that intercepts requests to these domains and serves up modified content from your local machine.

    Example: Using mitmproxy or a custom Node.js proxy to intercept docs.mycompany.com requests and serve local_docs/sdk_v2_draft.html.

    // simple-doc-proxy.js
    const http = require('http');
    const fs = require('fs');
    const path = require('path');
    
    const proxy = http.createServer((req, res) => {
        if (req.url.includes('sdk_v2.md')) {
            const localPath = path.join(__dirname, 'local_docs', 'sdk_v2_draft.md');
            fs.readFile(localPath, (err, data) => {
                if (err) {
                    res.writeHead(500); res.end('Error reading local doc'); return;
                }
                res.writeHead(200, {'Content-Type': 'text/markdown'});
                res.end(data);
            });
        } else {
            // Fallback to original, or block, depending on strategy
            res.writeHead(404); res.end('Not found in local proxy');
        }
    });
    
    proxy.listen(8080, () => console.log('Doc proxy listening on port 8080'));
    

    You'd then configure your agent or system to route docs.mycompany.com requests through localhost:8080 (e.g., via /etc/hosts or environment variables).

  3. Containerized Environments: Package your agent and its dependencies into Docker containers. This allows you to easily swap out mock service containers (e.g., a mock API server) or mount different documentation volumes.

Core Strategy 2: Transparent API Mocking for Skill Evaluation

AI agents often possess "skills" that involve calling external APIs. Testing these skills directly against real APIs during evaluation poses two major problems:

  1. Cost and Rate Limits: Every API call costs money and consumes rate limit quotas, especially for third-party services.
  2. Side Effects: Calling mutable APIs (e.g., creating resources, updating records) can corrupt test data, trigger unintended workflows, or even impact production.

The solution is transparent API mocking. The key here is transparency: the agent skill code itself should ideally remain unchanged. The mocking layer should intercept calls made by the agent and return predefined responses without the agent being aware it's talking to a mock.

How to Implement Transparent API Mocking

  1. Network Proxy (Layer 7): Similar to documentation proxies, a network proxy can intercept HTTP/S requests made by the agent to specific API endpoints. You can then configure the proxy to return mock JSON responses or even simulate network errors.

    Example: Mocking a GET /users API call.

    // simple-api-proxy.js
    const http = require('http');
    const { createProxyMiddleware } = require('http-proxy-middleware');
    
    const mockUsers = [
        { id: 1, name: 'Alice' },
        { id: 2, name: 'Bob' }
    ];
    
    const apiProxy = createProxyMiddleware('/api/v1/users', {
        target: 'http://localhost:3000', // Default or real API
        changeOrigin: true,
        onProxyReq: (proxyReq, req, res) => {
            // Intercept specific requests
            if (req.url === '/api/v1/users' && req.method === 'GET') {
                res.writeHead(200, { 'Content-Type': 'application/json' });
                res.end(JSON.stringify(mockUsers));
                proxyReq.destroy(); // Prevent actual request from going through
            }
        }
    });
    
    const server = http.createServer((req, res) => {
        if (req.url.startsWith('/api/v1/users')) {
            apiProxy(req, res); // Handle with proxy middleware
        } else {
            res.writeHead(404); res.end('Not found');
        }
    });
    
    server.listen(8081, () => console.log('API proxy listening on port 8081'));
    

    You'd configure your agent or runtime environment to point to localhost:8081 for the target API domain.

  2. DNS or hosts File Redirection: For more systemic redirection, you can modify your system's hosts file (/etc/hosts on Linux/macOS) to point an API domain (e.g., api.mycompany.com) to 127.0.0.1 or the IP of your local mock server.

    127.0.0.1 api.mycompany.com
    
  3. Environment Variable Overrides: Many well-designed clients allow you to configure the base URL of an API via an environment variable. This is the simplest and often preferred method if the API client supports it.

    export MY_API_BASE_URL="http://localhost:8081/api/v1"
    # Then run your agent which will use this env var for API calls
    
  4. Specialized Mocking Frameworks: Tools like Mock Service Worker (MSW) or Pact for consumer-driven contract testing can be adapted to intercept network requests at a lower level or define API contracts, making them powerful for comprehensive mocking strategies.

Crafting Effective AX Evals: Metrics and Iteration

With robust local emulation and API mocking in place, the next step is to design evaluations that actually work. Effective AX evals are:

  • Goal-Oriented: Each eval should test a specific hypothesis about agent behavior (e.g., "Does the agent correctly use the new AuthService.getToken() API?").
  • Reproducible: Given the non-deterministic nature, run evals multiple times and analyze statistical outcomes. Use fixed seeds if your LLM provider supports it.
  • Targeted Scenarios: Focus on common use cases, edge cases, and areas where previous agent behavior was suboptimal.
  • Automated and Assertable: Define clear pass/fail criteria. For code generation, this might involve running unit tests on the generated code, linting checks, or static analysis for specific patterns. For agent actions, it could be asserting specific API calls were made with correct payloads.

Example: Code Generation Eval

import subprocess
import json

def run_test_suite(code_string: str) -> bool:
    # Write generated code to a temporary file
    with open("temp_module.py", "w") as f:
        f.write(code_string)
    
    # Run a predefined unit test suite against it
    result = subprocess.run(
        ["pytest", "-s", "./test_temp_module.py"],
        capture_output=True, text=True
    )
    return result.returncode == 0

def evaluate_agent_response(agent_generated_code: str) -> dict:
    passed_tests = run_test_suite(agent_generated_code)
    # Add more checks: linting, specific function calls, etc.
    
    return {
        "passed_tests": passed_tests,
        "lint_errors": "...", # e.g., from a linter run
        "correct_api_usage": True # Custom logic
    }

# Workflow:
# 1. Agent receives prompt and local emulation is active.
# 2. Agent generates code based on (mocked) documentation.
# 3. Captured code is passed to `evaluate_agent_response`.
# 4. Results inform whether the documentation change improved AX.

Iterate by running these evals after each change to your documentation, API schema, or agent configuration. The faster your feedback loop, the quicker you converge on an optimal Agent Experience.

Trade-offs and Considerations

While powerful, these strategies are not without their trade-offs:

  • Setup Overhead: Initial setup of proxies, mock servers, and local environments can take time.
  • Maintenance of Mocks: Mocks need to be kept in sync with evolving APIs, which requires discipline.
  • Realism vs. Control: Over-mocking can lead to a false sense of security. It's crucial to balance control over the environment with sufficient realism to capture true agent behavior.
  • Complexity: As your agent's capabilities grow, the mocking and emulation setup can become complex. Invest in robust tools and clear documentation for your evaluation infrastructure.

Despite these considerations, the benefits—reduced costs, faster iteration, and higher-quality agent experiences—far outweigh the initial investment.

Key Takeaways

  • Agent Experience (AX) is a critical, complex discipline for AI agents, demanding specialized evaluation strategies.
  • Traditional testing falls short due to non-determinism, complex dependencies, and cost implications of live interactions.
  • Local emulation of documentation, API schemas, and environment variables allows for rapid, isolated, and cost-effective testing of AX changes.
  • Transparent API mocking is essential for evaluating agent skills without incurring costs or mutating production data.
  • Effective AX evals are goal-oriented, reproducible, and automated, using metrics like test suite pass rates, linting results, and specific action assertions.
  • Invest in your evaluation infrastructure to balance realism with control, accelerating your agent development lifecycle.

What You Should Do Today

  1. Identify a core agent skill or behavior that currently relies on external documentation or APIs. This is your initial target for AX evaluation.
  2. Experiment with local emulation: Try setting up a simple local proxy or modifying your hosts file to serve a mock version of a document or API endpoint that your agent consumes.
  3. Implement transparent API mocking: If your agent uses external APIs, explore using environment variables or a local proxy like mitmproxy or a custom Node.js server to intercept and mock a specific API call.
  4. Define a measurable success metric for your chosen agent behavior. Can you write a small script to automatically validate its output or actions under your mocked environment?
  5. Start iterating! Make a small change to your mocked documentation or API, run your local eval, and observe how your agent's behavior changes. This immediate feedback loop is the essence of effective AX evaluation.