A Voyage AI se une ao MongoDB para impulsionar aplicativos de AI mais precisos e confiáveis no Atlas.

Explore o novo chatbot do Developer Center! O MongoDB AI chatbot pode ser acessado na parte superior da sua navegação para responder a todas as suas perguntas sobre o MongoDB .

Desenvolvedor do MongoDB
Centro de desenvolvedores do MongoDB
chevron-right
Produtos
chevron-right
Atlas
chevron-right

Pesquisa híbrida em profundidade para GraphRAG

Shounak Acharya, Sneha Das Gupta14 min read • Published Feb 01, 2025 • Updated Feb 02, 2025
IAAtlasPython
Ícone do FacebookÍcone do Twitterícone do linkedin
Avalie esse Artigo
star-empty
star-empty
star-empty
star-empty
star-empty
No campo da geração aumentada de recuperação (RAG), cinco abordagens principais se destacam: pré-filtragem, pesquisa vetorial, pesquisa de texto completo, pesquisa híbrida e gráfico. Este artigo demonstra um caso de uso prático comparando esses métodos aplicados a um único conjunto de dados focado no suporte social para o Envelhecimento da população. Ao analisar suas respostas à mesma query do usuário em uma plataforma unificada, pretendemos avaliar e mostrar a precisão relativa de cada abordagem.

RAG

A arquitetura RAG é eficaz, permitindo que os aplicativos de IA aproveitem o poder dos dados não estruturados e, ao mesmo tempo, promovam a acessibilidade do conhecimento e a relevância de saída de modelos de linguagem de grande formato (LLM). É dada atenção especial aos documentos PDF — o formato de arquivo predominante em todos os setores — que permanecem notoriamente difíceis de pesquisar com eficiência.
Os sistemas RAG são eficazes para várias tarefas de uso intensivo de conhecimento, incluindo tarefas de geração de texto, como responder a perguntas de forma abrangente e informativa, e geração de conteúdo, como poemas, roteiros, peças músicas, e-mails, cartas etc.
Ao construir aplicativos em escala completa para uma base de conhecimento, encontramos várias limitações, incluindo:
  • Dificuldade em encontrar correspondências próximas: os sistemas RAG podem ter problemas em distinguir entre tópicos relacionados em grandes conjuntos de dados, levando a correspondências menos precisas.
  • Correspondência com base em critérios errados: os sistemas RAG podem corresponder queries com base em amplas similaridades em vez de detalhes específicos.
  • Necessidade de taxa de transferência eficiente: à medida que mais usuários embarcam, o RAG precisará ser capaz de lidar com eficiência com o aumento da taxa de transferência.
O RAG não tem uma compreensão abrangente dos dados, dependendo principalmente de pontuações de similaridade entre as incorporações de vetores de query e os documentos semanticamente semelhantes recuperados. Neste tutorial, estamos usando o GraphRAG com o MongoDB, que oferece uma compreensão geral dos dados mais robusta ao capturar informações associadas e entidades relacionadas.

GraphRAG

GraphRAG é um conceito que pode aprimorar a fonte de informações recuperadas de um simples RAG baseado em pesquisa semântica, também capturando relacionamentos entre as entidades nomeadas que formam a ontologia subjacente ao texto real. Um dos métodos para construir esses tipos de ontologias é a biblioteca Graph Transformer da LangChain, que pode receber documentos de entrada e construir uma ontologia que consiste em termos-chave (entidades nomeadas) e seu relacionamento.
Para fins deste tutorial, criamos uma onologia de amostra obtida transformando vários documentos PDF sobre o estresse de periódicos médicas. Isso pode ser feito combinando todas as páginas dos PDFs, colocando-as em um único diretório e, em seguida, passando-o para o transformador de gráficos.
Uma pesquisa híbrida é uma agregação e reclassificação de resultados de pesquisa de diferentes métodos de recuperação de informações, como pesquisa de texto completo e semântica, para os mesmos critérios de query. Enquanto o texto completo encontra efetivamente correspondências exatas para termos de query, a pesquisa semântica oferece o benefício adicional de identificar documentos semanticamente semelhantes, mesmo que os documentos não contenham o termo exato de query . Isso garante que as correspondências sinônimas e contextualmente semelhantes também sejam incluídas nos resultados combinados de ambos os métodos de pesquisa.

