Build a GraphRAG Incident Agent

Build an AI agent that routes incident questions to GraphRAG search tools.

Introduction

30 Second Summary

When an online service fails, clues sit across timelines, team notes, and customer reports. A search that explains one outage can miss patterns spread across the full incident history.

In this project, you will build a browser-based AI agent in Google ADK that investigates synthetic production incidents. It chooses between GraphRAG Local Search for named entities and GraphRAG Global Search for whole-dataset patterns.

What You'll Build

Your browser shows a grounded incident answer with the investigator's chosen search method printed at the top.

By the end of this project, you'll have:

  • Named-incident answers that connect a specific failure to its services, causes, mitigations, and customer effects.
  • Whole-dataset synthesis that surfaces recurring causes, customer effects, and monitoring gaps across every incident report.
  • Observable routing decisions through a Search method: prefix that shows which retrieval tool handled each question.
  • Secret Mission: Add Basic Search as a third tool for exact wording and fallback evidence.

Are there any prerequisites?

You only need a Windows computer. The guide covers Python, Visual Studio Code, the required packages, and Gemini API key setup.

Before We Start

Before any hands-on work, this checkpoint captures your commitment to building an incident investigator that chooses the right GraphRAG retrieval method for each question. That decision gives every tool you add later a clear purpose.

Set Up the Windows Development Environment

Your incident investigator depends on Microsoft GraphRAG plus the Google Agent Development Kit. Pinned versions prevent package drift across the retrieval layer and the agent layer.

In this step, you will prepare Python 3.11.9 inside an isolated project environment. You will also protect your Gemini credentials before any project configuration exists.

In this step, get ready to:
  • Verify Python plus Visual Studio Code on Windows.
  • Build an isolated environment with the pinned GraphRAG and ADK packages.
  • Protect your Gemini API key with a complete .gitignore file.
Install and verify the desktop tools

Python 3.11.9 satisfies the supported version ranges for both pinned packages. Windows PowerShell gives you one terminal for creating the project and running both command-line tools.

  • Press the Windows key to open Windows search.
  • Type Windows PowerShell into the search field.
  • Press Enter to open Windows PowerShell.
  • Check for Python 3.11 by running this command:
py -3.11 --version

PowerShell either reports your Python 3.11 version or indicates that the requested interpreter is unavailable.

✔️ I see the required Python version

Python 3.11.9 is ready for the project.

ⓧ I see an older version

The project uses Python 3.11.9 so every learner starts from the same bugfix release.

  • Open the official Python release page.
  • Select Windows installer (64-bit) for Python 3.11.9.
  • Expect Windows to request permission when the installer starts.
  • Run the downloaded installer with its recommended options.
  • Approve the Windows permission request if it appears.
  • Close Windows PowerShell after the installation finishes.
  • Return to Windows search to open a fresh Windows PowerShell window.
  • Verify the installed interpreter by running:
py -3.11 --version

You should now see Python 3.11.9 in the output.

ⓧ Command not found

Python 3.11 is unavailable through the Windows Python launcher.

  • Open the official Python release page.
  • Select Windows installer (64-bit) for Python 3.11.9.
  • Expect Windows to request permission when the installer starts.
  • Run the downloaded installer with its recommended options.
  • Approve the Windows permission request if it appears.
  • Close Windows PowerShell after the installation finishes.
  • Return to Windows search to open a fresh Windows PowerShell window.
  • Verify the installed interpreter by running:
py -3.11 --version

You should now see Python 3.11.9 in the output.

Still not seeing Python 3.11?

Close every PowerShell window after the installation. A fresh terminal reloads the Python launcher configuration.

If the requested version remains unavailable, help me troubleshoot the Python launcher. Share the command output in the NextWork community if the problem continues.

Visual Studio Code gives you a file editor plus an integrated view of the project folder. Its command-line launcher also lets PowerShell open the correct folder directly.

  • Check whether the Visual Studio Code launcher is available by running:
code --version

A working installation prints version information. An unavailable launcher produces a command error.

✔️ I see a version number

Visual Studio Code is available from PowerShell.

ⓧ Command not found

Install the recommended Windows User setup so the Visual Studio Code launcher becomes available after PowerShell restarts.

  • Open the official Visual Studio Code Windows setup guide.
  • Download the recommended User setup for Windows.
  • Expect Windows to request permission when the installer starts.
  • Run the downloaded installer.
  • Approve the Windows permission request if it appears.
  • Close Windows PowerShell after the installation finishes.
  • Return to Windows search to open a fresh Windows PowerShell window.
  • Verify the command-line launcher by running:
code --version

You should now see Visual Studio Code version information in PowerShell.

  • Prepare the agentic-graphrag-investigator folder on your Desktop by running these commands:
Set-Location -Path ~\Desktop
New-Item -Path . -Name "agentic-graphrag-investigator" -ItemType Directory
Set-Location -Path ".\agentic-graphrag-investigator"
code .

What do these commands do?

  • The first Set-Location command places the project on your Desktop.
  • New-Item creates the agentic-graphrag-investigator directory.
  • The second Set-Location command moves PowerShell into the new directory.
  • code . opens that exact directory in Visual Studio Code.
  • Confirm Visual Studio Code shows agentic-graphrag-investigator as the open folder.
  • Keep the PowerShell window from earlier open in the project folder.

You now have a named project location in both tools. Every file created from this point lands inside agentic-graphrag-investigator.

Did Visual Studio Code fail to open?

Close PowerShell if you installed Visual Studio Code in the current session. Open a fresh PowerShell window so it can load the updated command path.

