Using AI Agents to execute engineering work in complex projects

AI is a fantastic pair programmer. We all use it to write boilerplate, fix bugs and churn out unit tests. But a senior developer’s real bottleneck isn’t writing code line-by-line; it’s managing the complexity of a large project: juggling multiple repositories, remembering different build steps, and orchestrating work across teams.

We need a way to scale AI beyond the code editor, a way to deploy a team of agents to handle entire engineering tasks in a secure, repeatable way. This post breaks down our agent environment setup using GitHub Copilot Agents, showing you how we delegate complex work to AI agents so our engineers can focus on architecture, not admin.

What we mean by an “Agent Environment”

“Agent environment” sounds abstract, but in practice, it’s just like onboarding a new engineer. You have to give them three things:

  1. A Computer with the Code: A complete, self-contained, secure workspace where they can run the project.
  2. The Right Tools and Permissions: The SDKs, dependencies and credentials needed to build, test and push their work.
  3. A Clear Playbook: A step-by-step guide on how your team creates branches, commits code and opens pull requests.

Our agent environment provides that for a GitHub Copilot AI Agent. It’s a combination of a centralised repository, an automated setup script and a markdown instruction file. These three steps only have to be configured once, and can be reused for all future tasks.

Putting an Agent to Work: A Real-World Walkthrough

Let’s walk through a common task: “Add a ‘user export’ button to the admin panel that triggers a new backend API endpoint to generate a CSV”. This task touches two different repositories(ProjectBackend and ProjectAdmin) and has a specific contribution process.

Instead of having a developer context-switching between the two, a senior engineer gives this high-level directive to a Copilot Agent. Here’s what happens next.

1. The Workspace: A Single Source of Truth

The agent needs the full project context. Our first step was creating a central “wrapper” repository that pulls in ProjectBackend and ProjectAdmin as Git submodules. When an agent session starts, it gets a complete, sandboxed copy of the entire application stack.

2. The Tools: Automated Environment Setup

Next, the agent needs its tools. We handle this with a workflow file that GitHub Copilot automatically runs for each agent session. This is our provisioning script, defining the entire development environment.

It checks out the submodules, sets up Node.js, installs dependencies, and configures Git credentials so the agent can push its work and open a PR.

3. Security: The Built-in Firewall

Each GitHub Copilot Agent operates within a secure, sandboxed environment that has its own network firewall. By default, it only has access to a recommended list of external resources. To grant it the ability to create pull requests, you have to explicitly add GitHub’s API endpoints (“api.github.com” and “https://api.github.com/graphql”) to the allowlist in your repository settings (Settings > Copilot > Coding agent).

This is what makes autonomous work feasible. The agent has internet access, but it’s restricted to approved endpoints. It can’t hit a random URL or exfiltrate data, which gives us the confidence to grant it this level of autonomy.

4. The Playbook: The Agent’s Standard Operating Procedure

The agent instructions are handled by a simple markdown file, .github/copilot-instructions.md. This is our playbook, where we define our team’s specific, multi-step contribution workflow.

This is where you get ultra-specific. You can’t assume the agent knows how to work with your submodule architecture. You have to tell it, step-by-step.

<!-- .github/copilot-instructions.md -->
## Repository Structure & Contribution Workflow

This repository contains two primary submodules: `ProjectBackend/` and `ProjectAdmin/`.

**CRITICAL:** Changes made within a submodule (e.g., `ProjectBackend/`) must be pushed to the submodule's own remote repository. The agent's environment is pre-configured with the necessary Git credentials.

### How to Submit Changes

Follow this exact sequence to propose changes to a submodule:

` ` ` bash
# 1. Navigate into the target submodule directory.
cd ProjectBackend

# 2. Create a new branch for your task.
git checkout -b copilot/feature-name

# 3. Stage and commit your code changes.
git add .
git commit -m "feat: A clear and concise commit message"

# 4. Push the new branch to the SUBMODULE's remote.
git push origin copilot/feature-name

# 5. Use the GitHub CLI to open a pull request against the submodule's repository.
gh pr create --repo your-org/your-backend-repo --title "Your Feature Title" --body "Detailed description of changes." --base main --head copilot/feature-name
` ` `

Do not push directly to the `main` branch.

Now, the agent has the code, the tools and the rules. We can start a new Github Copilot Agent session, provide the requirements defined by the senior developer and the agent gets to work, writing the API endpoint, adding the frontend button, and finally, packaging it all up into a pull request, following our playbook to the letter.

The Human’s Role: Architect and Reviewer

This system doesn’t replace our engineers. It elevates them. The boundary is crystal clear:

  • Humans provide the strategic direction and final judgment. We define what needs to be done, review the agent’s plan, and ultimately own the code review. The pull request is the critical control point where human experience is applied. We are the architects.
  • The agent handles the tedious execution. It does the context-switching, writes the boilerplate, runs the linters, performs an initial code review and follows contribution rules perfectly every time. It’s the tireless executor.

Why This Is a Game-Changer for Complex Projects

On a simple, single-repo project, this might be overkill. But in a complex, multi-stream environment, it’s incredibly effective.

  1. It enables true parallel work. We can spin up many agents to work on many different features in separate sandboxes simultaneously. No more developer bottlenecks.
  2. It drastically reduces cognitive load. Our engineers no longer have to keep the mental map of five different repos, build systems and deployment scripts in their heads. They can offload that mental model to the agent and focus on solving the hard problems.
  3. It enforces ironclad consistency. Agents don’t get creative with commit messages or forget to link a Jira ticket. Our standards are followed perfectly, which improves code hygiene and makes our git history far more useful.

By building this repeatable model, we’ve shifted from using AI as an interactive assistant to a tool for delegating entire workflows. This changes the job of a senior developer, from writing code to directing a parallelised, autonomous workforce. And that lets us build better systems, faster.