Building Knowledge Graphs with Microsoft GraphRAG and Azure OpenAI.
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 | β |
Learn the basics of Microsoft GraphRAG - transforming documents into knowledge graphs for complex reasoning.
- Microsoft Research GraphRAG fundamentals
- Entity extraction from documents
- Relationship detection between entities
- Community detection (Leiden algorithm)
- Local vs Global search strategies
| 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?" | β | β |
- 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
# 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.
The src/core/ module provides a modern Python API for GraphRAG 3.0.x:
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 runimport 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.
Expose GraphRAG as an MCP (Model Context Protocol) server for AI agent integration.
- Model Context Protocol (MCP) fundamentals
- FastMCP server implementation
- MCP tool design patterns
- Testing with MCP Inspector
- Agent-to-knowledge-graph communication
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 |
# 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:6274MCP Inspector / Client β Streamable HTTP (/mcp) β MCP Server (FastMCP) β GraphRAG (core/)
| 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" |
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/inspectorIn the Inspector UI:
- Set transport to Streamable HTTP and URL to
http://localhost:8011/mcp - Click Connect β Tools tab shows all 5 tools
- Select a tool, fill in parameters, click Run
π MCP Documentation: See src/mcp_server/README.md for complete documentation.
Build the Knowledge Captain: a conversational agent that connects to the GraphRAG MCP server and automatically routes questions to the right search tool.
- Microsoft Agent Framework fundamentals (1.0.0rc5)
MCPStreamableHTTPToolfor MCP server integrationAgentas 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
@toolfunctions and research delegate sub-agent AgentSessionfor conversation memory across multiple turns- MCP transport upgrade: SSE (
/sse) β Streamable HTTP (/mcp)
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
Two round trips to Azure OpenAI per query: call 1 selects the tool, call 2 composes the answer.
# 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.pyThe 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" |
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()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.
After indexing the 10 sample documents, the knowledge graph contains:
| Metric | Count |
|---|---|
| Entities | 147 |
| Relationships | 263 |
| Communities | 32 |
| Documents | 10 |
| Text Units | 20 |
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
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.
Question: "What are the main initiatives at TechVenture?"
Answer:
TechVenture Inc. is pursuing major strategic initiatives:
- Project Alpha - Quantum computing research led by Dr. Emily Harrison (Phase 4 - GA Preparation)
- 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.
Extend the single Knowledge Captain agent with multi-agent workflow patterns that chain, parallelize, and route between specialized agents.
- 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.stepsprovides full traceability across all agents
| 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 |
# 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?" User Query
β
βββββββββββββββΌββββββββββββββ
β β β
βΌ βΌ βΌ
Sequential Concurrent Handoff
Pipeline Search Router
β β β
Analyze local + global Classify
Search (parallel) β
Write β ββ EntityExpert
β Synthesize ββ ThemesExpert
β β
βββββββββββββββ΄ββββββββ WorkflowResult
.answer
.steps β full trace
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.
| 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 |
| 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) |
MIT License - See LICENSE for details.
Cristopher Coronado

