Skip to content

cristofima/maf-graphrag-series

Repository files navigation

MAF + GraphRAG Series

Building Knowledge Graphs with Microsoft GraphRAG and Azure OpenAI.

Quality Gate Status Bugs Vulnerabilities Security Rating Maintainability Rating Technical Debt

Series Overview

This repository contains the code for the MAF + GraphRAG article series, demonstrating enterprise-grade knowledge graph integration with Microsoft GraphRAG and Azure OpenAI.

Part Title Status Folder/Module
1 GraphRAG Fundamentals βœ… Complete src/core/
2 GraphRAG MCP Server βœ… Complete src/mcp_server/
3 Supervisor Agent Pattern βœ… Complete src/agents/
4 Workflow Patterns βœ… Complete src/workflows/
5 Agent Evaluation ⏳ Planned β€”
6 Human-in-the-Loop ⏳ Planned β€”
7 Tool Registry ⏳ Planned β€”
8 Production Deployment ⏳ Planned β€”

Part 1: GraphRAG Fundamentals

Learn the basics of Microsoft GraphRAG - transforming documents into knowledge graphs for complex reasoning.

What You'll Learn

  • Microsoft Research GraphRAG fundamentals
  • Entity extraction from documents
  • Relationship detection between entities
  • Community detection (Leiden algorithm)
  • Local vs Global search strategies

Why GraphRAG (Not Standard RAG)?

Question Type Standard RAG GraphRAG
"Find similar documents" βœ… βœ…
"What is the relationship between X and Y?" ❌ βœ…
"What are all the connections to Project Alpha?" ❌ βœ…
"What themes span the entire organization?" ❌ βœ…

Prerequisites

  • Python 3.11+ (tested with 3.11 and 3.12)
  • Poetry for dependency management
  • Azure OpenAI resource with:
    • GPT-4o deployment (for entity extraction and queries)
    • text-embedding-3-small deployment (for embeddings)
  • Azure subscription

Quick Start

