Skip to content

Commit f00d1ee

Browse files
victordibiaekzhu
andauthored
upgrade graphrag sample to v2.3+ (#6744)
Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
1 parent 5f1c69d commit f00d1ee

12 files changed

Lines changed: 885 additions & 305 deletions

File tree

python/packages/autogen-ext/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ llama-cpp = [
4141
"llama-cpp-python>=0.3.8",
4242
]
4343

44-
graphrag = ["graphrag>=1.0.1"]
44+
graphrag = ["graphrag>=2.3.0"]
4545
chromadb = ["chromadb>=1.0.0"]
4646
mem0 = ["mem0ai>=0.1.98"]
4747
mem0-local = [

python/packages/autogen-ext/src/autogen_ext/tools/graphrag/_config.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,19 @@
33

44
class DataConfig(BaseModel):
55
input_dir: str
6-
entity_table: str = "create_final_nodes"
7-
entity_embedding_table: str = "create_final_entities"
6+
entity_table: str = "entities"
7+
entity_embedding_table: str = "entities"
8+
community_table: str = "communities"
89
community_level: int = 2
910

1011

1112
class GlobalDataConfig(DataConfig):
12-
community_table: str = "create_final_communities"
13-
community_report_table: str = "create_final_community_reports"
13+
community_report_table: str = "community_reports"
1414

1515

1616
class LocalDataConfig(DataConfig):
17-
relationship_table: str = "create_final_relationships"
18-
text_unit_table: str = "create_final_text_units"
17+
relationship_table: str = "relationships"
18+
text_unit_table: str = "text_units"
1919

2020

2121
class ContextConfig(BaseModel):

python/packages/autogen-ext/src/autogen_ext/tools/graphrag/_global_search.py

Lines changed: 45 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
# mypy: disable-error-code="no-any-unimported,misc"
21
from pathlib import Path
32

43
import pandas as pd
@@ -7,14 +6,15 @@
76
from autogen_core.tools import BaseTool
87
from pydantic import BaseModel, Field
98

10-
from graphrag.config.config_file_loader import load_config_from_file
9+
import graphrag.config.defaults as defs
10+
from graphrag.config.load_config import load_config
11+
from graphrag.language_model.manager import ModelManager
12+
from graphrag.language_model.protocol import ChatModel
1113
from graphrag.query.indexer_adapters import (
1214
read_indexer_communities,
1315
read_indexer_entities,
1416
read_indexer_reports,
1517
)
16-
from graphrag.query.llm.base import BaseLLM
17-
from graphrag.query.llm.get_client import get_llm
1818
from graphrag.query.structured_search.global_search.community_context import GlobalCommunityContext
1919
from graphrag.query.structured_search.global_search.search import GlobalSearch
2020

@@ -64,6 +64,7 @@ class GlobalSearchTool(BaseTool[GlobalSearchToolArgs, GlobalSearchToolReturn]):
6464
.. code-block:: python
6565
6666
import asyncio
67+
from pathlib import Path
6768
from autogen_ext.models.openai import OpenAIChatCompletionClient
6869
from autogen_agentchat.ui import Console
6970
from autogen_ext.tools.graphrag import GlobalSearchTool
@@ -78,7 +79,7 @@ async def main():
7879
)
7980
8081
# Set up global search tool
81-
global_tool = GlobalSearchTool.from_settings(settings_path="./settings.yaml")
82+
global_tool = GlobalSearchTool.from_settings(root_dir=Path("./"), config_filepath=Path("./settings.yaml"))
8283
8384
# Create assistant agent with the global search tool
8485
assistant_agent = AssistantAgent(
@@ -104,7 +105,7 @@ async def main():
104105
def __init__(
105106
self,
106107
token_encoder: tiktoken.Encoding,
107-
llm: BaseLLM,
108+
model: ChatModel,
108109
data_config: DataConfig,
109110
context_config: ContextConfig = _default_context_config,
110111
mapreduce_config: MapReduceConfig = _default_mapreduce_config,
@@ -115,22 +116,20 @@ def __init__(
115116
name="global_search_tool",
116117
description="Perform a global search with given parameters using graphrag.",
117118
)
118-
# Use the provided LLM
119-
self._llm = llm
119+
# Use the provided model
120+
self._model = model
120121

121122
# Load parquet files
122123
community_df: pd.DataFrame = pd.read_parquet(f"{data_config.input_dir}/{data_config.community_table}.parquet") # type: ignore
123124
entity_df: pd.DataFrame = pd.read_parquet(f"{data_config.input_dir}/{data_config.entity_table}.parquet") # type: ignore
124125
report_df: pd.DataFrame = pd.read_parquet( # type: ignore
125126
f"{data_config.input_dir}/{data_config.community_report_table}.parquet"
126127
)
127-
entity_embedding_df: pd.DataFrame = pd.read_parquet( # type: ignore
128-
f"{data_config.input_dir}/{data_config.entity_embedding_table}.parquet"
129-
)
130128

131-
communities = read_indexer_communities(community_df, entity_df, report_df)
132-
reports = read_indexer_reports(report_df, entity_df, data_config.community_level)
133-
entities = read_indexer_entities(entity_df, entity_embedding_df, data_config.community_level)
129+
# Fix: Use correct argument order and types for GraphRAG API
130+
communities = read_indexer_communities(community_df, report_df)
131+
reports = read_indexer_reports(report_df, community_df, data_config.community_level)
132+
entities = read_indexer_entities(entity_df, community_df, data_config.community_level)
134133

135134
context_builder = GlobalCommunityContext(
136135
community_reports=reports,
@@ -164,7 +163,7 @@ def __init__(
164163
}
165164

166165
self._search_engine = GlobalSearch(
167-
llm=self._llm,
166+
model=self._model,
168167
context_builder=context_builder,
169168
token_encoder=token_encoder,
170169
max_data_tokens=context_config.max_data_tokens,
@@ -178,37 +177,56 @@ def __init__(
178177
)
179178

180179
async def run(self, args: GlobalSearchToolArgs, cancellation_token: CancellationToken) -> GlobalSearchToolReturn:
181-
search_result = await self._search_engine.asearch(args.query)
180+
search_result = await self._search_engine.search(args.query)
182181
assert isinstance(search_result.response, str), "Expected response to be a string"
183182
return GlobalSearchToolReturn(answer=search_result.response)
184183

185184
@classmethod
186-
def from_settings(cls, settings_path: str | Path) -> "GlobalSearchTool":
185+
def from_settings(cls, root_dir: str | Path, config_filepath: str | Path | None = None) -> "GlobalSearchTool":
187186
"""Create a GlobalSearchTool instance from GraphRAG settings file.
188187
189188
Args:
190-
settings_path: Path to the GraphRAG settings.yaml file
189+
root_dir: Path to the GraphRAG root directory
190+
config_filepath: Path to the GraphRAG settings file (optional)
191191
192192
Returns:
193193
An initialized GlobalSearchTool instance
194194
"""
195195
# Load GraphRAG config
196-
config = load_config_from_file(settings_path)
197-
198-
# Initialize token encoder
199-
token_encoder = tiktoken.get_encoding(config.encoding_model)
200-
201-
# Initialize LLM using graphrag's get_client
202-
llm = get_llm(config)
196+
if isinstance(root_dir, str):
197+
root_dir = Path(root_dir)
198+
if isinstance(config_filepath, str):
199+
config_filepath = Path(config_filepath)
200+
config = load_config(root_dir=root_dir, config_filepath=config_filepath)
201+
202+
# Get the language model configuration from the models section
203+
chat_model_config = config.models.get(defs.DEFAULT_CHAT_MODEL_ID)
204+
205+
if chat_model_config is None:
206+
raise ValueError("default_chat_model not found in config.models")
207+
208+
# Initialize token encoder based on the model being used
209+
try:
210+
token_encoder = tiktoken.encoding_for_model(chat_model_config.model)
211+
except KeyError:
212+
# Fallback to cl100k_base if model is not recognized by tiktoken
213+
token_encoder = tiktoken.get_encoding("cl100k_base")
214+
215+
# Create the LLM using ModelManager
216+
model = ModelManager().get_or_create_chat_model(
217+
name="global_search_model",
218+
model_type=chat_model_config.type,
219+
config=chat_model_config,
220+
)
203221

204222
# Create data config from storage paths
205223
data_config = DataConfig(
206-
input_dir=str(Path(config.storage.base_dir)),
224+
input_dir=str(config.output.base_dir),
207225
)
208226

209227
return cls(
210228
token_encoder=token_encoder,
211-
llm=llm,
229+
model=model,
212230
data_config=data_config,
213231
context_config=_default_context_config,
214232
mapreduce_config=_default_mapreduce_config,

python/packages/autogen-ext/src/autogen_ext/tools/graphrag/_local_search.py

Lines changed: 52 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
# mypy: disable-error-code="no-any-unimported,misc"
2-
import os
32
from pathlib import Path
43

54
import pandas as pd
@@ -8,14 +7,15 @@
87
from autogen_core.tools import BaseTool
98
from pydantic import BaseModel, Field
109

11-
from graphrag.config.config_file_loader import load_config_from_file
10+
import graphrag.config.defaults as defs
11+
from graphrag.config.load_config import load_config
12+
from graphrag.language_model.manager import ModelManager
13+
from graphrag.language_model.protocol import ChatModel, EmbeddingModel
1214
from graphrag.query.indexer_adapters import (
1315
read_indexer_entities,
1416
read_indexer_relationships,
1517
read_indexer_text_units,
1618
)
17-
from graphrag.query.llm.base import BaseLLM, BaseTextEmbedding
18-
from graphrag.query.llm.get_client import get_llm, get_text_embedder
1919
from graphrag.query.structured_search.local_search.mixed_context import LocalSearchMixedContext
2020
from graphrag.query.structured_search.local_search.search import LocalSearch
2121
from graphrag.vector_stores.lancedb import LanceDBVectorStore
@@ -64,6 +64,7 @@ class LocalSearchTool(BaseTool[LocalSearchToolArgs, LocalSearchToolReturn]):
6464
.. code-block:: python
6565
6666
import asyncio
67+
from pathlib import Path
6768
from autogen_ext.models.openai import OpenAIChatCompletionClient
6869
from autogen_agentchat.ui import Console
6970
from autogen_ext.tools.graphrag import LocalSearchTool
@@ -78,7 +79,7 @@ async def main():
7879
)
7980
8081
# Set up local search tool
81-
local_tool = LocalSearchTool.from_settings(settings_path="./settings.yaml")
82+
local_tool = LocalSearchTool.from_settings(root_dir=Path("./"), config_filepath=Path("./settings.yaml"))
8283
8384
# Create assistant agent with the local search tool
8485
assistant_agent = AssistantAgent(
@@ -103,8 +104,8 @@ async def main():
103104
104105
Args:
105106
token_encoder (tiktoken.Encoding): The tokenizer used for text encoding
106-
llm (BaseLLM): The language model to use for search
107-
embedder (BaseTextEmbedding): The text embedding model to use
107+
model: The chat model to use for search (GraphRAG ChatModel)
108+
embedder: The text embedding model to use (GraphRAG EmbeddingModel)
108109
data_config (DataConfig): Configuration for data source locations and settings
109110
context_config (LocalContextConfig, optional): Configuration for context building. Defaults to default config.
110111
search_config (SearchConfig, optional): Configuration for search operations. Defaults to default config.
@@ -113,8 +114,8 @@ async def main():
113114
def __init__(
114115
self,
115116
token_encoder: tiktoken.Encoding,
116-
llm: BaseLLM,
117-
embedder: BaseTextEmbedding,
117+
model: ChatModel, # ChatModel from GraphRAG
118+
embedder: EmbeddingModel, # EmbeddingModel from GraphRAG
118119
data_config: DataConfig,
119120
context_config: LocalContextConfig = _default_context_config,
120121
search_config: SearchConfig = _default_search_config,
@@ -125,30 +126,23 @@ def __init__(
125126
name="local_search_tool",
126127
description="Perform a local search with given parameters using graphrag.",
127128
)
128-
# Use the adapter
129-
self._llm = llm
129+
# Use the provided models
130+
self._model = model
130131
self._embedder = embedder
131132

132133
# Load parquet files
133134
entity_df: pd.DataFrame = pd.read_parquet(f"{data_config.input_dir}/{data_config.entity_table}.parquet") # type: ignore
134-
entity_embedding_df: pd.DataFrame = pd.read_parquet( # type: ignore
135-
f"{data_config.input_dir}/{data_config.entity_embedding_table}.parquet"
136-
)
137135
relationship_df: pd.DataFrame = pd.read_parquet( # type: ignore
138136
f"{data_config.input_dir}/{data_config.relationship_table}.parquet"
139137
)
140138
text_unit_df: pd.DataFrame = pd.read_parquet(f"{data_config.input_dir}/{data_config.text_unit_table}.parquet") # type: ignore
139+
community_df: pd.DataFrame = pd.read_parquet(f"{data_config.input_dir}/{data_config.community_table}.parquet") # type: ignore
141140

142141
# Read data using indexer adapters
143-
entities = read_indexer_entities(entity_df, entity_embedding_df, data_config.community_level)
142+
entities = read_indexer_entities(entity_df, community_df, data_config.community_level)
144143
relationships = read_indexer_relationships(relationship_df)
145144
text_units = read_indexer_text_units(text_unit_df)
146145
# Set up vector store for entity embeddings
147-
description_embedding_store = LanceDBVectorStore(
148-
collection_name="default-entity-description",
149-
)
150-
description_embedding_store.connect(db_uri=os.path.join(data_config.input_dir, "lancedb"))
151-
152146
description_embedding_store = LanceDBVectorStore(
153147
collection_name="default-entity-description",
154148
)
@@ -180,47 +174,70 @@ def __init__(
180174
}
181175

182176
self._search_engine = LocalSearch(
183-
llm=self._llm,
177+
model=self._model,
184178
context_builder=context_builder,
185179
token_encoder=token_encoder,
186-
llm_params=llm_params,
187-
context_builder_params=context_builder_params,
188180
response_type=search_config.response_type,
181+
context_builder_params=context_builder_params,
182+
model_params=llm_params,
189183
)
190184

191185
async def run(self, args: LocalSearchToolArgs, cancellation_token: CancellationToken) -> LocalSearchToolReturn:
192-
search_result = await self._search_engine.asearch(args.query) # type: ignore
186+
search_result = await self._search_engine.search(args.query) # type: ignore[reportUnknownMemberType]
193187
assert isinstance(search_result.response, str), "Expected response to be a string"
194188
return LocalSearchToolReturn(answer=search_result.response)
195189

196190
@classmethod
197-
def from_settings(cls, settings_path: str | Path) -> "LocalSearchTool":
191+
def from_settings(cls, root_dir: Path, config_filepath: Path | None = None) -> "LocalSearchTool":
198192
"""Create a LocalSearchTool instance from GraphRAG settings file.
199193
200194
Args:
201-
settings_path: Path to the GraphRAG settings.yaml file
195+
root_dir: Path to the GraphRAG root directory
196+
config_filepath: Path to the GraphRAG settings file (optional)
202197
203198
Returns:
204199
An initialized LocalSearchTool instance
205200
"""
206201
# Load GraphRAG config
207-
config = load_config_from_file(settings_path)
208-
209-
# Initialize token encoder
210-
token_encoder = tiktoken.get_encoding(config.encoding_model)
202+
config = load_config(root_dir=root_dir, config_filepath=config_filepath)
203+
204+
# Get the language model configurations from the models section
205+
chat_model_config = config.models.get(defs.DEFAULT_CHAT_MODEL_ID)
206+
embedding_model_config = config.models.get(defs.DEFAULT_EMBEDDING_MODEL_ID)
207+
208+
if chat_model_config is None:
209+
raise ValueError("default_chat_model not found in config.models")
210+
if embedding_model_config is None:
211+
raise ValueError("default_embedding_model not found in config.models")
212+
213+
# Initialize token encoder based on the model being used
214+
try:
215+
token_encoder = tiktoken.encoding_for_model(chat_model_config.model)
216+
except KeyError:
217+
# Fallback to cl100k_base if model is not recognized by tiktoken
218+
token_encoder = tiktoken.get_encoding("cl100k_base")
219+
220+
# Create the models using ModelManager
221+
model = ModelManager().get_or_create_chat_model(
222+
name="local_search_model",
223+
model_type=chat_model_config.type,
224+
config=chat_model_config,
225+
)
211226

212-
# Initialize LLM and embedder using graphrag's get_client functions
213-
llm = get_llm(config)
214-
embedder = get_text_embedder(config)
227+
embedder = ModelManager().get_or_create_embedding_model(
228+
name="local_search_embedder",
229+
model_type=embedding_model_config.type,
230+
config=embedding_model_config,
231+
)
215232

216233
# Create data config from storage paths
217234
data_config = DataConfig(
218-
input_dir=str(Path(config.storage.base_dir)),
235+
input_dir=str(config.output.base_dir),
219236
)
220237

221238
return cls(
222239
token_encoder=token_encoder,
223-
llm=llm,
240+
model=model,
224241
embedder=embedder,
225242
data_config=data_config,
226243
context_config=_default_context_config,

0 commit comments

Comments
 (0)