Ship Agents that Ship: A Hands-On Workshop - Kyle Penfound, Jeremy Adams, Dagger

A detailed summary of a workshop on building and deploying production-minded AI coding agents using Dagger. The session covers creating controlled, observable, and test-driven agent workflows and integrating them into CI/CD systems like GitHub Actions for automated, reliable software development.

4 min read
Ship Agents that Ship: A Hands-On Workshop - Kyle Penfound, Jeremy Adams, Dagger
source: https://www.youtube.com/watch?v=Fzb1a24hF-o

The core challenge with AI coding agents is moving them from impressive demos to reliable, production-ready tools that engineering teams can trust. Dagger provides a framework to achieve this by treating agents as components within a larger, programmable, and containerized CI/CD workflow, ensuring control, observability, and repeatability.

What is Dagger? A Programmable Engine for Workflows

Dagger is a workflow engine that orchestrates tasks inside containers. While its founders also created Docker, Dagger’s scope is different. Docker containerizes an application to make it portable. Dagger containerizes an entire workflow—like a build, test, and deploy pipeline—making the entire process portable and ensuring it runs identically on a developer’s laptop and in a CI environment like GitHub Actions.

Workflows in Dagger are not defined in YAML but are written as functions in standard programming languages such as Python, Go, or TypeScript. This allows developers to use familiar tools and paradigms to construct their pipelines. A key feature is Dagger’s cross-language interoperability; a module written in Go can be seamlessly imported and used within a Python project, creating a unified ecosystem of reusable components available on the “Daggerverse”.

Building a Production-Minded Agent

The workshop demonstrates building an agent by separating its “body” (the tools and environment) from its “brain” (the LLM). This approach is designed to counter the problem of unconstrained AI generating massive, untestable pull requests.

The Agent’s “Body”: A Controlled, Sandboxed Workspace

Instead of giving an agent free rein, the first step is to construct a purpose-built, sandboxed environment. This is accomplished by creating a dedicated Dagger sub-module (e.g., dagger/workspace) that contains a curated set of tools. For a code modification task, these tools are simple but powerful functions:

  • list_files(): To analyze the existing project structure.
  • read_file(path): To read the contents of a specific file.
  • write_file(path, contents): To modify or create a file.

The most critical tool is a test() function. This function is not a generic command but a wrapper around the project’s actual, established test suite (e.g., npm run test). This ensures the agent validates its generated code using the exact same standards as a human developer and the CI pipeline.

The Agent’s “Brain”: The LLM and Prompt Engineering

The “brain” is an LLM (like GPT or Claude) that is given access to the “body.” This is orchestrated within a primary Dagger function, for example, develop(assignment). This function constructs the agent’s environment, declaratively defining the inputs (the assignment string) and the tools (the workspace module). Dagger automatically generates the necessary tool-use schemas for the LLM directly from the Dagger function signatures, eliminating the need to manually write complex JSON tool definitions.

The prompt is engineered to guide the agent toward a reliable workflow:

  1. Analyze First: “Before you write code, make sure you analyze the workspace to understand the project structure.”
  2. Constrain Changes: “Don’t make unnecessary changes.”
  3. Mandatory Validation: “Always run the tests after you’ve made changes.”
  4. Iterate to Success: “Don’t stop until you’ve completed the assignment and the tests pass.”

The core of the agent logic is a single line of code that invokes the Dagger LLM client, passing it the environment and the prompt: work = client.llm().work(env=environment, prompt=prompt_contents).

Observability and Guardrails: Establishing Trust

A major challenge with agents is understanding their decision-making process. Dagger Cloud provides a detailed, real-time visualization of the agent’s execution. It traces every step: the initial prompt, the LLM’s reasoning, which tools it selects (e.g., workspace.list_files), the data returned from those tools, and the final output. This observability is crucial for debugging the agent’s behavior and refining its prompts and tools.

Dagger also enables programmatic “guardrails.” After the agent’s iterative loop is complete and it believes the task is done, the main develop function performs a final, non-negotiable test() call on the resulting code. This final check ensures that no matter what the agent did, the output must pass the project’s quality gates before it can be exported or committed.

From Local Agent to CI/CD Automation

The workshop culminates in deploying the agent to GitHub Actions, automating the development workflow. This is achieved by creating a new wrapper function, develop_issue, that orchestrates a higher-level process:

  1. It uses another module from the Daggerverse (github-issue) to read a feature request directly from a GitHub issue.
  2. It passes the issue’s body as the assignment to the develop agent function.
  3. Once the agent returns the completed, tested code, the function creates a new Git branch and opens a Pull Request with the changes, automatically linking it back to the original issue.

This entire flow is triggered by a simple GitHub Actions workflow that runs a single command (dagger call develop_issue ...) whenever a specific label (e.g., “develop”) is added to a GitHub issue. This transforms the agent from a command-line tool into a fully automated collaborator in the software development lifecycle.

Share post

Stay In The Loop! Subscribe to Our Newsletter.

Get updates straight to your inbox. No spam, just useful content.

Recommended for You

Devin 2.0 and the Future of SWE - Scott Wu, Cognition

Devin 2.0 and the Future of SWE - Scott Wu, Cognition

Scott Wu, CEO of Cognition AI, discusses the exponential growth of AI capabilities in software engineering, likening it to a "Moore's Law for AI agents" with a doubling time of every 70 days. He chronicles the evolution of their AI agent, Devin, from handling repetitive code migrations to autonomously managing entire backlogs, highlighting the key technical challenges and paradigm shifts at each stage.

Strategies for LLM Evals (GuideLLM, lm-eval-harness, OpenAI Evals Workshop) — Taylor Jordan Smith

Strategies for LLM Evals (GuideLLM, lm-eval-harness, OpenAI Evals Workshop) — Taylor Jordan Smith

Traditional benchmarks and leaderboards are insufficient for production AI. This summary details a practical, multi-layered evaluation strategy, moving from foundational system performance to factual accuracy and finally to safety and bias, using open-source tools like GuideLLM, lm-eval-harness, and Promptfoo.