<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0"><channel><title>Pulumi Blog: Artur Laksberg</title><link>https://www.pulumi.com/blog/author/artur-laksberg/</link><description>Pulumi blog posts: Artur Laksberg.</description><language>en-us</language><pubDate>Tue, 07 Oct 2025 00:00:00 +0000</pubDate><item><title>Announcing Pulumi Remote MCP Server</title><link>https://www.pulumi.com/blog/remote-mcp-server/</link><pubDate>Tue, 07 Oct 2025 00:00:00 +0000</pubDate><guid>https://www.pulumi.com/blog/remote-mcp-server/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/remote-mcp-server/index.png" /&gt;
&lt;p&gt;We&amp;rsquo;re excited to announce the Pulumi Remote MCP Server—a hosted service that brings AI-powered infrastructure management to any AI assistant that supports the &lt;a href="https://modelcontextprotocol.io"&gt;Model Context Protocol&lt;/a&gt;. Connect your favorite AI assistant to &lt;code&gt;https://mcp.ai.pulumi.com/mcp&lt;/code&gt; and instantly access your Pulumi Cloud infrastructure, search resources across stacks, and delegate complex automation tasks to &lt;a href="https://www.pulumi.com/docs/pulumi-cloud/neo/"&gt;Pulumi Neo&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="the-evolution-of-pulumi-mcp"&gt;The Evolution of Pulumi MCP&lt;/h2&gt;
&lt;p&gt;Earlier this year, we &lt;a href="https://www.pulumi.com/blog/mcp-server-ai-assistants/"&gt;launched the Pulumi MCP server&lt;/a&gt; as a local npm package that brought AI-assisted infrastructure management to developers&amp;rsquo; machines. The adoption and feedback from users and partners has been positive, validating the power of combining AI assistants with infrastructure-as-code.&lt;/p&gt;
&lt;p&gt;As the MCP ecosystem has matured and more organizations have adopted the protocol, a clear pattern has emerged: remote MCP servers are becoming the industry standard. Remote servers provide a key advantage—&lt;strong&gt;accessibility&lt;/strong&gt;. One endpoint works everywhere, with no per-machine setup.&lt;/p&gt;
&lt;p&gt;Following industry trends and feedback from users and partners, we&amp;rsquo;re introducing the Remote MCP Server to ease installation and version management. The remote server preserves everything developers love about the local version while adding powerful new capabilities like seamless Pulumi Neo integration.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The local MCP server continues to be available and fully supported for developers who prefer local tooling or need offline capabilities.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="why-remote-mcp"&gt;Why Remote MCP?&lt;/h2&gt;
&lt;p&gt;The Pulumi Remote MCP Server runs as a hosted service. Instead of managing local installations, you configure it once and get automatic updates and consistent functionality across all your development environments.&lt;/p&gt;
&lt;h3 id="zero-local-setup-universal-access"&gt;Zero local setup, universal access&lt;/h3&gt;
&lt;p&gt;Instead of installing npm packages, you simply configure your AI assistant with a single URL: &lt;code&gt;https://mcp.ai.pulumi.com/mcp&lt;/code&gt;. That&amp;rsquo;s it.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;No per-machine installations&lt;/strong&gt; - Works the same on your laptop, desktop, or cloud workstation&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No manual updates&lt;/strong&gt; - New features and improvements roll out automatically to all users&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Works with any MCP-compatible AI assistant&lt;/strong&gt; - Cursor, Claude Code, Windsurf, Claude Desktop, and more&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For instructions on how to configure different AI assistants, see &lt;a href="https://www.pulumi.com/docs/iac/using-pulumi/mcp-server"&gt;Pulumi MCP Server&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id="centralized-authentication--secrets"&gt;Centralized authentication &amp;amp; secrets&lt;/h3&gt;
&lt;p&gt;Remote MCP also solves a critical security challenge: credential management. Instead of scattering Pulumi Access Tokens across laptops, containers, and scripts, the Remote MCP Server uses OAuth-based authentication with your Pulumi Cloud organization.&lt;/p&gt;
&lt;p&gt;When you first connect, a browser window opens where you:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Enter your Pulumi Access Token (which is validated server-side)&lt;/li&gt;
&lt;li&gt;Select which organization to access&lt;/li&gt;
&lt;li&gt;Return to your AI assistant - now authenticated&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Your credentials are stored securely in Pulumi Cloud, not on your individual machine.&lt;/p&gt;
&lt;h2 id="what-can-you-do-with-it"&gt;What Can You Do With It?&lt;/h2&gt;
&lt;p&gt;The Remote MCP Server is your AI assistant&amp;rsquo;s gateway to your entire Pulumi infrastructure. It combines real-time access to your cloud resources with the power of autonomous infrastructure automation through Pulumi Neo.&lt;/p&gt;
&lt;h3 id="discover-and-query-infrastructure"&gt;Discover and query infrastructure&lt;/h3&gt;
&lt;p&gt;Your AI assistant can instantly explore what you&amp;rsquo;ve deployed across your entire organization:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;List all stacks in your organization&lt;/li&gt;
&lt;li&gt;Search for specific resources across all stacks&lt;/li&gt;
&lt;li&gt;Find resources by type, name, tags, or any property&lt;/li&gt;
&lt;li&gt;Check for policy violations&lt;/li&gt;
&lt;li&gt;View organization members and their roles&lt;/li&gt;
&lt;li&gt;Identify security gaps, untagged resources, or misconfigured infrastructure&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ask questions like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&amp;ldquo;Show me all RDS databases without encryption enabled&amp;rdquo;&lt;/li&gt;
&lt;li&gt;&amp;ldquo;Which stacks have resources in us-east-1?&amp;rdquo;&lt;/li&gt;
&lt;li&gt;&amp;ldquo;Find all Lambda functions using deprecated runtimes&amp;rdquo;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="generate-infrastructure-code"&gt;Generate infrastructure code&lt;/h3&gt;
&lt;p&gt;The MCP server connects directly to the &lt;a href="https://www.pulumi.com/registry/"&gt;Pulumi Registry&lt;/a&gt;, giving your AI assistant access to thousands of cloud resources with complete type information:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Browse available resources&lt;/li&gt;
&lt;li&gt;Get detailed resource schemas&lt;/li&gt;
&lt;li&gt;Access property documentation, input/output types, and examples&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Your AI assistant can:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Look up the exact properties for any cloud resource&lt;/li&gt;
&lt;li&gt;Generate type-safe infrastructure code in TypeScript, Python, Go, or any Pulumi language&lt;/li&gt;
&lt;li&gt;Include proper configurations, security settings, and best practices&lt;/li&gt;
&lt;li&gt;Reference real documentation and examples&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This means code generation is more accurate and up-to-date with the latest provider versions.&lt;/p&gt;
&lt;h3 id="autonomous-infrastructure-with-pulumi-neo"&gt;Autonomous infrastructure with Pulumi Neo&lt;/h3&gt;
&lt;p&gt;This is where the Remote MCP Server truly shines. For complex infrastructure tasks that require multiple steps, code changes, testing, and pull requests, your AI assistant can delegate directly to &lt;a href="https://www.pulumi.com/docs/pulumi-cloud/neo/"&gt;Pulumi Neo&lt;/a&gt;—Pulumi&amp;rsquo;s autonomous infrastructure AI agent.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What makes Neo special:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Neo isn&amp;rsquo;t just an AI that writes code—it&amp;rsquo;s an AI that &lt;em&gt;ships&lt;/em&gt; infrastructure changes autonomously:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Multi-step planning&lt;/strong&gt; - Neo breaks down complex requests into actionable plans&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Code generation at scale&lt;/strong&gt; - Works across multiple stacks and repositories&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Automated testing&lt;/strong&gt; - Validates changes before creating pull requests&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pull request workflows&lt;/strong&gt; - Creates PRs with detailed explanations and comments&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Continuous execution&lt;/strong&gt; - Runs in Pulumi Cloud, not consuming your local resources&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Human-in-the-loop&lt;/strong&gt; - Pauses for approval on critical changes&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Real-world Neo examples:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Security remediation:
&lt;strong&gt;&amp;ldquo;Ask Neo to find all security groups allowing SSH from 0.0.0.0/0 and create a PR restricting them to my office IP&amp;rdquo;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Neo will:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Search your infrastructure for overly permissive security groups&lt;/li&gt;
&lt;li&gt;Create a detailed plan for restricting access&lt;/li&gt;
&lt;li&gt;Generate infrastructure code changes&lt;/li&gt;
&lt;li&gt;Create a pull request with explanations&lt;/li&gt;
&lt;li&gt;Wait for your approval to merge&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Runtime migrations:
&lt;strong&gt;&amp;ldquo;Ask Neo to migrate all Lambda functions from Python 3.8 to Python 3.12 and create PRs for each affected stack&amp;rdquo;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Neo handles:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Finding all Lambda functions with Python 3.8&lt;/li&gt;
&lt;li&gt;Checking for compatibility issues&lt;/li&gt;
&lt;li&gt;Updating runtime configurations&lt;/li&gt;
&lt;li&gt;Running tests to ensure functionality&lt;/li&gt;
&lt;li&gt;Creating separate PRs per stack for easy review&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Policy compliance:
&lt;strong&gt;&amp;ldquo;Ask Neo to scan for policy violations and fix them automatically&amp;rdquo;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Neo will:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Identify violations across all stacks&lt;/li&gt;
&lt;li&gt;Generate fixes following your policy rules&lt;/li&gt;
&lt;li&gt;Test changes to ensure compliance&lt;/li&gt;
&lt;li&gt;Create PRs with clear explanations of what was fixed and why&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Cost optimization:
&lt;strong&gt;&amp;ldquo;Ask Neo to find idle resources and create a plan to shut them down&amp;rdquo;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Neo analyzes usage patterns, identifies waste, and proposes infrastructure changes to reduce costs—all autonomously.&lt;/p&gt;
&lt;p&gt;The key difference: your AI assistant identifies &lt;em&gt;what&lt;/em&gt; needs to be done, and Neo &lt;em&gt;does&lt;/em&gt; it—writing code, running tests, creating PRs, and managing the entire workflow in Pulumi Cloud.&lt;/p&gt;
&lt;h2 id="real-world-workflow"&gt;Real-World Workflow&lt;/h2&gt;
&lt;p&gt;Here&amp;rsquo;s what a typical session looks like:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;You:&lt;/strong&gt; &amp;ldquo;What stacks do I have with &amp;lsquo;production&amp;rsquo; in the name?&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;AI Assistant:&lt;/strong&gt; Uses &lt;code&gt;get-stacks&lt;/code&gt; to list: &lt;code&gt;api-production&lt;/code&gt;, &lt;code&gt;web-production&lt;/code&gt;, &lt;code&gt;data-production&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;You:&lt;/strong&gt; &amp;ldquo;Are there any policy violations in those stacks?&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;AI Assistant:&lt;/strong&gt; Uses &lt;code&gt;get-policy-violations&lt;/code&gt; and reports: 3 S3 buckets without encryption, 2 security groups too permissive&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;You:&lt;/strong&gt; &amp;ldquo;Ask Neo to fix those violations and create a PR&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;AI Assistant:&lt;/strong&gt; Uses &lt;code&gt;neo-bridge&lt;/code&gt; to launch Neo task, provides link&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Neo:&lt;/strong&gt; Autonomously creates plan, generates fixes, tests changes, creates PR with detailed explanation&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;You:&lt;/strong&gt; Review PR, approve, merge&lt;/p&gt;
&lt;h2 id="getting-started"&gt;Getting Started&lt;/h2&gt;
&lt;p&gt;Ready to try it? Check out our &lt;a href="https://www.pulumi.com/docs/iac/using-pulumi/mcp-server/"&gt;documentation&lt;/a&gt; for configuration instructions for your AI assistant of choice.&lt;/p&gt;
&lt;p&gt;Key points:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Configure once&lt;/strong&gt; - Add &lt;code&gt;https://mcp.ai.pulumi.com/mcp&lt;/code&gt; to your AI assistant&amp;rsquo;s MCP settings&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Authenticate&lt;/strong&gt; - Browser popup for token entry and org selection (one time)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Start asking&lt;/strong&gt; - Query your infrastructure, generate code, delegate to Neo&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The Remote MCP Server is available now for all Pulumi users. No installation required—just configure and connect.&lt;/p&gt;
&lt;h2 id="learn-more"&gt;Learn More&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/docs/iac/using-pulumi/mcp-server/"&gt;Pulumi MCP Server Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/docs/pulumi-cloud/neo/"&gt;Pulumi Neo Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://modelcontextprotocol.io"&gt;Model Context Protocol&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We&amp;rsquo;re excited to see what you build with AI-assisted infrastructure management. Let us know what you think in our &lt;a href="https://slack.pulumi.com"&gt;Community Slack&lt;/a&gt;!&lt;/p&gt;</description><author>Artur Laksberg</author><category>mcp</category><category>ai</category></item><item><title>Pulumi Updates, Explained: AI-Powered Features in Pulumi CLI</title><link>https://www.pulumi.com/blog/cli-ai-extensions/</link><pubDate>Thu, 22 May 2025 00:00:00 +0000</pubDate><guid>https://www.pulumi.com/blog/cli-ai-extensions/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/cli-ai-extensions/index.png" /&gt;
&lt;div class="note note-info"&gt;
&lt;div class="icon-and-line"&gt;
&lt;svg xmlns="http://www.w3.org/2000/svg" class="ph-icon ph-icon--fill" fill="currentColor" aria-hidden="true" focusable="false"&gt;&lt;use href="https://www.pulumi.com/icons/sprite.74fadd1b94bae866bccf29a780f184a71c5cfc34c8677be70da8fe2ab0309b9e.svg#p-info-fill"/&gt;&lt;/svg&gt;
&lt;div class="line"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="content"&gt;Note: This post discusses Pulumi Copilot, which Pulumi Neo has replaced. &lt;a href="https://www.pulumi.com/docs/ai/"&gt;Learn about Neo →&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;We&amp;rsquo;re excited to announce the new AI capabilities for Pulumi CLI powered by Pulumi Copilot that translate complex infrastructure changes into clear, human-readable explanations and help resolve deployment errors with actionable guidance. Enable these preview features with the &lt;code&gt;--copilot&lt;/code&gt; flag.&lt;/p&gt;
&lt;p&gt;At Pulumi, we&amp;rsquo;re committed to helping you deploy infrastructure efficiently and with minimal friction. Anyone who has worked with cloud infrastructure knows the frustration of sifting through large previews with numerous changes and the difficulty of interpreting cryptic error messages from cloud provider APIs when deployments fail.&lt;/p&gt;
&lt;p&gt;There are two key challenges we&amp;rsquo;ve identified:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Understanding Preview Changes&lt;/strong&gt;: Reviewing raw update previews can be overwhelming, especially for complex deployments with many resources. It&amp;rsquo;s difficult to quickly grasp the full scope and impact of pending infrastructure changes.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Interpreting Error Messages&lt;/strong&gt;: When deployments fail, cloud providers often return error messages that, while comprehensive, bury the core issue within extensive diagnostics, requiring specialized expertise to interpret and address.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Our latest CLI update introduces AI capabilities that tackle both issues. Let&amp;rsquo;s explore how these new features improve your infrastructure management workflow.&lt;/p&gt;
&lt;h2 id="update-explanation"&gt;Update Explanation&lt;/h2&gt;
&lt;p&gt;To address the first challenge above, we&amp;rsquo;ve introduced a new &amp;ldquo;explain&amp;rdquo; menu item in the CLI. When running pulumi preview or &lt;code&gt;pulumi up&lt;/code&gt; with the &lt;code&gt;--copilot&lt;/code&gt; flag, you&amp;rsquo;ll see this option in the interactive menu:&lt;/p&gt;
&lt;p&gt;&lt;img src="preview.png" alt="Preview menu with the explain option"&gt;&lt;/p&gt;
&lt;p&gt;In this screenshot, you can see the standard Pulumi update preview showing an AWS VPC with multiple subnets, route tables, and gateways that need to be updated. The interactive menu at the bottom shows the new &amp;ldquo;explain&amp;rdquo; option with a sparkle emoji, indicating the AI-powered feature.
When selected, this tool analyzes and provides a clear summary of all changes in your pending infrastructure update:&lt;/p&gt;
&lt;p&gt;&lt;img src="explain.png" alt="Preview explanation by Pulumi Copilot"&gt;&lt;/p&gt;
&lt;p&gt;In this example, the AI explanation immediately identifies that this is a &amp;ldquo;VPC Renaming Operation - Tag Updates Only&amp;rdquo; and explains that the update is simply changing tags across all components. It clearly states this is a &amp;ldquo;safe, non-disruptive change that only affects resource labels.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;This explanation serves as a valuable sanity check before deployment. It presents a plain-language summary of exactly what changes will occur, helping you verify that the planned modifications align with your intentions. This visibility is particularly valuable when managing complex infrastructure with many resources, as it helps identify unexpected changes or potential drift between your code and deployed resources. The system also proactively flags potential issues such as security vulnerabilities or destructive updates that might impact your production environment.&lt;/p&gt;
&lt;h2 id="diagnostics-summarization"&gt;Diagnostics Summarization&lt;/h2&gt;
&lt;p&gt;For the second challenge, when infrastructure deployments fail, cloud providers often return error messages that are technically accurate but difficult to decipher without specialized knowledge. Consider the following scenario where a Go-based Docker image build fails with vendoring issues:&lt;/p&gt;
&lt;p&gt;&lt;img src="summary.png" alt="Error from the Docker Build provider"&gt;&lt;/p&gt;
&lt;p&gt;In this example, the standard Go build process failed with a cryptic error about inconsistent vendoring. While the raw output does contain the necessary information, it&amp;rsquo;s buried within extensive build logs. Our AI-powered Copilot diagnostics immediately identifies the problem and provides a clear, actionable solution: &amp;ldquo;Docker image update failed due to inconsistent vendoring. Sync vendor with &amp;lsquo;go mod vendor&amp;rsquo;.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;This clear explanation identifies root causes and provides actionable guidance, transforming dense technical output into concise explanations. It reduces time to resolution by pinpointing both the problem and the exact command needed to fix it, eliminating the need to search through documentation or guess.&lt;/p&gt;
&lt;h2 id="getting-started"&gt;Getting Started&lt;/h2&gt;
&lt;p&gt;The AI-powered features are currently in preview. You can enable them by adding the &lt;code&gt;--copilot&lt;/code&gt; flag to your Pulumi CLI commands:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pulumi preview --copilot
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pulumi up --copilot
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;These features require Pulumi CLI version v3.171.0 or greater and the Pulumi Cloud backend. Organization administrators must enable Pulumi Copilot by navigating to &lt;strong&gt;Settings &amp;gt; Access Management &amp;gt; Pulumi Copilot&lt;/strong&gt; in the Pulumi Cloud console.&lt;/p&gt;
&lt;p&gt;During this preview period, we&amp;rsquo;re focused on:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Refining explanations based on user feedback&lt;/li&gt;
&lt;li&gt;Adding new capabilities like suggesting fixes for common errors&lt;/li&gt;
&lt;li&gt;Improving performance to ensure minimal impact on command execution time&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We will continue to monitor usage patterns and incorporate your feedback before enabling these features by default.&lt;/p&gt;
&lt;h2 id="share-your-feedback"&gt;Share Your Feedback&lt;/h2&gt;
&lt;p&gt;We&amp;rsquo;re excited to see how these AI-powered insights enhance your infrastructure deployment workflow! Please share your experiences with us:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Connect with us in the &lt;a href="https://slack.pulumi.com"&gt;Pulumi Community Slack&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Open an issue on &lt;a href="https://github.com/pulumi/pulumi"&gt;GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Learn more about &lt;a href="http://pulumi.com/copilot"&gt;Pulumi Copilot&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Try this today, &lt;a href="https://pulumi.com/start"&gt;Get Started with Pulumi for free&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Your input will directly influence how we evolve these features from preview to general availability.&lt;/p&gt;</description><author>Artur Laksberg</author><author>Mikhail Shilkov</author><author>Simon Howe</author><category>copilot</category><category>ai</category><category>infrastructure-as-code</category><category>cli</category></item><item><title>A Recipe for a Better AI-based Code Generator</title><link>https://www.pulumi.com/blog/codegen-learnings/</link><pubDate>Tue, 07 Jan 2025 20:00:00 -0500</pubDate><guid>https://www.pulumi.com/blog/codegen-learnings/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/codegen-learnings/index.png" /&gt;
&lt;div class="note note-info"&gt;
&lt;div class="icon-and-line"&gt;
&lt;svg xmlns="http://www.w3.org/2000/svg" class="ph-icon ph-icon--fill" fill="currentColor" aria-hidden="true" focusable="false"&gt;&lt;use href="https://www.pulumi.com/icons/sprite.74fadd1b94bae866bccf29a780f184a71c5cfc34c8677be70da8fe2ab0309b9e.svg#p-info-fill"/&gt;&lt;/svg&gt;
&lt;div class="line"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="content"&gt;Note: This post discusses Pulumi Copilot, which Pulumi Neo has replaced. &lt;a href="https://www.pulumi.com/docs/ai/"&gt;Learn about Neo →&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;When asked about his research process, Anthony Bourdain would describe how he&amp;rsquo;d blend his formal culinary training with deep dives into local food culture - from market stalls to family recipes. Modern AI code generation follows a similar path: it can&amp;rsquo;t just rely on what it knows - it must tap into continuously evolving, domain-specific knowledge bases. Just as Bourdain would combine his classical French training with techniques learned from local kitchens, AI code generators blend their built-in knowledge with retrieved code snippets and type definitions to generate code that accurately represents the user&amp;rsquo;s intent.&lt;/p&gt;
&lt;p&gt;This fusion of base knowledge with contextual understanding is especially valuable for Infrastructure as Code (IaC), where rapidly evolving cloud providers and libraries make manual development challenging, traditional debugging cycles impractical, and errors catastrophically expensive.&lt;/p&gt;
&lt;p&gt;The role of IaC won&amp;rsquo;t diminish in the age of AI - if anything, it will become even more central as systems grow increasingly complex and automated. Trustworthy code generators will be a key ingredient in the recipe for modern infrastructure management.&lt;/p&gt;
&lt;p&gt;In this post, we share how we developed code generation for Pulumi and what we learned, based on both our production IaC generator powering &lt;a href="https://www.pulumi.com/solutions/ai/"&gt;Pulumi AI&lt;/a&gt; and &lt;a href="https://www.pulumi.com/product/copilot/"&gt;Pulumi Copilot&lt;/a&gt;, as well as features and approaches we&amp;rsquo;re still exploring.&lt;/p&gt;
&lt;h2 id="using-rag-for-code-generation"&gt;Using RAG for code generation&lt;/h2&gt;
&lt;p&gt;Pulumi supports over &lt;a href="https://www.pulumi.com/registry/"&gt;120 providers&lt;/a&gt;, including major cloud providers such as AWS, Azure, Google Cloud, and Kubernetes, as well as many other services and platforms. New providers are continuously added, and existing providers change as their capabilities grow.&lt;/p&gt;
&lt;p&gt;Our goal is to generate the most accurate code for every provider - code that is not only correct but also reflects their latest capabilities.&lt;/p&gt;
&lt;p&gt;LLMs are great at generating code however they are limited to what they have learned before their knowledge cutoff date. This means that the latest changes in the providers will not be reflected in the generated code. This also could lead to hallucinations when the model struggles to answer a question that requires up to date knowledge.&lt;/p&gt;
&lt;p&gt;To help us solve this, we rely on the technique known as the &lt;em&gt;Retrieval Augmented Generation&lt;/em&gt; (RAG). RAG helps code generation by integrating information retrieved from external data sources. In Pulumi, we call this data source the &lt;em&gt;Registry&lt;/em&gt; - it&amp;rsquo;s the database we maintain that contains type schema and usage information for every provider.&lt;/p&gt;
&lt;p&gt;At a high level, using RAG involves the following steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Analyze user&amp;rsquo;s question.&lt;/li&gt;
&lt;li&gt;Look up the pertinent information from the Registry.&lt;/li&gt;
&lt;li&gt;Format that information in a system prompt that LLM can understand.&lt;/li&gt;
&lt;li&gt;Make the LLM call asking it to generate the code using the additional information in the prompt.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;There is lot of fascinating details here, so let&amp;rsquo;s dig in!&lt;/p&gt;
&lt;h2 id="the-anatomy-of-pulumi-copilot-rag"&gt;The anatomy of Pulumi Copilot RAG&lt;/h2&gt;
&lt;p&gt;Before going into the details, let’s consider a simple yet essential insight: an effective dataset for RAG must meet two key requirements:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;It must &lt;em&gt;contain&lt;/em&gt; the necessary information.&lt;/li&gt;
&lt;li&gt;The information must be easily &lt;em&gt;searchable&lt;/em&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Let&amp;rsquo;s take a sample user query:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;Generate code for S3 Bucket&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;To fulfil the request, the system needs to intuit the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;cloud provider&lt;/strong&gt;. This can be determined based on the fact that S3 is a common storage solution in AWS, and possibly the fact that the user&amp;rsquo;s &lt;a href="https://www.pulumi.com/blog/copilot-system-prompts/"&gt;organization has stated&lt;/a&gt; AWS as their preferred cloud provider.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;programming language&lt;/strong&gt;. This information can again come directly from the organizational preferences, or from the user&amp;rsquo;s prior conversations.&lt;/li&gt;
&lt;li&gt;The information about the &lt;strong&gt;type&lt;/strong&gt; (or types) that must be created - its name and schema, the package it is in, and the capabilities it supports. Some of this information comes from the built-in LLM knowledge, supported and augmented by the Registry.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Putting it all together, we can now expand the original user query into the following prompt that is going to guide the code generation:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;Generate TypeScript code for S3 Bucket, the AWS resource defined in package &lt;code&gt;@pulumi/aws&lt;/code&gt;, type &lt;code&gt;aws.s3.Bucket&lt;/code&gt;
with its schema defined as follows: &amp;hellip;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;While we had to rely on some guesswork to come up with this prompt, fortunately this process can be iterative - if we don&amp;rsquo;t get all of it right the first time, we can try again with additional information that will help us refine the results. This is an important point we return to later in the post. &lt;!-- ref to self-debugging --&gt;&lt;/p&gt;
&lt;h3 id="assessing-search-quality-using-recall-and-precision"&gt;Assessing search quality using recall and precision&lt;/h3&gt;
&lt;p&gt;To assess how effective the RAG is, we need to first understand the two fundamental concepts used in the information retrieval systems: the &lt;em&gt;recall&lt;/em&gt; and the &lt;em&gt;precision&lt;/em&gt;. Imagine that you&amp;rsquo;re looking for apple pie recipes in one of Jamie Oliver&amp;rsquo;s cookbooks. The book has a recipe for a classic American apple pie, a Dutch apple pie and a modern take on a French apple tart. Due to the book&amp;rsquo;s narrative approach with the recipes woven into the stories and context, you&amp;rsquo;ve managed to retrieve only the first two recipes but missed the French apple tart. Having retrieved 2 ouf 3 relevant documents, you have achieved a &lt;strong&gt;67% recall&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Because you were looking for the word &amp;ldquo;pie&amp;rdquo;, you also retrieved a recipe for a Shepherd&amp;rsquo;s pie, which, while delicious, does not qualify as an apple pie. Another document that came up was a fish pie - a classic British dish that does not contain apples or even a pastry crust. Since only 2 of your 4 retrieved documents can be legitimately classified as apple pies, you have achieved a &lt;strong&gt;50% precision&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Now let&amp;rsquo;s formalize this a bit. Recall measures the ratio of the relevant documents retrieved to the total number of relevant documents in RAG dataset:&lt;/p&gt;
&lt;p&gt;$$Recall = \frac{N(Retrieved \cap Relevant)}{N(Relevant)}$$&lt;/p&gt;
&lt;p&gt;Where&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$N(Retrieved \cap Relevant)$ is the number of documents that are both retrieved and relevant.&lt;/li&gt;
&lt;li&gt;$N(Relevant)$ is the total number of relevant documents in the database.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Good recall means that many documents relevant to the query were retrieved.&lt;/p&gt;
&lt;p&gt;Precision is the ratio of the relevant documents retrieved to the total number of retrieved documents:&lt;/p&gt;
&lt;p&gt;$$Precision = \frac{N(Retrieved \cap Relevant)}{N(Retrieved)}$$&lt;/p&gt;
&lt;p&gt;Where $N(Retrieved)$ is the total number of documents that were retrieved.&lt;/p&gt;
&lt;p&gt;High precision means that many of the retrieved documents were relevant.&lt;/p&gt;
&lt;p&gt;Naturally, we want to maximize both the recall and the precision. It&amp;rsquo;s &lt;a href="https://buduroiu.com/blog/rag-llm-recall-problem"&gt;been said&lt;/a&gt; that high recall is essential to ensure relevant content is available to the code generator while precision is the parameter you want to optimize for to avoid hallucinations.&lt;/p&gt;
&lt;h3 id="practical-concerns"&gt;Practical concerns&lt;/h3&gt;
&lt;p&gt;Precision and recall are essential in understanding the information retrieval quality, but they are quite hard to measure in practice. Unlike a cookbook, Pulumi registry contains thousands of ever changing documents, and evaluating how many of them are relevant for every user-submitted query is impractical. This makes recall evaluation for live traffic next to impossible. Things are a little easier with precision, where we&amp;rsquo;re dealing with a small number of documents, but even that metric requires a non-trivial evaluation of relevance, which needs an LLM call or a human judge.&lt;/p&gt;
&lt;p&gt;Fortunately, other metrics that often can effectively estimate retrieval quality have been developed. We have found a metric that can predict, with some degree of accuracy, whether the generated code will successfully compile. For this metric, we compare the &lt;em&gt;tokens&lt;/em&gt; present in the LLM-produced prompt with the number of tokens present in the generated code. (By token here we understand a compiler token - an identifier such as the name of a class, method or a field and not a traditional LLM token concept),
Intuitively, if a token present in the prompt also appears in the generated program, it can be assumed that the token contributed to the generated program. Tokens in the generated program that were not part of the prompt are not necessarily wrong but they are less trusted (they can come from the LLM built-in knowledge or were guessed)&lt;/p&gt;
&lt;p&gt;$$prompt \ coverage = \frac{N(\text{Tokens in prompt} \cap \text{Tokens in code})}{N(\text{Tokens in code})}$$&lt;/p&gt;
&lt;!-- Note: our documents call is Recall, which is not how industry uses this term (see above) --&gt;
&lt;p&gt;Prompt coverage is a metric we can observe in production, and it&amp;rsquo;s one of several metrics we use when updating providers to ensure we haven&amp;rsquo;t regressed the quality of the RAG.&lt;/p&gt;
&lt;h3 id="semantic-search-with-vector-embeddings"&gt;Semantic search with vector embeddings&lt;/h3&gt;
&lt;p&gt;Semantic search is based on the conceptual similarity of the term you&amp;rsquo;re looking for with the elements in the data store. For example, searching for &amp;ldquo;dumplings&amp;rdquo; can return terms like pierogi and gyoza - words with different spelling but both representing different types of filled dough preparations.&lt;/p&gt;
&lt;p&gt;A common way to determine the similarity between the two strings is to first turn these strings into &lt;em&gt;vector embeddings&lt;/em&gt; - arrays of floating point values representing the semantic meaning of each string - and then calculate the &lt;em&gt;cosine similarity&lt;/em&gt; between the two vectors, which is the cosine of the angle between the vectors. &lt;a href="https://huggingface.co/blog/matryoshka"&gt;Various methods&lt;/a&gt; of producing vector embeddings are fascinating but we will not cover them here in depth.&lt;/p&gt;
&lt;p&gt;For Pulumi code generation we are using the OpenAI&amp;rsquo;s &lt;a href="https://www.downelink.com/a-deep-dive-into-openais-text-embedding-ada-002-unlocking-the-power-of-semantic-understanding/"&gt;Ada-002 embedding model&lt;/a&gt; which at this moment represents a good balance between performance and cost.&lt;/p&gt;
&lt;p&gt;Producing vector embeddings from the user query is the standard approach in this situation. However, for Pulumi code generator we added a little twist - to increase the odds of getting more relevant information from the Registry (i.e. to increase the recall) we first make an LLM call to generate a small set of relevant search terms that will produce an array of vector embeddings.&lt;/p&gt;
&lt;div style="text-align: center; width: 100%; margin: 0 auto;"&gt;
&lt;img src="flow-embeddings.png" alt="" style="width: 100%;"&gt;
&lt;figcaption&gt;
&lt;i&gt;Getting vector embeddings from user query&lt;/i&gt;
&lt;/figcaption&gt;
&lt;/div&gt;
&lt;p&gt;We then use the array of vector embeddings to retrieve the set of relevant documents from the Registry.&lt;/p&gt;
&lt;h3 id="full-text-vs-semantic-search"&gt;Full text vs semantic search&lt;/h3&gt;
&lt;p&gt;While semantic search is essential for any modern information retrieval system, we should not forget simple and effective methods for text search already exist. The &amp;ldquo;S3 Bucket&amp;rdquo; part of the user search happens to be easily searchable using traditional text search operations (such as SQL &lt;code&gt;LIKE&lt;/code&gt; operator).&lt;/p&gt;
&lt;p&gt;To be effective, our RAG must be able to handle queries that require semantic understanding (such as &amp;ldquo;simple storage service in AWS&amp;rdquo;) as well as the traditional text search to support situations where the user knows exactly what they are looking for. To that end, the industry has adopted an approach known as the &amp;ldquo;hybrid search&amp;rdquo;, in which the results of full-text search and semantic search are combined to provide the final result.&lt;/p&gt;
&lt;p&gt;For each of these search terms we generate a query that combines the full text search with the semantic search. The resulting documents are then evaluated based on the following criteria:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Dense score&lt;/em&gt;: Vector similarity using cosine distance between query embedding and stored embeddings&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Sparse score&lt;/em&gt;: Text search relevance according to the full-using algorithm (PostgreSQL full-text search in our case)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Both the dense and the sparse scores contribute to the final score that is used to sort the documents. Even though the final score is the average of the two in our current implementation, it would not be correct to say that they have the same weight, or the influence on the end result. This is so because the normalization of the scores must take into account their distribution in the real-world queries and calculating that is quite complex.&lt;/p&gt;
&lt;p&gt;Boosting the influence of one score relative to the other is an area we&amp;rsquo;re actively exploring, and achieving the optimal result depends highly on what parameters we decide to optimize for - high quality code, time to result and so on.&lt;/p&gt;
&lt;p&gt;Finally, we apply the rank-based scoring technique in which the results are penalized based on their position in the ranking. This creates separation between results that might have similar initial scores and gives preference to results that appear earlier in the ranking.&lt;/p&gt;
&lt;h3 id="pruning-the-results"&gt;Pruning the results&lt;/h3&gt;
&lt;p&gt;Our Pulumi code generator employs a two-phase document selection strategy. The first phase casts a wide net, gathering all potentially relevant documentation to maximize recall. The second phase applies precision-focused filtering to distill this collection down to the most pertinent documents.&lt;/p&gt;
&lt;p&gt;This filtering step serves two purposes. First, it prevents LLM hallucinations that arise from similarly-named types across different providers. Second, it optimizes performance by keeping prompts concise - a critical consideration given that larger prompts increase both latency and computational costs, even when within context window constraints.&lt;/p&gt;
&lt;p&gt;Through empirical testing with the Pulumi Registry search, we&amp;rsquo;ve established these baseline parameters: a maximum of 10 documents per query term selected by relevance score, and a 20K token ceiling for prompts. While these parameters have yielded good results in practice, they are likely not optimal for all scenarios. We continue to iterate on these values through ongoing experimentation.&lt;/p&gt;
&lt;h3 id="prompt-generation"&gt;Prompt generation&lt;/h3&gt;
&lt;p&gt;We&amp;rsquo;re now ready to create the system prompt for the code generation LLM call! We&amp;rsquo;ve already discussed some of the elements needed to build the effective prompt - the original user query, the search terms and the vector embeddings that produce the set of documents that will guide the code generation process.&lt;/p&gt;
&lt;p&gt;There is another element that goes into the prompt - a concise set of instructions produced by an LLM call based on the original user&amp;rsquo;s query. The approach when the output of one prompt is used as input for another is known as &amp;ldquo;prompt chaining&amp;rdquo;, and we used it to provide step-by-step instructions to the code generator. For our query, this set of instructions can look as follows:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Create an S3 bucket using Pulumi in TypeScript using the following steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Import the necessary Pulumi AWS package.&lt;/li&gt;
&lt;li&gt;Define a new S3 bucket resource with basic configuration.&lt;/li&gt;
&lt;li&gt;Export the bucket name as an output.&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;div style="text-align: center; width: 100%; margin: 0 auto;"&gt;
&lt;img src="retrieval.png" alt="" style="width: 100%;"&gt;
&lt;figcaption&gt;
&lt;i&gt;Composition of the system prompt for code generation&lt;/i&gt;
&lt;/figcaption&gt;
&lt;/div&gt;
&lt;p&gt;Finally, we use the resulting prompt to call the LLM and ask it to generate the code. We&amp;rsquo;re done!&lt;/p&gt;
&lt;h3 id="self-debugging"&gt;Self-debugging&lt;/h3&gt;
&lt;p&gt;Unfortunately, this isn&amp;rsquo;t always the final step of the process. Despite our best efforts, the code produced by the LLM will not always be correct.&lt;/p&gt;
&lt;p&gt;At this point, it&amp;rsquo;s worth pondering what &amp;ldquo;correct code&amp;rdquo; means. The generated program might have the following problems:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It might be syntactically or semantically incorrect, i.e. it might not compile or fail to typecheck.&lt;/li&gt;
&lt;li&gt;It might fail at runtime - for example by referring to a non-existing resource, a region and so on.&lt;/li&gt;
&lt;li&gt;It might run &amp;ldquo;successfully&amp;rdquo; but not do what the user intended - either because the user did not express themselves clearly or because the request was misunderstood.&lt;/li&gt;
&lt;li&gt;Finally, the code might run and do exactly what the user wants, but lead to an undesired outcome, for example loss of an asset, or a security vulnerability.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Solutions to many of these problems go well beyond the domain of code generation.&lt;/p&gt;
&lt;p&gt;However, the first of these problems can be addressed by the approach known as &amp;ldquo;self-debugging&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;We observed that many generated TypeScript programs that fail to typecheck contain only a few errors, and asking the LLM to fix these errors often produces a valid program. While this approach is still experimental, we see promising results where getting to a correct program requires only 1-2 iterations of self-debugging. The biggest challenge with this approach is doing it in real-time. The user is staring at the screen waiting for an answer, so latency is a major concern.&lt;/p&gt;
&lt;p&gt;Monitoring these typechecking errors in production can also provide valuable insight into the quality of the data used by the RAG and even suggest specific solutions. For example, failure to typecheck a member-access expression is a likely indicator of a missing type schema (a recall problem) or a &amp;ldquo;wrong&amp;rdquo; schema brought in by an irrelevant document (a precision problem).&lt;/p&gt;
&lt;p&gt;Self-debugging can also be extended to include the &lt;code&gt;pulumi preview&lt;/code&gt; command, which is a &amp;ldquo;dry run&amp;rdquo; operation before the actual deployment and can detect many real or potential problems such as destructive actions, incorrect configurations that cannot be detected at compile time, dependency conflicts, and policy violations.&lt;/p&gt;
&lt;h2 id="from-kitchen-to-table-testing-what-works"&gt;From kitchen to table: testing what works&lt;/h2&gt;
&lt;p&gt;The landscape of LLM-based code generation is moving fast, and we need to keep learning and adapting as we go. But with all this rapid technological change, it&amp;rsquo;s crucial to ground our decisions in real numbers. We need to make sure each new advancement actually makes things better, both in our test environments and out in the real world.&lt;/p&gt;
&lt;p&gt;The probabilistic nature of LLM-based code generation means we can&amp;rsquo;t rely solely on pre-production testing. Instead, we adopt multiple layers of quality control working together. Here&amp;rsquo;s what we&amp;rsquo;ve learned works best:&lt;/p&gt;
&lt;h3 id="building-confidence-through-testing"&gt;Building confidence through testing&lt;/h3&gt;
&lt;p&gt;Our testing strategy combines several approaches:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Systematic experimentation&lt;/strong&gt;: We run &amp;ldquo;what-if&amp;rdquo; scenarios against various test datasets to understand how the system behaves under different conditions.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Local evaluation pipeline&lt;/strong&gt;: While local testing has its limitations, it helps catch obvious issues early in development. We evaluate the performance of the code generator and run the code through the typechecker.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Deterministic generation&lt;/strong&gt;: We set the LLM temperature to 0 to ensure consistent outputs. For code generation, consistency and repeatability matters more than creative variations.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="monitoring-quality-in-production"&gt;Monitoring quality in production&lt;/h3&gt;
&lt;p&gt;We track several key metrics to ensure the system performs well:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;RAG effectiveness&lt;/strong&gt;: We measure prompt coverage to evaluate how well our retrieval system performs.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Code quality indicators&lt;/strong&gt;: We track the percentage of generated code that successfully typechecks for all supported languages along with how this metric responds to system changes.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;User feedback&lt;/strong&gt;: Every &amp;ldquo;thumbs down&amp;rdquo; report gets analyzed to identify patterns and potential improvements. This direct user feedback has been invaluable in refining our system.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="wrapping-up"&gt;Wrapping up&lt;/h2&gt;
&lt;p&gt;Building an effective AI-powered code generator requires carefully balancing multiple concerns: the raw capabilities of LLMs with retrieved contextual knowledge, semantic search with traditional text matching, and thorough testing with real-world scenarios.&lt;/p&gt;
&lt;p&gt;Our experience has taught us that success lies in treating code generation like a delicate soufflé - it requires precise measurements, careful monitoring, and constant refinement of technique. The key ingredients are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A robust RAG system with well-tuned recall and precision.&lt;/li&gt;
&lt;li&gt;End-to-end testing and monitoring across development and production.&lt;/li&gt;
&lt;li&gt;Self-debugging capabilities to handle common issues like type checking errors.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As we continue to evolve Pulumi&amp;rsquo;s code generation capabilities, we&amp;rsquo;re excited about expanding our self-debugging features and further refining our RAG implementation.&lt;/p&gt;
&lt;p&gt;We invite you to try these capabilities in your own projects and share your experiences. Your feedback helps us continue improving and advancing the state of AI-assisted infrastructure development.&lt;/p&gt;
&lt;!--raw material
1.2. get multiple "Pulumi Registry schema" elements (40 in our case, 29 unique) - some of them less relevant.
(We call them tokens internally but they are really type names)
This search uses vector embeddings
Resource metadata:
{
"name": "aws-native",
"version": "0.90.0",
"token": "aws-native:s3:Bucket",
"kind": "resource"
}
AWS native looks like this:
```
{
name: "aws-native",
version: "0.90.0",
token: "aws-native:s3:Bucket",
dense_score: 0.8639781475067139,
sparse_score: 0,
score: 0.3887901663780213,
dense_score_boosted: 0.7775803327560425,
sparse_score_boosted: 0,
kind: "resource",
text: "Create an S3 Bucket on AWS Native (preview)",
definition: {
...
```
They include the Definition structure that defines the JSON schema type for every such token.
Less relevant providers like yandex:
```
{
name: "yandex",
version: "0.13.0",
token: "yandex:index/storageBucket:StorageBucket",
...
```
They are then sorted by their density score.
Resulting generated prompt can be 1K or more lines of Yaml
4. Full text search and BM25
BM25:
- Inverse Document Frequency: how rare is the query term
- Term frequency in the document: how often does the term appear in the document
Detailed explanation: https://emschwartz.me/understanding-the-bm25-full-text-search-algorithm/
5. Vector embeddings, combine the two
similarity metrics like cosine similarity.
6. Reranking
6.1. It's good to have good recall - you can throw everything and the kitchen sink at the LLM - but too much information can actually be counterproductive:
- Context window limitation: LLMs have limits on how much text they can process, known as the “context window.” Even though modern LLMs support bigger context window, there is always a limit.
- Accuracy: recall relevant information.
- Cost: we pay by the token.
We need to pare if down.
Reranker analyzes the documents and assigns it a relevance score. It may consider additional features such as organizational preferences or user's prior history that can make the document more relevant.
## Evaluate quality of code generation
1. Does RAG even help? For many common providers, LLMs can already produce reasonably good code. How do we know that RAG adds value?
Ultimately, the only measure of quality that matters is whether the generated code correctly represents the user's intent. However, this is hard to test in an automated way.
One measure is recall: &lt;TODO: define&gt;
What about precision?
2. Evaluate generated programs
How do we assess the quality of our RAG? Intuitively, we want two things to be true:
- Useful information must be in the database
- We must have effective ways of finding that information
- Recall
- Typecheck
- `pulumi up` - a "dry run" before the actual deployment and can detect many real or potential problems such potentially destructive actions, incorrect configurations that cannot be detected at compile time, dependency conflicts and policy violations.
--&gt;</description><author>Artur Laksberg</author><author>Simon Howe</author><category>copilot</category><category>ai</category><category>infrastructure-as-code</category></item><item><title>Announcing the Pulumi Copilot REST API Preview</title><link>https://www.pulumi.com/blog/pulumi-copilot-rest/</link><pubDate>Thu, 12 Dec 2024 15:15:42 -0500</pubDate><guid>https://www.pulumi.com/blog/pulumi-copilot-rest/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/pulumi-copilot-rest/index.png" /&gt;
&lt;div class="note note-info"&gt;
&lt;div class="icon-and-line"&gt;
&lt;svg xmlns="http://www.w3.org/2000/svg" class="ph-icon ph-icon--fill" fill="currentColor" aria-hidden="true" focusable="false"&gt;&lt;use href="https://www.pulumi.com/icons/sprite.74fadd1b94bae866bccf29a780f184a71c5cfc34c8677be70da8fe2ab0309b9e.svg#p-info-fill"/&gt;&lt;/svg&gt;
&lt;div class="line"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="content"&gt;Note: This post discusses Pulumi Copilot, which Pulumi Neo has replaced. &lt;a href="https://www.pulumi.com/docs/ai/"&gt;Learn about Neo →&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;We built Pulumi Copilot to automate a broad spectrum of cloud management activities using the power of LLMs. Since its initial release earlier this year, hundreds of customers have used Pulumi Copilot to understand and manage cloud infrastructure more effectively and securely, and it is only getting better by the day.&lt;/p&gt;
&lt;p&gt;Today, we&amp;rsquo;re excited to announce the availability of the Pulumi Copilot REST API. This new API exposes the full power of Pulumi Copilot, enabling you to integrate infrastructure AI into your own tools, applications, and platforms. While currently in preview, we are eager to get your feedback to ensure it works for anything you can dream up.&lt;/p&gt;
&lt;h2 id="enhancing-copilot-capabilities"&gt;Enhancing Copilot Capabilities&lt;/h2&gt;
&lt;p&gt;With the Copilot REST API, you can extend the Copilot capabilities available in the Pulumi Console in the following ways:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Build Copilot capabilities into your platforms and tools, such as the CLI, development portals, Github actions and so on.&lt;/li&gt;
&lt;li&gt;Support multi-user interaction in workplace collaboration platforms such as Slack and Teams.&lt;/li&gt;
&lt;li&gt;Automate execution of Copilot queries based on scheduled triggers or events, such as deployment completions.&lt;/li&gt;
&lt;li&gt;Access Copilot from mobile clients through platforms like Slack or Teams.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="implementation-guide"&gt;Implementation Guide&lt;/h2&gt;
&lt;h3 id="initial-configuration"&gt;Initial Configuration&lt;/h3&gt;
&lt;p&gt;To begin using the Copilot API, set up the following environment variables:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nv"&gt;PULUMI_COPILOT_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;https://api.pulumi.com/api/ai/chat/preview&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nv"&gt;PULUMI_ACCESS_TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;pul-...&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Note: You can obtain your &lt;code&gt;PULUMI_ACCESS_TOKEN&lt;/code&gt; from the Pulumi Console.&lt;/p&gt;
&lt;h3 id="understanding-cloud-context"&gt;Understanding Cloud Context&lt;/h3&gt;
&lt;p&gt;All Copilot API interactions require two essential parameters:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Organization context through the &lt;code&gt;orgId&lt;/code&gt; field - this is conceptually similar to the organization you select in the dropdown menu on the left-hand side of the Pulumi Console&lt;/li&gt;
&lt;li&gt;Resource URL from the Pulumi Console, which must begin with &lt;code&gt;https://app.pulumi.com&lt;/code&gt; - think of this as the browser URL you see when navigating the Pulumi Console. This URL helps Copilot understand the context of your query. While you can provide the base URL (&lt;code&gt;https://app.pulumi.com&lt;/code&gt;), you can also point to specific resources or updates for more targeted queries. For example, &lt;code&gt;https://app.pulumi.com/myorg/my-demo-project/my-stack/updates/5&lt;/code&gt; would allow you to ask questions about that specific update&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;These parameters provide the necessary context for queries about specific resources or updates, allowing Copilot to respond with relevant information just as it would in the Console interface.&lt;/p&gt;
&lt;h3 id="making-api-requests"&gt;Making API Requests&lt;/h3&gt;
&lt;p&gt;Here&amp;rsquo;s an example of a basic API request:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;curl -L &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$PULUMI_COPILOT_URL&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;-H &lt;span class="s2"&gt;&amp;#34;Authorization: token &lt;/span&gt;&lt;span class="nv"&gt;$PULUMI_ACCESS_TOKEN&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;-H &lt;span class="s2"&gt;&amp;#34;Content-Type: application/json&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;-d &lt;span class="s1"&gt;&amp;#39;{
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;query&amp;#34;: &amp;#34;Who are the users in my org?&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;state&amp;#34;: {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;client&amp;#34;: {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;cloudContext&amp;#34;: {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;orgId&amp;#34;: &amp;#34;pulumi&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;url&amp;#34;: &amp;#34;https://app.pulumi.com&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt;}&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="supporting-multi-turn-conversations"&gt;Supporting Multi-turn Conversations&lt;/h3&gt;
&lt;p&gt;The API supports continuous dialogues, in which participants can refer to information shared earlier in the chat. This is supported through conversation IDs that are received with the response:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;&amp;#34;conversationId&amp;#34;&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;369a280c-63f3-4ee6-a13d-c1035a3d05de&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This ID enables follow-up queries that maintain context:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;curl -L &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$PULUMI_COPILOT_URL&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;-H &lt;span class="s2"&gt;&amp;#34;Authorization: token &lt;/span&gt;&lt;span class="nv"&gt;$PULUMI_ACCESS_TOKEN&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;-H &lt;span class="s2"&gt;&amp;#34;Content-Type: application/json&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;-d &lt;span class="s1"&gt;&amp;#39;{
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;conversationId&amp;#34;:&amp;#34;369a280c-63f3-4ee6-a13d-c1035a3d05de&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;query&amp;#34;: &amp;#34;Who of them are admins?&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;state&amp;#34;: {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;client&amp;#34;: {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;cloudContext&amp;#34;: {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;orgId&amp;#34;: &amp;#34;pulumi&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;url&amp;#34;: &amp;#34;https://app.pulumi.com&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt;}&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="moving-forward"&gt;Moving Forward&lt;/h2&gt;
&lt;p&gt;As we continue to evole our AI efforts, your feedback is essential. We are particularly interested in hearing about your implementation experiences, including features that work well, areas that need improvement, or capabilities you&amp;rsquo;d like to see added. You can consult the &lt;a href="https://www.pulumi.com/docs/pulumi-cloud/copilot/api"&gt;documentation&lt;/a&gt; and peruse the &lt;a href="https://github.com/pulumi/copilot-api-samples/tree/main/samples"&gt;samples&lt;/a&gt;. Please submit any feedback by opening an &lt;a href="https://github.com/pulumi/copilot-api-samples/issues"&gt;issue&lt;/a&gt; or by reaching out to us via our &lt;a href="https://pulumi-community.slack.com/archives/C055KGGFB1N"&gt;Community Slack&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;We can&amp;rsquo;t wait to see what you can build with Pulumi Copilot REST API!&lt;/p&gt;</description><author>Artur Laksberg</author><category>features</category><category>ai</category><category>llm</category><category>copilot</category><category>pulumi-copilot</category></item><item><title>AI Engineering Lessons from Building Pulumi Copilot</title><link>https://www.pulumi.com/blog/copilot-lessons/</link><pubDate>Thu, 12 Dec 2024 13:56:13 -0500</pubDate><guid>https://www.pulumi.com/blog/copilot-lessons/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/copilot-lessons/index.png" /&gt;
&lt;div class="note note-info"&gt;
&lt;div class="icon-and-line"&gt;
&lt;svg xmlns="http://www.w3.org/2000/svg" class="ph-icon ph-icon--fill" fill="currentColor" aria-hidden="true" focusable="false"&gt;&lt;use href="https://www.pulumi.com/icons/sprite.74fadd1b94bae866bccf29a780f184a71c5cfc34c8677be70da8fe2ab0309b9e.svg#p-info-fill"/&gt;&lt;/svg&gt;
&lt;div class="line"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="content"&gt;Note: This post discusses Pulumi Copilot, which Pulumi Neo has replaced. &lt;a href="https://www.pulumi.com/docs/ai/"&gt;Learn about Neo →&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Building AI-powered developer tools comes with unique challenges, and now that we&amp;rsquo;ve &lt;strong&gt;&lt;a href="https://www.pulumi.com/blog/pulumi-copilot-rest/"&gt;launched our REST API&lt;/a&gt;&lt;/strong&gt;, we want to share some lessons we&amp;rsquo;ve learned building Pulumi Copilot, an AI assistant for cloud infrastructure.&lt;/p&gt;
&lt;p&gt;One of the big challenges was determining what &amp;lsquo;working&amp;rsquo; really meant. So when a message landed in our feedback channel after months of rigorous testing - &amp;lsquo;Your tool doesn&amp;rsquo;t know anything!&amp;rsquo; - it caused some mild panic. We&amp;rsquo;d just made some changes, so we braced for the worst. But our evals were still looking strong, so what was going on?&lt;/p&gt;
&lt;p&gt;The user was attempting to force-delete a stack that still contained resources. But when we dug deeper, we found something fascinating: Copilot had confidently suggested a &amp;lsquo;&amp;ndash;force&amp;rsquo; flag, which would have been a logical solution&amp;hellip; except this flag doesn&amp;rsquo;t exist in Pulumi. Our AI was hallucinating exactly what the user wanted. But this wasn&amp;rsquo;t just a bug - it was the first of many insights that would reshape how we approach AI-powered tools.&lt;/p&gt;
&lt;p&gt;To understand how we got here - and why this &amp;ldquo;error&amp;rdquo; actually taught us something valuable about our product - let&amp;rsquo;s start with the core challenge we faced: balancing traditional software engineering with this new world of prompt engineering.&lt;/p&gt;
&lt;h2 id="engineering-for-reality-prompt-engineering-vs-software-engineering"&gt;Engineering for Reality: Prompt Engineering vs Software Engineering&lt;/h2&gt;
&lt;p&gt;&lt;img src="soft-eng.png" alt="Software Engineering vs Prompt Engineering"&gt;&lt;/p&gt;
&lt;p&gt;When building LLM-powered applications, it&amp;rsquo;s tempting to throw every task at the model. Modern LLMs can generate code, format text, and create clickable links. But this approach carries hidden costs.&lt;/p&gt;
&lt;p&gt;Working on Copilot taught us a key lesson: let the LLM do what it does best and use good old imperative code for everything else.&lt;/p&gt;
&lt;p&gt;Take a seemingly simple feature: listing a user&amp;rsquo;s Pulumi stacks with clickable links based on data from a backend API. Our first implementation used a complex prompt instructing the LLM to construct URLs in the format &lt;code&gt;app.pulumi.com/org/project/stack&lt;/code&gt;. The prompt explained the format, provided examples, and asked the LLM to generate these links from JSON data it had.&lt;/p&gt;
&lt;p&gt;It worked - almost all of the time. But we were seeing occasional malformed URLs and more importantly, this was burning input tokens (and money) on a complicated prompt that made AI construct strings that could be deterministically generated.&lt;/p&gt;
&lt;p&gt;The solution was straightforward: generate the full links in the backend service and include them directly in the context. The LLM then needs no instructions on how to create them. Simple stuff, but it gave faster responses and perfect URLs at a lower cost.&lt;/p&gt;
&lt;p&gt;When you find yourself writing elaborate prompts to handle structured data transformations, stop and ask: Could traditional code do this better? Could this be decomposed so that the LLM does less?&lt;/p&gt;
&lt;p&gt;To validate this approach, we tested Copilot ourselves to see what worked.&lt;/p&gt;
&lt;h2 id="copilot-in-action-real-world-dogfooding"&gt;Copilot in Action: Real-World Dogfooding&lt;/h2&gt;
&lt;p&gt;The internal testing phase taught us invaluable lessons about how people would actually use the tool. We watched our team try Copilot in their daily work, and three common use cases emerged:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Debugging Deployments:&lt;/strong&gt; LLMs clearly excel at summarization. One of the first questions our internal users asked was, &amp;lsquo;Why did my latest infrastructure deployment fail?&amp;rsquo; Using Copilot to extract a clear natural language explanation requests like these has been a clear win.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Understanding Complex Infrastructure:&lt;/strong&gt; Copilot helped our engineers gain insights into Pulumi&amp;rsquo;s own infrastructure. Asking, &amp;lsquo;How many resources are in production?&amp;rsquo; &amp;lsquo;What expensive compute is running&amp;rsquo; or &amp;lsquo;What version are the EKS clusters in EU?&amp;quot; shows the value of allowing users to express infrastructure questions in natural language.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Generating Code:&lt;/strong&gt; One of the first queries logged was, &amp;lsquo;I want a static website on AWS behind a CloudFront CDN.&amp;rsquo; Another came from a Solutions Engineer, tasked with demonstrating Pulumi&amp;rsquo;s CrossGuard policy engine to a prospect, asking Copilot to generate policy code.&lt;/p&gt;
&lt;p&gt;These early experiences showed the value of Copilot. But they also revealed the need for a systematic approach to handling diverse user queries. This led to the development of what we call skills.&lt;/p&gt;
&lt;h2 id="skillful-slicing-modular-mastery"&gt;Skillful Slicing: Modular Mastery&lt;/h2&gt;
&lt;p&gt;As Copilot grew, we broke it into smaller pieces we call skills. Each skill does one specific job. The Insights skill handles queries about resource usage and configuration (&amp;ldquo;How many S3 buckets do I have?&amp;rdquo;), the Cloud Skill interacts with the Pulumi Service API to manage infrastructure (&amp;ldquo;Show me my stacks.&amp;rdquo;), the Code Skill generates Pulumi code snippets (&amp;ldquo;Write a Typescript program&amp;hellip;&amp;rdquo;), and the Docs Skill retrieves information from Pulumi documentation (&amp;ldquo;How do I use &lt;a href="https://www.pulumi.com/docs/iac/concepts/update-plans/"&gt;update plans&lt;/a&gt;?&amp;rdquo;).&lt;/p&gt;
&lt;p&gt;When you ask Copilot something, it figures out what you need and picks the right skill for the job – like a manager deciding which expert to send your question to. This &lt;a href="https://platform.openai.com/docs/guides/function-calling"&gt;function-calling&lt;/a&gt; approach, orchestrated by a component we call the &amp;ldquo;outer loop,&amp;rdquo; allows Copilot to access and process information beyond its internal knowledge base.&lt;/p&gt;
&lt;p&gt;Fortunately, Pulumi Cloud already exposes a &lt;a href="https://www.pulumi.com/docs/pulumi-cloud/reference/cloud-rest-api/"&gt;rich API&lt;/a&gt; - in fact, this is what powers the Pulumi Console and the Pulumi CLI - so all we had to do is to build a &lt;em&gt;skill&lt;/em&gt; that maps the user query to the appropriate Pulumi Cloud REST API. A question like &amp;ldquo;Show me my stacks&amp;rdquo; translates into the &lt;a href="https://www.pulumi.com/docs/pulumi-cloud/reference/cloud-rest-api/#list-stacks"&gt;List Stacks&lt;/a&gt; API call. A question like &amp;lsquo;Show me my untagged EC2 instances&amp;rsquo; is a bit more complex but it breaks down into clear components - resource type (EC2), filter condition (untagged) - that route to the Insights skill. This mapping helped us handle the many ways users phrase the same technical request.&lt;/p&gt;
&lt;p&gt;Refining this routing system revealed another opportunity: streamlining the Debug button workflow.&lt;/p&gt;
&lt;h2 id="debug-dispatch"&gt;Debug Dispatch&lt;/h2&gt;
&lt;p&gt;&lt;img src="optimize.png" alt="Before and After"&gt;&lt;/p&gt;
&lt;p&gt;Originally, when a user clicked &amp;lsquo;Debug with Copilot&amp;rsquo;, the system would send a text query like &amp;ldquo;Analyze this update and explain any errors.&amp;rdquo; Copilot would then:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Determines the user wants to analyze an update&lt;/li&gt;
&lt;li&gt;Identifies which API to call&lt;/li&gt;
&lt;li&gt;Calls the API&lt;/li&gt;
&lt;li&gt;Summarize the result&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Having the LLM figure out what the user wants is the right approach in general, but in this case, we already know the user&amp;rsquo;s intent - they clicked a debug button. So, we can directly call the analysis API to get the results and use the LLM solely for what it does best: summarizing technical output into clear, actionable explanations.&lt;/p&gt;
&lt;p&gt;This is another small win for the &amp;ldquo;Software Engineering over Prompt Engineering&amp;rdquo; approach. Traditional code handles the predictable parts, while AI focuses on the human-facing explanations.&lt;/p&gt;
&lt;p&gt;But while minimizing the LLM workload helped with efficiency, we soon faced an even trickier challenge: the deceptive polish of AI-generated outputs.&lt;/p&gt;
&lt;h2 id="the-illusion-of-correctness"&gt;The Illusion of Correctness&lt;/h2&gt;
&lt;p&gt;&lt;img src="false-info.png" alt="Before and After"&gt;&lt;/p&gt;
&lt;p&gt;Large language models excel at generating well-structured, grammatically correct output. They make neat tables, tell good stories, and generally sound confident. That&amp;rsquo;s what makes them dangerous because this polished presentation can mask underlying flaws in the information itself, creating a false sense of confidence for users.&lt;/p&gt;
&lt;p&gt;One of our early testers, Pablo, a data engineer at Pulumi, encountered this firsthand. He posed a query to Pulumi Copilot, asking for a summary of resources within a specific project. The response he received was impeccably formatted, neatly categorizing resources by type and providing counts for each. It &lt;em&gt;looked&lt;/em&gt; right, and for us humans sometimes looking right carries a lot of weight.&lt;/p&gt;
&lt;p&gt;However, a closer inspection revealed the numbers were way off. Copilot had asked for the wrong data and then summarized it beautifully - but incorrectly. This highlighted our next challenge: how do you systematically test a system that can be confidently wrong while sounding completely right?&lt;/p&gt;
&lt;h2 id="testing-the-untestable-validating-llm-outputs"&gt;Testing the Untestable: Validating LLM Outputs&lt;/h2&gt;
&lt;p&gt;When testing traditional code, we expect consistent, predictable outputs. With LLMs, even correct answers can vary. Here&amp;rsquo;s how we tackle this challenge.&lt;/p&gt;
&lt;p&gt;Our first approach was simple: keyword checks. For example, when testing the update analysis feature, we checked if the LLM&amp;rsquo;s response included the word &amp;ldquo;security&amp;rdquo; and described the error. This worked for straightforward cases but broke down quickly. Take a question like, &amp;ldquo;How many Lambdas am I running?&amp;rdquo; The LLM might give the right numbers but skip the word &amp;ldquo;running,&amp;rdquo; failing the test even though the answer was correct.&lt;/p&gt;
&lt;p&gt;These early failures revealed the limitations of keyword-based validation and underscored the need for a more nuanced approach. Inspired by platforms like LangSmith and Promptfoo, we began leveraging LLMs themselves as evaluators. For deterministic tasks, simple keyword checks suffice, but for more complex scenarios—like assessing whether a response answers a specific question—we rely on an &amp;ldquo;LLM Judge.&amp;rdquo; This approach balances efficiency and flexibility, reserving LLM evaluation for cases where it truly adds value. The test suite now integrates both methods, running against every code change to validate response content, accuracy, and format.&lt;/p&gt;
&lt;p&gt;&lt;img src="promptfoo.png" alt="Example PromptFoo Eval"&gt;&lt;/p&gt;
&lt;p&gt;The eval suite keeps getting more robust, which means that when new AI models drop, we can quickly catch any weirdness before it hits production. The generative AI space moves crazy fast and the code changes a lot, but the evals are a safety net - catching hallucinations, maintaining quality, and making sure we don&amp;rsquo;t ship anything that&amp;rsquo;ll annoy our users.&lt;/p&gt;
&lt;p&gt;So, while hallucinations are now much rarer, what about that one with the &lt;code&gt;--force&lt;/code&gt; flag? Yes, it&amp;rsquo;s &amp;ldquo;just another bug,&amp;rdquo; but it taught us something fascinating about these AI errors.&lt;/p&gt;
&lt;div class="note note-tip"&gt;
&lt;div class="icon-and-line"&gt;
&lt;svg xmlns="http://www.w3.org/2000/svg" class="ph-icon ph-icon--fill" fill="currentColor" aria-hidden="true" focusable="false"&gt;&lt;use href="https://www.pulumi.com/icons/sprite.74fadd1b94bae866bccf29a780f184a71c5cfc34c8677be70da8fe2ab0309b9e.svg#p-lightbulb-fill"/&gt;&lt;/svg&gt;
&lt;div class="line"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="content"&gt;
&lt;p&gt;&lt;strong&gt;You might also like:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.pulumi.com/blog/codegen-learnings/"&gt;
A Recipe for a Better AI-based Code Generator
&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.pulumi.com/blog/pulumi-copilot-rest/"&gt;
Announcing the Pulumi Copilot REST API Preview
&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.pulumi.com/blog/pulumi-copilot/"&gt;
Introducing Pulumi Copilot: Intelligent Cloud Management
&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="llms-think-like-humans-sort-of"&gt;LLMs think like humans (sort of)&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;--force&lt;/code&gt; hallucination wasn&amp;rsquo;t totally wrong - it was revealing what users intuitively expect from the CLI, and the LLM accidentally showed us what was missing. Force deletion is a common pattern across developer tools, and the LLM, trained on vast amounts of documentation and code, simply reflects these established conventions.&lt;/p&gt;
&lt;p&gt;This has fundamentally changed how we view hallucinations. While the team works constantly to minimize them – and our eval work means they happen way less frequently – some of them are clearly product signals. The LLM, in this light, becomes an unexpected source of user research, drawing on its training across thousands of developer tools and experiences.&lt;/p&gt;
&lt;p&gt;This insight is one of the key lessons of building Copilot:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Minimize LLM Usage:&lt;/strong&gt; Let traditional code handle deterministic tasks, reserve LLMs for natural language work&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Decompose into Skills:&lt;/strong&gt; Break complex tasks into modular units that combine LLM and traditional code appropriately&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Test Rigorously:&lt;/strong&gt; Use multiple validation approaches, including LLMs testing LLMs&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Learn from Hallucinations:&lt;/strong&gt; Sometimes incorrect outputs reveal user expectations&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Learn from Users Continuously:&lt;/strong&gt; User interactions improve our AI systems - from training better skills to catching hallucinations and revealing product opportunities.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;These lessons helped shape our latest release: &lt;strong&gt;&lt;a href="https://www.pulumi.com/blog/pulumi-copilot-rest/"&gt;the Pulumi Copilot REST API&lt;/a&gt;&lt;/strong&gt;, now available in preview. You can integrate these same capabilities and skills into your own tools and workflows. Whether you&amp;rsquo;re building CLI extensions, chat integrations, or automated deployment checks, the API provides a contextual understanding of Copilot. &lt;strong&gt;&lt;a href="https://www.pulumi.com/docs/pulumi-cloud/copilot/api/"&gt;Try it out&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;We can&amp;rsquo;t wait to see what you build!&lt;/p&gt;</description><author>Artur Laksberg</author><author>Simon Howe</author><author>Adam Gordon Bell</author><category>copilot</category><category>ai</category><category>infrastructure-as-code</category><category>pulumi-copilot</category></item><item><title>Pulumi Copilot is Now Integrated with Pulumi Docs: A New Way to Learn and Explore</title><link>https://www.pulumi.com/blog/copilot-in-docs/</link><pubDate>Thu, 24 Oct 2024 23:59:00 -0700</pubDate><guid>https://www.pulumi.com/blog/copilot-in-docs/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/copilot-in-docs/index.png" /&gt;
&lt;div class="note note-info"&gt;
&lt;div class="icon-and-line"&gt;
&lt;svg xmlns="http://www.w3.org/2000/svg" class="ph-icon ph-icon--fill" fill="currentColor" aria-hidden="true" focusable="false"&gt;&lt;use href="https://www.pulumi.com/icons/sprite.74fadd1b94bae866bccf29a780f184a71c5cfc34c8677be70da8fe2ab0309b9e.svg#p-info-fill"/&gt;&lt;/svg&gt;
&lt;div class="line"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="content"&gt;Note: This post discusses Pulumi Copilot, which Pulumi Neo has replaced. &lt;a href="https://www.pulumi.com/docs/ai/"&gt;Learn about Neo →&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href="https://www.pulumi.com/docs/pulumi-cloud/copilot/"&gt;Pulumi Copilot&lt;/a&gt; has been making our customers&amp;rsquo; day-to-day tasks easier since its release, and today we’re excited to expand its capabilities—Pulumi Copilot is now available across Pulumi Documentation and pulumi.com, and comes equipped with a powerful new Documentation Skill!&lt;/p&gt;
&lt;div class="my-4"&gt;
&lt;video class="flex outline-none rounded w-full" title="Copilot in Docs"
autoplay muted playsinline
loop &gt;
&lt;source src="./copilot-in-docs.mp4" /&gt;
&lt;/video&gt;
&lt;/div&gt;
&lt;p&gt;These additions make learning about Pulumi more interactive and intuitive by allowing users to explore cloud infrastructure concepts directly within the documentation through a conversational interface. Whether you’re a seasoned Pulumi user or just starting out, Pulumi Copilot is here to help you when you need it most, where you need it most.&lt;/p&gt;
&lt;h2 id="new-enhancements-in-pulumi-copilot"&gt;New Enhancements in Pulumi Copilot&lt;/h2&gt;
&lt;h3 id="expanded-website-integration"&gt;Expanded Website Integration&lt;/h3&gt;
&lt;p&gt;Pulumi Copilot is now embedded throughout the Pulumi website, providing contextual assistance no matter where you are. Whether you’re exploring documentation, reading a blog post, browsing the Pulumi registry, or reviewing case studies, Pulumi Copilot offers helpful suggestions, explanations, and links to guide you to relevant resources.&lt;/p&gt;
&lt;h3 id="pulumi-documentation-skill"&gt;Pulumi Documentation Skill&lt;/h3&gt;
&lt;p&gt;The new Documentation Skill is designed to make Pulumi’s docs more accessible from wherever. You can ask questions like &amp;ldquo;How do I use the dependsOn resource option?&amp;rdquo; or “How do I use SAML in my organization?&amp;quot; or &amp;ldquo;How can I store and retrieve secrets using Pulumi ESC?&amp;rdquo; and Pulumi Copilot will answer them by searching through our documentation on your behalf. This new skill is available everywhere Pulumi Copilot is: in Pulumi Cloud, in Pulumi documentation, across the Pulumi website, and the Registry.&lt;/p&gt;
&lt;h2 id="try-pulumi-copilot-today"&gt;Try Pulumi Copilot Today&lt;/h2&gt;
&lt;p&gt;Pulumi Copilot’s new Documentation Skill and website integration are available now! These features are free to use today. You can unlock more messages by being logged in to Pulumi Cloud.&lt;/p&gt;
&lt;p&gt;To get started, visit the Pulumi Cloud console and enable Pulumi Copilot in your settings under Access Management.&lt;/p&gt;
&lt;p&gt;Pulumi Copilot is already making waves, and with these latest enhancements, it’s now easier than ever to manage and learn about your cloud infrastructure. We can’t wait for you to experience it firsthand!&lt;/p&gt;</description><author>Meagan Cojocar</author><author>Artur Laksberg</author><category>releases</category><category>features</category><category>pulumi-copilot</category></item><item><title>Enhancing Pulumi Copilot: Introducing System Prompts for Your Organization</title><link>https://www.pulumi.com/blog/copilot-system-prompts/</link><pubDate>Thu, 10 Oct 2024 00:00:00 -0700</pubDate><guid>https://www.pulumi.com/blog/copilot-system-prompts/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/copilot-system-prompts/index.png" /&gt;
&lt;div class="note note-info"&gt;
&lt;div class="icon-and-line"&gt;
&lt;svg xmlns="http://www.w3.org/2000/svg" class="ph-icon ph-icon--fill" fill="currentColor" aria-hidden="true" focusable="false"&gt;&lt;use href="https://www.pulumi.com/icons/sprite.74fadd1b94bae866bccf29a780f184a71c5cfc34c8677be70da8fe2ab0309b9e.svg#p-info-fill"/&gt;&lt;/svg&gt;
&lt;div class="line"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="content"&gt;Note: This post discusses Pulumi Copilot, which Pulumi Neo has replaced. &lt;a href="https://www.pulumi.com/docs/ai/"&gt;Learn about Neo →&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;We are excited to announce a new feature for Pulumi Copilot: System Prompts. This enhancement empowers organizations to customize Pulumi Copilot&amp;rsquo;s responses for your organization, making your interactions with our AI assistant even more personalized to save you even more time.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.pulumi.com/docs/pulumi-cloud/copilot/"&gt;Pulumi Copilot&lt;/a&gt; is a conversational chat interface integrated throughout Pulumi Cloud, enabling users to quickly accomplish a variety of cloud infrastructure management tasks by leveraging the power of large language models plus the rich capabilities of Pulumi Cloud. &lt;a href="https://www.pulumi.com/blog/pulumi-copilot/"&gt;We released Pulumi Copilot in June this year&lt;/a&gt;, and have seen remarkable uptake across our customer base. We are excited to be announcing enhancements on the Pulumi Copilot experience- keep an eye out for more to come in the near future.&lt;/p&gt;
&lt;p&gt;System prompts allow organization administrators to set default preferences and guidelines for Pulumi Copilot. By configuring these prompts, you can tailor Pulumi Copilot&amp;rsquo;s behavior to better suit your team&amp;rsquo;s needs and policies. Here are some ways you might use organization system prompts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Set a Default Programming Language:&lt;/strong&gt; Ensure that all code snippets and examples provided by Pulumi Copilot are in your team&amp;rsquo;s preferred language.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Specify a Default Cloud Provider:&lt;/strong&gt; Streamline resource searches and code generation by focusing on your primary cloud environment. Specify providers your organization prefers to use, such as using Azure Native instead of Azure Classic.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Enforce Compliance Guidelines:&lt;/strong&gt; Instruct Copilot to generate code and provide guidance that adheres to specific compliance standards, such as SOC 2.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Standardize Infrastructure Components:&lt;/strong&gt; Provide example code templates for resources to ensure consistency across your organization&amp;rsquo;s projects, such as &amp;ldquo;here is how we create VPCs&amp;rdquo;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="how-to-set-organization-system-prompts"&gt;How to Set Organization System Prompts&lt;/h2&gt;
&lt;p&gt;&lt;img src="org-system-prompts.png" alt="Access Management Copilot section in the UI"&gt;&lt;/p&gt;
&lt;p&gt;Setting up system prompts is straightforward:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Log in to Pulumi Cloud and go to your organization&amp;rsquo;s settings in the left hand navigation&lt;/li&gt;
&lt;li&gt;Under the settings menu, select &amp;ldquo;Access Management.&amp;rdquo;&lt;/li&gt;
&lt;li&gt;In the Copilot section, you&amp;rsquo;ll find the option to set your system prompts.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Though the system prompt supports 10k characters of context, we recommend keeping it concise to ensure optimal performance. See more information on setting system prompts &lt;a href="https://www.pulumi.com/docs/pulumi-cloud/copilot/"&gt;in our Pulumi Copilot documentation&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="wrapping-it-up"&gt;Wrapping it up&lt;/h2&gt;
&lt;p&gt;This is just the beginning. We&amp;rsquo;re dedicated to making Pulumi Copilot an indispensable part of your cloud infrastructure management toolkit. Stay tuned for more updates and enhancements based on your feedback.&lt;/p&gt;
&lt;p&gt;If you have suggestions or encounter any issues, please let us know through our &lt;a href="https://github.com/pulumi/pulumi-cloud-requests"&gt;Pulumi Cloud requests GitHub repository&lt;/a&gt;.&lt;/p&gt;</description><author>Meagan Cojocar</author><author>Artur Laksberg</author><category>features</category><category>releases</category><category>pulumi-copilot</category></item></channel></rss>