# Install Poetry (if not installed)
# Windows PowerShell:
(Invoke-WebRequest -Uri https://install.python-poetry.org -UseBasicParsing).Content | py -

# Linux/macOS:
# curl -sSL https://install.python-poetry.org | python3 -

# Clone the repository
git clone https://github.com/cristofima/maf-graphrag-series.git
cd maf-graphrag-series

# RECOMMENDED: Configure Poetry to create .venv in project folder
poetry config virtualenvs.in-project true

# Install dependencies (Poetry creates virtual environment automatically)
poetry install

# Configure environment variables
cp .env.example .env
# Edit .env with your Azure OpenAI credentials

# Build the knowledge graph
poetry run python -m core.index

# Query the knowledge graph
poetry run python -m core.example "Who leads Project Alpha?"
poetry run python -m core.example "What are the main projects?" --type global

πŸ’‘ Note: Poetry manages virtual environments automatically. You don't need to manually create .venv like with pip.

πŸ“– Poetry Guide: See docs/poetry-guide.md for detailed usage instructions.

Using the Python API

The src/core/ module provides a modern Python API for GraphRAG 3.0.x:

Building the Knowledge Graph

import asyncio
from core import build_index

# Build knowledge graph from documents in input/documents/
results = asyncio.run(build_index())

for result in results:
    print(f"{result.workflow}: {result.errors or 'success'}")

Or use the CLI:

poetry run python -m core.index
poetry run python -m core.index --resume  # Resume interrupted run

Querying the Knowledge Graph

import asyncio
from core import load_all, local_search, global_search

# Load the knowledge graph
data = load_all()
print(f"Loaded: {data.entities.shape[0]} entities, {data.relationships.shape[0]} relationships")

# Entity-focused search
response, context = asyncio.run(local_search("Who leads Project Alpha?", data))
print(response)

# Thematic search
response, context = asyncio.run(global_search("What are the main projects?", data))
print(response)

Or use the CLI:

poetry run python -m core.example "Who leads Project Alpha?"
poetry run python -m core.example "What are the main themes?" --type global

πŸ“– API Documentation: See src/core/README.md for full API reference.

Part 2: GraphRAG MCP Server

Expose GraphRAG as an MCP (Model Context Protocol) server for AI agent integration.

What You'll Learn

  • Model Context Protocol (MCP) fundamentals
  • FastMCP server implementation
  • MCP tool design patterns
  • Testing with MCP Inspector
  • Agent-to-knowledge-graph communication

Why MCP?

MCP enables agents to access external tools and data sources dynamically:

Pattern Description Use Case
Direct API calls Agent calls functions directly Simple, single-agent scenarios
MCP Tools Agent discovers and uses tools via protocol Multi-agent, extensible systems
Tool composition Multiple MCP servers, single agent Enterprise knowledge access

Quick Start

# Install Part 2 dependencies
poetry install

# Option 1: Test in notebook (recommended, no server needed)
jupyter notebook notebooks/02_test_mcp_server.ipynb

# Option 2: Start MCP Server + use MCP Inspector
poetry run python run_mcp_server.py
npx @modelcontextprotocol/inspector   # Opens browser UI at http://localhost:6274

Architecture

MCP Inspector / Client β†’ Streamable HTTP (/mcp) β†’ MCP Server (FastMCP) β†’ GraphRAG (core/)

MCP Tools Exposed

Tool Purpose Example Query
search_knowledge_graph Main entry point Any question with search_type parameter
local_search Entity-focused search "Who leads Project Alpha?"
global_search Thematic search "What are the main projects?"
list_entities Browse entities "List all projects"
get_entity Entity details "Details about Dr. Emily Harrison"

Testing with MCP Inspector

The MCP Inspector is the recommended way to interact with the server during development:

# Terminal 1: Start MCP Server
poetry run python run_mcp_server.py

# Terminal 2: Launch MCP Inspector
npx @modelcontextprotocol/inspector

In the Inspector UI:

  1. Set transport to Streamable HTTP and URL to http://localhost:8011/mcp
  2. Click Connect β†’ Tools tab shows all 5 tools
  3. Select a tool, fill in parameters, click Run

πŸ“– MCP Documentation: See src/mcp_server/README.md for complete documentation.

Part 3: Supervisor Agent Pattern

Build the Knowledge Captain: a conversational agent that connects to the GraphRAG MCP server and automatically routes questions to the right search tool.

What You'll Learn

  • Microsoft Agent Framework fundamentals (1.0.0rc5)
  • MCPStreamableHTTPTool for MCP server integration
  • Agent as async context manager for automatic MCP lifecycle management
  • System prompt-based tool routing (GPT-4o decides, no code router)
  • Multi-provider LLM support (Azure OpenAI, GitHub Models, OpenAI, Ollama)
  • Three-layer middleware pipeline (timing, token counting, logging, query rewriting)
  • Local @tool functions and research delegate sub-agent
  • AgentSession for conversation memory across multiple turns
  • MCP transport upgrade: SSE (/sse) β†’ Streamable HTTP (/mcp)

Architecture

Part 3 system architecture

flowchart TD
    A["run_agent.py<br/>CLI entry point Β· Rich"]
    B["agents/<br/>KnowledgeCaptainRunner Β· create_client()<br/>MCPStreamableHTTPTool Β· Middleware Pipeline<br/>Local @tools Β· Research Delegate"]
    C["mcp_server/<br/>FastMCP 3.1.x Β· port 8011<br/>local_search<br/>global_search<br/>list_entities Β· get_entity"]
    D["core/<br/>GraphRAG 3.0.x<br/>147 entities<br/>263 relationships<br/>32 communities"]

    A --> B
    B -->|"Streamable HTTP /mcp"| C
    C -->|"Python API"| D
Loading

Request Flow

Knowledge Captain request flow β€” two GPT-4o round trips per query

Two round trips to Azure OpenAI per query: call 1 selects the tool, call 2 composes the answer.

Quick Start

# Install dependencies
poetry install

# Start MCP server (Terminal 1)
poetry run python run_mcp_server.py

# Interactive agent (Terminal 2)
poetry run python run_agent.py

Key Pattern: System Prompt Routing

The agent uses its system prompt to decide which MCP tool to callβ€”no separate routing logic needed:

Question Type Tool Selected Example
Entity-focused local_search "Who leads Project Alpha?"
Thematic global_search "What are the main projects?"
Entity details get_entity "Details about Dr. Emily Harrison"

Usage Example

from agents import KnowledgeCaptainRunner

async with KnowledgeCaptainRunner() as runner:
    # First question
    response = await runner.ask("Who leads Project Alpha?")
    print(response.text)

    # Follow-up (has context from previous question)
    response = await runner.ask("What is their background?")
    print(response.text)

    # Reset conversation
    runner.clear_history()

Microsoft Agent Framework 1.0.0rc5

Key patterns used:

Pattern Description
Agent as async context manager async with agent: auto-manages MCP tool connect/close lifecycle
MCPStreamableHTTPTool Connect to MCP servers via Streamable HTTP
tool_name_prefix Avoids duplicate tool names when multiple agents share the same server
Multi-provider create_client() Azure OpenAI, GitHub Models, OpenAI, Ollama via API_HOST env var
Middleware pipeline TimingAgent, TokenCounting, LoggingFunction, QueryRewriting
Local @tool functions format_as_table, extract_key_entities β€” no MCP round-trip
create_research_delegate() Context-isolated sub-agent for deep knowledge graph searches
AgentSession Conversation memory across multiple turns

πŸ“– Agents Documentation: See src/agents/README.md for complete API reference.

Knowledge Graph Statistics

After indexing the 10 sample documents, the knowledge graph contains:

Metric Count
Entities 147
Relationships 263
Communities 32
Documents 10
Text Units 20

Project Structure

maf-graphrag-series/
β”œβ”€β”€ README.md
β”œβ”€β”€ pyproject.toml             # Poetry dependency management
β”œβ”€β”€ poetry.lock                # Locked dependency versions
β”œβ”€β”€ settings.yaml              # GraphRAG configuration
β”œβ”€β”€ .env.example
β”œβ”€β”€ run_agent.py               # Interactive agent CLI (Part 3)
β”œβ”€β”€ run_mcp_server.py          # Start MCP server (Part 2)
β”œβ”€β”€ run_workflow.py            # Multi-agent workflow CLI (Part 4)
β”œβ”€β”€ input/
β”‚   β”œβ”€β”€ README.md              # Document descriptions
β”‚   └── documents/             # 10 sample interconnected documents
β”‚       β”œβ”€β”€ company_org.md
β”‚       β”œβ”€β”€ team_members.md
β”‚       β”œβ”€β”€ project_alpha.md
β”‚       β”œβ”€β”€ project_beta.md
β”‚       β”œβ”€β”€ technical_architecture.md
β”‚       β”œβ”€β”€ technology_stack.md
β”‚       β”œβ”€β”€ customers_partners.md
β”‚       β”œβ”€β”€ engineering_processes.md
β”‚       β”œβ”€β”€ incidents_postmortems.md
β”‚       └── company_events_timeline.md
β”œβ”€β”€ output/                    # Generated knowledge graph
β”‚   β”œβ”€β”€ *.parquet
β”‚   └── lancedb/               # Vector store
β”œβ”€β”€ src/                       # Application source code
β”‚   β”œβ”€β”€ core/                  # Part 1: Python API for GraphRAG 3.0.x
β”‚   β”‚   β”œβ”€β”€ __init__.py        # Module exports
β”‚   β”‚   β”œβ”€β”€ config.py          # Configuration loading
β”‚   β”‚   β”œβ”€β”€ data_loader.py     # Parquet file loading
β”‚   β”‚   β”œβ”€β”€ indexer.py         # Build knowledge graph
β”‚   β”‚   β”œβ”€β”€ search.py          # Async search functions
β”‚   β”‚   β”œβ”€β”€ index.py           # CLI for indexing
β”‚   β”‚   β”œβ”€β”€ example.py         # CLI for querying
β”‚   β”‚   └── README.md          # Module documentation
β”‚   β”œβ”€β”€ mcp_server/            # Part 2: MCP Server
β”‚   β”‚   β”œβ”€β”€ __init__.py        # Package exports
β”‚   β”‚   β”œβ”€β”€ server.py          # FastMCP server
β”‚   β”‚   β”œβ”€β”€ config.py          # MCP configuration
β”‚   β”‚   β”œβ”€β”€ tools/             # MCP tools
β”‚   β”‚   β”‚   β”œβ”€β”€ __init__.py        # Tool exports
β”‚   β”‚   β”‚   β”œβ”€β”€ _data_cache.py     # Lazy singleton cache for GraphRAG data
β”‚   β”‚   β”‚   β”œβ”€β”€ types.py           # TypedDicts and validation helpers
β”‚   β”‚   β”‚   β”œβ”€β”€ local_search.py    # Entity-focused search (with source traceability)
β”‚   β”‚   β”‚   β”œβ”€β”€ global_search.py   # Thematic search (community reports only)
β”‚   β”‚   β”‚   β”œβ”€β”€ entity_query.py    # Entity lookup
β”‚   β”‚   β”‚   └── source_resolver.py # Resolves text unit IDs β†’ document titles
β”‚   β”‚   └── README.md          # MCP documentation
β”‚   β”œβ”€β”€ agents/                # Part 3: Conversational Agent
β”‚   β”‚   β”œβ”€β”€ __init__.py        # Public API re-exports
β”‚   β”‚   β”œβ”€β”€ config.py          # Multi-provider LLM configuration
β”‚   β”‚   β”œβ”€β”€ middleware.py      # Three-layer observability middleware pipeline
β”‚   β”‚   β”œβ”€β”€ prompts.py         # Knowledge Captain & Research Delegate prompts
β”‚   β”‚   β”œβ”€β”€ supervisor.py      # KnowledgeCaptainRunner, research delegate, MCP tool
β”‚   β”‚   β”œβ”€β”€ tools.py           # Local @tool functions (format_as_table, extract_key_entities)
β”‚   β”‚   └── README.md          # Agents documentation
β”‚   └── workflows/             # Part 4: Multi-agent orchestration
β”‚       β”œβ”€β”€ __init__.py        # Public API exports
β”‚       β”œβ”€β”€ base.py            # WorkflowResult, WorkflowStep, MCPWorkflowBase, factory functions
β”‚       β”œβ”€β”€ sequential.py      # Research Pipeline workflow
β”‚       β”œβ”€β”€ concurrent.py      # Parallel Search workflow
β”‚       β”œβ”€β”€ handoff.py         # Expert Routing workflow
β”‚       └── README.md          # Workflows documentation
β”œβ”€β”€ tests/                     # Test suite
β”œβ”€β”€ infra/                     # Terraform infrastructure
β”œβ”€β”€ docs/                      # Technical documentation
β”œβ”€β”€ prompts/                   # Custom GraphRAG prompt templates
└── notebooks/
    β”œβ”€β”€ 01_explore_graph.ipynb      # Part 1: Graph visualization
    └── 02_test_mcp_server.ipynb    # Part 2: MCP server testing

Sample Q&A Results

Local Search (Entity-Focused)

Question: "Who resolved the GraphRAG index corruption incident and what was the root cause?"

Answer:

The GraphRAG index corruption incident was resolved through the collaborative efforts of Sophia Lee, Priya Patel, Dr. Emily Harrison, and David Kumar. The root cause was identified as an interrupted indexing job during an Azure Container Apps scaling event, which left the graph in an inconsistent state. The resolution involved implementing a full re-index with validation checks and atomic swap procedures.

Question: "Who leads Project Alpha and what is their background?"

Answer:

Dr. Emily Harrison leads Project Alpha at TechVenture Inc. She holds a Ph.D. in Quantum Computing from MIT and has 15 years of experience in advanced computing research. Under her leadership, Project Alpha is developing a next-generation quantum-classical hybrid processor that has achieved 99.7% gate fidelity.

Global Search (Thematic)

Question: "What are the main initiatives at TechVenture?"

Answer:

TechVenture Inc. is pursuing major strategic initiatives:

  1. Project Alpha - Quantum computing research led by Dr. Emily Harrison (Phase 4 - GA Preparation)
  2. Project Beta - AI/ML platform for healthcare applications (Active production with enterprise customers)

These projects share resources through cross-functional collaboration, with teams spanning Research, Engineering, and Infrastructure departments.

See docs/qa-examples.md for more examples.


Part 4: Workflow Patterns

Extend the single Knowledge Captain agent with multi-agent workflow patterns that chain, parallelize, and route between specialized agents.

What You'll Learn

  • Sequential Workflow β€” chain agents in a research pipeline (Analyze β†’ Search β†’ Write)
  • Concurrent Workflow β€” run local + global search in parallel via asyncio.gather, then synthesize
  • Handoff Workflow β€” explicit Router agent routes queries to EntityExpert or ThemesExpert
  • When to use each pattern and how they complement each other
  • How WorkflowResult.steps provides full traceability across all agents

Workflow Patterns

Pattern Agents Best For
Sequential QueryAnalyzer β†’ KnowledgeSearcher β†’ Writer Complex multi-part research
Concurrent EntitySearcher βˆ₯ ThemesSearcher β†’ Synthesis Dual-perspective questions
Handoff Router β†’ EntityExpert | ThemesExpert Auditable specialist routing

Quick Start

# Prerequisites (same as Part 3)
poetry run python run_mcp_server.py          # Terminal 1

# Interactive workflow selector
poetry run python run_workflow.py            # Terminal 2

# Direct single-query mode
poetry run python run_workflow.py sequential "What are the key projects and their tech stack?"
poetry run python run_workflow.py concurrent "Who leads Project Alpha and what are the main themes?"
poetry run python run_workflow.py handoff    "Who leads Project Alpha?"

Architecture

                         User Query
                              β”‚
                β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                β”‚             β”‚             β”‚
                β–Ό             β–Ό             β–Ό
         Sequential      Concurrent      Handoff
         Pipeline        Search          Router
                β”‚             β”‚             β”‚
         Analyze         local + global   Classify
         Search          (parallel)    β”‚
         Write                β”‚         β”œβ”€ EntityExpert
                β”‚         Synthesize   └─ ThemesExpert
                β”‚             β”‚
                └─────────────┴──────── WorkflowResult
                                         .answer
                                         .steps     ← full trace

Usage Example

from workflows import ResearchPipelineWorkflow, ParallelSearchWorkflow, ExpertHandoffWorkflow

# Sequential: structured research pipeline
async with ResearchPipelineWorkflow() as wf:
    result = await wf.run("What is the technology strategy for Project Alpha?")
    print(result.answer)
    print(result.step_summary())  # Shows all steps with timing

# Concurrent: parallel local + global search
async with ParallelSearchWorkflow() as wf:
    result = await wf.run("Who leads the main projects and what are the key themes?")
    print(result.answer)

# Handoff: explicit router β†’ specialist
async with ExpertHandoffWorkflow() as wf:
    result = await wf.run("Who leads Project Alpha?")   # β†’ EntityExpert
    result = await wf.run("What are the initiatives?")  # β†’ ThemesExpert
    print(result.answer)

πŸ“– Workflows Documentation: See src/workflows/README.md for complete reference.


Azure AI Services Used

Service Purpose Model/Version
Azure OpenAI Entity extraction, queries GPT-4o
Azure OpenAI Document embeddings text-embedding-3-small
Agent Framework Multi-agent orchestration 1.0.0rc5

Key Files

File Description
settings.yaml GraphRAG configuration (LLM, embeddings, storage)
src/core/ Python API module for indexing, querying, and data access
src/mcp_server/ MCP server exposing GraphRAG tools
src/agents/ Knowledge Captain conversational agent
src/workflows/ Multi-agent workflow patterns
.env Azure OpenAI credentials (create from .env.example)

License

MIT License - See LICENSE for details.

Author

Cristopher Coronado