Traversal do grafo em profundidade

Profundidade da primeira travessia
A travessia de gráficos em profundidade explora o mais fundo possível em uma ramificação antes de retroceder para explorar outras ramificações. Ele começa em um nó, move para um nó adjacente e continua mais fundo até chegar a um sem saída, então volta para explorar outros nós não visitados.
Neste tutorial, primeiro armazenamos o gráfico de conhecimento obtido do módulo Graph Transformer da LangChain no MongoDB. Em seguida, aplicamos o operador do MongoDB $graphlookup para obter o relacionamento hierárquico entre essas entidades. Como esse relacionamento fornece apenas as conexões dos nós e a distância entre os nós, sem os nomes reais das conexões, transformamos a saída em uma estrutura de dados de grafo e um mapa de hash armazenando os nomes das relacionamento entre as entidades.
Em seguida, percorremos o grafo em profundidade para criar uma frase a partir da hierarquia de relacionamentos que menciona os nomes de relacionamento transitivos entre essas entidades. Essas frases são então combinadas com blocos de texto relevantes obtidos como parte da pesquisa vetorial a partir de um vetor de pergunta de entrada em documentos MongoDB a partir de coleções que armazenam blocos de texto reais e suas incorporações e são finalmente fornecidos aos LLMs como um contexto em um prompt. Isso garante que o LLM responda somente a partir do contexto de conhecimento do nosso domínio de armazenamento, dando assim respostas mais precisas, bem como menos atordoamentos.
Todo o código mostrado neste artigo pode ser acessado aqui.

Trecho de código

O seguinte trecho mostra o mesmo:
1# Instantiate an LLMGraphTransformer object
2llm_transformer = LLMGraphTransformer(llm=llm)
3
4# Create a ChatPromptTemplate object
5template = ChatPromptTemplate.from_messages(
6 [
7 (
8 "system",
9 """You are a scientist analyzing scientific journal articles on the effects of various factors, including stress. Your task is to identify and document all entity relationships within these articles, focusing on relationships involving stress as well as those involving other entities. Capture both direct and indirect relationships, exploring connections up to at least five levels deep. Ensure that you only document relationships explicitly mentioned in the articles. Be aware that relationships can be bidirectional. Exclude any nodes related to the author, publisher, and references."""
10 )
11 ]
12)
13
14# Init the graph transformer, specifying the nodes, relationships and prompt to guide it
15graph_transformer = LLMGraphTransformer(
16 llm=llm,
17 prompt=template
18)
19
20# Initialize a all_documents list
21all_documents = []
22
23# Process each page individually
24for page in all_pages:
25 document = Document(page_content=page_string)
26 all_documents.append(document)
27
28# Convert all accumulated documents to graph documents at once
29graph_docs = graph_transformer.convert_to_graph_documents(all_documents)
Isso produz nós e relacionamentos no seguinte formato:
1nodes = {
2"node1":Node(id='Stress', type='Concept'),
3"node2":Node(id='Heart Disease', type='Disease'),
4"node3":Node(id='Burnout', type='Condition'),
5"node4":Node(id='Mental Health', type='Aspect'),
6"node5":Node(id='Physical Activity', type='Behavior'),
7"node6":Node(id='Job Satisfaction', type='Emotional state'),
8"node7":Node(id='Obesity', type='Condition'),
9"node8":Node(id='Aging', type='Condition'),
10#... Redacted for conciseness
11}
12
13links = {
14"rel1":Relationship(source=Node(id='Immune System', type='System'), target=Node(id='Inflammation', type='Condition'), type='REDUCES'),
15"rel2":Relationship(source=Node(id='Inflammation', type='Condition'), target=Node(id='Heart Disease', type='Disease'), type='CAUSES'),
16"rel3":Relationship(source=Node(id='Stress', type='Concept'), target=Node(id='Sleep Quality', type='Health aspect'), type='DECREASES'),
17"rel4":Relationship(source=Node(id='Stress', type='Condition'), target=Node(id='Diet', type='Lifestyle factor'), type='WORSENS')
18#... Redacted for conciseness
19}
Depois de obter os nós e os relacionamentos do Transformador LLMGraph, é hora de transformar nosso conjunto de dados em um formato otimizado para o GraphRAG. Isso envolve as seguintes partes:
  1. Criação de uma estrutura de dados no banco de dados para armazenar os nós e relacionamentos que obtivemos na etapa acima para fazer um grafo transversal nas entidades usando a $graphlookup função do MongoDB.
  2. A vetorização e o armazenamento dos documentos PDF originais como blocos e a incorporação deles para permitir a pesquisa semântica de RAG de uso geral.
  3. Finalmente, vinculando os nós mais relevantes aos blocos de PDF mais relevantes para que, uma vez que possamos obter os blocos mais relevantes por meio de pesquisa vetorial para uma query do usuário, também possamos gerar os relacionamentos dos nós mais relevantes desses $graphlookup blocos por meio de e, em seguida, alimente os chunks, bem como essas relações, como um contexto para o LLM para gerar não apenas uma resposta semanticamente correta, mas também a procedência dessas informações por meio da vinculação das entidades de conhecimento.
