All Projects
·10 min read

Codebase Explainer: Three AI Agents, Three Frameworks, One A2A Pipeline That Reads Any GitHub Repo and Explains It

Give it any GitHub repository URL. Three AI agents built on three different frameworks — Google ADK, LangGraph, and CrewAI — communicate with each other using the Agent-to-Agent (A2A) protocol to produce a complete developer onboarding kit: a plain-English guide, a data flow diagram, and the five files every new developer should read first.

PythonGoogle ADKLangGraphCrewAIA2A ProtocolFastAPIDockerGoogle Cloud RunGeminiMulti-AgentVertex AI

What this is

Give it any GitHub repository URL. Three AI agents go to work. Each one is built on a completely different framework. They communicate with each other using the Agent-to-Agent (A2A) protocol, an open standard that lets AI agents from different companies and frameworks talk to each other over HTTP.

The result is a developer onboarding kit produced entirely by AI: a plain-English guide to the codebase, a diagram showing how data moves through the system, and a list of the five files every new developer should read first.

The interesting part is not the output. It is the architecture. This project was built specifically to understand three things: how Google ADK, LangGraph, and CrewAI each approach the problem of building an AI agent, and how the A2A protocol makes all three work together as one system.

What it produces

You enter a GitHub URL. The system returns three things:

New Developer Guide — a plain-English explanation of what the project is, what it does, how to set it up, and where to start reading the code.

Data Flow Explanation — a walkthrough of one user action traced through the entire codebase, with an ASCII diagram showing which files call which.

Top 5 Files — the five most important files in the codebase, each with one sentence explaining why a new developer should read it first.

The Three Agents and Why Each Uses a Different Framework

The goal was not just to build a tool that explains codebases. The goal was to understand three different agent frameworks side by side, in one project, connected by a real protocol.

Agent 1 uses Google ADK. ADK is Google's framework for defining an AI agent as a brain with a job description. You give it a model, a set of instructions, and optionally some tools. It is the right choice for a single, well-defined analytical task: look at this repository summary and tell me what the tech stack, entry points, and architecture are. One input. One structured output. ADK handles the session management and execution. This agent acts as the orchestrator for the whole pipeline.

Agent 2 uses LangGraph. LangGraph is built for processes that need to loop and make decisions. Reading source code is not a one-shot task. You read a file, find what it imports, read those files, find what they import, and keep going until you have enough to understand the system. LangGraph lets you define this as a graph with nodes (steps) and edges (paths between steps), including conditional edges that decide whether to keep reading or stop. No other framework in this project has this looping capability built in.

Agent 3 uses CrewAI. CrewAI is built for teams. Instead of one agent doing everything, you define multiple agents with different roles and personalities. Each gets its own task. They can run in parallel. A final task combines their outputs. For producing a developer onboarding kit, this is the right model: a Technical Writer produces the guide, an Architect draws the data flow, a Prioritiser selects the top five files, and a combining task assembles everything into one JSON object.

How A2A Connects Them

Each agent runs as a completely independent service. Each has its own server, its own port, its own Docker container. They do not share memory. They do not call each other's internal functions. They communicate the same way any two services on the internet communicate: HTTP requests.

The Agent-to-Agent (A2A) protocol defines exactly two things every agent must implement.

The first is an agent card, published at /.well-known/agent.json. This is a JSON document that describes what the agent can do, where to send it work, and what authentication it requires. Any other agent or system can fetch this URL to discover the agent's capabilities without reading any documentation.

The second is an endpoint that accepts work. In this project that endpoint is at /a2a. Agent 1 sends a POST request to Agent 2's /a2a endpoint with the repository map as the request body. Agent 2 runs its LangGraph loop, produces a code analysis, and returns it as JSON. Agent 1 then sends a POST request to Agent 3's /a2a endpoint with both the repository map and the code analysis. Agent 3 runs its CrewAI crew and returns the onboarding kit.

Because each agent follows A2A, they are interchangeable. You could replace Agent 2 with any other service anywhere in the world, as long as that service publishes an agent card and accepts work at a standard endpoint.

Agent Flow

You enter a GitHub Repository URL
        |
        v
Agent 1: Mapper  [Google ADK]
        Calls the GitHub API to get repo metadata, file structure, and README
        Builds a text summary of the entire repository
        Sends that summary to Gemini via ADK
        Gemini returns: tech stack, entry points, architecture summary
        |
        |  A2A  -->  sends repo map as JSON
        v
Agent 2: Code Reader  [LangGraph]
        Starts with the entry points Agent 1 identified
        Reads each file from GitHub
        Asks Gemini: what does this file do?
        Asks Gemini: what does this file import?
        Adds new files to the reading queue
        Loops up to 15 times until the queue is empty or the limit is reached
        Returns: file purposes, connection map, data flow summary
        |
        |  A2A  -->  sends repo map + code analysis as JSON
        v