If the folder still does not open, help me fix the Visual Studio Code launcher.

Create the virtual environment and install the packages

A virtual environment stores this project's Python packages inside .venv. This isolation prevents another Python project from changing the GraphRAG or ADK versions used here.

  • Create the .venv environment with Python 3.11 by running:
py -3.11 -m venv .venv

What does this command create?

Python creates an isolated interpreter plus its package installer inside .venv. The folder stays inside agentic-graphrag-investigator so the environment remains tied to this project.

  • Confirm .venv appears in the Visual Studio Code file list.

Is the .venv folder missing?

Check that PowerShell is still inside agentic-graphrag-investigator. Re-run the Python version check if the environment command returned an error.

For help with the failure, show me why the virtual environment was not created.

PowerShell can block activation scripts under its current execution policy. Try the normal activation first so you can choose the outcome that matches your terminal.

  • Activate the project environment by running:
.\.venv\Scripts\Activate.ps1

A successful activation adds the environment name to your PowerShell prompt. A policy restriction reports that the activation script cannot run.

✔️ The environment is active

Your PowerShell prompt now displays the active environment name. Package installation stays inside .venv.

ⓧ PowerShell blocked the script

The current-user execution policy can permit locally created activation scripts. This change applies to your Windows account.

  • Prepare to confirm the current-user policy change if PowerShell requests approval.
  • Apply the documented current-user policy by running:
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser

This policy permits local scripts while retaining restrictions for downloaded scripts.

  • Approve the policy change if PowerShell asks for confirmation.
  • Close Windows PowerShell.
  • Return to Windows search to open a fresh Windows PowerShell window.
  • Return to the existing project folder and activate its environment by running these commands:
Set-Location -Path ~\Desktop
Set-Location -Path ".\agentic-graphrag-investigator"
.\.venv\Scripts\Activate.ps1

Your prompt should now display the active environment name from .venv.

Still unable to activate the environment?

Confirm the activation command starts with .\ and points to the .venv folder inside your current project.

If PowerShell continues to block the script, help me troubleshoot the activation policy. Share the policy output in the NextWork community if you need another pair of eyes.

The package download can take a few minutes while pip resolves the pinned dependency sets. Keep the PowerShell window open until the command returns to the active environment prompt.

  • Install GraphRAG 3.3.0 plus Google ADK 2.11.0 by running:
python -m pip install "graphrag==3.3.0" "google-adk==2.11.0"

Why pin both packages?

graphrag==3.3.0 provides the indexing and retrieval commands used by the knowledge graph. google-adk==2.11.0 provides the agent framework plus its development web interface.

Exact version pins keep the project aligned with the command surfaces used in later steps. The active environment keeps those versions separate from system-wide packages.

When installation completes, PowerShell returns to the active environment prompt after listing the installed packages.

Did package installation fail?

Confirm your prompt still shows the active environment name. Check the earlier Python output if the installer reports an incompatible Python version.

For an environment-specific dependency error, help me diagnose the pinned package installation. Share the final error lines in the NextWork community if the installation remains blocked.

Protect the Gemini API key and verify the environment

An API key grants software access to your selected Gemini project. Treat the key like a password because anyone holding it can make requests through that project.

The .gitignore file blocks local environments plus future credential files from source control. Creating it before any .env file gives your key a safety boundary from the start.

  • Switch back to the Visual Studio Code window from earlier.
  • Select the Explorer view in the left sidebar.
  • Select New File... from the Explorer controls.
  • Enter .gitignore as the file name.
  • Add the following protection rules to .gitignore exactly as shown:
.venv/
**/.env
__pycache__/
*.pyc
graphrag_workspace/cache/
graphrag_workspace/output/

What does this file protect?

  • .venv/ excludes the isolated interpreter plus installed packages.
  • **/.env excludes credential files at every level of the project.
  • __pycache__/ plus *.pyc exclude generated Python cache files.
  • The two graphrag_workspace paths exclude generated cache data plus index output.
  • Save .gitignore.
  • Confirm the Explorer lists .gitignore inside agentic-graphrag-investigator.
  • Confirm the editor shows all six protection patterns.

Is .gitignore missing from the Explorer?

Check that the file name begins with a dot. Confirm Visual Studio Code still has agentic-graphrag-investigator open.

If the file name looks different, help me correct the .gitignore file.

✔️ Awesome, I've got everything!

Great. Double-check that .gitignore is saved before you create the Gemini API key.

ⓧ I'd like to double check the full code

.venv/
**/.env
__pycache__/
*.pyc
graphrag_workspace/cache/
graphrag_workspace/output/

Check the selected Gemini project

Gemini 3.5 Flash-Lite requests are free on the Gemini Free Tier. A key attached to a billing-enabled project uses current paid-tier pricing.

Free-tier content may be used to improve Google products. This project sends only synthetic incident reports in later steps.

Creating credentials can feel risky. You will store the key outside the project until a protected .env file is added in a later step.

  • Open Google AI Studio in your browser.
  • Sign in to your Google account if the page requests authentication.
  • Open the API Keys page.
  • Confirm the selected Google project has the billing state you intend to use.
  • Create or view a Gemini API key from the API Keys page.
  • Copy the key into a trusted password manager.
  • Close the key reveal after the credential is stored.

Before the final check, what do you expect each command to prove about your activated environment?

  • Switch back to the activated PowerShell window from earlier.
  • Verify Python plus both installed command-line tools by running:
python --version
graphrag --help
adk --help

You should see Python 3.11 version output first. Both remaining commands should print their help text.

Is one of the command-line tools unavailable?