Vejamos agora como implementar estas etapas uma a uma.

Etapa 1: Criando uma estrutura de dados para nós e relacionamentos para fazer transversal do gráfico

Embora haja várias maneiras de fazer isso, a maneira mais genérica é salvar todos os nós na mesma coleção e aproveitar o polimorfismo. A pesquisa de gráficos do MongoDB aproveita esse conceito percorrendo documentos em uma coleção relacionados por algum campo comum, conforme mostrado no diagrama abaixo:
Conflito de chave: o mesmo campo "Nome" com significados diferentes para máquinas e usuários.
Para realizar a pesquisa de gráficos, diferenciamos dois tipos de documento dentro da mesma coleção com um campo de tipo, mas ainda assim temos um campo comum em todos esses tipos de documento , que é percorrido sequencialmente. Por exemplo, no diagrama acima, embora a mesma coleção tenha dois tipos de documento diferentes, eles são diferenciados por seus campos de nome.
Além disso, se ambos os documentos tiverem um terceiro campo chamado requires_to, então uma pessoa (Storz, neste caso) pode ser relacionada a uma fábrica que tenha requires_to = X347BC-Large e a fábrica pode ser relacionada a um nome de departamento , digamos logstica, por ter requires_to = logstica. Isso é o que é utilizado pelo $graphlookup operador para percorrer os nós na coleção andando pelo campo requires_to e alcançando o próximo nó cujo valor está em requires_to e, a partir daqui, alcançando o terceiro nó cujo valor é igual a requires_to do nó atual. Então, neste exemplo, Storz -belongs_to->X347BC-Large -Belongs_to-> Logística. Isso é feito recursivamente até que não haja mais documentos encontrados ou cheguemos a uma configuração chamada de profundidade máxima.
No entanto, se examinarmos de perto, o nome exato do relacionamento não é capturado pelo $graphlookup operador. Então, embora saibamos que todas estão relacionadas por meio do campo concern_to , não podemos dizer exatamente o nome do relacionamento — por exemplo, a Storz trabalha para a X347BC-Large e a X347BC-Large faz parte do departamento de Logística .
Agora, retornando ao nosso exemplo em diários de saúde, não só precisamos armazenar os nós e capturar relacionamentos entre eles usando um campo nomeado comum, mas também precisamos retornar os nomes de relacionamento na $graphlookup saída. Portanto, transformamos os nós e os relacionamentos para capturar essas informações, de modo que os documentos do MongoDB se pareçam com os abaixo. Nós o armazenamos em uma coleção chamada nodes_relationship:
Relacionamentos entre nós: 'doença coronária' e 'pressão alta'; 'Burnout' para a saúde física e a produtividade.
O que vemos aqui é que todos os documentos têm um ID, que é a concatenação do ID e do tipo dos nós que obtemos da saída do LangGraph. Além disso, cada nó tem um campo de relacionamentos que captura o ID de todos os outros nós aos quais ele está diretamente conectado, que é usado pelo $graphlookup operador como o campo connect_from e _id como o campo connect_to para fazer as pesquisas recursivas. Além disso, temos mais um campotargets chamadoHeart Disease: Disease Blood Pressure: ConditionBurnout: Condition" " que captura os nomes de relacionamento para cada um dos relacionamentos capturados no campo de relacionamentos. Por exemplo " " está relacionado a " " de modo que o primeiro aumenta o último. Da mesma forma, " " está relacionado a "Mental Health: Condition " ao deteriorá-lo/afetá-lo. Temos vários nomes de relacionamento porque isso foi capturado pelo LangGraph e é algo que pode surgir em cenários de gráficos. Observe que precisamos salvá-lo para aumentar a $graphlookup saída com nomes de relacionamento , que podem ser enviados para um LLM para dar mais contexto a um grafo de conhecimento. Se observarmos de perto, até mesmo os nomes de relacionamento entre dois nós únicos são semanticamente equivalentes, como afeta/deteriora. Ao fornecer contexto ao LLM com esses nomes de relacionamento , você pode usar aleatoriamente qualquer um dos nomes da lista de nomes de relacionamento entre os nós.

