Prefácio
Nos últimos dois anos, a tecnologia Retrieval-Augmented Generation (RAG, Geração Aumentada por Recuperação) tornou-se gradualmente um componente essencial das inteligências aprimoradas. Ao combinar os recursos duplos de recuperação e geração, a RAG é capaz de introduzir conhecimento externo, oferecendo assim mais possibilidades para a aplicação de modelos grandes em cenários complexos. No entanto, em cenários práticos de aterrissagem, muitas vezes há problemas de baixa precisão de recuperação, interferência de ruído, integridade de recall e profissionalismo insuficiente, o que leva a sérias ilusões de LLM. Neste artigo, vamos nos concentrar nos detalhes de processamento e recuperação de conhecimento do RAG em cenários reais de aterrissagem, como otimizar o link RAG Pineline e, por fim, melhorar a precisão da recuperação.
É fácil criar rapidamente um aplicativo de perguntas e respostas inteligente RAG, mas colocá-lo em um cenário comercial real exige muita preparação.
1.RAG Interpretação do código-fonte do processo-chave
centroprocessamento de conhecimentoresponder cantandoRAGAlguns dos principais processos:
1. processamento de conhecimento
Carregamento de conhecimento -> Fatiamento de conhecimento -> Extração de informações -> Processamento de conhecimento (incorporação/gráfico/palavras-chave) -> Armazenamento de conhecimento
- Carregamento de conhecimento
# Fábrica de conhecimento para instanciação KnowledgeFactory -> create() -> load() -> Document - conhecimento - markdown - pdf - docx - txt - html - pptx - url - ...
Como expandir:
from abc import ABC from typing import List, Any class Knowledge(ABC): def load(self) -> List[Document]. def load(self) -> List[Document]. """Carregar conhecimento do carregador de dados.""""" """Carregar conhecimento do carregador de dados."" @classmethod def document_type(cls) -> Any. """Obter o tipo de documento."""" pass @classmethod def document_type(cls) -> Any. @classmethod def support_chunk_strategy(cls) -> List[ChunkStrategy]. """Retornar a estratégia de pedaços suportada."""" return [ ChunkStrategy.CHUNK_BY_SIZE, ChunkStrategy.CHUNK_BY_PAGE, """ return [ ChunkStrategy.CHUNK_BY_SIZE, ChunkStrategy. ChunkStrategy.CHUNK_BY_PARAGRAPH, ChunkStrategy. ChunkStrategy.CHUNK_BY_MARKDOWN_HEADER, ChunkStrategy. ChunkStrategy.CHUNK_BY_SEPARATOR, ChunkStrategy.CHUNK_BY_SEPARATOR, ] @classmethod def default_chunk_strategy(cls) -> ChunkStrategy. """ Retorna a estratégia de bloco padrão. Retorna. ChunkStrategy: estratégia de bloco padrão """ retorna ChunkStrategy.CHUNK_BY_SIZE
- fatia de conhecimento
ChunkManager: encaminha os dados de conhecimento carregados para o processador de blocos correspondente para alocação com base na política de blocos especificada pelo usuário e nos parâmetros de blocos.
classe ChunkManager. """Gerenciador de pedaços."""" def __init__( self. conhecimento: Conhecimento, chunk_parameter. chunk_parameter: Optional[ChunkParameters] = None, extractor: Optional[Extractor] = None, ). """ Cria um novo ChunkManager com o conhecimento fornecido. Args: knowledge: (Knowledge) Fonte de dados de conhecimento. chunk_parameter: (Optional[ChunkParameters]) Parâmetro de chunk. chunk_parameter: (Optional[ChunkParameters]) Parâmetro de chunk. extractor: (Optional[Extractor]) Extrator a ser usado para compactação. """ self._knowledge = conhecimento self._extractor = extractor self._chunk_parameters = chunk_parameter ou ChunkParameters() self._chunk_strategy = ( parâmetro_de_chunk.estratégia_de_chunk se chunk_parameter e chunk_parameter.chunk_strategy else self._knowledge.default_chunk_strategy().name ) self._text_splitter = self._chunk_parameters.text_splitter self._splitter_type = self._chunk_parameters.splitter_type
Como estender: se você quiser personalizar uma nova estratégia de fatiamento na interface
- Nova estratégia de fatiamento
- Nova lógica de implementação do Splitter
class ChunkStrategy(Enum). """Chunk Strategy Enum."""" CHUNK_BY_SIZE: _STRATEGY_ENUM_TYPE = ( RecursiveCharacterTextSplitter, """RecursiveCharacterTextSplitter, """Chunk Strategy Enum."" [ { "param_name": "chunk_size", "param_type": "int", "default_value": 512, "description": "O tamanho do bloco de dados". "description": "O tamanho dos blocos de dados usados no processamento.", }, { "param_name": "chunk_overlap", "param_type": "int": "chunk_type": "chunk_overlap", { "param_type": "int", "default_value": 50 "default_value": 50, "description": "A quantidade de sobreposição entre blocos de dados adjacentes.", } } ], "chunk size" (tamanho do bloco). "Dividir o documento por tamanho de bloco", ), "chunk_value": 50 ) CHUNK_BY_PAGE: _STRATEGY_ENUM_TYPE = ( PageTextSplitter, _STRATEGY_ENUM_TYPE = ( []. "page". "dividir documento por página", ) CHUNK_BY_PARAGRAPH: _STRATEGY_ENUM_TYPE = ( ParagraphTextSplitter, [ [ { "param_name": "separator", "param_type": "string", "default_value": "\n", "description": "paragraph", "\n", "\n", "\n", "\n", "\n", "\n", "\n". "description": "paragraph separator" (descrição: "separador de parágrafo"), } ], "paragraph" (parágrafo), "description" (descrição): "paragraph separator" (separador de parágrafo), } "parágrafo", "dividir documento por parágrafo", "descrição". "dividir documento por parágrafo". ) CHUNK_BY_SEPARATOR: _STRATEGY_ENUM_TYPE = ( SeparatorTextSplitter, [ [ { "param_name": "separator", "param_type": "string", }, { "param_name": "enable_merge", "param_type": "parameter_type", }, { "param_type": "boolean", "default_value": false "default_value": False, "description": ( "Se deve ser mesclado de acordo com o chunk_size após " "dividir pelo separador." ), } ], "separator", " "dividindo pelo separador.", }, } "separador", "dividir documento por separador", "Dividindo o documento pelo separador". ) CHUNK_BY_MARKDOWN_HEADER: _STRATEGY_ENUM_TYPE = ( MarkdownHeaderTextSplitter, [], "markdown header", "Dividir documento por cabeçalho de markdown", )
- Extração de conhecimento
- Extração de vetores -> incorporação, implementação
Embeddings
conector
@abstractmethod def embed_documents(self, texts: List[str]) -> List[List[float]]. """Incorporar documentos de pesquisa."""" @abstractmethod def embed_query(self, text: str) -> List[float]]. """Incorporar texto da consulta."""" async def aembed_documents(self, texts: List[str]) -> List[List[float]]. """Incorporação assíncrona de documentos de pesquisa.""""" return await asyncio.get_running_loop().run_in_executor( None, self.embed_documents, texts ) async def aembed_query(self, text: str) -> List[float]. """Consulta assíncrona de incorporação text."""" return await asyncio.get_running_loop().run_in_executor( None, self.embed_query, text )
# EMBEDDING_MODEL=proxy_openai # proxy_openai_proxy_server_url=https://api.openai.com/v1 # proxy_openai_proxy_api_key={sua-openai-sk} # proxy_openai_proxy_backend=text-embedding-ada-002 ## qwen embedding model, consulte dbgpt/model/parameter.py # EMBEDDING_MODEL=proxy_tongyi # proxy_tongyi_proxy_backend=text-embedding-v1 # proxy_tongyi_proxy_api_key={sua_chave_de_api} ## modelo de incorporação qianfan, consulte dbgpt/model/parameter.py # EMBEDDING_MODEL=proxy_qianfan # proxy_qianfan_proxy_backend=bge-large-zh # proxy_qianfan_proxy_api_key={sua_chave_api} # proxy_qianfan_proxy_api_secret={sua-secret-key}
- Extração do gráfico de conhecimento -> gráfico de conhecimento
class TripletExtractor(LLMExtractor). """Classe TripletExtractor."""" def __init__(self, llm_client: LLMClient, model_name: str). """Inicializar o TripletExtractor.""""" super(). __init__(llm_client, nome_do_modelo, TRIPLET_EXTRACT_PT) TRIPLET_EXTRACT_PT = ( "Algum texto é fornecido abaixo. Dado o texto, " " "extraia o maior número possível de tripletos de conhecimento " " "na forma de (sujeito, predicado, objeto). \n" "Evite palavras de parada. O sujeito, o predicado e o objeto não podem ser nenhum." "---------------------\n" "Exemplo:\n" "Texto: Alice é a mãe de Bob.\n" "Tripletos:\n(Alice, is mother of, Bob)\n" "Texto: Alice tem 2 maçãs.\n" "Triplets:\n(Alice, has 2, apple)\n" "Texto: Alice recebeu 1 maçã de Bob.\n" "Triplets:(Bob, gives 1 apple, Alice)\n" "Texto: Alice foi empurrada por Bob.\n" "Triplets:(Bob, empurra, Alice)\n" "Texto: A mãe de Bob, Alice, tem 2 maçãs.\n" "Triplets:\n(Alice, is mother of, Bob)\n(Alice, has 2, apple)\n" "Texto: Um macaco grande subiu na árvore frutífera alta e pegou 3 pêssegos.\n" "Trigêmeos:\n(monkey, climbed up, fruit tree)\n(monkey, picked 3, peach)\n" "Texto: Alice tem 2 maçãs, ela dá 1 para Bob.\n" "Trigêmeos:\n" "(Alice, tem 2, maçã)\n(Alice, dá 1 maçã, Bob)\n" "Texto: Philz é uma cafeteria fundada em Berkeley em 1982.\n" "Tripletos:\n" "(Philz, is, coffee shop)\n(Philz, founded in, Berkeley)\n" "(Philz, fundado em, 1982)\n" "---------------------\n" "Texto: {text}\n" "Triplets:\n" )
-
- Extração reversa de índices -> segmentação de palavras-chave
- Você pode usar o léxico padrão do es ou pode personalizar o léxico usando o modo de plug-in do es.
- Extração reversa de índices -> segmentação de palavras-chave
- Armazenamento de conhecimento
Toda a persistência do conhecimento é obtida de maneira uniformeIndexStoreBase
atualmente oferece três tipos de implementações: bancos de dados vetoriais, bancos de dados gráficos, indexação de texto completo
- VectorStore, a lógica principal do banco de dados vetorial está em load_document(), incluindo a criação do esquema de índice, gravação em lote de dados vetoriais e assim por diante.
# Hierarquia da classe base - VectorStoreBase - ChromaStore - MilvusStore - OceanbaseStore - ElasticsearchStore - PGVectorStore # Definição da classe base class VectorStoreBase(IndexStoreBase, ABC). """ Classe base do armazenamento de vetores. """ @abstractmethod def load_document(self, chunks: List[Chunk]) -> List[str]. """ Carrega o documento no banco de dados de índice. """ pass @abstractmethod async def aload_document(self, chunks: List[Chunk]) -> List[str]. """ Carrega o documento no banco de dados de índice de forma assíncrona. """ pass @abstractmethod def similar_search_with_scores( self. text: str, topk: int, score_threshold: float, filters: Optional[MetadataFilters] = None, ) -> List[Chunk]. """ Execute uma pesquisa semelhante com pontuações no banco de dados do índice. """ pass def similar_search( def similar_search( text: str, topk: int, filters: Optional[MetadataFilters] = None, def filters: Optional[MetadataFilters] = None, ) -> List[Chunk]. """ Execute uma pesquisa semelhante no banco de dados do índice. """ return self.similar_search_with_scores(text, topk, 1.0, filters)
- GraphStore , um armazenamento de gráficos concreto, fornece uma implementação de escrita ternária, que geralmente é feita chamando a linguagem de consulta de um banco de dados de gráficos concreto. Por exemplo
Armazém TuGraph
Uma instrução Cypher específica será gerada e executada com base no ternário.
-
- A interface de armazenamento de gráficos GraphStoreBase fornece uma abstração unificada para o armazenamento de gráficos e atualmente possui
Armazenamento de gráficos de memória
responder cantandoArmazém TuGraph
também fornecemos a interface do Neo4j aos desenvolvedores para acesso.
- A interface de armazenamento de gráficos GraphStoreBase fornece uma abstração unificada para o armazenamento de gráficos e atualmente possui
# GraphStoreBase -> TuGraphStore -> Neo4jStore def insert_triplet(self, subj: str, rel: str, obj: str) -> None. """Adicionar triplet."""" # Criar consultas para mesclar nós e relacionamentos subj_query = f "MERGE (n1:{self._node_label} {{id:'{subj}'}})"" obj_query = f "MERGE (n2:{self._node_label} {{id:'{obj}'}})" rel_query = ( f "MERGE (n1:{self._node_label} {{id:'{subj}'}})"" f"-[r:{self._edge_label} {{id:'{rel}'}}]->" f"(n2:{self._node_label} {{id:'{obj}'}})" ) # Executar consultas self.conn.run(query=subj_query) self.conn.run(query=obj_query) self.conn.run(query=rel_query)
-
- FullTextStore: construindo o índice do es, por meio do algoritmo interno de divisão de palavras do es para divisão de palavras e, em seguida, pelo es para construir o índice invertido keyword->doc_id.
{ "analysis": { "analyser": { "default": { "type": "standard" } } }, "similarity" (similaridade): { "default" (padrão): { "type" (tipo): "standard" (padrão) } "similarity": { "custom_bm25": { "type": "BM25", "k1": self._k1, "b": self._b } } } self._es_mappings = { "properties": { "content" (conteúdo): { "type": "text", "similarity": "custom_bm25 "similarity": "custom_bm25" }, "metadata": { "type": "keyword" } } } # FullTextStoreBase # ElasticDocumentStore # OpenSearchStore
2. recuperação de conhecimento
question -> rewrite -> similarity_search -> rerank -> context_candidates
A lógica atual de recuperação da comunidade é dividida principalmente nestas etapas: se você definir os parâmetros de reescrita da consulta, no momento, você terá uma rodada de reescrita da pergunta por meio do modelo grande e, em seguida, ela será encaminhada para o recuperador correspondente de acordo com sua forma de processamento de conhecimento; se você for processado por meio dos vetores, ela será recuperada por meio do EmbeddingRetriever; se você criar uma forma for construído por meio do gráfico de conhecimento, ele será recuperado de acordo com o modo do gráfico de conhecimento e, se você configurar o modelo de classificação, ele fornecerá aos valores candidatos, após a triagem grosseira, uma triagem fina para tornar os valores candidatos mais relevantes para a pergunta do usuário.
- EmbeddingRetriever
classe EmbeddingRetriever(BaseRetriever). """Embedding retriever.""""" def __init__( self, __init__( index_store: IndexStoreBase, top_k: int = 4, query_rewrite: Optional[QueryRewrite] = None, rerank: Optional[Ranker] = None, retrieve_strategy: Optional[RetrieverStrategy] = RetrieverStrategy.EMBEDDING, ). EMBEDDING, ): pass async def _aretrieve_with_score( self. self, query: str, score_threshold: float, score_with_score( score_threshold: float, filters: Optional[MetadataFilters] = None, } filters: Optional[MetadataFilters] = None, ) -> List[Chunk]. ) -> List[Chunk]. """ Recupera blocos de conhecimento com pontuação. Args. Args: query (str): Texto da consulta. score_threshold (float): Limite de pontuação. filters: Filtros de metadados. Retorna: List[Chunk]: lista de blocos com pontuação. List[Chunk]: Lista de blocos com pontuação. """ consultas = [consulta] new_queries = await self._query_rewrite.rewrite( origin_query=query, context=context, nums=1 ) queries.extend(new_queries) candidates_with_score = [ self._similarity_search_with_score( query, score_threshold, filtros, root_tracer.get_current_span_id() root_tracer.get_current_span_id() ) para consulta em consultas ] new_candidates_with_score = await self._rerank.arank( novos_candidatos_com_score, new_candidates_with_score, query ) return new_candidates_with_score
-
- index_store: banco de dados vetorial específico
- top_k: o número de blocos candidatos específicos retornados
- query_rewrite: função de reescrita de consulta
- rerank: função de reordenação
- consulta:consulta original
- score_threshold: pontuação; por padrão, filtramos os contextos com uma pontuação de similaridade menor que o limite
- filtros:
Opcional[MetadataFilters]
O filtro de informações de metadados pode ser usado principalmente para analisar as informações de atributos e filtrar algumas informações candidatas incompatíveis.
from enum import Enum from typing import Union, List from pydantic import BaseModel, Field class FilterCondition(str, Enum). """Condições de filtro de metadados do armazenamento de vetores."""" AND = "e" OR = "or" (ou) class MetadataFilter(BaseModel). """Filtro de metadados."""" key: str = Field( ... , description="A chave dos metadados a serem filtrados."" ) operador: FilterOperator = Field( default=FilterOperator.EQ, description="O operador do filtro de metadados.", description="A chave dos metadados a serem filtrados.") EQ, description="O operador do filtro de metadados." ) valor: Union[str, int, float, List[str], List[int], List[float]] = Field( ... , description="O valor dos metadados a serem filtrados." )
- Gráfico RAG
Em primeiro lugar, a extração de palavras-chave é realizada por meio do modelo, o que pode ser feito por meio da técnica tradicional de PNL para a divisão de palavras ou por meio do modelo grande para a divisão de palavras e, em seguida, as palavras-chave são feitas de acordo com os sinônimos para fazer a expansão, para encontrar a lista de palavras-chave candidatas, e é melhor chamar o método de exploração para recuperar os subgrafos locais de acordo com a lista de palavras-chave candidatas.
KEYWORD_EXTRACT_PT = ( "Dada a pergunta, extraia até " "palavras-chave do texto. Dada a pergunta, extraia até " "palavras-chave do texto. Concentre-se em extrair as palavras-chave que podemos usar " Concentre-se em extrair as palavras-chave que podem ser usadas " "para procurar as melhores respostas para a pergunta.\n" "Gerar o maior número possível de sinônimos ou apelidos das palavras-chave" "considerando possíveis casos de capitalização, pluralização, " "expressões comuns etc.\n" "Evite stopwords.\n" "Forneça as palavras-chave e os sinônimos em formato separado por vírgulas." "O texto formatado de palavras-chave e sinônimos deve ser separado por ponto e vírgula.\n" "\n" "---------------------\n" "Exemplo:\n" "Texto: Alice é a mãe de Bob.\n" "Palavras-chave:\nAlice,mother,Bob;mummy\n" "Texto: Philz é uma cafeteria fundada em Berkeley em 1982.\n" "Palavras-chave:\nPhilz,cafeteria,Berkeley,1982;café-bar,cafeteria\n" "---------------------\n" "Texto: {text}\n" "Palavras-chave:\n" ) def explore( self, subs. subs: List[str], direct: Direction = Direction. direct: Direction = Direction. depth: Optional[int] = None, fan: Optional[int] = None, fan: Optional[int] = None, limite: Optional[int] = None, ) -> Graph. """Explore em graph."""""
DBSchemaRetriever
Em parte, trata-se de uma pesquisa de vinculação de esquema para cenários de ChatDataPrincipalmente por meio do modo de vinculação de esquemas, por meio da recuperação de similaridade em dois estágios, primeiro encontre a tabela mais relevante e, em seguida, as informações de campo mais relevantes.
Prós: essa busca em dois estágios também tem o objetivo de atender aos comentários da comunidade sobre a experiência da mesa grande.
def _similarity_search(self, query, filters: Optional[MetadataFilters] = None) -> List[Chunk]. """Pesquisa semelhante.""" # Realizar pesquisa de similaridade com pontuações table_chunks = self._table_vector_store_connector.similar_search_with_scores( consulta, self._top_k, 0, filtros ) # Filtrar pedaços com metadados "separados not_sep_chunks = [ chunk for chunk in table_chunks if not chunk.metadata.get("separated") ] separated_chunks = [ chunk for chunk in table_chunks if chunk.metadata.get("separated") ] # Se não houver pedaços separados, retorne os pedaços não separados if not separated_chunks: return not_sep_chunks return not_sep_chunks # Criar lista de tarefas para recuperar campos de blocos separados tasks = [ lambda c=chunk: self._retrieve_field(c, query) for chunk in separated_chunks ] # Executar tarefas simultaneamente com um limite de simultaneidade de 3 separated_result = run_tasks(tasks, concurrency_limit=3) # Combinar e retornar os resultados return not_sep_chunks + separated_result
-
- table_vector_store_connector: responsável por recuperar a tabela mais relevante.
- field_vector_store_connector: responsável por recuperar os campos mais relevantes.
2. processamento de conhecimento, ideias de otimização de recuperação de conhecimento
Atualmente, os aplicativos de questionário inteligente RAG têm vários pontos problemáticos:
- Após a inclusão de mais e mais documentos na base de conhecimento, a pesquisa fica ruidosa e a precisão da recuperação não é alta
- Recalls incompletos e falta de completude
- Os recalls e a intenção de perguntas do usuário têm pouca relevância
- O fato de só poder responder a dados estáticos e não poder acessar o conhecimento de forma dinâmica leva a um aplicativo de resposta monótono e sem graça.
1. Otimização do processamento de conhecimento
O processamento de dados não estruturados/semiestruturados/estruturados está pronto para determinar o limite superior do aplicativo RAG, portanto, antes de tudo, é necessário fazer muito trabalho de ETL refinado no processamento do conhecimento, no estágio de indexação e na otimização principal da direção da ideia:
- Não estruturado -> Estruturado: organização de informações de conhecimento de forma estruturada.
- Extrair informações semânticas mais ricas e diversificadas.
1.1 Carregamento de conhecimento
Objetivo: A análise precisa de documentos é necessária para identificar diferentes tipos de dados de forma mais diversificada.
Recomendações de otimização:
- Recomenda-se que docx, txt ou outro texto seja processado antes do formato pdf ou markdown, para que você possa usar algumas ferramentas de reconhecimento para extrair melhor o conteúdo do texto.
- Extrai informações de tabela do texto.
- Preservar as informações de hierarquia de títulos de PDF e markdown para a próxima árvore de relacionamento hierárquico e outros métodos de indexação a serem preparados.
- Retenha links de imagens, fórmulas e outras informações, também processadas de maneira uniforme no formato markdown.
1.2 Fatie o pedaço o mais intacto possível
Objetivo: preservar a integridade e a relevância do contexto, o que está diretamente relacionado à precisão da resposta.
Mantendo-se dentro dos limites contextuais do modelo maior, o chunking garante que a entrada de texto nos LLMs não exceda seus limites de tokens.
Recomendações de otimização:
- Imagens + tabelas extraídas como blocos separados, mantendo as legendas das tabelas e das imagens nos metadados
- O conteúdo do documento é dividido o máximo possível de acordo com a hierarquia de cabeçalhos ou com o Markdown Header, preservando a integridade do bloco o máximo possível.
- Se houver um separador personalizado, você poderá cortar e dividir pelo separador personalizado.
1.3 Extração de informações diversificadas
Além da extração do vetor de incorporação de documentos, outras extrações de informações diversificadas podem aprimorar os dados dos documentos e melhorar significativamente o efeito de recuperação do RAG.
- mapa de conhecimento
-
- Vantagens: 1. Ao lidar com a falta de integridade do NativeRAG, ainda há o problema da ilusão, e a precisão do conhecimento, incluindo a integridade dos limites do conhecimento, a clareza da estrutura e da semântica do conhecimento, é um complemento semântico para a capacidade de recuperação de similaridade.
- Cenários: para domínios profissionais rigorosos (saúde, O&M etc.) em que a preparação do conhecimento precisa ser limitada e em que as relações hierárquicas entre os conhecimentos podem ser claramente estabelecidas.
- Como conseguir:
1) Depender do grande modelo para extrair o relacionamento ternário (entidade, relacionamento, entidade).
2) Confiar na preparação, limpeza e extração de conhecimento estruturado e de pré-qualidade por meio de regras de negócios por meio de um processo SOP manual ou personalizado para criar o gráfico de conhecimento.
-
- Árvore de Doces
-
- Cenários aplicáveis: resolve o problema de integridade contextual insuficiente, mas também faz correspondências com base apenas em semântica e palavras-chave, e pode reduzir o ruído
- Como fazer: construir um nó de árvore de pedaços no nível do título para formar uma estrutura de árvore multinomial, em que cada nó de nível só precisa armazenar o título do documento e os nós de folha armazenam o conteúdo de texto específico. Dessa forma, usando o algoritmo de passagem de árvore, se uma pergunta do usuário atingir um nó de título não-folha relevante, os dados do nó filho relevante poderão ser recuperados. Dessa forma, não há problema de deficiência na integridade dos blocos.
-
Essa parte do recurso também será colocada na comunidade no início do próximo ano.
- A extração de pares de controle de qualidade requer a extração de front-end de informações de pares de controle de qualidade por métodos de extração predefinidos ou de modelo
-
- Cenários aplicáveis:
-
-
- A capacidade de acertar a pergunta na recuperação e na recuperação direta, recuperar diretamente a resposta que o usuário deseja, aplicável a alguns cenários de perguntas frequentes, a integridade da recuperação não é suficiente.
-
-
- Como conseguir:
-
-
- Predefinido: adicione algumas perguntas para cada bloco com antecedência.
- Extração de modelo: dado um contexto, deixe o modelo realizar a extração de pares de QA.
-
- Extração de metadados
-
- Como fazer: de acordo com as características de seus próprios dados comerciais, extraia as características dos dados para retenção, como tags, categorias, tempo, versão e outros atributos de metadados.
- Cenários aplicáveis: a recuperação pode ser pré-filtrada com base em atributos de metadados para filtrar a maior parte do ruído.
- Resumir e extrair
-
- Cenários aplicáveis: resolução
Sobre o que é esse artigo?
(matemática) gêneroEm resumo.
e outros cenários de problemas globais. - Como implementar: extração segmentada por meio de mapreduce etc., extraindo informações resumidas para cada parte por meio de um modelo.
- Cenários aplicáveis: resolução
1.4 Fluxo de trabalho de processamento de conhecimento
Atualmente, a base de conhecimento DB-GPT oferece recursos de processamento de conhecimento, como upload de documentos -> análise -> fatiamento -> incorporação -> extração de tríade de gráfico de conhecimento -> armazenamento de banco de dados vetorial -> armazenamento de banco de dados gráfico etc., mas não tem a capacidade de extrair informações complexas e personalizadas de documentos, portanto, espera-se que a construção do modelo de fluxo de trabalho de processamento de conhecimento conclua os processos de extração, transformação e processamento de conhecimento complexos, visuais e definidos pelo usuário. Portanto, esperamos criar um modelo de fluxo de trabalho de processamento de conhecimento para concluir um processo de extração, conversão e processamento de conhecimento complexo, visual e definido pelo usuário.
Fluxo de trabalho de processamento de conhecimento:
https://www.yuque.com/eosphoros/dbgpt-docs/vg2gsfyf3x9fuglf
2. otimização do processo de RAG A otimização do processo de RAG é subdividida em RAG de documentos estáticos e RAG de aquisição de dados dinâmicos. A maior parte do RAG atual envolve apenas os ativos estáticos de documentos não estruturados, mas o negócio real de muitos cenários de P&R é por meio da ferramenta para obter dados dinâmicos + dados de conhecimento estático juntos para responder ao cenário, não apenas a necessidade de recuperar o conhecimento estático, mas também a necessidade de ser RAG Além de recuperar o conhecimento estático, o RAG também precisa recuperar as informações das ferramentas dentro da biblioteca de ativos da ferramenta e executar a aquisição de dados dinâmicos.
2.1 Otimização do RAG de conhecimento estático
(1) Tratamento do problema original
Objetivo: Esclarecer a semântica do usuário e otimizar a pergunta original do usuário de uma consulta difusa e mal definida para uma consulta recuperável que seja mais rica em significado.
- Classificação de problemas brutos, por meio da qual os problemas podem ser
-
- Classificação do LLM (
LLMExtractor
) - Criação de incorporação + regressão logística para implementar um modelo de duas torres, text2nlu DB-GPT-Hub/src/dbgpt-hub-nlu/README.zh.md at main - eosphoros-ai/DB-GPT-Hub
- Classificação do LLM (
-
-
- Dica: se você precisar de um modelo de incorporação de alta qualidade, recomende o bge-v1.5-large
-
- Pergunte de volta ao usuário e, se a semântica não estiver clara, envie a pergunta de volta ao usuário para esclarecimento, por meio de várias rodadas de interação
-
- Sugere uma lista de perguntas para o usuário com base na relevância semântica usando um dicionário de sinônimos pesquisável.
- Extração de slots, que visa obter as principais informações de slots na pergunta do usuário, como intenção, atributos comerciais, etc.
-
- Extração do LLM (
LLMExtractor
)
- Extração do LLM (
- Reescreva a pergunta
-
- Reescrevendo o Hot Search Thesaurus
- interação em várias camadas
(2) Filtragem de metadados
Quando dividimos o índice em muitos blocos e eles são armazenados no mesmo espaço de conhecimento, a eficiência da recuperação se torna um problema. Por exemplo, quando os usuários solicitam informações sobre a "Zhejiang I Wu Technology Company", eles não querem recuperar informações sobre outras empresas. Portanto, se você puder filtrar primeiro pelo atributo de metadados do nome da empresa, isso aumentará muito a eficiência e a relevância.
async def aretrieve( self, query: str, async consulta: str, assíncrono filtros: Optional[MetadataFilters] = None ) -> List[Chunk]. """ Recupera pedaços de conhecimento. Args. Args: query (str): texto de consulta assíncrona. filters (Optional[MetadataFilters]): filtros de metadados. Retorna: List[Chunk]: lista de blocos. List[Chunk]: lista de pedaços """ return await self._aretrieve(query, filters)
(3) Recuperação híbrida de múltiplas estratégias
- Definir prioridades para diferentes recuperadores, de acordo com a prioridade de recuperação, e retornar o conteúdo assim que ele for recuperado
-
- Defina diferentes recuperações, como qa_retriever, doc_tree_retriever, a serem gravadas na fila e obtenha recuperação prioritária por meio da propriedade first-in-first-out da fila.
-
classe RetrieverChain(BaseRetriever). """Classe da cadeia Retriever."""" def __init__( self, retrievers: Optional[List[BaseRetriever]] = None, None retrievers: Optional[List[BaseRetriever]] = None, executor: Optional[Executor] = None, ). """Criar instância de cadeia de recuperadores."""" self._retrievers = retrievers ou [] self._executor = executor ou ThreadPoolExecutor() async def retrieve(self, query: str, score_threshold: float, filters: Optional[dict] = None). """Executa a recuperação com a consulta, o limite de pontuação e os filtros fornecidos."""" for retriever in self._retrievers. candidates_with_scores = await retriever.aretrieve_with_scores( query=query, score_threshold=score_threshold, filters=filters ) se candidates_with_scores. return candidates_with_scores
- Indexação de múltiplos conhecimentos/recuperação paralela espacial
-
- Obtenção de listas de candidatos por meio de recuperação paralela através de diferentes formas de indexação de conhecimento para garantir a integridade da recuperação
-
(4) Pós-filtragem
Depois de passar pela lista de candidatos da triagem grosseira, como você filtra o ruído por meio da triagem fina?
- Eliminação de fatias de candidatos irrelevantes
-
- Rejeição de pontualidade
- Os atributos de negócios não satisfazem a seleção
-
- desduplicação de topk
- Reordenação Não basta confiar na recuperação da triagem grosseira; nesse momento, precisamos ter algumas estratégias para reordenar os resultados recuperados, por exemplo, reajustar alguns fatores, como combinação, relevância, correspondência etc., para obter uma ordenação mais alinhada com nossos cenários de negócios. Como após essa etapa, enviaremos os resultados ao LLM para o processamento final, os resultados dessa parte são muito importantes.
- Triagem fina usando modelos de reordenação relevantes, modelos de código aberto ou modelos com ajuste fino de semântica comercial.
## Modelo de Rerank # RERANK_MODEL = bce-reranker-base ##### Se você não definir RERANK_MODEL_PATH, o DB-GPT lerá o caminho do modelo de EMBEDDING_MODEL_CONFIG com base em RERANK_MODEL. # RERANK_MODEL_PATH = /Users/chenketing/Desktop/project/DB-GPT-NEW/DB-GPT/models/bce-reranker-base_v1 ##### O número de resultados do rerank a serem retornados # RERANK_TOP_K = 5
-
- Seleção de pontuação composta ponderada por RRF de negócios com base em diferentes recalls indexados
pontuação = 0,0 for q in queries: if d in result(q) if d in result(q): score += 1,0 / (k + rank(result(q), d)) pontuação += 1,0 / (k + classificação (resultado (q), d)) return score # onde. # k é uma constante de classificação # q é uma consulta no conjunto de consultas # d é um documento no conjunto de resultados de q # result(q) é o conjunto de resultados de q # rank(result(q), d) é a classificação de d no result(q), começando em 1
(5) Otimização de exibição + Touting / Liderança de tópico
- Obter a saída do modelo usando a formatação markdown
Com base nas informações conhecidas fornecidas abaixo, siga as restrições normativas e responda às perguntas do usuário de forma profissional e breve. Restrições normativas: 1. se as informações conhecidas contiverem imagens, links, tabelas, blocos de código e outros formatos especiais de tag markdown, certifique-se de incluir o texto original dessas imagens, links, tabelas e tags de código em sua resposta e não os descarte ou modifique, por exemplo: - Formato da imagem: `! [image.png](xxx)` - Formato do link: `[xxx](xxx)` - Formato de tabela: `|xxx|xxx|xxx|` - Formato de código: ```xxx``. 2. se a resposta não puder ser obtida com o conteúdo fornecido, diga: ``O conteúdo fornecido na base de conhecimento não é suficiente para responder a essa pergunta''; é proibido inventar coisas. 3) De preferência, as respostas devem ser resumidas de acordo com o item 1.2.3 e exibidas no formato Markdown.
2.2 Otimização do RAG de conhecimento dinâmico
O conhecimento da documentação é relativamente estático, não pode responder a informações personalizadas e dinâmicas, precisa contar com algumas ferramentas de plataformas de terceiros para responder. Com base nessa situação, precisamos de uma abordagem RAG dinâmica, por meio da definição de ativos de ferramentas -> seleção de ferramentas -> validação de ferramentas -> execução de ferramentas para obter dados dinâmicos.
(1) Biblioteca de ativos de ferramentas
Crie uma biblioteca de ativos de ferramentas de domínio corporativo para integrar APIs de ferramentas, scripts de ferramentas espalhados por várias plataformas e, assim, fornecer recursos de uso de ponta a ponta para inteligências. Por exemplo, além da base de conhecimento estática, podemos processar ferramentas importando bibliotecas de ferramentas.
(2) Recall de ferramentas
A recuperação de ferramentas segue a ideia da recuperação RAG para conhecimento estático e, em seguida, o ciclo de vida completo da execução da ferramenta é usado para obter os resultados da execução da ferramenta.
- Extração de slots: obtenha LLM por meio de nlp tradicional para analisar o problema do usuário, incluindo tipos de negócios comuns, marcadores de ambiente, parâmetros de modelo de domínio, etc.
- Seleção de ferramentas: chamada de acordo com as linhas do RAG estático com duas camadas principais, chamada do nome da ferramenta e chamada do parâmetro da ferramenta.
-
- O Tool Parameter Recall, cuja ideia é semelhante à do TableRAG, recupera primeiro o nome da tabela e depois o nome do campo.
-
- Preenchimento de parâmetros: é necessário fazer a correspondência dos parâmetros extraídos dos slots de acordo com as definições dos parâmetros da ferramenta dos recalls
-
- Você pode codificar para preenchê-lo ou pode fazer com que o modelo o preencha.
- Ideias de otimização: como os nomes dos mesmos parâmetros das várias ferramentas da plataforma não são unificados e não é conveniente ir até a governança, sugere-se que primeiro seja realizada uma rodada de expansão dos dados do modelo de domínio e, depois de obter todo o modelo de domínio, os parâmetros necessários estarão presentes.
-
- calibração de parâmetros
-
- Verificação de integridade: realiza a verificação de integridade no número de parâmetros
- Verificação de regras de parâmetros: executa a verificação de regras no tipo de nome de parâmetro, valor de parâmetro, enumeração etc.
-
- Correção/alinhamento de parâmetros: essa parte tem como objetivo principal reduzir o número de interações com o usuário, a conclusão automatizada da correção de erros de parâmetros do usuário, incluindo regras de caso, regras de enumeração etc., por exemplo.
2.3 Revisão do RAG
Ao avaliar o processo de Q&A inteligente, a precisão da relevância da recordação e a relevância do modelo de Q&A precisam ser avaliadas separadamente e, em seguida, consideradas em conjunto para determinar onde o processo de RAG ainda precisa ser aprimorado.
Avaliação de indicadores:
EvaluationMetric LLMEvaluationMetric │ ├── AnswerRelevancyMetric RetrieverEvaluationMetric │ ├─── RetrieverSimilarityMetric │ ├─── RetrieverMRRMetric │ └── RetrieverHitRateMetric
RAG
RetrieverEvaluationMetric:-
RetrieverHitRateMetric
:: A taxa de acerto mede o RAGretriever
A proporção de recalls que aparecem nos principais documentos dos resultados de recuperação.RetrieverMRRMetric
:Classificação recíproca média
A precisão de cada consulta é calculada analisando a classificação dos documentos mais relevantes nos resultados da pesquisa. Mais especificamente, é a média da classificação inversa dos documentos relevantes para todas as consultas. Por exemplo, se o documento mais relevante for classificado em primeiro lugar, sua classificação inversa será 1; se for classificado em segundo lugar, será 1/2; e assim por diante.RetrieverSimilarityMetric
Métricas de similaridade: as métricas de similaridade são calculadas para calcular a similaridade entre o conteúdo recuperado e o conteúdo previsto.
-
Geração de modelos
Indicador de resposta.
AnswerRelevancyMetric
: métrica de relevância da resposta do corpo inteligente, que mede a correspondência da resposta do corpo inteligente com a pergunta do usuário. Uma resposta de alta relevância não só exige que o modelo compreenda a pergunta do usuário, mas também que ele gere uma resposta que esteja intimamente relacionada à pergunta. Isso afeta diretamente a satisfação do usuário e a utilidade do modelo.
3.Compartilhamento de casos de aterrissagem RAG
1. RAG na área de infraestrutura de dados
1.1 Histórico do órgão de inteligência de O&M
No espaço da infraestrutura de dados, há muitos SREs de operações que recebem um grande número de alertas todos os dias, portanto, muito tempo é gasto respondendo a emergências, o que, por sua vez, leva à solução de problemas e, em seguida, à revisão da solução de problemas, o que, por sua vez, leva à experiência. Outra parte do tempo é gasta respondendo a consultas de usuários, exigindo que eles respondam a perguntas com seu conhecimento e experiência de uso das ferramentas.
Portanto, esperamos resolver esses problemas de diagnóstico de alarme e resposta a perguntas criando uma inteligência geral para a infraestrutura de dados.
1.2 RAG rigoroso e profissional
A tecnologia tradicional RAG + Agent pode resolver cenários de tarefas de uma única etapa, de uso geral e menos determinísticos. No entanto, ao enfrentar cenários profissionais no campo da infraestrutura de dados, todo o processo de recuperação deve ser determinístico, profissional e realista, e requer um raciocínio passo a passo.
À direita, há um resumo generalizado por meio do NativeRAG, que pode ser uma informação útil para um usuário C-suite que não tenha muito conhecimento do domínio e, para um profissional, essa parte da resposta não fará muito sentido.
Portanto, comparamos a diferença entre as inteligências genéricas e as inteligências de infraestrutura de dados em relação ao RAG:
- Inteligências de uso geral: os RAGs tradicionais não exigem tanto rigor intelectual e conhecimento especializado e são adequados para alguns cenários de negócios, como atendimento ao cliente, turismo e bots de plataforma de perguntas e respostas.
- Corpo de inteligência da infraestrutura de dados: o processo RAG é rigoroso e profissional, exigindo fluxos de trabalho RAG exclusivos com contextos que incluem (Alerta -> Localizar -> Parar o sangramento -> Recuperar) e extração estruturada de perguntas e respostas e experiência de resposta a emergências precipitada por especialistas para estabelecer relações hierárquicas. Por isso, escolhemos o Knowledge Graph como portador de dados.
1.3 Processamento de conhecimento
Com base no determinismo e na especificidade da infraestrutura de dados, optamos por usá-la como portadora de conhecimento para diagnosticar experiências de resposta a emergências por meio da combinação de gráficos de conhecimento. Nossa experiência de conhecimento de eventos de solução de problemas de emergência precipitados pelo SRE Combinado com o processo de revisão de emergência, estabelecemos um gráfico de conhecimento orientado por eventos de emergência de BD, tomamos o jitter do BD como exemplo, vários eventos que afetam o jitter do BD, incluindo problemas de SQL lento, problemas de capacidade, estabelecemos relações entre cada evento de emergência.
Por fim, estabelecemos um sistema de processamento de conhecimento padronizado de conhecimento de várias fontes -> extração estruturada de conhecimento -> extração de relacionamento de emergência -> revisão especializada -> armazenamento de conhecimento, passo a passo, normalizando as regras de eventos de emergência.
1.4 Recuperação de conhecimento
Na fase de recuperação inteligente de corpos, usamos o GraphRAG como portador da recuperação de conhecimento estático; portanto, depois de identificar a anomalia de jitter do BD, encontramos os nós relacionados ao nó de anomalia de jitter do BD como base de nossa análise, pois cada nó também retém algumas informações de metadados para cada evento na fase de extração de conhecimento, incluindo o nome do evento, a descrição do evento, as ferramentas relacionadas, os parâmetros da ferramenta e assim por diante.
Portanto, podemos obter os resultados de retorno por meio do link do ciclo de vida da execução da ferramenta de execução para obter os dados dinâmicos a serem usados como base do diagnóstico de emergência para solução de problemas. Por meio dessa abordagem de recall híbrido dinâmico e estático, a certeza, o profissionalismo e o rigor da execução das inteligências de infraestrutura de dados são garantidos em comparação com o recall RAG puro e simples.
1,5 AWEL + Agente
Por fim, por meio da tecnologia comunitária AWEL+AGENT, o paradigma da orquestração AGENT foi usado para criar um especialista de intenção -> especialista em diagnóstico de emergência -> especialista em análise de causa raiz do diagnóstico.
Cada agente tem uma função diferente. O especialista em intenção é responsável por identificar e analisar a intenção do usuário e identificar mensagens de alerta. O especialista em diagnóstico precisa localizar o nó de causa raiz a ser analisado por meio do GraphRAG e obter informações específicas sobre a causa raiz. O especialista em análise precisa combinar os dados de cada nó de causa raiz + relatório de revisão de análise histórica para gerar um relatório de análise de diagnóstico.
2. RAG na área de análise de relatórios financeiros
Última prática! Como criar um assistente de análise de relatórios financeiros com base no DB-GPT?
Você pode criar seu próprio repositório de ativos de domínio, incluindo ativos de conhecimento, ativos de ferramentas e ativos de gráficos de conhecimento sobre seu domínio.
- Ativos de domínio: os ativos de domínio incluem bases de conhecimento, APIs e scripts de ferramentas.
- Processamento de ativos, todo o link de dados de ativos envolve o processamento de ativos de domínio, a recuperação de ativos de domínio e a avaliação de ativos de domínio.
-
- Não estruturado -> Estruturado: categorizado de forma estruturada, informações de conhecimento corretamente organizadas.
- Extrair informações semânticas mais ricas.
-
- Recuperação de ativos:
-
- Esperamos que seja uma pesquisa em cascata e priorizada, em vez de uma única pesquisa
- A pós-filtragem é importante, de preferência por meio da semântica comercial de algumas regras.
-