Using AI for development is no longer limited to asking one assistant to generate a component or fix a bug. On a real project, I may use several AI coding tools for different parts of the same work.
One agent might implement a feature. Another might review the implementation, investigate a difficult bug, or suggest a better architecture. An IDE assistant might handle smaller changes while I work.
That creates a new problem:
How do multiple AI agents work on the same project without constantly losing context?
The code itself is usually not the biggest issue. Every agent can inspect the repository.
What gets lost is everything around the code:
Why was this architecture chosen?
What approaches were already tried?
What constraints does the project have?
What is currently being worked on?
What should not be changed?
What does the next agent need to know?
A practical solution is to stop treating an AI conversation as the project's memory.
Instead, make the repository itself the shared memory between AI agents.
Imagine this workflow.
You ask AI Agent A to implement a new search feature.
During the work, it discovers that the existing API has a limitation. After investigating several approaches, you decide to solve part of the problem on the frontend and leave another part for a backend change.
The implementation works.
The next day, you open the project with AI Agent B and ask:
Improve the search implementation.
Agent B can see the code, but it doesn't automatically know why Agent A made those decisions.
It may "fix" something intentionally implemented that way.
Or worse, it may spend another 30 minutes rediscovering exactly what Agent A already discovered.
The problem looks something like this:
The repository contains the final implementation, but not necessarily the reasoning behind it.
We need another layer.
Instead of expecting AI tools to share conversations, we can store important project context directly inside the repository.
A simple structure might look like this:
project/
│
├── README.md
├── AI_CONTEXT.md
├── ARCHITECTURE.md
├── DECISIONS.md
├── CURRENT_STATE.md
│
├── .ai/
│ ├── RULES.md
│ ├── frontend.md
│ ├── backend.md
│ ├── testing.md
│ └── handoff.md
│
├── CLAUDE.md
├── AGENTS.md
│
├── .github/
│ └── copilot-instructions.md
│
└── src/
The exact filenames are not important.
The important part is separating shared project knowledge from agent-specific instructions.
For example:
ARCHITECTURE.mdDescribes how the application is structured.
It might contain:
# Architecture
Frontend:
- React
- TypeScript
- React Query
Backend:
- Node.js
- Express
Search:
- Azure AI Search
Authentication:
- OAuth
Important:
Search filtering happens on the server before pagination.
Do not apply filtering to paginated results on the client.
This prevents another AI from accidentally implementing filtering in the wrong layer.
DECISIONS.mdThis file records important technical decisions.
For example:
# Technical Decisions
## Search sorting
Decision:
Sorting must happen in Azure Search before pagination.
Reason:
Sorting paginated results on the frontend only sorts the
current page and produces inconsistent results.
Status:
Accepted.
This is much more useful than simply documenting what the code does.
It documents why the code works that way.
CURRENT_STATE.mdThis file acts as a lightweight handoff between agents.
For example:
# Current Work
Feature:
Exact-match asset search
Status:
Frontend implementation complete.
Known limitation:
Descriptions containing HTML links cannot be reliably
matched using the current index.
Reason:
The search index stores the original HTML description.
Next step:
Backend should create a normalized plain-text description
field and re-index existing assets.
Files changed:
- searchRequest.ts
- searchUtils.ts
- searchUtils.test.ts
Now another AI can enter the project and quickly understand where the previous work stopped.
It doesn't need access to the previous AI conversation.
One mistake is putting every instruction into every AI configuration file.
For example, you might have:
CLAUDE.md
AGENTS.md
copilot-instructions.md
and copy the same 200 lines into all three.
That creates another problem.
Eventually one file gets updated and the others don't.
Now different AI agents are following different versions of the project's rules.
Instead, keep the shared rules centralized.
Agent-specific files should mainly explain how that agent should interact with the shared context.
For example, an agent instruction might say:
Before making significant changes:
1. Read `.ai/RULES.md`.
2. Read `ARCHITECTURE.md`.
3. Read `CURRENT_STATE.md`.
4. Check `DECISIONS.md` for relevant previous decisions.
Do not override documented architectural decisions
without explaining why the decision should change.
The actual architecture remains in ARCHITECTURE.md.
The coding rules remain in .ai/RULES.md.
The current work remains in CURRENT_STATE.md.
This creates one source of truth.
The most useful part of this setup is the handoff.
Every agent should know what it must do before and after significant work.
For example:
# AI Handoff Rules
## Before starting work
1. Read `.ai/RULES.md`.
2. Read `ARCHITECTURE.md`.
3. Read `CURRENT_STATE.md`.
4. Review relevant entries in `DECISIONS.md`.
5. Inspect the existing implementation before proposing changes.
## After significant work
1. Update `CURRENT_STATE.md`.
2. Record new architectural decisions in `DECISIONS.md`.
3. Update `ARCHITECTURE.md` only if the architecture changed.
4. Update `.ai/RULES.md` only when a reusable project rule was discovered.
5. Record unresolved problems or limitations.
6. Leave enough context for another AI agent to continue the work.
## Important
Do not duplicate documentation unnecessarily.
Do not rewrite documentation that is unrelated to the task.
Code remains the source of truth for implementation details.
Documentation should capture context, constraints, and decisions.
The workflow now becomes:
Agent B doesn't need Agent A's conversation.
The repository becomes the communication channel.
There is an important trade-off here.
It might sound useful to create a rule like:
After every code change, update all AI documentation.
Don't do that.
It creates noise very quickly.
A CSS change shouldn't cause an AI to rewrite ARCHITECTURE.md.
A unit test shouldn't create a new architectural decision.
Instead, documentation updates should be triggered by specific events.
| When this happensUpdate | |
|---|---|
| Architecture changes | ARCHITECTURE.md |
| Important technical decision | DECISIONS.md |
| Feature completed, blocked, or paused | CURRENT_STATE.md |
| Reusable coding rule discovered | .ai/RULES.md |
| Agent behavior changes | Agent-specific instruction file |
This keeps the documentation small enough that AI agents can actually use it.
Multiple AI agents become more useful when they don't all do exactly the same thing.
For example:
One agent can focus on implementation.
Another can act as a skeptical reviewer.
A third can inspect tests, edge cases, documentation, or accessibility.
The specific AI product doesn't need to own a permanent role. You can switch them depending on the task.
The important idea is separation of responsibility.
If three AI agents receive the same prompt and independently write the same feature, you're mostly paying for three versions of the same work.
A better workflow is:
Agent A → Build
Agent B → Challenge
Agent C → Verify
That gives each model a reason to exist in the workflow.
This isn't only a theoretical workflow. I've used a similar approach while building EasySmartPDF, one of my Android projects.
Instead of asking one AI agent to handle the entire project, I divided the work based on where each tool was most useful.
For UI work that was tightly connected to Android Studio, I used the AI agent available directly in the development environment. It could work close to the actual Android code, layouts, resources, and project structure.
For larger implementation problems and application logic, I used Claude. This was especially useful when a task required understanding several files together, tracing how a feature worked, or making a more substantial change across the project.
I also used ChatGPT and Copilot for tasks that sat between those two areas: investigating problems, reviewing approaches, generating smaller pieces of code, discussing architecture, and getting a second opinion before changing an implementation.
The workflow looked roughly like this:
The important part wasn't deciding which AI was "best."
It was deciding which AI should own which part of the problem.
For example, if I was adjusting an Android-specific UI flow, keeping that work close to Android Studio made sense. If I needed to trace a feature across multiple classes and rethink its logic, I could hand that problem to Claude. If I wanted to challenge an approach, investigate an error, or connect the work happening between those areas, ChatGPT or Copilot could take that role.
But this creates exactly the context problem discussed earlier.
If Claude discovers an important limitation while changing the application logic, the Android Studio agent won't automatically know about it. ChatGPT won't automatically know either.
That's where the shared project files become useful.
Instead of transferring the entire conversation from one AI to another, the agent finishing a significant task can leave behind the information that actually matters:
## Current Feature
Feature:
Document Scanner
Status:
UI integration complete.
Implementation:
Scanner entry flow is handled in Android.
Important finding:
The scanner must receive an Activity context.
Do not cast an arbitrary Context directly to Activity.
Files affected:
- ScannerEntryScreen.kt
- NavGraph.kt
Next:
Verify behavior on physical Samsung devices.
The next AI doesn't need the previous AI's entire conversation.
It needs the result of that conversation: what changed, why it changed, what was discovered, and what still needs to happen.
That distinction is what makes a multi-AI workflow practical.
Rules should describe constraints that are stable across many tasks.
For example:
# Frontend Rules
- Use TypeScript for new code.
- Do not introduce `any` unless necessary.
- Prefer existing shared components before creating new ones.
- Do not add a dependency without explaining why it is needed.
- Maintain WCAG 2.1 AA accessibility.
- Preserve existing API contracts unless the task requires changing them.
- Run tests for affected functionality.
But avoid turning your rules file into a giant programming textbook.
Bad rules look like this:
Always write clean code.
Use best practices.
Make the application scalable.
Write professional code.
These instructions add almost no useful project context.
Good rules describe specific constraints the model could otherwise get wrong.
Not everything belongs in one global file.
Suppose the frontend and backend have very different requirements.
You might create:
.ai/
├── RULES.md
├── frontend.md
├── backend.md
└── testing.md
Then the global rules can say:
When modifying frontend code:
Read `.ai/frontend.md`.
When modifying backend code:
Read `.ai/backend.md`.
When creating or modifying tests:
Read `.ai/testing.md`.
This avoids loading irrelevant instructions for every task.
It also scales better as the project grows.
There is another major advantage to keeping AI context inside the repository:
Git can track it.
If someone changes an architectural decision, the change appears in the pull request.
If an AI incorrectly updates a rule, the team can review it.
If the architecture changes six months later, the history still exists.
Your AI instructions become part of the engineering system instead of hidden configuration inside someone's local AI tool.
The flow becomes:
Humans and AI agents are now reading from the same project history.
There is one danger with this approach.
If AI agents are allowed to continuously update their own instructions without limits, the documentation can slowly drift.
One agent adds a preference.
Another treats that preference as an architectural rule.
A third expands it.
After a few months, RULES.md contains 800 lines of instructions nobody intentionally designed.
So AI agents shouldn't have unlimited authority over the project's memory.
A useful distinction is:
AI can automatically update:
CURRENT_STATE.md
temporary handoff information
known issues
implementation notes
But important changes such as:
ARCHITECTURE.md
security rules
API contracts
major coding standards
should normally be reviewed by a developer.
AI should help maintain project memory.
It shouldn't quietly become the project's architect.
For many projects, you don't need anything complicated.
This is enough:
project/
│
├── README.md
├── ARCHITECTURE.md
├── DECISIONS.md
├── CURRENT_STATE.md
│
├── .ai/
│ ├── RULES.md
│ ├── frontend.md
│ ├── backend.md
│ └── handoff.md
│
├── CLAUDE.md
├── AGENTS.md
├── .github/
│ └── copilot-instructions.md
│
└── src/
Think of it as three layers:
Layer 1 knows the project.
Layer 2 defines how AI should work on the project.
Layer 3 teaches each AI tool where to find that information.
That separation is what keeps the system manageable.
Using multiple AI coding agents isn't really a model-selection problem.
It's a context-management problem.
The more AI tools we introduce into development, the less practical it becomes to keep important engineering knowledge trapped inside individual chat histories.
A better model is:
AI conversations are temporary.
Project knowledge is persistent.
The repository is the shared memory.
Once the repository contains the architecture, decisions, rules, current state, and handoff information, switching between AI agents becomes much easier.
Claude can implement something today.
Codex can review it tomorrow.
Copilot can help modify it inside the IDE next week.
Another AI agent can join the project months later.
They don't need access to each other's conversations.
They need access to the same source of truth.
And that source of truth should live with the code.
Masoud
September 6th, 2026