Etapa 2: vetorizar e armazenar os documentos PDF originais como blocos e incorporá-los

Para vetorizar e armazenar documentos PDF como blocos no MongoDB, siga estas etapas:
  1. Carregar e extrair texto de PDF
  2. dividir texto em blocos
  3. Gerar incorporações
  4. Armazene chunks e incorporações na coleção do MongoDB chamada Knowledge_graph
Pipeline de processamento de dados
1pdf_files = ['Pdf1','pdf2',......'pdfn']
2for pdf_file in pdf_files:
3 text = load_pdf(pdf_file)
4 text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=20)
5 docs = text_splitter.split_documents(text)
6 MongoDBAtlasVectorSearch.from_documents(docs, OpenAIEmbeddings(), db_config)
Amostra de documento em partes

Etapa 3: vinculando os nós mais relevantes aos blocos de PDF mais relevantes

Para esta etapa, pegamos cada nó obtido na etapa 1 e convertemos o _id de forma que "Stress: Concept" se pareça com "Stress as a Concept." Esselmente, substituímos o ":" pela string "as a " para fazer uma pesquisa de texto completo desses IDs de nó transformados com o texto dos chunks PDF.
O diagrama a seguir representa o algoritmo:
Mapeamento de documento para gráfico: vinculando blocos de texto a nós de gráfico por meio de pesquisa de texto completo e relacionamentos
Então, para cada chunk, encontramos os node_ids convertidos mais relevantes (node_ids com “:” convertidos na string “as a") e, em seguida, adicionamos esses node_ids originais (sem substituir ":" por "as a) junto com sua pontuação de pesquisa em um campo de array de tags nos documentos do Knowledge_graph, conforme mostrado acima.

Etapa 4: query final

