Buscar/Crie um sistema que lê documentos enviados e permite que agentes de IA os pesquisem

Crie um sistema que lê documentos enviados e permite que agentes de IA os pesquisem

Para criar um serviço que recebe PDFs e outros arquivos para busca com IA. Envia cada arquivo a um analisador adequado, mantém títulos e tabelas, salva trechos em formato fixo e busca dentro de um orçamento, retornando evidências com citações.

Para usar estas regras de IA
## Nomeie branches de forma clara e separe o código de API, workers e compartilhado Torne a responsabilidade visível antes de alterar o código, para que cada comportamento permaneça na camada capaz de testá-lo e mantê-lo. ### Usar ramificações rastreáveis - Nomeie as ramificações conforme `type/user/description pattern`. - Mantenha `type` em minúsculas e escolha uma classe de mudança reconhecida, como `feat`, `fix`, `refactor`, `chore`, `docs`, `test`, `perf`, `ci`, `build` ou `revert`. - Use em `user` a pessoa responsável pelo trabalho; nunca a substitua pelo nome genérico de um agente ou de uma ferramenta. - Mantenha `description` curta, em minúsculas e no formato kebab-case. ### Separar as responsabilidades de execução - Mantenha em pacotes distintos o processamento síncrono da API, o trabalho assíncrono com documentos, os modelos e serviços compartilhados e as questões de implantação. - Coloque a orquestração de endpoints, as regras de negócio, a persistência, a análise, a recuperação e os utilitários genéricos em módulos com responsabilidade explícita; trate SDKs distribuídos de forma independente como produtos separados. - Quando um comportamento atravessar pacotes, defina primeiro o contrato compartilhado e teste cada implementação responsável. ## Direcione cada arquivo recebido a um analisador adequado ao formato Use um pipeline em etapas para que cada documento percorra um caminho visível desde o upload até evidências de recuperação que possam ser citadas. 1. Aceite o upload, crie um trabalho, persista o objeto de origem e enfileire o processamento assíncrono. 2. Analise o perfil do documento uma única vez e encaminhe-o a um analisador conforme o tipo de arquivo e as evidências estruturais. 3. Converta a saída do analisador em um único contrato tabular tipado. 4. Converta as linhas em registros de fragmentos tipados. 5. Publique os estados do documento, das seções, dos fragmentos e do grafo antes da recuperação. ### Manter explícito o roteamento dos analisadores - Use um único ponto de entrada tipado para os analisadores de todos os formatos e retorne caminhos de artefatos locais à tarefa. - Encaminhe entradas PDF, DOCX, PPTX, de planilha, Markdown, texto, imagem e fragmentos brutos por estratégias específicas para cada formato; converta formatos antigos de arquivos de escritório antes de usar o analisador moderno. - Em PDFs, separe a classificação semântica aberta das categorias usadas apenas para roteamento, como atlas, documento digitalizado, apresentação e documento genérico. - Execute a análise estrutural uma única vez no ponto de entrada de documentos grandes demais e passe o plano de fragmentação resultante para as etapas posteriores. - Após a análise, remova imagens não referenciadas e aplique uma compactação determinística de imagens. ## Detecte a hierarquia de títulos e mantenha tabelas e imagens na conversão Determine a estrutura pelas evidências disponíveis mais fortes e preserve tabelas, imagens e relações entre cabeçalhos durante a conversão. ### Resolver cabeçalhos segundo a ordem das evidências 1. Use um sumário incorporado como fonte de verdade quando estiver disponível. 2. Identifique padrões explícitos de numeração e marcadores de capítulo específicos do idioma. 3. Use um modelo de hierarquia com LLM apenas para candidatos a cabeçalho que ainda não tenham sido resolvidos. 4. Em PDFs com layout complexo, agrupe a geometria das fontes em um conjunto limitado de níveis de cabeçalho. ### Preservar o comportamento específico de cada formato - Percorra os elementos do corpo do DOCX na ordem da origem, incluindo parágrafos, tabelas, imagens e regiões do sumário. - Mantenha uma pilha de cabeçalhos que feche os descendentes quando um novo cabeçalho retornar ao nível do pai. - Converta tabelas em HTML com valores precisos de `rowspan` e `colspan` e elimine imagens duplicadas com um hash perceptual. - Encaminhe PDFs padrão para extração e análise de Markdown; encaminhe documentos semelhantes a atlas ou grandes demais para seus caminhos especializados. - Mantenha a sumarização, o reconhecimento de hierarquia, a descrição de imagens, o OCR e a classificação ampla em chaves separadas de configuração do modelo. ## Salve trechos, navegação e manifesto em formato fixo Trate o corpus persistido como a fonte oficial; DataFrames intermediários são detalhes transitórios de implementação. ### Armazenar o estado do corpus e dos documentos - Mantenha os metadados do grafo de todo o corpus e as estatísticas de acertos da recuperação ao lado de um diretório para cada documento ingerido. - Persista fragmentos ordenados, navegação hierárquica, metadados de análise, a árvore completa de cabeçalhos, recursos de origem arquivados, imagens e tabelas extraídas e saídas de diagnóstico. - Use exatamente três tipos principais de fragmento: `text`, `image` e `table`. - Atribua a cada fragmento um `chunk_id` determinístico, conteúdo tipado, um caminho hierárquico e metadados de comprimento, resumos, números de página, tokens, palavras-chave, caminhos de arquivos e referências entre fragmentos. ### Preservar referências e navegação - Represente relações embutidas por entradas `connect_to` que contenham `target`, `relation`, `ref` e a `position` expressa como deslocamento de caracteres. - Use `embeds` para recursos embutidos e `related` para associações não embutidas. - Crie `doc_nav.json` como uma árvore de seções com resumos, quantidades de fragmentos, filhos e recursos de imagem ou tabela. - Crie `manifest.json` com metadados da origem, estatísticas e uma `HIERARCHY` aninhada. - Converta linhas transitórias do analisador em cargas de fragmentos tipadas antes de gravar `chunks.json`. ## Publique juntos registros do banco de dados, índices de busca e ligações do grafo Publique uma revisão coerente para que os registros relacionais, os canais de pesquisa e as arestas do grafo descrevam o mesmo conjunto de fragmentos. ### Manter a responsabilidade pelos dados relacionais - Armazene no nível do documento sua identidade, proprietário, namespace, estado, revisão ativa e nome do arquivo de origem. - Armazene links para os pais, caminhos, títulos, níveis, resumos e ordem de classificação em uma árvore de seções que reconheça a revisão. - Armazene para cada fragmento os hashes de conteúdo, os tipos de fragmento, o texto pesquisável, os caminhos de origem, os caminhos de recursos, os metadados e a ordem de classificação. - Mantenha os nós do grafo no escopo do documento e use arestas não direcionadas quando elas representarem relações simétricas. ### Publicar em uma sequência fixa 1. Elimine fragmentos duplicados entre documentos por meio de um hash determinístico do conteúdo. 2. Crie as seções ancestrais a partir dos caminhos dos fragmentos, de cima para baixo. 3. Gere para cada fragmento canais separados de pesquisa por conteúdo, caminho e termos brutos. 4. Crie nós no grafo do documento e arestas por sobreposição de palavras-chave apenas quando houver pelo menos 3 palavras-chave compartilhadas e a pontuação for de no mínimo 0.8. Use conteúdo tokenizado com resumos na pesquisa por conteúdo, nomes de arquivo e caminhos de seção tokenizados na pesquisa por caminho e conteúdo e caminhos brutos na pesquisa por substring. ## Ofereça busca clássica por ranking e busca com agentes dentro de um orçamento Separe por responsabilidade a preparação de solicitações, a pesquisa lexical, a hidratação, o acesso ao grafo, as estatísticas de acertos, a execução de fluxos de trabalho, a navegação e a renderização de evidências. ### Preservar os dois modos de recuperação - No modo legado, combine os canais de caminho, conteúdo e termos por fusão de classificação recíproca. - Use os pesos padrão de canal `path=1.0`, `content=2.0` e `term=1.5`, com `score = weight / (k + rank + 1)` e `k=60`. - No modo baseado em agentes, permita que um planejador decomponha consultas complexas em um DAG de etapas de recuperação; não planeje etapas de síntese de respostas dentro da recuperação. - Aplique um único orçamento de tokens a todo o DAG. Quando ele se esgotar, pare com segurança e retorne as melhores evidências coletadas até então. - Execute descoberta, navegação de seções em largura com restrições e renderização de evidências como fases distintas. - Exponha `evidence_text` como a resposta principal e mantenha o `answer_text` descontinuado apenas como um campo de compatibilidade vazio. ### Hidratar e classificar deliberadamente - Renderize seções não abertas como esboços de título e resumo e hidrate fragmentos `text`, `image` e `table` brutos apenas para as folhas selecionadas. - Resolva de forma nativa os recursos conectados e incorpore-os em linha sem marcadores frágeis baseados em substituição de strings. - Classifique os resultados do agente primeiro por `agent_score` e depois por `discovery_score`; rebaixe as linhas com `agent_score=0` para um grupo alternativo. - Antes da montagem, exclua os documentos e as seções indicados e limite o resultado aos tipos de fragmento permitidos. - Anexe citações que contenham `document_id`, `chunk_id`, `source_file_name` e `section_path`. ## Mantenha os IDs dos trechos estáveis e guarde no cache só resultados bem-sucedidos Torne explícitos os atalhos, os identificadores, a ordem das mutações e a telemetria para que as otimizações não alterem a semântica da recuperação. ### Manter resultados reproduzíveis - Derive IDs de fragmentos apenas de um hash estável do conteúdo textual, excluindo referências a imagens e tabelas, para que conteúdos idênticos sejam desduplicados entre uploads. - Planeje primeiro as mutações do DOM e depois as aplique em ordem inversa para evitar deslocamentos de índices. - Elimine imagens iguais dentro de um documento por hash perceptual e reutilize os metadados em cache. - Dê às imagens repetidas em posições diferentes IDs determinísticos, porém únicos, e avance além de identificadores binários ao procurar o contexto textual próximo. ### Limitar atalhos e caches - Quando `total_chunks <= top_k`, retorne todos os fragmentos diretamente por uma rota explícita para corpus pequenos. - Armazene em cache por usuário, namespace, consulta, `top_k` e filtros; verifique a versão do cache antes da execução e grave somente após o sucesso. - Registre acertos por fragmento e por documento para melhorar a classificação sem alterar o conteúdo de origem. - Mantenha registros de execuções e etapas que aceitem apenas acréscimos para as ações, entradas, saídas, latência e uso de tokens do agente. ## Trate as particularidades da API do LLM e verifique localmente antes de concluir Mantenha explícitas as restrições dos modelos e os comandos de verificação local para que as falhas continuem diagnosticáveis. ### Fortalecer as integrações de modelos - Inclua a palavra `json` ao solicitar o modo `json_object` do DeepSeek. - Durante a transmissão, concatene `delta.content` somente quando não for `None`. - Alterne tokens de API dentro dos limites de taxa de cada token, aplique períodos de espera e repita no mesmo ponto com o próximo token disponível. - Mantenha a recuperação limitada a evidências; os agentes posteriores decidem se elas são suficientes e sintetizam respostas fora do serviço de recuperação. ### Verificar o sistema localmente - Instale a partir do workspace com versões fixadas, copie localmente os arquivos-modelo de ambiente e inicie os serviços necessários de banco de dados, cache, armazenamento de objetos, API e processamento. - Forneça comandos de depuração de ponta a ponta focados em analisador, perfilador, hierarquia e processamento baseado em agentes; depois execute lint, correções automáticas seguras e verificações de tipo nos pacotes de API, processamento e componentes compartilhados. - Verifique a documentação da API local e os endpoints dos serviços subjacentes antes de diagnosticar falhas da camada superior no pipeline. - Não informe a conclusão até obter resultados diretos do analisador afetado, do caminho de publicação, do modo de recuperação e das verificações de qualidade.