Desenvolva um aplicativo de perguntas e respostas para cenários educacionais usando a base de conhecimento do Alibaba Cloud Milvus. Essa base transforma livros didáticos, planos de aula, questões e gabaritos em um assistente de banco de questões pesquisável: os alunos fazem perguntas em linguagem natural e recebem explicações acompanhadas de citações do material original. Também é possível enviar a imagem de uma questão para localizar itens semelhantes no banco, combinando-os com as explicações do livro didático.
Visão geral da solução
O pipeline de ponta a ponta é idêntico ao descrito em Criar um aplicativo inteligente de perguntas e respostas para atendimento ao cliente com a base de conhecimento do Alibaba Cloud Milvus: definir tags no console → importar materiais em massa por tag → publicar uma versão → recuperação via SDK (com suporte a filtragem por tags e anexo de imagens) → o LLM gera respostas com citações das fontes → o Flask serve a página de perguntas e respostas. Este tutorial reutiliza diretamente o código do projeto daquele tutorial. Este tópico descreve apenas as partes que mudam para cenários educacionais: tags de disciplina e ponto de conhecimento, tratamento de materiais com imagens, limites de capacidade das consultas por imagem e exibição de fórmulas.
Para a primeira versão, selecione apenas de 5 a 20 materiais de uma única série e disciplina e expanda após a validação. Todo o processo leva cerca de 25 a 40 minutos. O tempo de processamento dos documentos depende da quantidade e do tamanho dos materiais.
Pré-requisitos
-
Você concluiu o tutorial Criar um aplicativo inteligente de perguntas e respostas para atendimento ao cliente com a base de conhecimento do Alibaba Cloud Milvus. Este tutorial reutiliza os seguintes arquivos de código daquele projeto:
kb_client.py,upload.py,app.py,templates/index.htmlestart.shO arquivo de configuração
config.json
-
Uma base de conhecimento multimodal (
ALL_MODAL) do Milvus, com o ID da base de conhecimento registrado (por exemplo,kd-803ae9b10cc31). Crie uma nova base de conhecimento para este tutorial ou reutilize a do tutorial de atendimento ao cliente. Observe o seguinte:O tipo da base de conhecimento não pode ser alterado após a criação.
Uma base de conhecimento estruturada aceita apenas cinco formatos: xlsx, xls, csv, jsonl e faq. O upload direto de uma imagem retorna um erro de parâmetro. Portanto, um banco de questões que contenha materiais com imagens deve usar uma base de conhecimento multimodal.
Atualmente, o console sempre usa o tipo multimodal (
ALL_MODAL) ao criar bases de conhecimento. Como não há outra opção na página, nenhuma decisão extra é necessária. Para verificar o tipo de uma base existente, visualize o campo Data Type em Basic Information na página de detalhes da base de conhecimento.
Um usuário RAM para sua conta Alibaba Cloud. Selecione Access with a permanent AccessKey para o usuário RAM e conceda a política de sistema
AliyunMilvusFullAccess.Um endpoint de LLM compatível com o protocolo OpenAI
chat/completionse uma chave de API.Python 3.8 ou posterior instalado localmente.
Etapa 1: Definir tags de série e ponto de conhecimento
Na seção Basic Information da página de detalhes da base de conhecimento, escolha Tags > Manage e adicione as quatro tags a seguir. Todas as tags são do tipo string.
|
Nome da tag |
Descrição |
Exemplo de valor |
|
grade |
Série |
Grade 8 |
|
subject |
Disciplina |
Mathematics, Physics |
|
knowledgePoint |
Ponto de conhecimento |
quadratic function, Pythagorean theorem |
|
questionType |
Tipo de material |
textbook, practice question, ground truth |
Os valores das tags aceitam caracteres em chinês. Você pode usar diretamente os nomes em chinês para séries, disciplinas e pontos de conhecimento.
A caixa de diálogo de gerenciamento de tags é salva como um todo. Após a abertura da caixa, a lista de tags carrega de forma assíncrona. Aguarde até que todas as tags existentes sejam exibidas antes de adicionar novas tags e clicar em OK. Caso contrário, toda a lista poderá ser sobrescrita por uma lista vazia mais as novas tags, e as definições de tags existentes serão excluídas.
Etapa 2: Preparar materiais e o manifesto de importação
Coloque seus materiais no diretório
documents/. Há suporte para PDF, DOCX, Markdown, TXT e imagens. Faça o upload de livros didáticos, questões e gabaritos como um conjunto: ao gerar explicações, o modelo cita métodos do livro didático, o texto original da questão e os critérios de pontuação da resposta simultaneamente, tornando as respostas significativamente mais completas.-
Crie o arquivo
documents.jsonle anote cada material com a série, disciplina, ponto de conhecimento e tipo de material.{"path": "documents/math-grade8-textbook.pdf", "metadata": {"grade": "Grade 8", "subject": "Mathematics", "knowledgePoint": "quadratic function", "questionType": "textbook"}} {"path": "documents/math-quadratic-problem.png", "metadata": {"grade": "Grade 8", "subject": "Mathematics", "knowledgePoint": "quadratic function", "questionType": "practice question"}} {"path": "documents/math-quadratic-answers.docx", "metadata": {"grade": "Grade 8", "subject": "Mathematics", "knowledgePoint": "quadratic function", "questionType": "ground truth"}} {"path": "documents/math-pythagorean-exercise.docx", "metadata": {"grade": "Grade 8", "subject": "Mathematics", "knowledgePoint": "Pythagorean theorem", "questionType": "practice question"}} -
Para materiais com imagens, compreenda como ocorre a importação. As imagens passam primeiro por reconhecimento óptico de caracteres (OCR) para conversão em texto; em seguida, o texto é fragmentado e indexado. Portanto:
A possibilidade de reconhecer o texto de uma imagem determina se ela pode ser recuperada. Uma imagem sem texto, como uma figura geométrica ou gráfico de função sem rótulos, dificilmente será encontrada e não é adequada para upload como material isolado. Coloque-a na mesma imagem ou no mesmo documento que o enunciado da questão que contém texto.
Mantenha as imagens das questões nítidas, com tamanho de fonte adequado e preferência por texto impresso. Os resultados de reconhecimento podem apresentar desvios. Por exemplo, a vírgula ideográfica (、) pode ser reconhecida como outro símbolo, ou a variável
xcomo o sinal de multiplicação×. Símbolos matemáticos são especialmente suscetíveis a isso.
Ajuste a granularidade de fragmentação. Questões e explicações são majoritariamente itens curtos. Em Processing Strategy na página de detalhes da base de conhecimento, clique em Create Strategy para ajustar a granularidade. A unidade do comprimento máximo do fragmento é caracteres (padrão 512). Defina entre 580 e 770 caracteres (cerca de 384 a 512 tokens) para que o enunciado e a explicação permaneçam no mesmo fragmento sempre que possível.
-
semantic_weight=0.75comqwen3-rerankativado: as perguntas dos alunos são majoritariamente descrições em linguagem natural de problemas, e um peso semântico maior favorece a correspondência com questões semelhantes.Note que a pontuação de reranking e a pontuação vetorial não estão na mesma escala. A pontuação final é calculada como
score ≈ (1-semantic_weight) × keywordScore + semantic_weight × semanticScore(um recurso de classificação também pode ser adicionado). Quando o reranking está desativado,semanticScorerepresenta a similaridade vetorial. Quando o reranking está ativado, torna-se a pontuação do modelo de reranking, emin_scoresempre filtra com base nessa pontuação final. Nos testes, ativar o reranking reduziu o número de resultados para a mesma pergunta de 5 para 4. Esse é o efeito combinado do limiar e da nova escala; não significa que o reranking piora o recall.Não existe uma combinação recomendada que generalize para todos os corpora. Primeiro defina
min_scorecomo 0 para recuperar um lote de resultados e rotule manualmente sua relevância; depois, escolha um limiar com base na distribuição de recall e falsos positivos. Recalibre sempre que trocar o modelo de reranking, alternar o reranking ou ajustarsemantic_weight. Fixar
subjectemtag_filterevita eficazmente falsos recalls entre disciplinas. Nos testes, perguntar sobre um ponto de conhecimento de física sob o filtrosubject=Mathematicsretornou 0 resultados, e o modelo respondeu "material insuficiente" seguindo o prompt.-
Para
op, apenas os três operadores =, in e not in têm efeito real. Aliases comoeq,==,equaloulikeretornam400 Unsupported tag filter operatore causam falha em todas as consultas. Embora≠,>,<,≥,≤,empty,not empty,start witheend withapareçam na lista "Supported operators" dessa mensagem de erro, nos testes as condições são ignoradas silenciosamente e todos os dados não filtrados são retornados.Observe que
containsenot containssão meramente aliases parain/not in. Eles não realizam verificação de substring, e passar um fragmento de string como valor retorna 0 resultados.Para filtrar por intervalo, enumere os valores com
in. Para verificar se uma tag está vazia, use= "". Após configurar, sempre compare o número total de resultados com e sem o filtro para confirmar que ele está funcionando. No
system_prompt, declare explicitamente "formulas in plain text". Prompts educacionais tendem a fazer o modelo gerar LaTeX, mas a página de exemplo exibe texto simples com<pre>, então as fórmulas não renderizam e aparecem como cifrões e barras invertidas brutos. Se quiser manter LaTeX, integre KaTeX ou MathJax à página.-
Faça o upload dos materiais.
MetaFieldsaplica-se a todo o lote; o script agrupa os materiais por tag primeiro e os envia em lotes.python upload.py --manifest documents.jsonl Na página Data Management do console, confirme se o status do material é Processed. Para materiais com imagens, clique em View Chunks e confirme se o texto reconhecido corresponde ao conteúdo da imagem antes de publicar uma versão.
-
Na página Version Management, clique em Publish Version. Após concluir o assistente de três etapas, confirme se o status da nova versão é Published.
ImportantePodem existir no máximo três versões publicadas simultaneamente. Ao atingir o limite, o botão Publish Version fica desabilitado, mas a página ainda mostra "There are currently N pending changes to publish". Você deve primeiro excluir versões antigas que não são mais necessárias nos registros de versão. A exclusão de versão não pode ser desfeita. Bancos de questões geralmente recebem novos materiais a cada semestre ou unidade, portanto mantenha apenas "a versão atual + a versão histórica mais recente".
-
Inicie o service. A página de perguntas e respostas estará disponível em
http://127.0.0.1:7860.python app.py -
Se seu banco de questões contiver materiais com imagens, teste uma consulta por imagem. O endpoint
/api/askdoapp.pyaceita um parâmetro opcionalimage_urle o repassa ao campoimagedeSearchKnowledgeBase. Imagens ajudam principalmente em questões com referências pouco claras. Nos testes, para a mesma pergunta "Which knowledge points does this question test?": sem imagem, o resultado foi um exercício do teorema de Pitágoras (relevância 0,431, não a questão desejada); com uma imagem de uma questão de função quadrática anexada, o resultado foi a questão de função quadrática do banco (0,583). A imagem forneceu a semântica essencial para a recuperação.curl -sS http://127.0.0.1:7860/api/ask \ -H 'Content-Type: application/json' \ -d '{"question":"Which knowledge points does this question test?","image_url":"https://<publicly accessible image URL>"}' -
Valide o resultado com base nas quatro verificações a seguir:
A página em
http://127.0.0.1:7860abre normalmente. O cenário educacional exibe adicionalmente uma caixa de entrada para a URL da imagem da questão. Enviar uma pergunta retorna tanto a resposta quanto as fontes de recuperação.Cada referência
[Source N]na resposta tem um fragmento de material correspondente na seção de fontes abaixo.Ao perguntar sobre conteúdo não coberto pelo banco de questões, a resposta afirma explicitamente que o material é insuficiente em vez de inventar uma resposta.
Após adicionar materiais e republicar uma versão, a página consegue recuperar o novo conteúdo.
Adicione mais uma verificação para recall semântico: pesquise usando informações que aparecem apenas no conteúdo do material, não no nome do arquivo (por exemplo, um número de questão) e confirme se o material correspondente é encontrado. Essa verificação também serve para validar se uma imagem foi corretamente reconhecida e importada.
Exiba um aviso na página informando que "a imagem é usada para encontrar questões semelhantes no banco de questões".
-
Exija no prompt que o modelo aponte diferenças entre os resultados da recuperação e a descrição do usuário.
Essa funcionalidade deve ser chamada de "recuperação assistida por imagem" ou "busca de questões por imagem", e não deve ser apresentada externamente como "resolução por foto". Para resolver uma nova questão presente em uma imagem, a camada de aplicação deve passar a imagem original separadamente para um LLM compatível com entrada multimodal. Instrua o LLM a cruzar as informações com o material recuperado. Não confie apenas na recuperação da base de conhecimento.
Formato: utilize apenas JPG, JPEG, PNG e GIF. O reconhecimento subjacente de arquivos pode aceitar formatos como WebP e TIFF, mas não há compromisso público unificado; não dependa deles.
Tamanho: a API não tem limite rígido separado para bytes ou pixels de imagem, mas é restrita conjuntamente pelo gateway de upload, decodificação de imagem, memória e service de modelo de conversão de imagem para texto. Imagens muito grandes ainda podem falhar.
Precisão de reconhecimento: não há métrica de precisão garantida para escrita manual, fórmulas matemáticas, figuras geométricas ou sistemas de coordenadas. Uma imagem sem texto pode receber uma descrição gerada pela conversão de imagem para texto, mas acertos na recuperação não são garantidos. Nos testes deste tópico,
xfoi reconhecido como×, e a vírgula ideográfica foi reconhecida como um caractere de traço simples. Símbolos matemáticos exigem verificações manuais pontuais em particular.Sem limiar de qualidade de reconhecimento: desde que a imagem possa ser decodificada e o pipeline não reporte erro, o status do documento será Processed, mesmo que o texto reconhecido seja muito esparso ou incorreto. Somente quando a decodificação falha ou uma chamada obrigatória de modelo gera erro é que Processing Failed aparece. Portanto, você deve verificar amostras do texto dos fragmentos na página Data Management após o upload; não confie apenas no status.
Faça o upload de livros didáticos, questões e respostas como um conjunto, diferenciando-os com
questionTypepara permitir filtragem conforme necessário (por exemplo, permitir que alunos recuperem apenas "practice question" e professores recuperem "ground truth").Crie uma entrada independente por disciplina: após fixar
subjectemtag_filter, essa entrada só poderá responder perguntas daquela disciplina. Mantenha as perguntas de exemplo na mesma disciplina; caso contrário, alunos que perguntarem sobre outras disciplinas receberão apenas "material insuficiente".Restrinja o acesso aos materiais de resposta separadamente: se os alunos não devem obter o gabarito diretamente, filtre com uma condição como
questionType not in ["ground truth"]na entrada do aluno.Os resultados da recuperação contêm um campo
images. Por design, esse campo retorna as imagens associadas aos fragmentos, e o servidor gera URLs assinadas de curta duração para imagens persistidas. Esse campo é uma capacidade implementada, não um campo reservado vazio. No entanto, atualmente o campo não retorna URL de imagem. Quando um documento de imagem é encontrado, mas o campo está vazio, as imagens desses materiais não foram persistidas nos fragmentos correspondentes durante a fase de processamento e fragmentação, ou a associação de assinatura não foi estabelecida — um problema de pipeline a ser investigado por documento específico. Nenhum parâmetro de requisição pode ativá-lo, portanto não trate "sempre vazio" como design do produto. Você não precisa manter uma tabela de mapeamento "nome do arquivo → URL da imagem" a longo prazo: a curto prazo, a página pode recorrer à exibição do texto reconhecido; quando a imagem original da questão precisar ser mostrada, trate temporariamente associando viadocumentIdcom o manifesto de importação.Mantenha revisão manual para conclusões importantes e lembre aos alunos que os livros didáticos oficiais e as explicações dos professores prevalecem.
Etapa 3: Configurar parâmetros de recuperação e o prompt
Ajuste retrieval e scenario no arquivo config.json para o cenário educacional.
{
"retrieval": {
"page_size": 8,
"candidate_count": 64,
"min_score": 0.2,
"semantic_weight": 0.75,
"enable_query_expansion": true,
"rerank_model_name": "qwen3-rerank",
"tag_filter": {
"relation": "and",
"conditions": [
{"field": "subject", "op": "=", "value": "Mathematics"}
]
}
},
"scenario": {
"title": "Education question bank retrieval and explanation",
"system_prompt": "You are a teaching assistant. Explain only based on the retrieved textbooks, questions, and ground truth. Give the approach first, then the steps, and finally the answer, citing [Source N]. Write formulas in plain text; do not use LaTeX syntax. If a retrieved question does not match the user's description, explicitly point out the difference instead of applying the answer from the question bank directly. Do not guess the ground truth when the material is insufficient.",
"image_enabled": true,
"sample_questions": [
"How do I find the maximum value from the vertex form of a quadratic function?",
"Find an example problem that uses the Pythagorean theorem and explain it.",
"Which knowledge points does this question test?"
]
}
}
Descrição dos parâmetros:
Etapa 4: Fazer upload, publicar e verificar
Capacidades e limites da consulta por imagem
As imagens participam apenas da recuperação e nunca são enviadas ao LLM. O comportamento do sistema é "encontrar a questão mais semelhante no banco com base na imagem e depois explicar com base no material recuperado", não "reconhecer e resolver a questão da imagem". Se você enviar uma nova questão que não existe no banco, o sistema responderá com a questão mais semelhante disponível, e a resposta pode diferir da questão da imagem sem que isso seja percebido. Por exemplo, ao enviar y=-(x-1)²+4 (valor máximo é 4), se y=-2(x-3)²+5 existir no banco, a resposta pode indicar um valor máximo de 5. Portanto:
image_url deve ser um endereço publicamente acessível. O servidor valida o endereço:
|
Entrada |
Resposta do servidor |
|
Endereço interno ou local (como |
|
|
Link para recurso que não é imagem |
|
|
Nome de domínio não resolvido |
|
|
Campo vazio |
Retorna à recuperação por texto simples (comportamento normal) |
O reconhecimento de imagens possui os seguintes limites, que devem ser conhecidos antes de preparar os materiais do banco de questões:
Notas de uso para cenários educacionais
Perguntas frequentes
|
Sintoma |
Causa e solução |
|
Uma consulta retorna 500 e o log mostra |
|
|
Com filtragem por tags adicionada, o número de resultados é exatamente o mesmo sem ela |
Um operador inoperante (como |
|
Materiais com imagens não são encontrados após o upload |
Verifique em ordem: se o tipo de dados da base de conhecimento suporta imagens; se o status dos dados é Processed; se o texto reconhecido em View Chunks está vazio ou inconsistente com a imagem (imagens sem texto, tamanho de fonte muito pequeno e escrita manual podem causar falha no reconhecimento). |
|
Você pergunta com uma imagem da questão, mas a resposta trata de uma questão diferente |
Comportamento esperado. A imagem é usada apenas para recuperar questões semelhantes; o modelo explica a questão recuperada. |
|
Uma consulta retorna |
|
|
Fórmulas aparecem como |
O modelo gerou LaTeX, mas a página renderiza como texto simples. Exija fórmulas em texto simples no prompt ou integre uma biblioteca de renderização de fórmulas à página. |
|
Menos resultados após ativar o reranking |
Pontuações de reranking e pontuações vetoriais têm escalas diferentes; combinadas com |
|
Filtragem por tags sempre retorna 0 resultados |
A grafia do nome da tag difere do que foi cadastrado (a API não reporta erro e apenas retorna 0 resultados). Verifique na página de detalhes da base de conhecimento → Tags → Manage. |
|
Upload retorna |
Todos os arquivos do lote foram deduplicados devido a nomes idênticos. Renomeie os arquivos ou exclua os dados antigos no console primeiro. |
|
Recuperação retorna |
Nenhuma versão foi publicada ou o número de versão especificado não existe. |