Antes de entrarmos nas especificidades desta etapa, vamos entender como $graphlookup opera. A sintaxe geral de $graphlookup é a seguinte:
1[
2 {
3 '$match': {
4 '_id': node_name
5 }
6 }, {
7 '$graphLookup': {
8 'from': 'nodes_relationships',
9 'startWith': '$_id',
10 'connectFromField': 'relationships',
11 'connectToField': '_id',
12 'as': 'relates_to',
13 'maxDepth': max_depth,
14 'depthField': 'distance',
15 'restrictSearchWithMatch': {}
16 }
17 }
18 ]
O que isso faz é ir para a coleção nodes_relationships e descobrir o documento cujo _id é igual ao node_name. Este node_name pode ser obtido de várias maneiras. Quando chegar a esse documento, ele pegará cada elemento da array de relacionamentos e tentará encontrar o documento cujo _id corresponda ao valor desse elemento. Isso continuará recursivamente até que nenhum documento permaneça ou tenhamos atingido o valor de max_depth. O diagrama a seguir explica o processo:
query do Graph: rastreando conexões do 'Stress' dentro da profundidade 2.
Aqui, começando com o node_name = “”Stress e percorremos recursivamente a array de relacionamentos entre documentos, até um nível máximo 2 de. O leitor é fortemente encorajado a ler a documentação do MongoDB em $graphlookup para entender melhor este conceito. No entanto, uma coisa que podemos notar aqui é que, embora graphlookup possa percorrer documentos com base em um valor de campo , ele realmente não retorna os nomes reais das relacionamento enquanto atravessa o caminho da árvore. É o que resolvemos modificando a saída do graphlookup em uma estrutura de dados de grafo e fazendo uma pesquisa em profundidade nessa estrutura, como verá mais adiante.
Nesta etapa, combinamos pesquisa vetorial e graphlookup para fornecer um contexto maior ao LLM para dar uma resposta que utiliza o conhecimento uber em todos os documentos que criamos nas etapas anteriores e, em seguida, criamos o gráfico de conhecimento.
O primeiro passo é pegar a pergunta do usuário, vetorizá-la e fazer uma pesquisa vetorial na coleção Knowledge_graph com todos os blocos PDF. A pesquisa vetorial opera no campo de incorporação , que contém os vetores dos blocos obtidos na etapa 2.
1question = "How is Social support Related to Aging?"
2
3k = 3
4multiplier = 10
5
6embeddings = embedding_create_backoff(
7 input=question,
8 model="text-embedding-ada-002"
9 )
10
11query_vector = embeddings.data[0].embedding
12
13agg_pipeline = [
14 {
15 "$vectorSearch": {
16 "index":'vector_index',
17 "path": "embedding",
18 "queryVector": query_vector,
19 "limit": k,
20 "numCandidates": k * multiplier,
21 },
22 },
23 {
24 "$project": {"embedding": 0}
25 }
26]
Isso retornará uma array dos três principais documentos cujos vetores de chunk se assemelham à nossa pergunta, conforme mostrado abaixo:
1[{'_id': ObjectId('66e2d52d00e19b410567a4e8'),
2 'chunks': 'numerous definitions of social support have been examined (e.g., size, \nquality, and intensity of the support network, type of relation, frequency of\nReproduced with permission of the copyright owner. Further reproduction prohibited without permission.',
3 'source': './PDF_KG/Stress and Headache.pdf',
4 'pdf': {'version': '1.10.100',
5 'info': {'PDFFormatVersion': '1.7',
6 'IsAcroFormPresent': False,
7 'IsXFAPresent': False,
8 'Title': 'Stress and Headache.',
9 'Author': 'Thomas Hamilton Mosley Jr',
10 'Creator': 'Appligent AppendPDF Pro 6.3',
11 'Producer': 'Prince 14.2 (www.princexml.com)',
12 'CreationDate': "D:20230906103014-07'00'",
13 'ModDate': "D:20230906103014-07'00'"},
14 'metadata': {'_metadata': {'dc:format': 'application/pdf',
15 'dc:creator': 'Thomas Hamilton Mosley Jr',
16 'dc:title': 'Stress and Headache.',
17 'pdf:producer': 'Prince 14.2 (www.princexml.com)',
18 'pdf:appligent': 'AppendPDF Pro 6.3 Linux 64 bit Aug 30 2019 Library 15.0.4',
19 'xmp:creatortool': 'Appligent AppendPDF Pro 6.3',
20 'xmp:modifydate': '2023-09-06T10:30:14-07:00',
21 'xmp:createdate': '2023-09-06T10:30:14-07:00',
22 'xmp:metadatadate': '2023-09-06T10:30:14-07:00',
23 'pdfuaid:part': '1',
24 'xmpmm:documentid': 'uuid:15f91e58-b7e4-11b2-0a00-c04a83010000',
25 'xmpmm:instanceid': 'uuid:15f91e59-b7e4-11b2-0a00-d0b25ff8ff7f'}},
26 'totalPages': 201},
27 'loc': {'pageNumber': 57, 'lines': {'from': 24, 'to': 26}},
28 'tags': [{'tagName': 'Social Support:Social factor',
29 'score': 4.098155975341797},
30 {'tagName': 'Social Support:Behavior', 'score': 2.827536106109619},
31 {'tagName': 'Social Support:Factor', 'score': 2.827536106109619},
32 {'tagName': 'Sleep Quality:Health aspect', 'score': 2.2594480514526367},
33 {'tagName': 'Social Relationships:Condition', 'score': 1.2706201076507568},
34 {'tagName': 'Social Support:Aspect', 'score': 2.827536106109619},
35 {'tagName': 'Sleep Quality:Condition', 'score': 2.2594480514526367},
36 {'tagName': 'Social Support:Activity', 'score': 2.827536106109619},
37 {'tagName': 'Sleep Quality:Aspect', 'score': 2.2594480514526367},
38 {'tagName': 'Social Support:Condition', 'score': 2.827536106109619}]},
39...
40]
Agora que temos todos os documentos principais correspondentes, pegamos o documento com a maior pontuação de pesquisa vetorial e a tag com a maior pontuação dentro desse documento. Então, por exemplo, no resultado acima, teriamos selecionado a tag chamada "Social Support Factor " pois a pontuação 4.09 é, maior do que qualquer outra tag para esse chunk. Isso garante que tenhamos o nó mais relevante com o qual esse chunk está relacionado.
Pegamos este nó e depois fazem um $graphlookup na tabela nodes_relationship. Isso gera uma saída como abaixo:
1[{'_id': 'Social Support:Social factor',
2 'relates_to': [ {'_id': 'Inflammation:Biological process',
3 'distance': 2,
4 'relationships': ['Heart Disease:Disease'],
5 'targets': {'Heart Disease:Disease': ['CONTRIBUTES_TO']},
6 'type': 'Biological process'}],
7 'relationships': ['Stress:Concept',
8 'Mental Health:Condition',
9 'Stress:Condition',
10 'Mental Health:Health aspect'],
11 'targets': {'Mental Health:Condition': ['IMPROVES'],
12 'Mental Health:Health aspect': ['IMPROVES'],
13 'Stress:Concept': ['REDUCES'],
14 'Stress:Condition': ['DECREASES', 'REDUCES']},
15 'type': 'Social factor'},
16{'_id': 'Exercise:Activity',
17 'distance': 2,
18 'relationships': ['Physical Health:Condition',
19 'Stress:Concept',
20 'Stress:Condition'],
21 'targets': {'Physical Health:Condition': ['IMPROVES'],
22 'Stress:Concept': ['REDUCES'],
23 'Stress:Condition': ['DECREASES', 'REDUCES']},
24 'type': 'Activity'},...]
25]
Se notarmos a saída acima do graphlookup, vemos que obtemos vários nós que estão a uma distância de 2 doSocial Support Factor nó " ". No entanto, não poderíamos descobrir a partir dessa saída o nó intermediário que conecta "Social Support Factor " com, digamos, " ". NoInflammation process. entanto, otargets campo " " em " "Inflammation process diz que está relacionado a " "Heart Disease no fato de que "Inflammation process " contribui para " "Heart Disease. Então, embora o graphlookup nos forneça o caminho, ele não nos fornece os nomes de relacionamento entre os nós de caminho no caminho. É aqui que aproveitamos otargets campo" ". Transformamos a saída acima e criamos duas estruturas de dados:
O gráfico: essa estrutura de dados contém as relações entre quaisquer dois nós consecutivos, conforme mostrado no trecho abaixo:
1{'Inflammation:Condition': ['Heart Disease:Disease',
2 'Diabetes:Disease'],
3 'Job Satisfaction:Condition': ['Burnout:Condition',
4 'Productivity:Condition',
5 'Stress:Condition'],
6 'Social Support:Condition': ['Mental Health:Condition',
7 'Stress:Condition'],
8 'Diet:Behavior': ['Stress:Concept',
9 'Inflammation:Condition',
10 'Stress:Condition'],...
11}
O que isto contém é, por exemplo, "Inflammation " está conectado a " "Heart Disease e " "Diabetes. Da mesma forma, "Social Support " está conectado a "Mental Health " e "Stress. "
O Hashmap: O HashMap contém os nomes de relacionamento entre os nós, conforme mostrado abaixo:
1{('Inflammation:Condition', 'Heart Disease:Disease'): {'CAUSES',
2 'CONTRIBUTES',
3 'CONTRIBUTES_TO',
4 'INCREASES_RISK'},
5 ('Inflammation:Condition',
6 'Diabetes:Disease'): {'CONTRIBUTES_TO'},
7 ('Job Satisfaction:Condition', 'Burnout:Condition'): {'DECREASES',
8 'REDUCES'},
9 ('Job Satisfaction:Condition',
10 'Productivity:Condition'): {'INCREASES'},
11 ('Job Satisfaction:Condition', 'Stress:Condition'): {'INFLUENCES',
12 'REDUCES'},
13 ('Social Support:Condition',
14 'Mental Health:Condition'): {'IMPROVES'},
15 ('Social Support:Condition', 'Stress:Condition'): {'DECREASES',
16 'REDUCES'},
17 ('Diet:Behavior', 'Stress:Concept'): {'INFLUENCES'},
18 ('Diet:Behavior', 'Inflammation:Condition'): {'REDUCES'},
19 ('Diet:Behavior', 'Stress:Condition'): {'INFLUENCES'},...
20}
Então,Inflammation“” Causa/Contributes/Contributes_To/Increases_Risk deHeart Disease.“”
Agora, realizamos uma travessia em profundidade no grafo e construímos uma string de relacionamento . Essa string de relacionamento continua sendo anexada sempre que visitamos qualquer nó em que o nome do nó pai e o nome do nó filho sejam anexados à string com os nomes do relacionamento escritos entre colchetes com barras entre eles. Então, no caso acima, começar com " "Social Support factor e percorrer o gráfico em um formato de profundidade produz a seguinte string:
“Social Support (REDUCES / DECREASES) Stress, Stress (WORSENS) Diet, Diet (IMPROVES) Physical Health, Work Environment (AFFECTS / INFLUENCES) Job Satisfaction, Job Satisfaction (INCREASES) Productivity, Productivity (INCREASES) Employee Turnover, Stress (WORSENS) Diet, ”
Agora, usando o bloco do documento de pontuação mais alta com base na pesquisa vetorial no vetor de perguntas e na cadeia de relacionamento que obtemos acima, enviamos o prompt para o LLM. O prompt que usamos é parecido com o seguinte:
1chunk = tag_docs[top_id_idx]['chunks']
2chunk = chunk + f"\n Entity Relationships: {path}"
3prompt = f'''
4You are a doctor who specialises in mental health and psychiatry. Please use the below context to answer {question}
5Please note that the below text has relationship between various entities written after the text Entity Relationships:
6The relationships are written in comma separated sentences with the relationship names between the entities written in brackets. There can be multiple
7entity names which are given by slashes. You can choose any of the names to answer the question. Please only answer the question based upon the relationships
8provided and context given and not from your own previous knowledge. Try and link the relationships with the context, while giving the answer.
9'''
10response = chat_completion_backoff(
11 model="gpt-3.5-turbo",
12 messages=[
13 {"role": "system", "content": prompt},
14 {"role": "user", "content": chunk},
15 ]
16 )
Isso dá o uber contexto ao LLM que obtivemos mantendo o grafo de conhecimento, bem como o chunk, que mais se relaciona com a questão em questão. Isso garante que o LLM responda com o conhecimento exato do seu domínio e não tenha visões. A saída parece abaixo:
“”Social support is related to aging primarily through its effects on stress. According to the given relationships, Social Support REDUCES Stress. Since stress can negatively impact various aspects of health, including diet, which in turn IMPROVES Physical Health, the presence of social support can thus contribute positively to overall health and well-being as one ages. This reduction in stress through social support can help mitigate some of the health challenges associated with aging.
Como podemos ver, o LLM responde com o contexto de conhecimento fornecido a ele e não com base em seu próprio conhecimento, melhorando as imagens e as grades de proteção.
A travessia em profundidade também pode ser usada para gerar nós e relacionamentos que são exigidos pelo3 d.js para exibir os relacionamentos, como fizemos no tutorial Visualização RAG da base de conhecimento do MongoDB . A figura a seguir mostra uma das ramificações transversais em profundidade que foi gerada e exibida em3 d.js.
Relacionamentos de entidade no GraphRAG: o suporte social reduz o estresse, o que piora a alimentação, mas melhora a saúde física.