Confirm your PowerShell prompt still shows the active environment name. Reactivate .venv if you opened a different terminal.

If one tool remains unavailable, help me verify the GraphRAG and ADK installations.

That is the environment locked down. Python plus both command-line tools now run from the isolated project environment.

Your Windows toolchain is ready. Next up, you will turn the synthetic incident reports into a searchable knowledge graph.

Build the Incident Knowledge Graph

Your pinned Python environment can now run GraphRAG. The next challenge is giving your future agent a real incident graph to investigate.

The agent needs a retrieval target before it can choose a search strategy. FastGraphRAG builds that target from five synthetic incident reports.

In this step, get ready to:
  • Scaffold the GraphRAG workspace with its models and API key configuration.
  • Build an incident knowledge graph from five synthetic reports.
  • Compare Local Search across entity-focused and whole-corpus questions.
Scaffold and configure the GraphRAG workspace

A GraphRAG workspace keeps the source documents beside the configuration that turns them into a searchable graph. Initialization creates that structure before you add any incident data.

  • Return to the activated PowerShell terminal from the previous step.
  • Initialize the workspace with the chosen models by running this command:
graphrag init --root .\graphrag_workspace --model gemini-3.5-flash-lite --embedding gemini-embedding-001

What does this command create?

The command creates graphrag_workspace with generated prompt files and an input folder. It also creates the configuration files you replace next.

  • Switch back to Visual Studio Code from earlier.
  • Refresh the file sidebar.
  • Expand the graphrag_workspace folder.

You should see .env, settings.yaml, input, and prompts. This confirms the workspace scaffold exists.

Workspace folder missing?

Confirm the terminal prompt still begins with (.venv). Confirm the terminal is still inside agentic-graphrag-investigator.

If the command failed during setup, use the terminal output to identify whether GraphRAG could create the workspace.

help me troubleshoot why GraphRAG did not initialize my workspace

GraphRAG reads its Gemini API key from the workspace environment file. Your existing .gitignore keeps this file out of source control.

  • Select graphrag_workspace/.env in the Visual Studio Code file sidebar.
  • Replace its contents with this template:
GEMINI_API_KEY=your-api-key-here

How does GraphRAG find the key?

The GEMINI_API_KEY name matches the environment reference used in settings.yaml. GraphRAG reads the key when it calls the configured models.

  • Replace your-api-key-here with the Gemini API key you created earlier.
  • Save graphrag_workspace/.env.
  • Close the file tab so your key stays out of later screenshots.

The workspace also needs a YAML configuration that selects the completion model and embedding model. Smaller chunks help FastGraphRAG build co-occurrence relationships from this compact corpus.

  • Select graphrag_workspace/settings.yaml in the file sidebar.
  • Replace the generated contents with this configuration:
completion_models:
  default_completion_model:
    model_provider: gemini
    model: gemini-3.5-flash-lite
    auth_method: api_key
    api_key: ${GEMINI_API_KEY}

embedding_models:
  default_embedding_model:
    model_provider: gemini
    model: gemini-embedding-001
    auth_method: api_key
    api_key: ${GEMINI_API_KEY}

chunking:
  type: tokens
  size: 100
  overlap: 20

How does this configuration work?

  • The completion model generates GraphRAG community reports from the incident data.
  • The embedding model converts text into values that support retrieval.
  • The size value limits each chunk to 100 tokens.
  • The overlap value carries 20 tokens between neighboring chunks.
  • Save graphrag_workspace/settings.yaml.
  • Confirm the saved file shows gemini-3.5-flash-lite under the completion model.
  • Confirm the saved file shows gemini-embedding-001 under the embedding model.

Seeing a YAML warning?

Check that each nested line uses spaces for indentation. Make sure the ${GEMINI_API_KEY} reference includes both braces.

help me compare my GraphRAG YAML with the required configuration

Add and index the synthetic incidents

The graph needs repeated incident names and service relationships that FastGraphRAG can detect. These reports are synthetic so the indexing request contains no real production data.

  • Expand graphrag_workspace/input in the Visual Studio Code file sidebar.
  • Use the folder's new-file control to create incidents.txt.
  • Add the five synthetic incident reports with this content:
INC-101 occurred on 2026-08-04. API Gateway latency increased after the Auth Service connection pool reached its limit during a traffic spike. Checkout requests waited for authentication and some customers saw timeouts. The SRE Team first received an alert twelve minutes after customer reports began. Restarting Auth Service workers restored capacity. The follow-up action was to add connection pool saturation alerts and load tests.

INC-102 occurred on 2026-08-11. Payments API returned elevated errors after Release 42 introduced a long-running database migration. The Database Cluster experienced lock contention, which delayed payment writes. Customers saw duplicate retry messages, although completed payments were not duplicated. The SRE Team rolled back Release 42. The first automated alert arrived nine minutes after support tickets.

INC-103 occurred on 2026-08-18. API Gateway returned HTTP 502 responses because Auth Service could not validate tokens after a certificate rotation. The deployment checklist did not include a certificate compatibility test. Customers were repeatedly signed out. The Platform Team restored the previous certificate and added a pre-deployment validation step. Monitoring detected generic errors but did not identify the certificate mismatch.

INC-104 occurred on 2026-08-25. Payments API processing slowed when the Database Cluster reached high CPU during a promotional event. A queue backlog grew until payment confirmations were delayed. The SRE Team scaled the database and drained the queue. Capacity planning used average traffic rather than peak traffic. The customer-impact alert fired after the queue had already exceeded its target.

