Простая реализация GraphRAG, которую легко взломать.
? GraphRAG — это хорошо и мощно, но официальную реализацию сложно/болезненно читать или взломать .
? Этот проект предоставляет меньший, более быстрый и чистый GraphRAG , сохраняя при этом основные функциональные возможности (см. тесты и проблемы).
? Без учета tests
и подсказок nano-graphrag
— это около 1100 строк кода .
? Маленький, но портативный (faiss, neo4j, ollama...), асинхронный и полностью типизированный.
Установить из исходного кода (рекомендуется)
# clone this repo first
cd nano-graphrag
pip install -e .
Установить из PyPi
pip install nano-graphrag
Кончик
Установите ключ API OpenAI в среде: export OPENAI_API_KEY="sk-..."
.
Кончик
Если вы используете Azure OpenAI API, обратитесь к файлу .env.example, чтобы настроить Azure OpenAI. Затем передайте GraphRAG(...,using_azure_openai=True,...)
для включения.
Кончик
Если вы используете API Amazon Bedrock, убедитесь, что ваши учетные данные заданы правильно с помощью таких команд, как aws configure
. Затем включите его, настроив следующим образом: GraphRAG(...,using_amazon_bedrock=True, best_model_id="us.anthropic.claude-3-sonnet-20240229-v1:0", cheap_model_id="us.anthropic.claude-3-haiku-20240307-v1:0",...)
. Обратитесь к примеру сценария.
Кончик
Если у вас нет ключа, посмотрите этот пример использования transformers
и ollama
. Если вы хотите использовать другую LLM или модель внедрения, отметьте «Дополнения».
скачать копию «Рождественской песни» Чарльза Диккенса:
curl https://raw.githubusercontent.com/gusye1234/nano-graphrag/main/tests/mock_data.txt > ./book.txt
Используйте приведенный ниже фрагмент Python:
from nano_graphrag import GraphRAG , QueryParam
graph_func = GraphRAG ( working_dir = "./dickens" )
with open ( "./book.txt" ) as f :
graph_func . insert ( f . read ())
# Perform global graphrag search
print ( graph_func . query ( "What are the top themes in this story?" ))
# Perform local graphrag search (I think is better and more scalable one)
print ( graph_func . query ( "What are the top themes in this story?" , param = QueryParam ( mode = "local" )))
В следующий раз, когда вы инициализируете GraphRAG
из того же working_dir
, он автоматически перезагрузит все контексты.
graph_func . insert ([ "TEXT1" , "TEXT2" ,...])
nano-graphrag
поддерживает инкрементную вставку, дублированные вычисления или данные добавляться не будут:
with open ( "./book.txt" ) as f :
book = f . read ()
half_len = len ( book ) // 2
graph_func . insert ( book [: half_len ])
graph_func . insert ( book [ half_len :])
nano-graphrag
использует md5-хеш содержимого в качестве ключа, чтобы не было дублированного фрагмента.Однако каждый раз, когда вы вставляете данные, сообщества графа будут пересчитываться, и отчеты сообщества будут генерироваться заново.
nano-graphrag
также поддерживает наивную вставку и запрос RAG:
graph_func = GraphRAG ( working_dir = "./dickens" , enable_naive_rag = True )
...
# Query
print ( rag . query (
"What are the top themes in this story?" ,
param = QueryParam ( mode = "naive" )
)
Для каждого метода NAME(...)
существует соответствующий асинхронный метод aNAME(...)
await graph_func . ainsert (...)
await graph_func . aquery (...)
...
GraphRAG
и QueryParam
— это dataclass
в Python. Используйте help(GraphRAG)
и help(QueryParam)
чтобы увидеть все доступные параметры! Или посетите раздел «Дополнения», чтобы увидеть некоторые варианты.
Ниже приведены компоненты, которые вы можете использовать:
Тип | Что | Где |
---|---|---|
Магистр права | ОпенАИ | Встроенный |
Амазонка | Встроенный | |
ДипСик | примеры | |
ollama | примеры | |
Встраивание | ОпенАИ | Встроенный |
Амазонка | Встроенный | |
Преобразователи предложений | примеры | |
Векторная база данных | nano-vectordb | Встроенный |
hnswlib | Встроенный, примеры | |
milvus-lite | примеры | |
Фейсс | примеры | |
Хранение графов | networkx | Встроенный |
neo4j | Встроенный (документ) | |
Визуализация | графмл | примеры |
Разбивка на части | по размеру токена | Встроенный |
с помощью текстового разделителя | Встроенный |
Built-in
означает, что эта реализация есть внутри nano-graphrag
. examples
означают, что эта реализация есть в руководстве в папке примеров.
Проверьте примеры/тесты, чтобы увидеть несколько сравнений между компонентами.
Всегда рады внести больше компонентов.
GraphRAG(...,always_create_working_dir=False,...)
пропустит этап создания каталога. Используйте его, если вы переключаете все свои компоненты на нефайловые хранилища. graph_func.query
возвращает окончательный ответ без потоковой передачи.
Если вы хотите использовать nano-graphrag
в своем проекте, вы можете использовать param=QueryParam(..., only_need_context=True,...)
, который будет возвращать только полученный контекст из графика, что-то вроде:
# Local mode
-----Reports-----
```csv
id, content
0, # FOX News and Key Figures in Media and Politics...
1, ...
```
...
# Global mode
----Analyst 3----
Importance Score: 100
Donald J. Trump: Frequently discussed in relation to his political activities...
...
Вы можете интегрировать этот контекст в свою персонализированную подсказку.
nano-graphrag
использует подсказки из объекта dict nano_graphrag.prompt.PROMPTS
. Вы можете поиграть с ним и заменить любую подсказку внутри.
Несколько важных подсказок:
PROMPTS["entity_extraction"]
используется для извлечения сущностей и отношений из фрагмента текста.PROMPTS["community_report"]
используется для организации и обобщения описания кластера графов.PROMPTS["local_rag_response"]
— это шаблон системного приглашения для генерации локального поиска.PROMPTS["global_reduce_rag_response"]
— это шаблон системного приглашения для создания глобального поиска.PROMPTS["fail_response"]
— это резервный ответ, когда с запросом пользователя ничего не связано. nano-graphrag
позволяет вам настроить свой собственный метод фрагментации, посмотрите пример.
Переключитесь на встроенный метод разделения текста:
from nano_graphrag . _op import chunking_by_seperators
GraphRAG (..., chunk_func = chunking_by_seperators ,...)
В nano-graphrag
нам нужны два типа LLM: отличный и дешевый. Первый используется для планирования и реагирования, второй — для подведения итогов. По умолчанию лучший вариант — gpt-4o
, а дешевый — gpt-4o-mini
Вы можете реализовать свою собственную функцию LLM (см. _llm.gpt_4o_complete
):
async def my_llm_complete (
prompt , system_prompt = None , history_messages = [], ** kwargs
) -> str :
# pop cache KV database if any
hashing_kv : BaseKVStorage = kwargs . pop ( "hashing_kv" , None )
# the rest kwargs are for calling LLM, for example, `max_tokens=xxx`
...
# YOUR LLM calling
response = await call_your_LLM ( messages , ** kwargs )
return response
Замените стандартный на:
# Adjust the max token size or the max async requests if needed
GraphRAG ( best_model_func = my_llm_complete , best_model_max_token_size = ..., best_model_max_async = ...)
GraphRAG ( cheap_model_func = my_llm_complete , cheap_model_max_token_size = ..., cheap_model_max_async = ...)
Вы можете сослаться на этот пример, в котором используется deepseek-chat
как на модель LLM.
Вы можете сослаться на этот пример, в котором ollama
используется в качестве модели LLM.
nano-graphrag
будет использовать best_model_func
для вывода JSON с параметрами "response_format": {"type": "json_object"}
. Однако есть некоторые модели с открытым исходным кодом, которые могут создавать нестабильный JSON.
nano-graphrag
представляет интерфейс постобработки, позволяющий преобразовать ответ в JSON. Подпись этой функции приведена ниже:
def YOUR_STRING_TO_JSON_FUNC ( response : str ) -> dict :
"Convert the string response to JSON"
...
И передайте свою собственную функцию с помощью GraphRAG(...convert_response_to_json_func=YOUR_STRING_TO_JSON_FUNC,...)
.
Например, вы можете обратиться к json_repair, чтобы восстановить строку JSON, возвращаемую LLM.
Вы можете заменить функции внедрения по умолчанию любым экземпляром _utils.EmbedddingFunc
.
Например, по умолчанию используется API встраивания OpenAI:
@ wrap_embedding_func_with_attrs ( embedding_dim = 1536 , max_token_size = 8192 )
async def openai_embedding ( texts : list [ str ]) -> np . ndarray :
openai_async_client = AsyncOpenAI ()
response = await openai_async_client . embeddings . create (
model = "text-embedding-3-small" , input = texts , encoding_format = "float"
)
return np . array ([ dp . embedding for dp in response . data ])
Замените функцию внедрения по умолчанию на:
GraphRAG ( embedding_func = your_embed_func , embedding_batch_num = ..., embedding_func_max_async = ...)
Вы можете обратиться к примеру, в котором используется sentence-transformer
для локального вычисления вложений.
Вы можете заменить все компоненты, связанные с хранилищем, на свою собственную реализацию, nano-graphrag
в основном использует три типа хранилища:
base.BaseKVStorage
для хранения пар данных ключ-json
GraphRAG(.., key_string_value_json_storage_cls=YOURS,...)
base.BaseVectorStorage
для индексирования вложений
nano-vectordb
в качестве бэкэнда.hnswlib
, посмотрите этот пример.milvus-lite
реализуется в качестве серверной части (недоступно в Windows).GraphRAG(.., vector_db_storage_cls=YOURS,...)
base.BaseGraphStorage
для хранения графа знаний
networkx
в качестве бэкэнда.Neo4jStorage
для графа, ознакомьтесь с этим руководством.GraphRAG(.., graph_storage_cls=YOURS,...)
Вы можете обратиться к nano_graphrag.base
, чтобы увидеть подробные интерфейсы для каждого компонента.
Проверьте вопросы и ответы.
См. ROADMAP.md
nano-graphrag
открыт для любого вклада. Прочтите это, прежде чем внести свой вклад.
nano-graphrag
Добро пожаловать в запросы на вытягивание, если ваш проект использует
nano-graphrag
, это поможет другим доверять этому репозиторию❤️
nano-graphrag
не реализовал функцию covariates
GraphRAG
nano-graphrag
реализует глобальный поиск, отличный от оригинала. В оригинале используется стиль, подобный Map-Reduce, чтобы заполнить все сообщества контекстом, в то время как nano-graphrag
использует только топ-K важных и центральных сообществ (для управления используйте QueryParam.global_max_consider_community
, по умолчанию — 512 сообществ).