Agent 3: Explainer  [CrewAI]
        Three agents run in parallel:
            Technical Writer   -->  New Developer Guide
            Architect          -->  Data Flow Explanation with ASCII diagram
            Prioritiser        -->  Top 5 Files to Read First
        One combining task assembles all three outputs into a single JSON object
        Returns: complete developer onboarding kit
        |
        v
Dashboard displays the result live

Full System Architecture

LangGraph: Reading Code as a Loop

LangGraph is based on the idea that some problems require iteration, not a single pass. Reading a codebase is one of them.

The graph in Agent 2 has four nodes: PRIORITIZE, READ, CONNECT, and SUMMARIZE.

PRIORITIZE runs once at the start. It looks at Agent 1's analysis to identify which files are entry points and which are main modules. These become the starting queue.

READ takes the next file from the queue, downloads it directly from GitHub, and asks Gemini to describe what it does in one sentence.

CONNECT asks Gemini which local files the last-read file imports. Any files not already read get added to the queue.

A decision function runs after CONNECT. If there are still files in the queue and the loop count is under 15, it routes back to READ. If the queue is empty or the limit is reached, it routes to SUMMARIZE.

SUMMARIZE sends all file descriptions and all discovered connections to Gemini and asks it to produce the final structured analysis.

The shared state object carries the queue, the files read so far, the discovered connections, and the loop count across every step. Nothing is lost between iterations.

CrewAI: Three Agents, One Deliverable

CrewAI is built for the pattern where different specialists produce different parts of one final output.

Agent 3 has three agents. The Technical Writer's goal is to produce a plain-English guide with no jargon. The Architect's goal is to explain data flow by tracing one user action through the code. The Prioritiser's goal is to identify which five files a new developer must read to understand the system.

All three run at the same time. Each receives the same brief: the repository metadata, the architecture summary from Agent 1, and the code analysis from Agent 2.

When all three finish, a fourth task runs. It reads the three outputs and combines them into a single JSON object with three keys: new_developer_guide, data_flow, and top_5_files. This is what Agent 3 returns to Agent 1.

How the Dashboard Updates in Real Time

The dashboard does not wait for the full pipeline to finish before showing anything. It connects to a live update stream from Agent 1 the moment you click Analyze.

Agent 1 uses Server-Sent Events (SSE), a standard web technology where the server keeps an HTTP connection open and pushes messages down it as they arrive. Every time something happens in the pipeline, Agent 1 broadcasts a message to the stream. The browser listens and updates the dashboard immediately.

You see the file tree appear file by file. You see tech stack badges appear as Gemini identifies each technology. You see the A2A messages as Agent 1 hands work to Agent 2 and then to Agent 3. You see the final guide appear section by section.

Tech Stack

| Layer | Technology | |---|---| | Agent 1 framework | Google ADK (LlmAgent + Runner) | | Agent 2 framework | LangGraph (StateGraph) | | Agent 3 framework | CrewAI (Agent + Task + Crew) | | AI model | Gemini 2.5 Flash via Vertex AI | | Agent communication | A2A Protocol (HTTP + JSON) | | API server | FastAPI + Uvicorn | | Live updates | Server-Sent Events (SSE) | | Containerization | Docker (one Dockerfile per agent) | | Cloud runtime | Google Cloud Run (three separate services) | | Source data | GitHub REST API |

What I Learned

The A2A protocol reduces coupling to a single HTTP call. Agent 1 does not import Agent 2's code. It does not need to know which framework Agent 2 uses or how its loop works internally. It sends a POST request to a URL and waits for a JSON response. The protocol is the contract. Everything else is an implementation detail. This means any agent in this system could be replaced with any other A2A-compliant service from any company without changing a single line in the other agents.

Each framework solves a genuinely different problem. ADK is for a clear analytical task with one well-defined output. LangGraph is for iterative processes that need to loop and branch based on what they discover. CrewAI is for parallel specialist work that gets combined into one deliverable. Knowing which framework fits which problem is more useful than knowing all three in depth.

Deployment order matters when agents call each other. Agent 3 must be deployed before Agent 2, and both must be deployed before Agent 1. Agent 1 needs the live URLs of Agents 2 and 3 as environment variables at startup. You cannot inject a URL that does not exist yet.

State design in LangGraph is the most important decision. The TypedDict that defines what the graph carries between nodes has to be thought through before writing any node function. Changing it later means changing every function that touches it. Getting the shape of the state right at the start saves significant rework.

Server-Sent Events are the right primitive for live agent pipelines. WebSockets are bidirectional and require more infrastructure. Polling wastes requests and adds latency. SSE is one open connection, push-only, natively supported by every browser, and requires no special libraries. For a pipeline where the browser only needs to receive updates, not send them, SSE is the correct choice.