INC-105 occurred on 2026-09-02. Cache Service memory pressure caused repeated evictions, which increased load on Product API and Database Cluster. Product pages loaded slowly and some inventory checks timed out. A configuration change had reduced the cache memory limit earlier that day. The Platform Team restored the previous limit and added a configuration guardrail. Infrastructure monitoring showed memory pressure, but no alert connected the evictions to customer-facing latency.

What does this corpus contain?

Each report names an incident and its affected services. Each report also records a cause and a mitigation.

Repeated service names create connections across reports. Those connections give the graph evidence for entity-centered retrieval.

  • Save graphrag_workspace/input/incidents.txt.
  • Confirm the file contains five blank-line-separated reports.
  • Confirm the first report starts with INC-101.
  • Confirm the last report starts with INC-105.

Incident file in the wrong folder?

Confirm the file path is graphrag_workspace/input/incidents.txt. GraphRAG reads source documents from the workspace input folder.

help me check whether my incidents file is in the GraphRAG input folder

Use this checkpoint to compare every file before indexing the corpus.

✔️ Awesome, I've got everything!

Your workspace files are ready. Make sure each open file is saved.

ⓧ I'd like to double check the full code

.venv/
**/.env
__pycache__/
*.pyc
graphrag_workspace/cache/
graphrag_workspace/output/

What does this file protect?

This file keeps the virtual environment and environment files out of source control. It also excludes generated Python and GraphRAG data.

GEMINI_API_KEY=your-api-key-here

What should you replace?

Your saved file contains the real Gemini API key in place of your-api-key-here. Keep that value private.

completion_models:
  default_completion_model:
    model_provider: gemini
    model: gemini-3.5-flash-lite
    auth_method: api_key
    api_key: ${GEMINI_API_KEY}

embedding_models:
  default_embedding_model:
    model_provider: gemini
    model: gemini-embedding-001
    auth_method: api_key
    api_key: ${GEMINI_API_KEY}

chunking:
  type: tokens
  size: 100
  overlap: 20

What should the settings contain?

The configuration uses the Gemini completion and embedding models from this project. It also applies the FastGraphRAG chunk settings.

INC-101 occurred on 2026-08-04. API Gateway latency increased after the Auth Service connection pool reached its limit during a traffic spike. Checkout requests waited for authentication and some customers saw timeouts. The SRE Team first received an alert twelve minutes after customer reports began. Restarting Auth Service workers restored capacity. The follow-up action was to add connection pool saturation alerts and load tests.

INC-102 occurred on 2026-08-11. Payments API returned elevated errors after Release 42 introduced a long-running database migration. The Database Cluster experienced lock contention, which delayed payment writes. Customers saw duplicate retry messages, although completed payments were not duplicated. The SRE Team rolled back Release 42. The first automated alert arrived nine minutes after support tickets.

INC-103 occurred on 2026-08-18. API Gateway returned HTTP 502 responses because Auth Service could not validate tokens after a certificate rotation. The deployment checklist did not include a certificate compatibility test. Customers were repeatedly signed out. The Platform Team restored the previous certificate and added a pre-deployment validation step. Monitoring detected generic errors but did not identify the certificate mismatch.

INC-104 occurred on 2026-08-25. Payments API processing slowed when the Database Cluster reached high CPU during a promotional event. A queue backlog grew until payment confirmations were delayed. The SRE Team scaled the database and drained the queue. Capacity planning used average traffic rather than peak traffic. The customer-impact alert fired after the queue had already exceeded its target.

INC-105 occurred on 2026-09-02. Cache Service memory pressure caused repeated evictions, which increased load on Product API and Database Cluster. Product pages loaded slowly and some inventory checks timed out. A configuration change had reduced the cache memory limit earlier that day. The Platform Team restored the previous limit and added a configuration guardrail. Infrastructure monitoring showed memory pressure, but no alert connected the evictions to customer-facing latency.

What should the source contain?

The source file contains five synthetic incident reports. The incident identifiers run from INC-101 through INC-105.

Indexing converts the source reports into graph relationships and community reports. It also creates the local retrieval data used by the next query.

This command sends only the synthetic reports through the configured Gemini models. A billing-enabled API project uses the current paid rates.

  • Return to the activated PowerShell terminal.
  • Build the FastGraphRAG index by running this command:
graphrag index --root .\graphrag_workspace --method fast

What does FastGraphRAG do?

FastGraphRAG extracts noun phrases from each text unit. It creates relationships when those phrases occur together.

The index also uses the configured completion model to generate community reports. Those reports support questions about broader patterns.

The indexing run may take several minutes while the models process the corpus. A quiet terminal during part of this run does not mean it has stopped.

  • Keep the terminal running until the index command finishes.
  • Return to Visual Studio Code after the terminal reports completion.
  • Refresh the file sidebar.
  • Expand graphrag_workspace/output.

You should see generated Parquet files in graphrag_workspace/output. This proves the incident corpus has been indexed.

Indexing did not finish?

Confirm graphrag_workspace/.env contains your real key. Confirm the file still uses the GEMINI_API_KEY name.

Check the terminal output for a model configuration or authentication problem. Keep your API key out of any message you share.

help me diagnose my FastGraphRAG indexing failure without exposing my API key

Test Local Search against two question scopes

Local Search combines graph entities with their relationships and linked source text. A named incident gives it a clear entity around which to gather evidence.

Before you run this, which services do you expect the graph to connect to INC-101?

  • Query the graph for the named incident by running this command:
graphrag query "What caused INC-101 and which services were involved?" --root .\graphrag_workspace --method local

What does this query test?

The question gives Local Search a named incident as its center. The retrieval path can follow relationships from that incident to connected services and causes.