Conclusão

Conforme mostrado neste tutorial, o RAG ingênuo ou padrão tem muitas limitações ao fornecer respostas contextualmente corretas à pergunta de um usuário. A razão mais importante para isso é que fornecemos apenas uma quantidade limitada de informações - o texto correspondente ao bloco mais relevante, ao LLM - e confiamos nos recursos de argumento do LLM para fornecer a melhor resposta com base no contexto limitado. É aqui que mecanismos como fornecer as relações uber entre entidades capturadas na base de conhecimento e compartilhar seus relacionamentos com o LLM durante o aumento prompt melhoram a precisão das respostas chamadas RAGs do gráfico.
O Graph RAG forneceu informações valiosas sobre a integração de estruturas de gráficos com geração aumentada de recuperação, enfatizando sua eficácia no gerenciamento de relacionamentos de dados complexos. A demonstração dos recursos do MongoDB em representar e consultar dados de gráficos, juntamente com a implementação de algoritmos de gráficos, aprimorará os processos de recuperação de dados. Este tutorial mostra uma dessas abordagens, e isso pode ser melhorado ainda mais com a modificação da mesma abordagem. Por fim, este tutorial tem como objetivo capacitar os setores para aproveitar o RAG do grafo em seus próprios projetos, impulsionando a tecnologia e melhorando a eficiência dos aplicativos orientados por dados.
Existem outros mecanismos também. Por exemplo, o chunking recursivo captura relacionamentos pai-filho entre chunks menores e seus chunks pai e fornece-os como contextos adicionados também ajuda a melhorar a precisão. Abordaremos melhorias e estratégias de chunking em nossos próximos tutoriais, portanto, fique atento.
Se você tiver dúvidas ou comentários, Junte-se a nós na Comunidade de desenvolvedores MongoDB.
Interessado em um papel na equipe de pré-vendas de parceiros da MongoDB? Temos várias funções abertas em nossas equipes em todo o mundo e gostariamos que você transformasse sua carreia conosco!
Principais comentários nos fóruns
Ainda não há comentários sobre este artigo.
Iniciar a conversa

Ícone do FacebookÍcone do Twitterícone do linkedin
Avalie esse Artigo
star-empty
star-empty
star-empty
star-empty
star-empty
Relacionado
Tutorial

Como criar um sistema RAG com LlamaIndex, OpenAI e MongoDB Vector Database


Feb 16, 2024 | 10 min read
exemplo de código

Apresentando o planejador de passeios com a Vector Search do MongoDB


Sep 24, 2024 | 5 min read
Tutorial

Como desenvolver um aplicativo web com funções sem servidor da Netlify e MongoDB


Jan 13, 2025 | 6 min read
Artigo

Descubra a estrutura semântica latente com o cluster vetorial


Oct 11, 2024 | 10 min read
Sumário