Introdução geral
O KAG (Knowledge Augmented Generation) é uma estrutura de raciocínio e recuperação orientada por forma lógica baseada no mecanismo OpenSPG e em modelos de linguagem ampla (LLMs). A estrutura foi projetada especificamente para criar soluções de raciocínio lógico e questionamento de fatos para bases de conhecimento de domínio profissional, superando de forma eficaz as deficiências do modelo tradicional de computação de similaridade vetorial RAG (Retrieval Augmented Generation). O KAG aprimora os LLMs e os gráficos de conhecimento por meio dos pontos fortes complementares do Knowledge Graph e do Vector Retrieval de quatro maneiras em ambas as direções: representações de conhecimento amigáveis aos LLMs, interindexação entre gráficos de conhecimento e fragmentos de texto bruto, solucionador de raciocínio híbrido e solucionador de raciocínio híbrido. A estrutura é particularmente adequada para a indexação de conhecimento LLM, para os solucionadores de inferência híbrida e para os mecanismos de avaliação de plausibilidade. A estrutura é particularmente adequada para lidar com problemas complexos de lógica de conhecimento, como computação numérica, relações temporais e regras de especialistas, fornecendo recursos de resposta a perguntas mais precisos e confiáveis para aplicativos de domínio profissional.
Lista de funções
- Capacidade de suportar formas lógicas complexas de raciocínio
- Fornecer um mecanismo de pesquisa híbrido de gráfico de conhecimento e recuperação de vetores
- Implementação da conversão de representação de conhecimento compatível com LLM
- Oferece suporte à indexação bidirecional de estruturas de conhecimento e blocos de texto
- Integração de raciocínio LLM, raciocínio intelectual e raciocínio lógico matemático
- Fornecer mecanismos para avaliação e validação da credibilidade
- Oferece suporte a Q&A de vários saltos e processamento de consultas complexas
- Fornecer soluções personalizadas para bases de conhecimento de domínios especializados
Usando a Ajuda
1. preparação ambiental
A primeira coisa que você precisa fazer é garantir que seu sistema atenda aos seguintes requisitos:
- Python 3.8 ou superior
- Ambiente do mecanismo OpenSPG
- Interfaces de API suportadas para modelos de linguagem grandes
2. etapas de instalação
- Clonagem do Project Warehouse:
git clone https://github.com/OpenSPG/KAG.git
cd KAG
- Instale os pacotes de dependência:
pip install -r requirements.txt
3. processo de uso da estrutura
3.1 Preparação da base de conhecimento
- Importação de dados de conhecimento de domínio especializado
- Configuração do modelo de gráfico de conhecimento
- Estabelecimento de um sistema de indexação de texto
3.2 Processamento de consultas
- Entrada de perguntas: o sistema recebe perguntas em linguagem natural do usuário
- Conversão de formas lógicas: conversão de problemas em expressões lógicas padronizadas
- Recuperação mista:
- Realizar pesquisas no gráfico de conhecimento
- Realizar uma pesquisa de similaridade de vetores
- Integração de resultados de pesquisa
3.3 Processo de raciocínio
- Raciocínio lógico: Raciocínio em várias etapas com solucionadores de raciocínio misto
- Fusão de conhecimento: combinação de raciocínio LLM e resultados de raciocínio de gráficos de conhecimento
- Geração de respostas: formação da resposta final
3.4 Garantia de credibilidade
- Verificação de respostas
- Raciocínio Traçado de caminhos
- avaliação da confiança (matemática)
4. uso de funções avançadas
4.1 Representação personalizada do conhecimento
O formato de representação do conhecimento pode ser personalizado de acordo com as necessidades de sua área de especialização, garantindo a compatibilidade com o LLM:
Exemplo de código #
knowledge_config = {
"domínio": "seu_domínio",
"schema": sua_definição_de_schema,
"representation" (representação): your_custom_representation (sua representação personalizada)
}
4.2 Configuração da regra de raciocínio
Regras de inferência especializadas podem ser configuradas para lidar com a lógica específica do domínio:
# Exemplo de código
reasoning_rules = {
"numerical": numerical_processing_rules,
"temporal": temporal_reasoning_rules,
"domain_specific": your_domain_rules
}
5. melhores práticas
- Garantir a qualidade e a integridade dos dados da base de conhecimento
- Otimização das estratégias de pesquisa para aumentar a eficiência
- Atualização e manutenção regulares da base de conhecimento
- Monitorar o desempenho e a precisão do sistema
- Colete feedback do usuário para aprimoramento contínuo
6. resolução de problemas comuns
- Se você encontrar problemas de eficiência de recuperação, poderá ajustar os parâmetros do índice adequadamente
- Para consultas complexas, uma estratégia de raciocínio em etapas pode ser usada
- Verificar a representação do conhecimento e a configuração da regra quando os resultados da inferência forem imprecisos
Apresentação do projeto KAG
1. introdução
Há alguns dias, a Ant lançou oficialmente uma estrutura de serviço de conhecimento de domínio profissional, chamada Knowledge Augmented Generation (KAG: Knowledge Augmented Generation), que tem como objetivo aproveitar ao máximo as vantagens do Knowledge Graph e do Vector Retrieval para resolver o problema da RAG Alguns desafios com a pilha de tecnologia.
A partir do aquecimento dessa estrutura, fiquei mais interessado em algumas das principais funções do KAG, especialmente o raciocínio simbólico lógico e o alinhamento de conhecimento, no sistema RAG convencional existente, esses dois pontos de discussão não parecem ser muito grandes, aproveite esse código aberto e apresse-se para estudar uma onda.
- Endereço da tese da KAG: https://arxiv.org/pdf/2409.13731
- Endereço do projeto KAG: https://github.com/OpenSPG/KAG
2. visão geral da estrutura
Antes de ler o código, vamos dar uma breve olhada nos objetivos e no posicionamento da estrutura.
2.1 O que e por quê?
De fato, quando vejo a estrutura do KAG, acredito que a primeira pergunta que vem à mente de muitas pessoas é por que ela não se chama RAG, mas KAG. De acordo com artigos e documentos relacionados, a estrutura do KAG foi projetada principalmente para resolver alguns dos desafios atuais enfrentados por modelos grandes em serviços de conhecimento de domínio profissional:
- O LLM não tem a capacidade de pensar criticamente e não possui habilidades de raciocínio
- Erros de fato, lógica, precisão, incapacidade de usar estruturas de conhecimento de domínio predefinidas para restringir o comportamento do modelo
- Os RAGs genéricos também têm dificuldades para lidar com as ilusões do LLM, especialmente as informações enganosas ocultas
- Desafios e exigências dos serviços especializados, falta de um processo decisório rigoroso e controlado
Portanto, a equipe do Ant acredita que uma estrutura de serviço de conhecimento profissional deve ter as seguintes características:
- É importante garantir a precisão do conhecimento, incluindo a integridade dos limites do conhecimento e a clareza da estrutura e da semântica do conhecimento;
- É necessário rigor lógico, sensibilidade ao tempo e sensibilidade numérica;
- Informações contextuais completas também são necessárias para facilitar o acesso a informações de apoio completas ao tomar decisões baseadas em conhecimento;
O posicionamento oficial do KAG da Ant é: Professional Domain Knowledge Augmentation Service Framework, especificamente para a combinação atual de grandes modelos de linguagem e gráficos de conhecimento para aprimorar as cinco áreas a seguir
- Conhecimento aprimorado sobre a facilidade do LLM
- Estrutura de inter-indexação entre gráficos de conhecimento e fragmentos de texto originais
- Mecanismo de raciocínio híbrido guiado por símbolos lógicos
- Mecanismo de alinhamento de conhecimento baseado em raciocínio semântico
- Modelo KAG
Esta versão de código aberto abrange os quatro primeiros recursos principais em sua totalidade.
Voltando à questão da nomenclatura do KAG, eu pessoalmente especulo que ainda pode ser para fortalecer o conceito de ontologia do conhecimento. Pela descrição oficial e pela implementação real do código, a estrutura do KAG, seja na fase de construção ou de raciocínio, enfatiza constantemente o conhecimento em si para criar um vínculo lógico completo e rigoroso, a fim de melhorar ao máximo alguns dos problemas conhecidos da pilha de tecnologia RAG.
2.2 O que (como) está sendo alcançado?
A estrutura do KAG consiste em três partes: KAG-Builder, KAG-Solver e KAG-Model:
- O KAG-Builder é usado para indexação off-line e inclui os recursos 1 e 2 mencionados acima: aprimoramento da representação do conhecimento, estrutura de indexação mútua.
- O módulo KAG-Solver abrange os recursos 3 e 4: mecanismo de raciocínio híbrido lógico-simbólico, mecanismo de alinhamento de conhecimento.
- O KAG-Model, por outro lado, tenta criar um modelo KAG de ponta a ponta.
3. análise do código-fonte
Esse código-fonte aberto envolve principalmente os dois módulos KAG-Builder e KAG-Solver, que correspondem diretamente ao código-fonte dos dois subdiretórios do builder e do solver.
Durante o estudo real do código, é recomendável começar com o exemplos
A primeira coisa que você precisa fazer é começar com um diretório para entender o fluxo de toda a estrutura e, em seguida, aprofundar-se em módulos específicos. Os caminhos para os arquivos de entrada de várias demonstrações são semelhantes, como kag/examples/medicine/builder/indexer.py
também kag/examples/medicine/solver/evaForMedicine.py
Está claro que o construtor combina diferentes módulos, enquanto o ponto de entrada real para o solucionador está no módulo kag/solver/logic/solver_pipeline.py
.
3.1 KAG-Builder
Vamos postar a estrutura completa do catálogo primeiro
❯ Árvore .
.
├── __init__.py
├─── componente
│ ├─── __init__.py
│ ├─── alinhador
│ │ ├─── __init__.py
│ │ ├─── kag_post_processor.py
│ │ └─── spg_post_processor.py
│ ├─── base.py
│ ├─── extractor
│ │ ├─── __init__.py
│ │ ├─── kag_extractor.py
│ │ ├─── spg_extractor.py
│ └─── user_defined_extractor.py
│ ├─── mapeamento
│ │ ├─── __init__.py
│ │ ├─── relation_mapping.py
│ ├─── spg_type_mapping.py
│ └─── spo_mapping.py
│ ├─── leitor
│ ├─── __init__.py
│ │ ├─── csv_reader.py
│ ├─── dataset_reader.py
│ │ ├─── docx_reader.py
│ ├─── json_reader.py
│ │ ├─── markdown_reader.py
│ │ ├─── pdf_reader.py
│ │ ├─── txt_reader.py
│ └── yuque_reader.py
│ ├─── splitter
│ │ ├─── __init__.py
│ │ ├─── base_table_splitter.py
│ │ ├─── length_splitter.py
│ │ ├─── outline_splitter.py
│ │ ├─── pattern_splitter.py
│ └── semantic_splitter.py
│ ├─── vetorizador
│ │ ├─── __init__.py
│ │ └─── batch_vectorizer.py
│ └── writer
│ ├─── __init__.py
│ └─ kg_writer.py
├─ default_chain.py
├─ model
│ ├─── __init__.py
│ ├─── chunk.py
│ ├─── spg_record.py
│ └─ sub_graph.py
├─ operador
│ ├─ __init__.py
│ └── base.py
└─ prompt
├─ __init__.py
analisar_tabela_prompt.py
Padrão
│ ├── __init__.py
│ ├─── ner.py
│ ├─── std.py
│ └─ triple.py
├─ médico
│ ├─── __init__.py
│ ├─── ner.py
│ ├─── std.py
│ └─ triple.py
├── oneke_prompt.py
├── outline_prompt.py
├── semantic_seg_prompt.py
└── spg_prompt.py
A seção Builder abrange uma ampla gama de funcionalidades, portanto, examinaremos aqui apenas um dos componentes mais importantes. KAGExtractor
O fluxograma básico é mostrado abaixo:
O principal objetivo aqui é a criação automática de um gráfico de conhecimento de texto não estruturado para conhecimento estruturado usando um modelo grande, com uma breve descrição de algumas das etapas importantes envolvidas.
- Primeiramente, há o módulo de reconhecimento de entidades, em que o reconhecimento de entidades específicas será realizado primeiro para tipos de gráficos de conhecimento predefinidos, seguido pelo reconhecimento de entidades nomeadas genéricas. Esse mecanismo de identificação em duas camadas deve garantir que as entidades específicas do domínio sejam capturadas e que as entidades genéricas não sejam perdidas.
- O processo de construção do mapeamento é, na verdade, realizado pelo
assemble_sub_graph_with_spg_records
O método de construção é feito e é especial, pois o sistema converte atributos de tipos não básicos em nós e bordas no gráfico, em vez de continuar a mantê-los como os atributos originais da entidade. Honestamente, essa parte da mudança não é muito bem compreendida e, até certo ponto, deve simplificar a complexidade da entidade, mas, na prática, não está muito claro qual é o benefício dessa estratégia; a complexidade da construção definitivamente aumentou. - Padronização de entidades por
named_entity_standardisation
responder cantandoappend_official_name
As duas abordagens são feitas em conjunto. Primeiro, os nomes das entidades são normalizados e, em seguida, esses nomes normalizados são associados às informações originais da entidade. Esse processo é semelhante à resolução de entidades.
De modo geral, a funcionalidade do módulo Builder é bastante próxima da pilha de tecnologia de construção de gráficos comum atual, e os artigos e códigos relacionados não são muito difíceis de entender, portanto, não os repetirei aqui.
3.2 KAG-Solver
A parte do Solver da estrutura envolve muitos pontos funcionais essenciais, especialmente a lógica do conteúdo relacionado ao raciocínio simbólico:
❯ Árvore .
.
├── __init__.py
├── comum
│ ├─── __init__.py
│ └── base.py
├─── implementação
│ ├─── __init__.py
│ ├── default_generator.py
│ ├── default_kg_retrieval.py
│ ├── default_lf_planner.py
│ ├── default_memory.py
│ ├── default_reasoner.py
│ ├── default_reflector.py
lf_chunk_retriever.py
├─ lógica
│ ├─── __init__.py
│ ├─── core_modules
│ │ ├─── __init__.py
│ │ ├─── comum
│ │ ├ ├── __init__.py
│ │ │ ├─── base_model.py
│ │ │ ├─── one_hop_graph.py
│ │ │ ├─── schema_utils.py
│ │ ├─── text_sim_by_vector.py
│ │ └─── utils.py
│ ├─── config.py
│ ├─── lf_executor.py
│ │ ├─── lf_generator.py
│ ├─── lf_solver.py
│ │ ├─── op_executor
│ │ ├─── __init__.py
│ │ ├─── op_deduce
│ │ │ ├─── __init__.py
│ │ │ │ ├─── deduce_executor.py
│ │ │ │ └── módulo
│ │ │ ├─── __init__.py
│ │ │ ├─── choice.py
│ │ │ │ ├─── entailment.py
│ │ │ │ ├─── julgamento.py
│ │ │ │ └─── multi_choice.py
│ │ ├─── op_executor.py
│ │ │ ├─── op_math
│ │ │ ├─── __init__.py
│ │ │ │ └─── math_executor.py
│ │ ├─── op_output
│ │ │ │ ├── __init__.py
│ │ │ │ ├── module
│ │ │ │ ├─── __init__.py
│ │ │ │ └─── get_executor.py
│ │ │ │ └─── output_executor.py
│ │ │ ├─── op_retrieval
│ │ │ ├─── __init__.py
│ │ │ │ ├── module
│ │ │ │ ├─── __init__.py
│ │ │ │ ├─── get_spo_executor.py
│ │ │ │ └─── search_s.py
│ │ │ │ └─── retrieval_executor.py
│ │ │ └─ op_sort
│ │ │ ├─── __init__.py
│ │ └─── sort_executor.py
│ │ ├─── parser
│ │ ├ ├── __init__.py
│ │ └─── logic_node_parser.py
│ │ ├─── retriver
│ │ ├── __init__.py
│ │ │ ├─── entity_linker.py
│ │ ├─── graph_retriver
│ │ │ ├─── __init__.py
│ │ │ │ ├─── dsl_executor.py
│ │ │ └─── dsl_model.py
│ │ ├─── retrieval_spo.py
│ │ └── schema_std.py
│ └── rule_runner
│ ├─── __init__.py
│ │ └─── rule_runner.py
│ └─ solver_pipeline.py
├─ main_solver.py
├─ prompt
│ ├── __init__.py
│ ├─── default
│ │ ├─── __init__.py
│ │ ├─── deduce_choice.py
│ ├─── deduce_entail.py
│ │ ├─── deduce_judge.py
│ │ ├─── deduce_multi_choice.py
│ ├─── logic_form_plan.py
│ ├─── question_ner.py
│ ├─── resp_extractor.py
│ │ ├─── resp_generator.py
│ │ ├─── resp_judge.py
│ ├─── resp_reflector.py
│ ├─── resp_verifier.py
│ ├── solve_question.py
│ ├── solve_question_without_docs.py
│ ├─── solve_question_without_spo.py
│ │ └─── spo_retrieval.py
│ ├─── lawbench
│ │ ├─── __init__.py
│ │ └─── logic_form_plan.py
│ └── médico
│ ├── __init__.py │ └─ question_form_plan.py │ └─ médico
│ └─ question_ner.py
└─ ferramentas
├─ __init__.py │ └─ info_process.py
└─ info_processor.py
Já mencionei o arquivo de entrada do solver antes, portanto, publicarei o código relevante aqui:
class SolverPipeline.
def __init__(self, max_run=3, reflector: KagReflectorABC = None, reasoner: KagReasonerABC = None, generator: KagGeneratorABC = None, **kwargs): **kwargs
generator: KAGGeneratorABC = None, **kwargs).
"""
Inicializa a classe de loop do tipo pensar e agir.
param max_run: número máximo de execuções para limitar o loop de raciocínio e ação; o padrão é 3.
param reflector: instância do refletor para tarefas de reflexão.
:param reflector: instância do refletor para refletir tarefas. :param reasoner: instância do raciocinador para raciocinar sobre tarefas.
:param generator: instância do gerador para gerar ações.
"""
self.max_run = max_run
self.memory = DefaultMemory(**kwargs)
self.reflector = reflector ou DefaultReflector(**kwargs)
self.reasoner = reasoner ou DefaultReasoner(**kwargs)
self.generator = generator ou DefaultGenerator(**kwargs)
self.trace_log = []
def run(self, question):
"""
Executa a lógica central do sistema de solução de problemas.
Parâmetros.
- question (str): a pergunta a ser respondida.
Parâmetros: question (str): A pergunta a ser respondida.
- tupla: resposta, registro de rastreamento
"""
instrução = pergunta
if_finished = False
logger.debug('instrução de entrada:{}'.format(instrução))
present_instruction = instrução
run_cnt = 0
while not if_finished and run_cnt < self.max_run:: run_cnt += 1
run_cnt += 1
logger.debug('present_instruction is:{}'.format(present_instruction))
# Tentativa de resolver a instrução atual e obter a resposta, os fatos de apoio e o registro do histórico
solved_answer, supporting_fact, history_log = self.reasoner.reason(present_instruction)
# Extrair evidências dos fatos de apoio
self.memory.save_memory(solved_answer, supporting_fact, instruction)
history_log['present_instruction'] = present_instruction
history_log['present_memory'] = self.memory.serialise_memory()
self.trace_log.append(history_log)
# Reflete a instrução atual com base na memória e na instrução atuais
if_finished, present_instruction = self.reflector.reflect_query(self.memory, present_instruction)
response = self.generator.generate(instruction, self.memory)
return response, self.trace_log
total SolverPipeline.run()
A metodologia envolve três módulos principais:Raciocinador
, Refletor
responder cantando Gerador
A lógica geral ainda é muito clara: primeiro tente responder à pergunta, depois reflita se o problema foi resolvido e, caso contrário, continue a pensar profundamente até obter uma resposta satisfatória ou atingir o número máximo de tentativas. Basicamente, ele imita a maneira geral de pensar dos seres humanos na solução de problemas complexos.
A seção a seguir analisa mais detalhadamente os três módulos mencionados acima.
3.3 Raciocinador
O módulo de inferência é provavelmente a parte mais complexa de toda a estrutura, e seu código principal é o seguinte:
class DefaultReasoner(KagReasonerABC)::
def __init__(self, lf_planner: LFPlannerABC = None, lf_solver: LFSolver = None, **kwargs).
def reason(self, question: str).
"""
Processa uma determinada pergunta planejando e executando formas lógicas para obter uma resposta.
Parâmetros.
- question (str): a pergunta de entrada a ser processada.
Parâmetros: question (str): a pergunta de entrada a ser processada.
- solved_answer: a resposta final derivada da resolução dos formulários lógicos.
- supporting_fact: fatos de apoio reunidos durante o processo de raciocínio.
- history_log: um dicionário que contém o histórico de pares de controle de qualidade e documentos reclassificados.
"""
Planejamento do formulário lógico #
lf_nodes: lista [LFPlanResult] = self.lf_planner.lf_planing(question)
Execução do formulário lógico #
solved_answer, sub_qa_pair, recall_docs, history_qa_log = self.lf_solver.solve(question, lf_nodes)
# Gerar fatos de apoio para o par subpergunta-resposta
supporting_fact = '\n'.join(sub_qa_pair)
# Recuperar e classificar documentos
sub_querys = [lf.query for lf in lf_nodes]
if self.lf_solver.chunk_retrieve:
docs = self.lf_solver.chunk_retriever.retrieve_docs([question] + sub_querys, recall_docs)
caso contrário.
logger.info("DefaultReasoner não habilita o recuperador de pedaços")
docs = []
history_log = {
'history': history_qa_log,
'rerank_docs': docs
}
if len(docs) > 0.
# Acrescente fatos de apoio para os blocos recuperados
supporting_fact += f"\nPassages:{str(docs)}"
return solved_answer, supporting_fact, history_log
Isso resulta em um fluxograma geral do módulo de raciocínio: (a lógica, como o tratamento de erros, foi omitida)
É fácil perceber queDefaultReasoner.reason()
A metodologia é amplamente dividida em três etapas:
- Planejamento do Formulário Lógico (LFP): envolve principalmente
LFPlanner.lf_planing
- Logic Form Execution (LFE): envolve principalmente
LFSolver.solve
- Reranking de documentos: envolve principalmente
LFSolver.chunk_retriever.rerank_docs
Cada uma das três etapas é analisada em detalhes a seguir.
3.3.1 Planejamento de formulários lógicos
DefaultLFPlanner.lf_planing()
é usado principalmente para decompor uma consulta em uma série de formas lógicas independentes (lf_nodes: Lista [LFPlanResult].
).
lf_nodes: Lista[LFPlanResult] = self.lf_planner.lf_planing(question)
A lógica de implementação pode ser encontrada em kag/solver/implementation/default_lf_planner.py
O foco principal está em llm_output
Faça a análise regularizada ou chame o LLM para gerar uma nova forma lógica, se não for fornecida.
Aqui está algo para ficar de olho kag/solver/prompt/default/logic_form_plan.py
assuntos relevantes LogicFormPlanPrompt
O design detalhado do projeto se concentra em como decompor um problema complexo em várias subconsultas e suas formas lógicas correspondentes.
3.3.2 Execução de formulário lógico
LFSolver.solve()
Os métodos são usados para resolver problemas específicos de formulário lógico, retornando respostas, pares de respostas de subproblemas, documentos de recuperação associados e histórico, etc.
solved_answer, sub_qa_pair, recall_docs, history_qa_log = self.lf_solver.solve(question, lf_nodes)
em profundidadekag/solver/logic/core_modules/lf_solver.py
A seção do código-fonte, que pode ser encontrada LFSolver
A classe (Logical Form Solver) é a classe principal de todo o processo de raciocínio e é responsável por executar a forma lógica (LF) e gerar a resposta:
- Os principais métodos são
resolver
que recebe uma consulta e um conjunto de nós de formulário lógico (Lista [LFPlanResult].
). - fazer uso de
LogicExecutor
para executar formulários lógicos que geram respostas, caminhos de gráficos de conhecimento e históricos. - Processa subconsultas e pares de respostas, bem como a documentação relacionada.
- Tratamento de erros e estratégia de fallback: se nenhuma resposta ou documentação relevante for encontrada, será feita uma tentativa de usar o
retriever de pedaços
Recuperar documentos relacionados.
Os principais processos são os seguintes:
Entre eles LogicExecutor
é uma das classes mais críticas, portanto, aqui está o código principal:
executor = LogicExecutor(
query, self.project_id, self.schema,
kg_retriever=self.kg_retriever,
chunk_retriever=self.chunk_retriever, std_schema=self.
std_schema=self.std_schema,
el=self.el, text_similarity=self.
text_similarity=self.
dsl_runner=DslRunnerOnGraphStore(...) ,
generator=self.generator, report_tool=self.
report_tool=self.report_tool,
req_id=generate_random_string(10)
)
kg_qa_result, kg_graph, history = executor.execute(lf_nodes, query)
- lógica de implementação
LogicExecutor
O código relevante para a classe está localizado no arquivokag/solver/logic/core_modules/lf_executor.py
. seuexecutar
O fluxo principal de execução do método é mostrado a seguir.
Esse fluxo de execução demonstra uma estratégia de recuperação dupla: priorizar o uso de dados de gráficos estruturados para recuperação e inferência, e voltar para a recuperação de informações textuais não estruturadas quando o gráfico não puder ser respondido.
O sistema primeiro tenta responder à pergunta por meio do gráfico de conhecimento, para cada nó de expressão lógica, por meio de diferentes atuadores (envolvendo odeduzir
ematemática
eclassificar
erecuperação
esaída
etc.) são processados, e o processo de recuperação coleta triplas SPO (sujeito-predicado-objeto) para a geração de respostas subsequentes; quando o gráfico não consegue fornecer uma resposta satisfatória (retornando "Não sei"), o sistema volta à recuperação de blocos de texto: usando os resultados de entidade nomeada (NER) obtidos anteriormente como ponto de ancoragem de recuperação e combinando-os com os registros históricos de perguntas e respostas para construir uma consulta aprimorada pelo contexto, que é então passada peloretriever de pedaços
Gerar novamente a resposta com base no documento recuperado.
Todo o processo pode ser visto como uma estratégia de degradação elegante e, ao combinar gráficos de conhecimento estruturados com dados textuais não estruturados, essa recuperação híbrida é capaz de fornecer respostas tão completas e contextualmente coerentes quanto possível, mantendo a precisão. - componente principal
Além da lógica de implementação específica descrita acima, observe que oLogicExecutor
A inicialização requer a passagem de vários componentes. Por limitação de espaço, apresentamos aqui apenas uma breve descrição da função principal de cada componente; a implementação específica pode ser consultada no código-fonte.- kg_retriever: Recuperador de gráficos de conhecimento
consultakag/solver/implementation/default_kg_retrieval.py
médioKGRetrieverByLlm(KGRetrieverABC)
que implementa a recuperação de entidades e relacionamentos, envolvendo vários métodos de correspondência, como exato/fuzzy e subgrafos de um salto. - chunk_retriever: recuperador de pedaços de texto
consultakag/common/retriever/kag_retriever.py
médioDefaultRetriever(ChunkRetrieverABC)
Vale a pena investigar o código aqui, em primeiro lugar, a padronização do processamento de entidades. Além disso, a recuperação aqui se refere ao HippoRAG, usando uma estratégia de recuperação híbrida que combina DPR (Dense Passage Retrieval) e PPR (Personalized PageRank) e, em seguida, com base na integração de DPR e PPR Score. Além disso, uma estratégia de recuperação híbrida que combina DPR (Dense Passage Retrieval) e PPR (Personalized PageRank) é adotada aqui, e a fusão subsequente das pontuações baseadas em DPR e PPR alcança ainda mais a alocação dinâmica de peso dos dois métodos de recuperação. - entity_linker (el): vinculador de entidades
consultakag/solver/logic/core_modules/retriver/entity_linker.py
médioDefaultEntityLinker(EntityLinkerBase)
Em um exemplo de um sistema de links de entidades, a ideia de construir recursos antes de paralelizar o processamento de links de entidades é usada aqui. - dsl_runner: consultor de banco de dados de gráficos
consultakag/solver/logic/core_modules/retriver/graph_retriver/dsl_executor.py
médioDslRunnerOnGraphStore(DslRunner)
O banco de dados de gráficos é responsável pelas informações da consulta estruturada em uma instrução de consulta específica do banco de dados de gráficos.
- kg_retriever: Recuperador de gráficos de conhecimento
Analisando o código e o fluxograma acima, é possível observar que todo o loop do Logic Form Execution (LFE) adota uma arquitetura de processamento hierárquico:
- o topo de um edifício
LFSolver
Responsável pelo processo geral - mesosfera
LogicExecutor
Responsável pela implementação de formulários lógicos específicos (LF) - fundo (de uma pilha)
Corredor DSL
Responsável por interagir com o banco de dados de gráficos
3.3.3 Reranking de documentos
Se você ativar o retriever de pedaços
também reordenará os documentos recuperados.
if self.lf_solver.chunk_retriever.
docs = self.lf_solver.chunk_retriever.recall_docs(
[question] + sub_querys, recall_docs
)
3.4 Refletor
Refletor
implementa principalmente a classe _can_answer
junto com _refine_query
Dois métodos, o primeiro para determinar se uma pergunta pode ser respondida e o segundo para otimizar os resultados intermediários de uma consulta multihop para orientar a geração da resposta final.
Referências de implementação relacionadas kag/solver/prompt/default/resp_judge.py
junto com kag/solver/prompt/default/resp_reflector.py
Esses dois arquivos do Prompt são mais fáceis de entender.
3.5 Gerador
grampo LFGenerator
seleciona dinamicamente modelos de palavras de alerta com base em diferentes cenários (com ou sem gráficos de conhecimento, com ou sem documentos, etc.) e gera respostas para as perguntas correspondentes.
As implementações relevantes estão localizadas no kag/solver/logic/core_modules/lf_generator.py
Se o código for relativamente intuitivo, ele não será repetido.
4. algumas reflexões
E essa estrutura KAG de código aberto, com foco em serviços de aprimoramento de conhecimento de domínio profissional, abrangendo raciocínio simbólico, alinhamento de conhecimento e uma série de pontos inovadores, estudo abrangente, sinto que a estrutura é particularmente adequada para a necessidade de restrições rigorosas no esquema do conhecimento profissional do cenário, seja no estágio de indexação ou de consulta, todo o fluxo de trabalho é repetidamente reforçado de um ponto de vista: você deve estar a partir das restrições da base de conhecimento, para construir os gráficos ou fazer o raciocínio lógico. Essa mentalidade deve aliviar, até certo ponto, o problema da falta de conhecimento de domínio, bem como a ilusão de modelos grandes.
Desde que a estrutura GraphRAG da Microsoft passou a ter código aberto, a comunidade tem pensado mais sobre a integração de gráficos de conhecimento e a pilha de tecnologia RAG, como o trabalho recente do LightRAG, StructRAG etc., que fez muitas explorações úteis. O KAG, embora haja algumas diferenças entre a rota técnica e o GraphRAG, pode ser considerado, até certo ponto, como uma prática na direção de serviços de aprimoramento do conhecimento no domínio profissional do GraphRAG, especialmente para compensar as deficiências no alinhamento e raciocínio do conhecimento. Embora existam algumas diferenças entre o KAG e o GraphRAG em termos de tecnologia, o KAG pode ser considerado uma prática do GraphRAG na direção dos serviços de aprimoramento do conhecimento em domínios profissionais, especialmente para compensar as deficiências no alinhamento do conhecimento e no raciocínio. A partir dessa perspectiva, eu pessoalmente prefiro chamá-lo de GraphRAG com restrições de conhecimento.
O GraphRAG nativo, com sumarização hierárquica baseada em diferentes comunidades, pode responder a perguntas de alto nível relativamente abstratas, mas também devido ao foco excessivo na sumarização focada em consultas (QFS), a estrutura pode não ter um bom desempenho em perguntas factuais de granulação fina e, considerando a questão do custo, o GraphRAG nativo tem muitos desafios no domínio pendente, enquanto a estrutura KAG fez mais otimizações no estágio de construção do gráfico, como operações de alinhamento e padronização de entidades com base em esquemas específicos, e na estrutura KAG, com base em esquemas específicos. O GraphRAG tem muitos desafios no domínio pendente, enquanto a estrutura KAG fez mais otimizações no estágio de construção do gráfico, como alinhamento de entidades e operações de padronização com base em um esquema específico e, no estágio de consulta, também introduz o raciocínio do gráfico de conhecimento com base na lógica simbólica, embora o raciocínio simbólico tenha sido mais pesquisado no campo do gráfico, embora não seja comum aplicá-lo aos cenários RAG. O fortalecimento da capacidade de raciocínio do RAG é uma direção de pesquisa na qual o autor está mais otimista e, há algum tempo, a Microsoft resumiu as quatro camadas de capacidade de raciocínio da pilha de tecnologia RAG:
- Fatos explícitos de nível 1, Fatos explícitos
- Nível 2 Fatos implícitos, fatos ocultos
- Raciocínios interpretáveis de nível 3, Raciocínios interpretáveis (pendentes)
- Racionalidades ocultas de nível 4, racionalidades invisíveis (domínio pendente)
No momento, a capacidade de raciocínio da maioria das estruturas RAG ainda está limitada ao nível 1, e os níveis acima de Nível 3 e Nível 4 enfatizam a importância do raciocínio vertical, e a dificuldade está na falta de conhecimento de modelos grandes no domínio vertical, e a introdução do raciocínio simbólico no estágio de consulta da estrutura KAG pode ser considerada como uma exploração dessa direção até certo ponto, e pode-se prever que uma onda de novas pesquisas será realizada nos próximos anos na área de raciocínio RAG. É previsível que o raciocínio RAG possa desencadear uma nova onda de pesquisa, como a fusão adicional da capacidade de raciocínio do próprio modelo, como RL ou CoT, etc. Neste estágio, algumas tentativas foram feitas no cenário, mas ainda há mais ou menos limitações.
Além da sessão de raciocínio, o KAG adota uma estratégia de recuperação híbrida de DPR e PPR em referência ao HippoRAG para recuperação, e o uso eficiente do PageRank demonstra ainda mais as vantagens dos gráficos de conhecimento em relação à recuperação tradicional de vetores, e acredita-se que mais algoritmos de recuperação de gráficos serão integrados à pilha de tecnologia RAG no futuro.
Obviamente, estima-se que a estrutura do KAG ainda esteja no estágio inicial e de iteração rápida, e ainda deve haver algum espaço para discussão sobre a implementação concreta das funções, como, por exemplo, se o Planejamento de Formulário Lógico e a Execução de Formulário Lógico existentes têm suporte teórico completo no nível de design e se haverá decomposição insuficiente e falha de execução diante de problemas complexos. Se haverá decomposição insuficiente, falha de execução, mas essa definição de limite e questões de robustez são geralmente muito difíceis de lidar, mas também exigem muitos custos de tentativa e erro, se toda a cadeia de raciocínio for muito complexa, a taxa de falha final pode ser maior, afinal, uma variedade de degradação de volta à estratégia é apenas um certo grau de alívio do problema. Além disso, notei que o GraphStore na parte inferior da estrutura realmente reservou uma interface de atualização incremental, mas o aplicativo da camada superior não mostrou os recursos relevantes, o que também é um recurso que, pessoalmente, entendo que a comunidade GraphRAG exige mais.
De modo geral, a estrutura do KAG é considerada um trabalho muito intenso no passado recente, contendo muitos pontos inovadores, e o código realmente passou por um grande polimento de detalhes, o que se acredita ser um impulso importante para o processo de aterrissagem da pilha de tecnologia RAG.