You should receive an answer connecting INC-101 with API Gateway and Auth Service. The answer should identify connection pool exhaustion as the cause.

That is the graph's first successful investigation. Your synthetic incidents now support entity-centered retrieval.

Query returned no useful answer?

Confirm the index command completed before you ran the query. Confirm incidents.txt starts with the full INC-101 report.

help me diagnose why GraphRAG Local Search cannot find INC-101

A whole-corpus question tests a wider evidence scope. Run that question through the same retrieval method before changing the project.

Before you run this, do you think one entity-centered context can represent recurring patterns across all five incidents?

  • Send the whole-corpus question through Local Search by running this command:
graphrag query "What recurring operational patterns appear across all incidents?" --root .\graphrag_workspace --method local

What did this reveal?

The response may focus on a few nearby entities. It may also miss themes that require evidence from several incident communities.

That awkward fit is the intended result. Local Search is strongest when a specific entity anchors the question.

  • Compare the response with the five reports in incidents.txt.
  • Identify which recurring causes or monitoring gaps the response leaves underdeveloped.

Your incident graph is indexed and its first retrieval limitation is visible. Next, you will wrap Local Search in an agent tool and investigate incidents through a browser chat.

Give the Agent One GraphRAG Tool

Your indexed synthetic incidents can already answer entity-focused questions through GraphRAG Local Search. Now you will place that retrieval path behind a Google ADK agent.

This first agent receives one function tool. Testing two question shapes against the same tool creates the baseline you need for retrieval routing.

In this step, get ready to:
  • Create the ADK package with protected Gemini API configuration.
  • Expose GraphRAG Local Search as a Python function tool.
  • Run the agent against named-incident questions plus corpus-wide questions.
Create the ADK project package

An ADK project is a Python package that exposes a variable named root_agent. Its local .env file supplies the credential that ADK uses for Gemini requests.

Why Google ADK for this agent?

Google ADK automatically exposes ordinary Python functions as tools. Its development interface keeps this build focused on retrieval decisions.

A lower-level orchestration framework such as LangGraph would add graph-routing code to this lesson.

  • Switch back to Visual Studio Code from earlier.
  • Click New Folder in the Explorer header.
  • Enter incident_agent as the folder name.
  • Press Enter.

You should see incident_agent beside graphrag_workspace in the Explorer.

  • Select the incident_agent folder in the Explorer.
  • Click New File in the Explorer header.
  • Enter .env as the file name.
  • Press Enter.

This file holds a live credential. Your existing **/.env rule keeps every project .env file out of source control.

  • Configure ADK authentication by pasting this line into incident_agent\.env:
GOOGLE_API_KEY=your-api-key-here

Why a second environment variable?

GraphRAG reads GEMINI_API_KEY from its workspace. ADK reads GOOGLE_API_KEY from the agent package.

Both names can hold the same Gemini API key. Each tool receives the name it expects.

  • Replace your-api-key-here with the same Gemini API key used in graphrag_workspace\.env.
  • Save incident_agent\.env.

You should see .env inside incident_agent in the Explorer. Keep the file closed whenever you capture a screenshot.

  • Select the incident_agent folder in the Explorer.
  • Click New File.
  • Enter __init__.py as the file name.
  • Press Enter.
  • Click New File again.
  • Enter agent.py as the file name.
  • Press Enter.

The Explorer should now list .env, __init__.py, and agent.py inside incident_agent.

  • Export the agent package entry point by pasting this code into incident_agent\__init__.py:
from .agent import root_agent

__all__ = ["root_agent"]

What does the package initializer do?

The relative import exposes root_agent when ADK loads the package. The __all__ list records that public entry point.

  • Save incident_agent\__init__.py.
  • Confirm the file contains the import plus the __all__ declaration.

The main agent file needs a stable path to the existing graph. It also needs a subprocess bridge that can call the documented GraphRAG CLI.

  • Add the imports plus graph location by pasting this code into the empty incident_agent\agent.py file:
from pathlib import Path
import subprocess

from google.adk import Agent

GRAPH_ROOT = Path(__file__).resolve().parent.parent / "graphrag_workspace"

What does this scaffold prepare?

  • Path builds a reliable location for the indexed GraphRAG workspace.
  • subprocess lets Python launch GraphRAG as a separate command-line process.
  • GRAPH_ROOT points from the agent package to graphrag_workspace.
  • Save incident_agent\agent.py.
  • Add the shared GraphRAG subprocess helper below GRAPH_ROOT by pasting this code:
def _run_graphrag(question: str, method: str) -> dict:
    completed = subprocess.run(
        [
            "graphrag",
            "query",
            question,
            "--root",
            str(GRAPH_ROOT),
            "--method",
            method,
        ],
        capture_output=True,
        text=True,
        encoding="utf-8",
        errors="replace",
        check=False,
    )

    if completed.returncode != 0:
        return {
            "status": "error",
            "method": method,
            "error": completed.stderr.strip() or completed.stdout.strip(),
        }

    return {
        "status": "success",
        "method": method,
        "report": completed.stdout.strip(),
    }

How does the subprocess bridge work?

  • subprocess.run() sends the question plus workspace path to the GraphRAG query command.
  • method supplies the retrieval strategy selected by the calling tool.
  • capture_output=True keeps the GraphRAG report available to the agent.
  • returncode separates successful reports from command failures.
  • Save incident_agent\agent.py.
  • Check the partial file syntax in the activated PowerShell terminal by running this command:
python -m py_compile incident_agent\agent.py

What does this syntax check do?

The py_compile module compiles the named Python source file. A successful check creates a byte-code file under incident_agent\__pycache__.

