{"id":98436,"date":"2026-04-09T08:00:00","date_gmt":"2026-04-09T15:00:00","guid":{"rendered":""},"modified":"2026-04-09T06:54:54","modified_gmt":"2026-04-09T13:54:54","slug":"how-drasi-used-github-copilot-to-find-documentation-bugs","status":"publish","type":"post","link":"https:\/\/opensource.microsoft.com\/blog\/2026\/04\/09\/how-drasi-used-github-copilot-to-find-documentation-bugs\/","title":{"rendered":"How Drasi used GitHub Copilot to find documentation bugs"},"content":{"rendered":"\n<p>For early-stage open-source projects, the \u201cGetting started\u201d guide is often the first real interaction a developer has with the project. If a command fails, an output doesn\u2019t match, or a step is unclear, most users won\u2019t file a bug report, they will just move on.<\/p>\n\n\n\n<p><a href=\"https:\/\/drasi.io\/\">Drasi<\/a>, a CNCF sandbox project that detects changes in your data and triggers immediate reactions, is supported by our small team of four engineers in Microsoft Azure&#8217;s Office of the Chief Technology Officer. We have comprehensive tutorials, but we are shipping code faster than we can manually test them.<\/p>\n\n\n\n<div class=\"wp-block-buttons is-content-justification-center is-layout-flex wp-container-core-buttons-is-layout-16018d1d wp-block-buttons-is-layout-flex\">\n<div class=\"wp-block-button\"><a class=\"wp-block-button__link wp-element-button\" href=\"https:\/\/drasi.io\/drasi-kubernetes\/getting-started\/\" target=\"_blank\" rel=\"noreferrer noopener\">Detect and react to your first database change using Drasi<\/a><\/div>\n<\/div>\n\n\n\n<p>The team <a id=\"post-98436-OLE_LINK33\"><\/a>didn&#8217;t realize how big this gap was until late 2025, when GitHub updated its Dev Container infrastructure, bumping the minimum Docker version. The update broke the Docker daemon connection, and every single tutorial stopped working. Because we relied on manual testing, we didn&#8217;t immediately know the extent of the damage. Any developer trying Drasi during that window would have hit a wall.<a id=\"post-98436-OLE_LINK10\"><\/a><a id=\"post-98436-OLE_LINK11\"><\/a><a id=\"post-98436-OLE_LINK34\"><\/a><\/p>\n\n\n\n<p>This incident forced a realization: <strong>with advanced AI coding assistants, documentation testing can be converted to a monitoring problem<\/strong>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"the-problem-why-does-documentation-break\"><a id=\"post-98436-OLE_LINK12\"><\/a><a id=\"post-98436-OLE_LINK14\"><\/a>The problem: Why does documentation break?<\/h2>\n\n\n\n<p>\n  Documentation usually breaks for two reasons:\n<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"1-the-curse-of-knowledge\">1. The curse of knowledge<\/h3>\n\n\n\n<p>Experienced developers write documentation with implicit context. When we write &#8220;wait for the query to bootstrap,&#8221; we know to run `drasi list query` and watch for the `Running` status, or even better to run the `drasi wait` command. A new user has no such context. Neither does an AI agent. They read the instructions literally and don&#8217;t know what to do. They get stuck on the &#8220;how,&#8221; while we only document the &#8220;what.&#8221; <\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"2-silent-drift\"><a id=\"post-98436-OLE_LINK13\"><\/a>2. Silent drift<\/h3>\n\n\n\n<p>\n  Documentation doesn&#8217;t fail loudly like code does. When you rename a configuration file in your codebase, the build fails immediately. But when your documentation still references the old filename, nothing happens. The drift accumulates silently until a user reports confusion.\n<\/p>\n\n\n\n<p>\n  This is compounded for tutorials like ours, which spin up sandbox environments with Docker, k3d, and sample databases. When any upstream dependency changes\u2014a deprecated flag, a bumped version, or a new default\u2014our tutorials can break silently.\n<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"the-solution-agents-as-synthetic-users\"><a id=\"post-98436-OLE_LINK15\"><\/a>The solution: Agents as synthetic users<\/h2>\n\n\n\n<p>To solve this, we treated tutorial testing as a simulation problem. We built an AI agent that acts as a \u201csynthetic new user.\u201d<\/p>\n\n\n\n<p>\n  This agent has three critical characteristics:\n<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>It is na\u00efve<\/strong>: It has no prior knowledge of Drasi\u2014it knows only what is explicitly written in the tutorial.<\/li>\n\n\n\n<li><strong>It is literal<\/strong>: It executes every command exactly as written. If a step is missing, it fails.<\/li>\n\n\n\n<li><strong>It is unforgiving<\/strong>: It verifies every expected output. If the doc says, \u201cYou should see \u2018Success\u2019\u201d, and the command line interface (CLI) just returns silently, the agent flags it and fails fast.<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"the-stack-github-copilot-cli-and-dev-containers\"><a id=\"post-98436-OLE_LINK16\"><\/a>The stack: GitHub Copilot CLI and Dev Containers<\/h3>\n\n\n\n<p>We built a solution using GitHub Actions, Dev Containers, Playwright, and the GitHub Copilot CLI. <\/p>\n\n\n\n<p>\n  Our tutorials require heavy infrastructure:\n<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>A full Kubernetes cluster (k3d)  <\/li>\n\n\n\n<li>Docker-in-Docker  <\/li>\n\n\n\n<li>Real databases (such as PostgreSQL and MySQL)  <\/li>\n<\/ul>\n\n\n\n<p>We needed an environment that exactly matches what our human users experience. If users run in a specific Dev Container on GitHub Codespaces, our test must run in that <strong>same<\/strong> Dev Container.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"the-architecture\"><a id=\"post-98436-OLE_LINK17\"><\/a>The architecture<\/h3>\n\n\n\n<p>\n  Inside the container, we invoke the Copilot CLI with a specialized system prompt (<a href=\"https:\/\/github.com\/drasi-project\/learning\/blame\/main\/.github\/prompts\/tutorial-evaluation.md\">view the full prompt here<\/a>):\n<\/p>\n\n\n<figure data-wp-context=\"{&quot;imageId&quot;:&quot;69d7ed581ea1a&quot;}\" data-wp-interactive=\"core\/image\" class=\"wp-block-image wp-lightbox-container\"><img decoding=\"async\" data-wp-class--hide=\"state.isContentHidden\" data-wp-class--show=\"state.isContentVisible\" data-wp-init=\"callbacks.setButtonStyles\" data-wp-on-async--click=\"actions.showLightbox\" data-wp-on-async--load=\"callbacks.setButtonStyles\" data-wp-on-async-window--resize=\"callbacks.setButtonStyles\" src=\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2026\/04\/a-screen-shot-of-a-computer-terminal-bash-co.webp\" alt=\"A screen shot of a computer terminal:\n\nbash \n \n\ncopilot -p &quot;$(cat prompt.md)&quot; \\ \n  --allow-all-tools \\ \n  --allow-all-paths \\ \n  --deny-tool 'fetch' \\ \n  --deny-tool 'websearch' \\ \n  --deny-tool 'githubRepo' \\ \n  --deny-tool 'shell(curl *)' \\ \n \n\n    # ... additional deny-tool flags \n \n  --allow-url localhost \\ \n  --allow-url 127.0.0.1 \" class=\"wp-image-98438 webp-format\" srcset=\"\" data-orig-src=\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2026\/04\/a-screen-shot-of-a-computer-terminal-bash-co.webp\"><button\n\t\t\tclass=\"lightbox-trigger\"\n\t\t\ttype=\"button\"\n\t\t\taria-haspopup=\"dialog\"\n\t\t\taria-label=\"Enlarge\"\n\t\t\tdata-wp-init=\"callbacks.initTriggerButton\"\n\t\t\tdata-wp-on-async--click=\"actions.showLightbox\"\n\t\t\tdata-wp-style--right=\"state.imageButtonRight\"\n\t\t\tdata-wp-style--top=\"state.imageButtonTop\"\n\t\t>\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" fill=\"none\" viewBox=\"0 0 12 12\">\n\t\t\t\t<path fill=\"#fff\" d=\"M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z\" \/>\n\t\t\t<\/svg>\n\t\t<\/button><\/figure>\n\n\n\n<p>This prompt using the prompt mode (-p) of the CLI agent gives us an agent that can execute terminal commands, write files, and run browser scripts\u2014just like a human developer sitting at their terminal. For the agent to simulate a real user, it needs these capabilities.<\/p>\n\n\n\n<p>To enable the agents to open webpages and interact with them as any human following the tutorial steps would, we also install Playwright on the Dev Container. The agent also takes screenshots which it then compares against those provided in the documentation. <\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"security-model\">Security model<\/h3>\n\n\n\n<p>Our security model is built around one principle: <strong>the container is the boundary<\/strong>.<\/p>\n\n\n\n<p>Rather than trying to restrict individual commands (a losing game when the agent needs to run arbitrary node scripts for Playwright), we treat the entire Dev Container as an isolated sandbox and control what crosses its boundaries: no outbound network access beyond localhost, a Personal Access Token (PAT) with only \u201cCopilot Requests\u201d permission, ephemeral containers destroyed after each run, and a maintainer-approval gate for triggering workflows. <\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"dealing-with-non-determinism\">Dealing with non-determinism<\/h3>\n\n\n\n<p>One of the biggest challenges with AI-based testing is non-determinism. Large language models (LLMs) are probabilistic\u2014sometimes the agent retries a command; other times it gives up.<\/p>\n\n\n\n<p>\n  We handled this with a three-stage <a href=\"https:\/\/github.com\/drasi-project\/learning\/blob\/b826ab8a7e1116a274d3a670a270516d9eaa81d2\/.github\/workflows\/tutorial-evaluation-scheduled.yml#L95\">retry with model escalation<\/a> (start with Gemini-Pro, on failure try with Claude Opus), <a href=\"https:\/\/github.com\/drasi-project\/learning\/blame\/b826ab8a7e1116a274d3a670a270516d9eaa81d2\/.github\/prompts\/tutorial-evaluation.md#L26C7-L26C7\">semantic comparison for screenshots<\/a> instead of pixel-matching, and verification of core-data fields <a href=\"https:\/\/github.com\/drasi-project\/learning\/blame\/b826ab8a7e1116a274d3a670a270516d9eaa81d2\/.github\/prompts\/tutorial-evaluation.md#L25\">rather than volatile values<\/a>.\n<\/p>\n\n\n\n<p>\n  We also have a <a href=\"https:\/\/github.com\/drasi-project\/learning\/blame\/b826ab8a7e1116a274d3a670a270516d9eaa81d2\/.github\/prompts\/tutorial-evaluation.md#L49-L49C12\">list of tight constraints<\/a> in our prompts that prevent the agent from going on a debugging journey, <a href=\"https:\/\/github.com\/drasi-project\/learning\/blame\/b826ab8a7e1116a274d3a670a270516d9eaa81d2\/.github\/prompts\/tutorial-evaluation.md#L31\">directives to control<\/a> the structure of the final report, and also <a href=\"https:\/\/github.com\/drasi-project\/learning\/blame\/b826ab8a7e1116a274d3a670a270516d9eaa81d2\/.github\/prompts\/tutorial-evaluation.md#L43-L43C17\">skip directives<\/a> that tell the agent to bypass optional tutorial sections like setting up external services.\n<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"artifacts-for-debugging\"><a id=\"post-98436-OLE_LINK19\"><\/a>Artifacts for debugging<\/h3>\n\n\n\n<p>When a run fails, we need to know why. Since the agent is running in a transient container, we can&#8217;t just Secure Shell (SSH) in and look around.<\/p>\n\n\n\n<p>So, our agent preserves evidence of every run, screenshots of web UIs, terminal output of critical commands, and a final markdown report detailing its reasoning like shown here:<\/p>\n\n\n<figure data-wp-context=\"{&quot;imageId&quot;:&quot;69d7ed581fdc2&quot;}\" data-wp-interactive=\"core\/image\" class=\"wp-block-image wp-lightbox-container\"><img decoding=\"async\" data-wp-class--hide=\"state.isContentHidden\" data-wp-class--show=\"state.isContentVisible\" data-wp-init=\"callbacks.setButtonStyles\" data-wp-on-async--click=\"actions.showLightbox\" data-wp-on-async--load=\"callbacks.setButtonStyles\" data-wp-on-async-window--resize=\"callbacks.setButtonStyles\" src=\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2026\/04\/drasi-getting-started-tutorial-evaluation-e.webp\" alt=\"# Drasi Getting Started Tutorial Evaluation \n\n## Environment \n- Timestamp: 2026-02-20T13:32:07.998Z \n- Directory: \/workspaces\/learning\/tutorial\/getting-started \n\n## Step 1: Setup Drasi Environment \n- Skipped as per instructions (already in DevContainer). \n- Verified environment setup by checking `resources` folder existence. \n\n## Step 2: Create PostgreSQL Source \n- Command: `drasi apply -f .\/resources\/hello-world-source.yaml`\n\n.................................... \n............  more steps  .......... \n.................................... \n\n### Scenario 1: hello-world-from \n- Initial check: &ldquo;Brian Kernighan&rdquo; present. (Screenshot: `09_hello-world-from.png`) \n- Action: Insert &lsquo;Allen&rsquo;, &lsquo;Hello World&rsquo;. \n- Verification: &ldquo;Allen&rdquo; appeared in UI. (Screenshot: `10_hello-world-from-updated.png`) \n- Result: **PASSED** \n\n............................................................ \n..... more validation by playwright taking screenshots ..... \n............................................................ \n\n## Conclusion \nThe tutorial instructions were clear and the commands executed successfully. The expected behavior matches the actual behavior observed via the Debug Reaction UI. \n\n## STATUS: SUCCESS \" class=\"wp-image-98439 webp-format\" srcset=\"\" data-orig-src=\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2026\/04\/drasi-getting-started-tutorial-evaluation-e.webp\"><button\n\t\t\tclass=\"lightbox-trigger\"\n\t\t\ttype=\"button\"\n\t\t\taria-haspopup=\"dialog\"\n\t\t\taria-label=\"Enlarge\"\n\t\t\tdata-wp-init=\"callbacks.initTriggerButton\"\n\t\t\tdata-wp-on-async--click=\"actions.showLightbox\"\n\t\t\tdata-wp-style--right=\"state.imageButtonRight\"\n\t\t\tdata-wp-style--top=\"state.imageButtonTop\"\n\t\t>\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" fill=\"none\" viewBox=\"0 0 12 12\">\n\t\t\t\t<path fill=\"#fff\" d=\"M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z\" \/>\n\t\t\t<\/svg>\n\t\t<\/button><\/figure>\n\n\n\n<p>\n  These <a href=\"https:\/\/github.com\/drasi-project\/learning\/blob\/b826ab8a7e1116a274d3a670a270516d9eaa81d2\/.github\/workflows\/tutorial-evaluation-scheduled.yml#L156\">artifacts are uploaded<\/a> to the GitHub Action run summary, allowing us to &#8220;time travel&#8221; back to the exact moment of failure and see what the agent saw.\n<\/p>\n\n\n<figure data-wp-context=\"{&quot;imageId&quot;:&quot;69d7ed5820e61&quot;}\" data-wp-interactive=\"core\/image\" class=\"wp-block-image wp-lightbox-container\"><img decoding=\"async\" data-wp-class--hide=\"state.isContentHidden\" data-wp-class--show=\"state.isContentVisible\" data-wp-init=\"callbacks.setButtonStyles\" data-wp-on-async--click=\"actions.showLightbox\" data-wp-on-async--load=\"callbacks.setButtonStyles\" data-wp-on-async-window--resize=\"callbacks.setButtonStyles\" src=\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2026\/04\/screenshot-of-agents-report-output-in-a-folder-wit.webp\" alt=\"Screenshot of Agents report output in a folder with other files. \" class=\"wp-image-98440 webp-format\" srcset=\"\" data-orig-src=\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2026\/04\/screenshot-of-agents-report-output-in-a-folder-wit.webp\"><button\n\t\t\tclass=\"lightbox-trigger\"\n\t\t\ttype=\"button\"\n\t\t\taria-haspopup=\"dialog\"\n\t\t\taria-label=\"Enlarge\"\n\t\t\tdata-wp-init=\"callbacks.initTriggerButton\"\n\t\t\tdata-wp-on-async--click=\"actions.showLightbox\"\n\t\t\tdata-wp-style--right=\"state.imageButtonRight\"\n\t\t\tdata-wp-style--top=\"state.imageButtonTop\"\n\t\t>\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" fill=\"none\" viewBox=\"0 0 12 12\">\n\t\t\t\t<path fill=\"#fff\" d=\"M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z\" \/>\n\t\t\t<\/svg>\n\t\t<\/button><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"parsing-the-agent-s-report\"><a id=\"post-98436-OLE_LINK18\"><\/a>Parsing the agent&#8217;s report<\/h3>\n\n\n\n<p>\n  With LLMs, getting a definitive &#8220;Pass\/Fail&#8221; signal that a machine can understand can be challenging. An agent might write a long, nuanced conclusion like:\n<\/p>\n\n\n<figure data-wp-context=\"{&quot;imageId&quot;:&quot;69d7ed5822c6c&quot;}\" data-wp-interactive=\"core\/image\" class=\"wp-block-image size-large wp-lightbox-container\"><img decoding=\"async\" data-wp-class--hide=\"state.isContentHidden\" data-wp-class--show=\"state.isContentVisible\" data-wp-init=\"callbacks.setButtonStyles\" data-wp-on-async--click=\"actions.showLightbox\" data-wp-on-async--load=\"callbacks.setButtonStyles\" data-wp-on-async-window--resize=\"callbacks.setButtonStyles\" src=\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2026\/04\/image-1024x119.webp\" alt=\"\" class=\"wp-image-98447 webp-format\" srcset=\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2026\/04\/image-1024x119.webp 1024w, https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2026\/04\/image-388x45.webp 388w, https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2026\/04\/image-768x90.webp 768w, https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2026\/04\/image-450x53.webp 450w, https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2026\/04\/image-650x76.webp 650w, https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2026\/04\/image.webp 1080w\" data-orig-src=\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2026\/04\/image-1024x119.webp\"><button\n\t\t\tclass=\"lightbox-trigger\"\n\t\t\ttype=\"button\"\n\t\t\taria-haspopup=\"dialog\"\n\t\t\taria-label=\"Enlarge\"\n\t\t\tdata-wp-init=\"callbacks.initTriggerButton\"\n\t\t\tdata-wp-on-async--click=\"actions.showLightbox\"\n\t\t\tdata-wp-style--right=\"state.imageButtonRight\"\n\t\t\tdata-wp-style--top=\"state.imageButtonTop\"\n\t\t>\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" fill=\"none\" viewBox=\"0 0 12 12\">\n\t\t\t\t<path fill=\"#fff\" d=\"M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z\" \/>\n\t\t\t<\/svg>\n\t\t<\/button><\/figure>\n\n\n\n<p>To make this actionable in a CI\/CD pipeline, we had to do some prompt engineering. We explicitly instructed the agent:<\/p>\n\n\n<figure data-wp-context=\"{&quot;imageId&quot;:&quot;69d7ed5823f68&quot;}\" data-wp-interactive=\"core\/image\" class=\"wp-block-image size-large wp-lightbox-container\"><img decoding=\"async\" data-wp-class--hide=\"state.isContentHidden\" data-wp-class--show=\"state.isContentVisible\" data-wp-init=\"callbacks.setButtonStyles\" data-wp-on-async--click=\"actions.showLightbox\" data-wp-on-async--load=\"callbacks.setButtonStyles\" data-wp-on-async-window--resize=\"callbacks.setButtonStyles\" src=\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2026\/04\/Picture1-1024x128.webp\" alt=\"\" class=\"wp-image-98454 webp-format\" srcset=\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2026\/04\/Picture1-1024x128.webp 1024w, https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2026\/04\/Picture1-388x49.webp 388w, https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2026\/04\/Picture1-768x96.webp 768w, https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2026\/04\/Picture1-1536x193.webp 1536w, https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2026\/04\/Picture1-450x56.webp 450w, https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2026\/04\/Picture1-650x82.webp 650w, https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2026\/04\/Picture1.webp 1650w\" data-orig-src=\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2026\/04\/Picture1-1024x128.webp\"><button\n\t\t\tclass=\"lightbox-trigger\"\n\t\t\ttype=\"button\"\n\t\t\taria-haspopup=\"dialog\"\n\t\t\taria-label=\"Enlarge\"\n\t\t\tdata-wp-init=\"callbacks.initTriggerButton\"\n\t\t\tdata-wp-on-async--click=\"actions.showLightbox\"\n\t\t\tdata-wp-style--right=\"state.imageButtonRight\"\n\t\t\tdata-wp-style--top=\"state.imageButtonTop\"\n\t\t>\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" fill=\"none\" viewBox=\"0 0 12 12\">\n\t\t\t\t<path fill=\"#fff\" d=\"M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z\" \/>\n\t\t\t<\/svg>\n\t\t<\/button><\/figure>\n\n\n\n<p>\n  In our GitHub Action, we then simply <a href=\"https:\/\/github.com\/drasi-project\/learning\/blob\/b826ab8a7e1116a274d3a670a270516d9eaa81d2\/.github\/workflows\/tutorial-evaluation-scheduled.yml#L143C11-L154C13\">grep for this specific string<\/a> to set the exit code of the workflow.\n<\/p>\n\n\n<figure data-wp-context=\"{&quot;imageId&quot;:&quot;69d7ed5825138&quot;}\" data-wp-interactive=\"core\/image\" class=\"wp-block-image size-large wp-lightbox-container\"><img decoding=\"async\" data-wp-class--hide=\"state.isContentHidden\" data-wp-class--show=\"state.isContentVisible\" data-wp-init=\"callbacks.setButtonStyles\" data-wp-on-async--click=\"actions.showLightbox\" data-wp-on-async--load=\"callbacks.setButtonStyles\" data-wp-on-async-window--resize=\"callbacks.setButtonStyles\" src=\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2026\/04\/image-1-1024x336.webp\" alt=\"\" class=\"wp-image-98448 webp-format\" srcset=\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2026\/04\/image-1-1024x336.webp 1024w, https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2026\/04\/image-1-388x127.webp 388w, https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2026\/04\/image-1-768x252.webp 768w, https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2026\/04\/image-1-450x148.webp 450w, https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2026\/04\/image-1-650x213.webp 650w, https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2026\/04\/image-1.webp 1080w\" data-orig-src=\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2026\/04\/image-1-1024x336.webp\"><button\n\t\t\tclass=\"lightbox-trigger\"\n\t\t\ttype=\"button\"\n\t\t\taria-haspopup=\"dialog\"\n\t\t\taria-label=\"Enlarge\"\n\t\t\tdata-wp-init=\"callbacks.initTriggerButton\"\n\t\t\tdata-wp-on-async--click=\"actions.showLightbox\"\n\t\t\tdata-wp-style--right=\"state.imageButtonRight\"\n\t\t\tdata-wp-style--top=\"state.imageButtonTop\"\n\t\t>\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" fill=\"none\" viewBox=\"0 0 12 12\">\n\t\t\t\t<path fill=\"#fff\" d=\"M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z\" \/>\n\t\t\t<\/svg>\n\t\t<\/button><\/figure>\n\n\n\n<p>Simple techniques like this bridge the gap between AI\u2019s fuzzy, probabilistic outputs and CI\u2019s binary pass\/fail expectations.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"automation\">Automation<\/h3>\n\n\n\n<p>We now have an <a href=\"https:\/\/github.com\/drasi-project\/learning\/blob\/main\/.github\/workflows\/tutorial-evaluation-scheduled.yml\">automated version of the workflow<\/a> which <a href=\"https:\/\/github.com\/drasi-project\/learning\/actions\/runs\/22225944239\/\">runs weekly<\/a>. This version evaluates all our tutorials every week in parallel\u2014each tutorial gets its own sandbox container and a fresh perspective from the agent acting as a synthetic user. If any of the tutorial evaluation fails, the workflow is configured to file an issue on our GitHub repo.<\/p>\n\n\n\n<p>This workflow can optionally also be run on pull-requests, but to prevent attacks we have added a maintainer-approval requirement and a `pull_request_target` trigger, which means that even on pull-requests by external contributors, the workflow that executes will be the one in our main branch. <\/p>\n\n\n\n<p>\n  Running the Copilot CLI requires a PAT token which is stored in the environment secrets for our repo. To make sure this does not leak, each run requires maintainer approval\u2014except the automated weekly run which only runs on the `main` branch of our repo.\n<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"what-we-found-bugs-that-matter\"><a id=\"post-98436-OLE_LINK21\"><\/a><a id=\"post-98436-OLE_LINK20\"><\/a>What we found: Bugs that matter<\/h2>\n\n\n\n<p>Since implementing this system, we have run over 200 &#8220;synthetic user&#8221; sessions. The agent identified 18 distinct issues including some serious environment issues and other documentation issues like these. <strong>Fixing them improved the docs for everyone, not just the bot<\/strong>.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Implicit dependencies<\/strong>: In one tutorial, we instructed users to create a tunnel to a service. The agent ran the command, and then\u2014following the next instruction\u2014killed the process to run the next command.<br><strong>The fix<\/strong>: We realized we hadn&#8217;t told the user to keep that terminal open. We added a warning: <em>&#8220;This command blocks. Open a new terminal for subsequent steps.&#8221;<\/em><\/li>\n\n\n\n<li><strong>Missing verification steps<\/strong>: We wrote: &#8220;Verify the query is running.&#8221; The agent got stuck: \u201cHow, exactly?\u201d<br><strong>The fix<\/strong>: We replaced the vague instruction with an explicit command: `drasi wait -f query.yaml`. <\/li>\n\n\n\n<li><strong>Format drift<\/strong>: Our CLI output had evolved. New columns were added; older fields were deprecated. The documentation screenshots still showed the 2024 version of the interface. A human tester might gloss over this (&#8220;it looks mostly right&#8221;). The agent flagged every mismatch, forcing us to keep our examples up to date.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"ai-as-a-force-multiplier\"><a id=\"post-98436-OLE_LINK23\"><\/a><a id=\"post-98436-OLE_LINK28\"><\/a><a id=\"post-98436-OLE_LINK29\"><\/a>AI as a force multiplier<\/h2>\n\n\n\n<p>\n  We often hear about AI replacing humans, but in this case, <strong>the AI is providing us with a workforce we never had<\/strong>.\n<\/p>\n\n\n\n<p>\n  To replicate what our system does\u2014running six tutorials across fresh environments every week\u2014we would need a dedicated QA resource or a significant budget for manual testing. For a four-person team, that is impossible. By deploying these <strong>Synthetic Users<\/strong>, we have effectively hired a tireless QA engineer who works nights, weekends, and holidays.\n<\/p>\n\n\n\n<p>Our tutorials are now validated weekly by synthetic users. <a href=\"https:\/\/drasi.io\/drasi-kubernetes\/getting-started\/\">try the Getting Started guide yourself<\/a> and see the results firsthand. And if you&#8217;re facing the same documentation drift in your own project, consider <a href=\"https:\/\/github.com\/features\/copilot\/cli\">GitHub Copilot CLI<\/a> not just as a coding assistant, but as an agent\u2014give it a prompt, a container, and a goal\u2014and let it do the work a human doesn&#8217;t have time for.<\/p>\n\n\n\n<div class=\"wp-block-buttons is-content-justification-center is-layout-flex wp-container-core-buttons-is-layout-16018d1d wp-block-buttons-is-layout-flex\">\n<div class=\"wp-block-button\"><a class=\"wp-block-button__link wp-element-button\" href=\"https:\/\/drasi.io\/drasi-kubernetes\/getting-started\/\" target=\"_blank\" rel=\"noreferrer noopener\">Get started with Drasi<\/a><\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>How Microsoft uses AI agents and Drasi to keep open\u2011source documentation accurate and working.<\/p>\n","protected":false},"author":6191,"featured_media":95464,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"msxcm_post_with_no_image":false,"ep_exclude_from_search":false,"_classifai_error":"","_classifai_text_to_speech_error":"","footnotes":""},"post_tag":[128,136,158,166,173],"content-type":[340],"topic":[],"programming-languages":[],"coauthors":[2634],"class_list":["post-98436","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","tag-docker","tag-github","tag-kubernetes","tag-azure","tag-mysql","content-type-tutorials-and-demos","review-flag-1593580428-734","review-flag-1-1593580432-963","review-flag-2-1593580437-411","review-flag-never-1593580314-283","review-flag-new-1593580248-669"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.2 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>How Drasi used GitHub Copilot to find documentation bugs | Microsoft Open Source Blog<\/title>\n<meta name=\"description\" content=\"Learn how GitHub Copilot CLI and AI agents automatically test tutorials, prevent documentation drift, and improve open-source onboarding.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/opensource.microsoft.com\/blog\/2026\/04\/09\/how-drasi-used-github-copilot-to-find-documentation-bugs\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"How Drasi used GitHub Copilot to find documentation bugs | Microsoft Open Source Blog\" \/>\n<meta property=\"og:description\" content=\"Learn how GitHub Copilot CLI and AI agents automatically test tutorials, prevent documentation drift, and improve open-source onboarding.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/opensource.microsoft.com\/blog\/2026\/04\/09\/how-drasi-used-github-copilot-to-find-documentation-bugs\/\" \/>\n<meta property=\"og:site_name\" content=\"Microsoft Open Source Blog\" \/>\n<meta property=\"article:published_time\" content=\"2026-04-09T15:00:00+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2024\/06\/CLO19_Ubisoft_Azure_030.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1170\" \/>\n\t<meta property=\"og:image:height\" content=\"640\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Aman Singh\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@OpenAtMicrosoft\" \/>\n<meta name=\"twitter:site\" content=\"@OpenAtMicrosoft\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Aman Singh\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"6 min read\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/2026\/04\/09\/how-drasi-used-github-copilot-to-find-documentation-bugs\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/2026\/04\/09\/how-drasi-used-github-copilot-to-find-documentation-bugs\/\"},\"author\":[{\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/author\/aman-singh\/\",\"@type\":\"Person\",\"@name\":\"Aman Singh\"}],\"headline\":\"How Drasi used GitHub Copilot to find documentation bugs\",\"datePublished\":\"2026-04-09T15:00:00+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/2026\/04\/09\/how-drasi-used-github-copilot-to-find-documentation-bugs\/\"},\"wordCount\":1528,\"publisher\":{\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/2026\/04\/09\/how-drasi-used-github-copilot-to-find-documentation-bugs\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2024\/06\/CLO19_Ubisoft_Azure_030.webp\",\"keywords\":[\"Docker\",\"GitHub\",\"Kubernetes\",\"Microsoft Azure\",\"MySQL\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/2026\/04\/09\/how-drasi-used-github-copilot-to-find-documentation-bugs\/\",\"url\":\"https:\/\/opensource.microsoft.com\/blog\/2026\/04\/09\/how-drasi-used-github-copilot-to-find-documentation-bugs\/\",\"name\":\"How Drasi used GitHub Copilot to find documentation bugs | Microsoft Open Source Blog\",\"isPartOf\":{\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/2026\/04\/09\/how-drasi-used-github-copilot-to-find-documentation-bugs\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/2026\/04\/09\/how-drasi-used-github-copilot-to-find-documentation-bugs\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2024\/06\/CLO19_Ubisoft_Azure_030.webp\",\"datePublished\":\"2026-04-09T15:00:00+00:00\",\"description\":\"Learn how GitHub Copilot CLI and AI agents automatically test tutorials, prevent documentation drift, and improve open-source onboarding.\",\"breadcrumb\":{\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/2026\/04\/09\/how-drasi-used-github-copilot-to-find-documentation-bugs\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/opensource.microsoft.com\/blog\/2026\/04\/09\/how-drasi-used-github-copilot-to-find-documentation-bugs\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/2026\/04\/09\/how-drasi-used-github-copilot-to-find-documentation-bugs\/#primaryimage\",\"url\":\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2024\/06\/CLO19_Ubisoft_Azure_030.webp\",\"contentUrl\":\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2024\/06\/CLO19_Ubisoft_Azure_030.webp\",\"width\":1170,\"height\":640,\"caption\":\"A woman smiles at coworker in an office.\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/2026\/04\/09\/how-drasi-used-github-copilot-to-find-documentation-bugs\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/opensource.microsoft.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"How Drasi used GitHub Copilot to find documentation bugs\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/#website\",\"url\":\"https:\/\/opensource.microsoft.com\/blog\/\",\"name\":\"Microsoft Open Source Blog\",\"description\":\"Open dialogue about openness at Microsoft \u2013 open source, standards, interoperability\",\"publisher\":{\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/opensource.microsoft.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/#organization\",\"name\":\"Microsoft Open Source Blog\",\"url\":\"https:\/\/opensource.microsoft.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2019\/08\/Microsoft-Logo.png\",\"contentUrl\":\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2019\/08\/Microsoft-Logo.png\",\"width\":259,\"height\":194,\"caption\":\"Microsoft Open Source Blog\"},\"image\":{\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/x.com\/OpenAtMicrosoft\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"How Drasi used GitHub Copilot to find documentation bugs | Microsoft Open Source Blog","description":"Learn how GitHub Copilot CLI and AI agents automatically test tutorials, prevent documentation drift, and improve open-source onboarding.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/opensource.microsoft.com\/blog\/2026\/04\/09\/how-drasi-used-github-copilot-to-find-documentation-bugs\/","og_locale":"en_US","og_type":"article","og_title":"How Drasi used GitHub Copilot to find documentation bugs | Microsoft Open Source Blog","og_description":"Learn how GitHub Copilot CLI and AI agents automatically test tutorials, prevent documentation drift, and improve open-source onboarding.","og_url":"https:\/\/opensource.microsoft.com\/blog\/2026\/04\/09\/how-drasi-used-github-copilot-to-find-documentation-bugs\/","og_site_name":"Microsoft Open Source Blog","article_published_time":"2026-04-09T15:00:00+00:00","og_image":[{"width":1170,"height":640,"url":"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2024\/06\/CLO19_Ubisoft_Azure_030.png","type":"image\/png"}],"author":"Aman Singh","twitter_card":"summary_large_image","twitter_creator":"@OpenAtMicrosoft","twitter_site":"@OpenAtMicrosoft","twitter_misc":{"Written by":"Aman Singh","Est. reading time":"6 min read"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/opensource.microsoft.com\/blog\/2026\/04\/09\/how-drasi-used-github-copilot-to-find-documentation-bugs\/#article","isPartOf":{"@id":"https:\/\/opensource.microsoft.com\/blog\/2026\/04\/09\/how-drasi-used-github-copilot-to-find-documentation-bugs\/"},"author":[{"@id":"https:\/\/opensource.microsoft.com\/blog\/author\/aman-singh\/","@type":"Person","@name":"Aman Singh"}],"headline":"How Drasi used GitHub Copilot to find documentation bugs","datePublished":"2026-04-09T15:00:00+00:00","mainEntityOfPage":{"@id":"https:\/\/opensource.microsoft.com\/blog\/2026\/04\/09\/how-drasi-used-github-copilot-to-find-documentation-bugs\/"},"wordCount":1528,"publisher":{"@id":"https:\/\/opensource.microsoft.com\/blog\/#organization"},"image":{"@id":"https:\/\/opensource.microsoft.com\/blog\/2026\/04\/09\/how-drasi-used-github-copilot-to-find-documentation-bugs\/#primaryimage"},"thumbnailUrl":"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2024\/06\/CLO19_Ubisoft_Azure_030.webp","keywords":["Docker","GitHub","Kubernetes","Microsoft Azure","MySQL"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/opensource.microsoft.com\/blog\/2026\/04\/09\/how-drasi-used-github-copilot-to-find-documentation-bugs\/","url":"https:\/\/opensource.microsoft.com\/blog\/2026\/04\/09\/how-drasi-used-github-copilot-to-find-documentation-bugs\/","name":"How Drasi used GitHub Copilot to find documentation bugs | Microsoft Open Source Blog","isPartOf":{"@id":"https:\/\/opensource.microsoft.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/opensource.microsoft.com\/blog\/2026\/04\/09\/how-drasi-used-github-copilot-to-find-documentation-bugs\/#primaryimage"},"image":{"@id":"https:\/\/opensource.microsoft.com\/blog\/2026\/04\/09\/how-drasi-used-github-copilot-to-find-documentation-bugs\/#primaryimage"},"thumbnailUrl":"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2024\/06\/CLO19_Ubisoft_Azure_030.webp","datePublished":"2026-04-09T15:00:00+00:00","description":"Learn how GitHub Copilot CLI and AI agents automatically test tutorials, prevent documentation drift, and improve open-source onboarding.","breadcrumb":{"@id":"https:\/\/opensource.microsoft.com\/blog\/2026\/04\/09\/how-drasi-used-github-copilot-to-find-documentation-bugs\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/opensource.microsoft.com\/blog\/2026\/04\/09\/how-drasi-used-github-copilot-to-find-documentation-bugs\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/opensource.microsoft.com\/blog\/2026\/04\/09\/how-drasi-used-github-copilot-to-find-documentation-bugs\/#primaryimage","url":"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2024\/06\/CLO19_Ubisoft_Azure_030.webp","contentUrl":"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2024\/06\/CLO19_Ubisoft_Azure_030.webp","width":1170,"height":640,"caption":"A woman smiles at coworker in an office."},{"@type":"BreadcrumbList","@id":"https:\/\/opensource.microsoft.com\/blog\/2026\/04\/09\/how-drasi-used-github-copilot-to-find-documentation-bugs\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/opensource.microsoft.com\/blog\/"},{"@type":"ListItem","position":2,"name":"How Drasi used GitHub Copilot to find documentation bugs"}]},{"@type":"WebSite","@id":"https:\/\/opensource.microsoft.com\/blog\/#website","url":"https:\/\/opensource.microsoft.com\/blog\/","name":"Microsoft Open Source Blog","description":"Open dialogue about openness at Microsoft \u2013 open source, standards, interoperability","publisher":{"@id":"https:\/\/opensource.microsoft.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/opensource.microsoft.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/opensource.microsoft.com\/blog\/#organization","name":"Microsoft Open Source Blog","url":"https:\/\/opensource.microsoft.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/opensource.microsoft.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2019\/08\/Microsoft-Logo.png","contentUrl":"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2019\/08\/Microsoft-Logo.png","width":259,"height":194,"caption":"Microsoft Open Source Blog"},"image":{"@id":"https:\/\/opensource.microsoft.com\/blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/x.com\/OpenAtMicrosoft"]}]}},"msxcm_display_generated_audio":true,"msxcm_animated_featured_image":null,"distributor_meta":false,"distributor_terms":false,"distributor_media":false,"distributor_original_site_name":"Microsoft Open Source Blog","distributor_original_site_url":"https:\/\/opensource.microsoft.com\/blog","push-errors":false,"_links":{"self":[{"href":"https:\/\/opensource.microsoft.com\/blog\/wp-json\/wp\/v2\/posts\/98436","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/opensource.microsoft.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/opensource.microsoft.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/opensource.microsoft.com\/blog\/wp-json\/wp\/v2\/users\/6191"}],"replies":[{"embeddable":true,"href":"https:\/\/opensource.microsoft.com\/blog\/wp-json\/wp\/v2\/comments?post=98436"}],"version-history":[{"count":21,"href":"https:\/\/opensource.microsoft.com\/blog\/wp-json\/wp\/v2\/posts\/98436\/revisions"}],"predecessor-version":[{"id":98473,"href":"https:\/\/opensource.microsoft.com\/blog\/wp-json\/wp\/v2\/posts\/98436\/revisions\/98473"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/opensource.microsoft.com\/blog\/wp-json\/wp\/v2\/media\/95464"}],"wp:attachment":[{"href":"https:\/\/opensource.microsoft.com\/blog\/wp-json\/wp\/v2\/media?parent=98436"}],"wp:term":[{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/opensource.microsoft.com\/blog\/wp-json\/wp\/v2\/post_tag?post=98436"},{"taxonomy":"content-type","embeddable":true,"href":"https:\/\/opensource.microsoft.com\/blog\/wp-json\/wp\/v2\/content-type?post=98436"},{"taxonomy":"topic","embeddable":true,"href":"https:\/\/opensource.microsoft.com\/blog\/wp-json\/wp\/v2\/topic?post=98436"},{"taxonomy":"programming-languages","embeddable":true,"href":"https:\/\/opensource.microsoft.com\/blog\/wp-json\/wp\/v2\/programming-languages?post=98436"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/opensource.microsoft.com\/blog\/wp-json\/wp\/v2\/coauthors?post=98436"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}