You should return to the PowerShell prompt without a syntax error. The new __pycache__ folder confirms that Python compiled the partial agent file.

Seeing a syntax problem?

Compare the indentation inside _run_graphrag() with the code block. Each nested list plus dictionary must keep its original spacing.

Check that every opening bracket has a matching closing bracket. Save agent.py before running the check again.

help me find the syntax problem in my GraphRAG subprocess helper

The helper can run any supported GraphRAG query method. The function tool below deliberately fixes that method to local.

  • Add the entity-search tool below _run_graphrag() by pasting this code:
def search_incident_entity(question: str) -> dict:
    """Search a specific incident, service, team, cause, or relationship.

    Use this for questions centered on a named entity or one incident.
    """
    return _run_graphrag(question, "local")

How does ADK understand this tool?

  • search_incident_entity gives the model a descriptive tool name.
  • question: str defines the expected parameter schema.
  • The docstring describes the questions that fit this capability.
  • local sends every tool call through GraphRAG Local Search.
  • Save incident_agent\agent.py.
  • Create the one-tool root agent below search_incident_entity() by pasting this code:
root_agent = Agent(
    name="incident_graph_agent",
    model="gemini-3.5-flash-lite",
    description="Investigates synthetic production incidents with GraphRAG.",
    instruction="""
You are an incident investigation agent. Always use search_incident_entity before
answering a factual incident question.

Base the answer on the selected tool result. Do not invent incident facts. If
the tool returns an error, explain the error instead of answering from memory.
Begin every successful answer with this line:
Search method: local
""",
    tools=[search_incident_entity],
)

What controls the agent?

  • incident_graph_agent gives ADK a stable agent name.
  • gemini-3.5-flash-lite handles the conversation plus tool call.
  • instruction requires a tool result before a factual answer.
  • tools=[search_incident_entity] leaves the model with one retrieval capability.
  • Save incident_agent\agent.py.
  • Confirm the Explorer shows saved versions of all three files inside incident_agent.

✔️ Awesome, I've got everything!

Your ADK package now contains its protected credential configuration plus a one-tool root agent.

ⓧ I'd like to double check the full code

These reference copies show the complete package state for this step. The .env reference keeps the secret placeholder visible.

GOOGLE_API_KEY=your-api-key-here

Environment file check

Your saved file holds the actual Gemini API key where this reference shows your-api-key-here.

from .agent import root_agent

__all__ = ["root_agent"]

Package initializer check

This file exposes root_agent when ADK discovers the package.

from pathlib import Path
import subprocess

from google.adk import Agent

GRAPH_ROOT = Path(__file__).resolve().parent.parent / "graphrag_workspace"


def _run_graphrag(question: str, method: str) -> dict:
    completed = subprocess.run(
        [
            "graphrag",
            "query",
            question,
            "--root",
            str(GRAPH_ROOT),
            "--method",
            method,
        ],
        capture_output=True,
        text=True,
        encoding="utf-8",
        errors="replace",
        check=False,
    )

    if completed.returncode != 0:
        return {
            "status": "error",
            "method": method,
            "error": completed.stderr.strip() or completed.stdout.strip(),
        }

    return {
        "status": "success",
        "method": method,
        "report": completed.stdout.strip(),
    }


def search_incident_entity(question: str) -> dict:
    """Search a specific incident, service, team, cause, or relationship.

    Use this for questions centered on a named entity or one incident.
    """
    return _run_graphrag(question, "local")


root_agent = Agent(
    name="incident_graph_agent",
    model="gemini-3.5-flash-lite",
    description="Investigates synthetic production incidents with GraphRAG.",
    instruction="""
You are an incident investigation agent. Always use search_incident_entity before
answering a factual incident question.

Base the answer on the selected tool result. Do not invent incident facts. If
the tool returns an error, explain the error instead of answering from memory.
Begin every successful answer with this line:
Search method: local
""",
    tools=[search_incident_entity],
)

Agent file check

The complete file contains one subprocess helper plus one Local Search function tool. Its tools list contains only search_incident_entity.

Run the one-tool agent

The package is ready for a live conversation. ADK Web discovers root_agent from the parent folder that contains incident_agent.

  • Start the development interface from the current agentic-graphrag-investigator folder by running this command:
adk web --port 8000

What does this command do?

ADK Web discovers the agent package before starting a local development interface on port 8000.

The server keeps this PowerShell terminal occupied while you test the agent. You will stop it after the final check.

  • Navigate to http://localhost:8000 in your browser.
  • Choose incident_agent if the interface asks which agent to load.
  • Enter What caused INC-101 and what mitigation restored service? in the chat input.
  • Press Enter to submit the question.

You should see an answer beginning with Search method: local. The evidence should connect the Auth Service connection pool limit to the traffic spike plus worker restart.

You now have a complete agentic retrieval loop working. The model calls your Python tool before it explains the indexed incident evidence.

Agent page not returning an answer?

Check that the activated PowerShell terminal is still running the ADK Web process. Confirm that the browser address uses port 8000.

Confirm that incident_agent\.env contains your Gemini API key. Keep the key private while checking the file.

help me debug why my ADK agent cannot return a GraphRAG Local Search result

Test the one-tool boundary

The named incident matched the tool's entity-centered purpose. A wider question now tests how the same capability handles evidence spread across all five incidents.

Before you send the next question, which part of the incident set do you think a one-tool agent will emphasize?

  • Enter What recurring causes and detection gaps appear across all incidents? in the chat input.
  • Press Enter to submit the question.

You should still see Search method: local at the beginning. The response will usually emphasize a small set of incidents or entities while leaving the recurring themes incomplete.

Why does the answer fall short?

Local Search gathers evidence around entities plus their nearby relationships. That scope fits a named incident such as INC-101.

A recurring-pattern question needs evidence from the complete incident collection. The one-tool agent has no second retrieval capability to choose.

That shortfall is intentional. You have proved that a working tool can still be a weak fit for a different evidence scope.

  • Return to the PowerShell terminal running ADK Web.
  • Press Ctrl+C to stop the development server.

Your PowerShell prompt should return with the virtual environment still active. Your one-tool agent works for named incidents while its corpus-wide limitation is now visible.

Next, you will add Global Search as a second capability. The agent will finally have a retrieval decision to make.

Route Between Local and Global Search

Your Local Search agent can investigate relationships inside the GraphRAG knowledge graph. Corpus-wide questions currently pass through the same entity-centered path.

You will expose Global Search as a second tool for whole-dataset analysis. Google ADK can then select a retrieval strategy from the intent of each question.

In this step, get ready to:
  • Add a Global Search function for whole-corpus analysis.
  • Define the decision boundary between the two retrieval tools.
  • Verify both routing branches in ADK Web.
Add the Global Search tool

The new function gives the agent a dedicated whole-dataset retrieval capability. GraphRAG Global Search uses community reports to identify themes across the incident collection.

  • In Visual Studio Code, switch back to incident_agent/agent.py.
  • Find the closing return _run_graphrag(question, "local") line in search_incident_entity().
  • Add the following function directly below search_incident_entity():
def analyze_incident_patterns(question: str) -> dict:
    """Analyze trends and themes across the complete incident collection.

    Use this for recurring causes, comparisons, patterns, and whole-corpus questions.
    """
    return _run_graphrag(question, "global")

What Does This Function Do?

  • The analyze_incident_patterns() name describes the tool's whole-dataset purpose.
  • The docstring tells ADK which questions fit this tool.
  • The return line passes global to the existing _run_graphrag() helper.
  • Save incident_agent/agent.py.
  • Confirm analyze_incident_patterns() appears directly below search_incident_entity().

Does the Function Look Nested?

  • Check that def analyze_incident_patterns begins at the far-left edge of the editor.
  • Confirm the new function sits outside search_incident_entity().

Help me check the placement of my new GraphRAG tool function.

Teach the agent the routing boundary

A second function only becomes selectable after the agent receives it as a tool. The instruction also needs a clear boundary between entity investigation and whole-corpus analysis.

  • In incident_agent/agent.py, find the block beginning with root_agent = Agent(.
  • Select the entire root_agent block through its final closing parenthesis.
  • Replace the selected block with the following code:
root_agent = Agent(
    name="incident_graph_agent",
    model="gemini-3.5-flash-lite",
    description="Investigates synthetic production incidents with GraphRAG.",
    instruction="""
You are an incident investigation agent. Always use one GraphRAG tool before
answering a factual incident question.

Use search_incident_entity for a named incident, service, team, cause, or
relationship. Use analyze_incident_patterns for trends, comparisons, recurring
causes, shared customer effects, monitoring gaps, or questions about the entire
incident collection.

Base the answer on the selected tool result. Do not invent incident facts. If
the tool returns an error, explain the error instead of answering from memory.
Begin every successful answer with exactly one of these lines, using the method
returned by the tool:
Search method: local
Search method: global
""",
    tools=[search_incident_entity, analyze_incident_patterns],
)

How Does the Agent Choose?

  • The tools list exposes both retrieval functions to the agent.
  • The instruction maps named entities to search_incident_entity().
  • Whole-corpus questions map to analyze_incident_patterns().
  • The response prefix makes the selected method visible in every successful answer.
  • Save incident_agent/agent.py.
  • Compare your file with the complete version below.

✔️ Awesome, I've got everything!

Your file now exposes both retrieval tools. Make sure incident_agent/agent.py is saved.

ⓧ I'd like to double check the full code

from pathlib import Path
import subprocess

from google.adk import Agent

GRAPH_ROOT = Path(__file__).resolve().parent.parent / "graphrag_workspace"


def _run_graphrag(question: str, method: str) -> dict:
    completed = subprocess.run(
        [
            "graphrag",
            "query",
            question,
            "--root",
            str(GRAPH_ROOT),
            "--method",
            method,
        ],
        capture_output=True,
        text=True,
        encoding="utf-8",
        errors="replace",
        check=False,
    )

    if completed.returncode != 0:
        return {
            "status": "error",
            "method": method,
            "error": completed.stderr.strip() or completed.stdout.strip(),
        }

    return {
        "status": "success",
        "method": method,
        "report": completed.stdout.strip(),
    }


def search_incident_entity(question: str) -> dict:
    """Search a specific incident, service, team, cause, or relationship.

    Use this for questions centered on a named entity or one incident.
    """
    return _run_graphrag(question, "local")


def analyze_incident_patterns(question: str) -> dict:
    """Analyze trends and themes across the complete incident collection.

    Use this for recurring causes, comparisons, patterns, and whole-corpus questions.
    """
    return _run_graphrag(question, "global")


root_agent = Agent(
    name="incident_graph_agent",
    model="gemini-3.5-flash-lite",
    description="Investigates synthetic production incidents with GraphRAG.",
    instruction="""
You are an incident investigation agent. Always use one GraphRAG tool before
answering a factual incident question.

Use search_incident_entity for a named incident, service, team, cause, or
relationship. Use analyze_incident_patterns for trends, comparisons, recurring
causes, shared customer effects, monitoring gaps, or questions about the entire
incident collection.

Base the answer on the selected tool result. Do not invent incident facts. If
the tool returns an error, explain the error instead of answering from memory.
Begin every successful answer with exactly one of these lines, using the method
returned by the tool:
Search method: local
Search method: global
""",
    tools=[search_incident_entity, analyze_incident_patterns],
)

Seeing a Code Mismatch?

  • Check that only one root_agent = Agent( block remains in the file.
  • Confirm the tools list contains search_incident_entity plus analyze_incident_patterns.

Help me compare my two-tool agent with the completed file.

Test both retrieval branches

The two questions below target different evidence scopes. Their response prefixes provide observable proof that the agent selected different tools.

  • Start the updated development server from the activated PowerShell terminal by running this command:
adk web --port 8000

What Does This Command Do?

This command starts the local ADK development interface at http://localhost:8000. The server keeps the PowerShell terminal occupied while it runs.

  • Return to the ADK Web browser tab from earlier.
  • Refresh http://localhost:8000.

You should see the development chat for incident_graph_agent.

Is the Development Page Unavailable?

  • Check that the PowerShell terminal still shows the ADK server running.
  • Confirm the terminal prompt includes (.venv) before restarting the server.

Help me troubleshoot why my local ADK Web page is unavailable.

Each answer can take a moment while ADK launches GraphRAG. The retrieval process is working during that wait.

Before you test the first branch, which method should a question about one named incident select?

  • Enter How were API Gateway and Auth Service connected to INC-101? in the chat input.
  • Press Enter to submit the question.

You should see the answer begin with Search method: local. That is the first branch proven: your agent selected entity-centered retrieval for a named relationship.

Before you test the second branch, which method should a whole-corpus pattern question select?

  • Enter What recurring causes, customer effects, and monitoring gaps appear across the incident set? in the chat input.
  • Press Enter to submit the question.

You should see the answer begin with Search method: global. Your investigator now routes whole-corpus analysis through the retrieval method built for dataset-wide themes.

  • Compare the evidence in the two responses.

Why Did the Route Change?

The first question names one incident plus two services. Local Search follows those entities and their relationships through the graph.

The second question asks for patterns across every incident. Global Search synthesizes community reports to cover the full dataset.

Secret mission

Add an Evidence Search Fallback

Add a third retrieval path for questions that need direct source evidence. Your agent will select Basic Search for quotations while preserving its Local Search and Global Search routes.

Clean Up Your Resources

Clean Up Your Resources

Your local project has no idle cost. Future Gemini API calls follow the billing tier attached to your key.

Resources you used:

  • The agentic-graphrag-investigator project folder with its Python virtual environment and installed packages.
  • The graphrag_workspace folder with its FastGraphRAG workspace, synthetic incident corpus, generated prompts, cache files, LanceDB vector store, and Parquet outputs.
  • The incident_agent package with its Local Search, Global Search, and Basic Search tools.
  • The local Google ADK development web server on port 8000.
  • The dedicated Gemini API key managed through Google AI Studio.

Keep everything running

No action is needed. Choose this if you plan to keep testing or extending the incident investigator.

  • Leave the agentic-graphrag-investigator folder in its current location.
  • Keep the dedicated Gemini API key active while you continue testing.
  • Press Ctrl+C in the activated PowerShell terminal when you finish the current session.

Your graph and index remain ready for the next session without creating an idle charge.

Pause - I'll come back to this later

Shut down the development server to free up local memory. Your graph, agent files, and virtual environment remain on disk.

  • Press Ctrl+C in the activated PowerShell terminal to stop ADK Web.
  • Deactivate the current virtual environment by running this command:
deactivate

What does this command do?

The deactivate command ends the active virtual environment session. Your project files stay unchanged.

  • Check the PowerShell prompt to confirm that the virtual environment indicator is gone.
  • Close Visual Studio Code.
  • Keep the dedicated Gemini API key active for your next session.

Your session is paused. The indexed incident graph remains ready when you return.

Delete - I don't want to use this again

Remove the local project only when you are certain you no longer need it. This permanently erases every file inside agentic-graphrag-investigator.

  • Press Ctrl+C in the activated PowerShell terminal to stop ADK Web.
  • Deactivate the current virtual environment by running this command:
deactivate

What does this command do?

The deactivate command releases the active virtual environment session. This prepares the project folder for removal.

  • Check the PowerShell prompt to confirm that the virtual environment indicator is gone.
  • Close Visual Studio Code.
  • Close PowerShell.

Confirm the Dedicated Key

Revoking a key permanently stops requests that depend on it. Confirm that you selected the dedicated key created for this project.

  • Go to the API Keys page in Google AI Studio.
  • Locate the dedicated key created for this project.
  • Revoke the dedicated key.
  • Confirm that the key is no longer available for use.

The dedicated credential can no longer authorize Gemini API requests.

  • Use Windows search to start the file browser.
  • Navigate to the location where you created agentic-graphrag-investigator.
  • Remove the entire agentic-graphrag-investigator folder.
  • Confirm that the folder is no longer listed.

That completes the cleanup. The development server, local project, indexed incident data, and dedicated key are gone.

Nice Work!

Nice Work!

You made it! Your GraphRAG incident investigator now routes every question to a specialized retrieval tool.

You've learned how to:

  • Build a searchable incident graph from synthetic production reports using FastGraphRAG.
  • Expose Local Search plus Global Search as function tools in Google ADK.
  • Make agentic routing observable through the Search method prefix on every successful answer.
  • Secret Mission: Extend the routing policy with Basic Search for quotations, exact source details, plus fallback evidence.

Ready to quiz yourself?