Como criar aplicações de IA agentiva com Mastra e Elasticsearch
Aprenda como construir aplicações de IA agentiva usando Mastra e Elasticsearch com um exemplo prático.
Neste artigo, vamos mostrar como usar o framework Mastra TypeScript para criar aplicações agentivas que interagem com Elasticsearch.
Recentemente, contribuímos para o projeto open source mastra-ai/mastra adicionando suporte ao Elasticsearch como banco de dados vetorial. Com esse novo recurso, você pode usar o Elasticsearch nativamente no Mastra para armazenar embeddings. Além dos vetores, o Elasticsearch oferece um conjunto de recursos avançados para atender a todos os seus requisitos de engenharia de contexto. (por exemplo, busca híbrida e reranking).
Este artigo detalha a criação de um agente para implementar uma arquitetura de retrieval augmented generation (RAG) usando o Elasticsearch. Vamos apresentar um projeto de demonstração onde uma abordagem agentiva é usada para interagir com um corpus de dados de filmes de ficção científica armazenados no Elasticsearch. O projeto está disponível em elastic/mastra-elasticsearch-example.
Mastra
Mastra é um framework TypeScript para criar aplicações de IA com agentes.
A estrutura do projeto em Mastra é a seguinte:
src/
├── mastra/
│ ├── agents/
│ │ └── weather-agent.ts
│ ├── tools/
│ │ └── weather-tool.ts
│ ├── workflows/
│ │ └── weather-workflow.ts
│ ├── scorers/
│ │ └── weather-scorer.ts
│ └── index.ts
├── .env.example
├── package.json
└── tsconfig.jsonNo Mastra, você pode criar agentes, ferramentas, fluxos de trabalho e métricas.
Um agente é uma classe que aceita uma mensagem na entrada e produz uma resposta como saída. Um agente pode usar ferramentas, grandes modelos de linguagem (LLMs) e uma memória (figura 1).

Figura 1: Um diagrama mostrando como um agente trabalha em Mastra.
As ferramentas de um agente permitem que ele interaja com o "mundo externo", como se comunicar com uma API web ou realizar uma operação interna, como consultar o Elasticsearch. O componente de memória é essencial para armazenar o histórico das conversas, incluindo entradas e saídas anteriores. Esse contexto armazenado permite que o agente forneça respostas mais informadas e relevantes para futuras perguntas utilizando suas interações passadas.
Os fluxos de trabalho permitem que você defina sequências complexas de tarefas usando etapas claras e estruturadas, em vez de depender do raciocínio de um único agente (figura 2). Eles dão controle total sobre como as tarefas são divididas, como os dados circulam entre elas e o que é executado e quando. Os fluxos de trabalho são executados usando o mecanismo de execução integrado por padrão ou podem ser implantados em executores de fluxo de trabalho.

Figura 2: Um exemplo de fluxo de trabalho em Mastra.
No Mastra, você também pode definir métricas, que são testes automatizados para avaliar as saídas dos agentes usando métodos baseados em modelos, regras e estatísticas. Os avaliadores retornam métricas: valores numéricos (normalmente entre 0 e 1) que quantificam o quanto uma saída atende aos seus critérios de avaliação. Essas métricas permitem que você acompanhe objetivamente o desempenho, compare diferentes abordagens e identifique áreas de melhoria em seus sistemas de IA. Os avaliadores podem ser personalizados com seus próprios prompts e funções de métrica.
Elasticsearch
Para executar o projeto de demonstração, precisamos ter uma instância do Elasticsearch em execução. Você pode ativar um teste gratuito no Elastic Cloud ou instalá-lo localmente usando o script start-local:
curl -fsSL https://elastic.co/start-local | shIsso instalará o Elasticsearch e o Kibana no seu computador e gerará uma chave API para ser usada na configuração da integração Mastra.
A chave API será mostrada como saída do comando anterior e armazenada em um arquivo .env na pasta elastic-start-local.
Instalar e configurar a demonstração
Criamos um repositório elastic/mastra-elasticsearch-example contendo o código-fonte do projeto de demonstração. O exemplo relatado no repositório ilustra como criar um agente no Mastra que implementa uma arquitetura RAG para recuperar documentos do Elasticsearch.
Fornecemos um conjunto de dados para a demonstração sobre filmes de ficção científica. Extraímos 500 filmes do conjunto de dados IMDb no Kaggle.
O primeiro passo é instalar as dependências do projeto com npm, usando o seguinte comando:
npm installEntão precisamos configurar o arquivo .env que conterá as configurações. Podemos gerar esse arquivo copiando a estrutura do arquivo .env.example, usando o seguinte comando:
cp .env.example .envAgora podemos editar o arquivo .env, adicionando as informações que faltam:
OPENAI_API_KEY=
ELASTICSEARCH_URL=
ELASTICSEARCH_API_KEY=
ELASTICSEARCH_INDEX_NAME=scifi-moviesO nome do índice do Elasticsearch é scifi-movies. Se quiser, pode mudar usando a variável de ambiente ELASTICSEARCH_INDEX_NAME.
Usamos a OpenAI como serviço de embeddings, o que significa que você precisa fornecer uma chave de API para a OpenAI na variável de ambiente OPENAI_API_KEY.
O modelo de embedding usado no exemplo é openai/text-embedding-3-small, com uma dimensão de embedding de 1.536.
Para gerar a resposta final, utilizamos o modelo openai/gpt-5-nano para reduzir os custos.
A arquitetura RAG permite que você use um modelo LLM final menos potente (e normalmente mais barato) porque o trabalho pesado de fundamentar a resposta é feito pelo componente de recuperação (Elasticsearch, neste caso).
O LLM menor é responsável apenas por duas tarefas principais:
Reformulação/embedding da consulta: conversão da pergunta do usuário em linguagem natural em um vetor de embedding para busca semântica.
Sintetização da resposta: pegar os fragmentos de contexto recuperados e altamente relevantes (documentos/filmes) e sintetizá-los em uma resposta coerente, final e legível por humanos, seguindo as instruções do prompt fornecido.
Como o processo RAG fornece o contexto factual exato necessário para a resposta, o LLM final não precisa ser massivo ou altamente complexo, nem precisa possuir todo o conhecimento necessário dentro de seus próprios parâmetros (é aí que modelos grandes e caros se destacam). Basicamente, ele atua como um sofisticado resumidor e formatador de texto para o contexto fornecido pelo Elasticsearch, e não como uma base de conhecimento completa em si. Isso permite o uso de modelos como gpt-5-nano para otimização de custos e latência.
Após a configuração do arquivo .env, você pode fazer a ingestão dos filmes no Elasticsearch usando o seguinte comando:
npx tsx src/utility/store.tsVocê deve ver uma saída da seguinte forma:
🚀 Starting ingestion of 500 movies from 500_scifi_movies.jsonl...
Ingesting ░░░░░░░░░░░░░░░░░░░░░░░░ 1/500 (0%) | ok:1 | fail:0 | chunks:1 | eta:19m 33s | current:Capricorn One
Ingesting ░░░░░░░░░░░░░░░░░░░░░░░░ 2/500 (0%) | ok:2 | fail:0 | chunks:2 | eta:10m 32s | current:Doghouse
Ingesting ░░░░░░░░░░░░░░░░░░░░░░░░ 3/500 (1%) | ok:3 | fail:0 | chunks:3 | eta:7m 33s | current:Dinocroc
Ingesting ░░░░░░░░░░░░░░░░░░░░░░░░ 4/500 (1%) | ok:4 | fail:0 | chunks:7 | eta:6m 10s | current:Back to the Future
Ingesting ░░░░░░░░░░░░░░░░░░░░░░░░ 5/500 (1%) | ok:5 | fail:0 | chunks:9 | eta:5m 14s | current:The Projected Man
Ingesting ░░░░░░░░░░░░░░░░░░░░░░░░ 6/500 (1%) | ok:6 | fail:0 | chunks:11 | eta:4m 41s | current:I, Robot
...
✅ Ingestion complete in 1m 46s. Success: 500, Failed: 0, Chunks: 693.O mapeamento do índice de filmes de ficção científica contém os seguintes campos:
embedding, dense_vector com dimensão de 1.536, similaridade cosseno.
description, texto contendo a descrição do filme.
director, texto contendo o nome do diretor.
título, texto contendo o título do filme.
Geramos os embeddings usando o título e a descrição. Como o título e a descrição são dois campos separados, a concatenação de ambos garante que o vetor de embedding resultante capture tanto a identidade específica e única (título) quanto o contexto rico e descritivo (descrição) do filme, resultando em buscas semânticas mais precisas e abrangentes. Essa entrada combinada oferece ao modelo de embedding uma representação mais adequada do conteúdo do documento para comparação de similaridade.
Execute a demonstração
Você pode executar a demonstração com o seguinte comando:
npm run devEsse comando iniciará uma aplicação web em localhost:4111 para acessar o Mastra Studio (Figura 3).

Figura 3: Uma captura de tela do Mastra Studio com o exemplo do agente Elasticsearch.
O Mastra Studio oferece uma interface de usuário interativa para criar e testar seus agentes, além de uma REST API que expõe seu aplicativo Mastra como um serviço local. Isso permite que você comece a trabalhar imediatamente, sem se preocupar com integração.
Fornecemos um Agente Elasticsearch que utiliza o createVectorQueryTool da Mastra como ferramenta para executar busca semântica usando Elasticsearch. Esse agente utiliza a abordagem RAG para buscar documentos relevantes (ou seja, filmes) para responder à pergunta do usuário.
Este agente usa o seguinte prompt:
You are a helpful assistant that answers questions based on the provided context.
Follow these steps for each response:
1. First, carefully analyze the retrieved context chunks and identify key information.
2. Break down your thinking process about how the retrieved information relates to the query.
3. Draw conclusions based only on the evidence in the retrieved context.
4. If the retrieved chunks don't contain enough information, explicitly state what's missing.
Format your response as:
THOUGHT PROCESS:
- Step 1: [Initial analysis of retrieved chunks]
- Step 2: [Reasoning based on chunks]
FINAL ANSWER:
[Your concise answer based on the retrieved context]
Important: When asked to answer a question, please base your answer only on the context provided in the tool.
If the context doesn't contain enough information to fully answer the question, please state that explicitly and stop it.
Do not add more information than what is present in the retrieved chunks.
Remember: Explain how you're using the retrieved information to reach your conclusions.Se você clicar no menu Mastra Studio > Agents e selecionar Agente Elasticsearch, pode testar o agente usando um sistema de chat. Por exemplo, você pode pedir informações sobre filmes de ficção científica com a seguinte pergunta:
Encontre 5 filmes ou séries de TV sobre OVNIs.
Você notará que o agente executará a ferramenta vectorQueryTool. Você pode clicar na ferramenta invocada para visualizar a entrada e a saída. Ao final da execução, o LLM responderá à sua pergunta, considerando o contexto do índice de filmes de ficção científica do Elasticsearch (figura 4).

Figura 4: Resposta do LLM usando o Agente Elasticsearch.
O Mastra executa internamente os seguintes passos:
Conversão de vetor: A pergunta do usuário, Encontre 5 filmes ou séries de TV sobre OVNIs, é convertida em uma incorporação vetorial usando o modelo
openai/text-embedding-3-smallda OpenAI.Busca vetorial: este embedding é então usado para consultar o Elasticsearch por meio de uma busca vetorial.
Recuperação do resultado: o Elasticsearch retorna um conjunto de 10 filmes altamente relevantes para a consulta (ou seja, aqueles cujos vetores estão mais próximos do vetor de consulta do usuário).
Geração de respostas: os filmes recuperados e a pergunta original do usuário são enviados para o LLM, especificamente
openai/gpt-5-nano. O LLM processa essas informações e gera uma resposta final, garantindo que o pedido do usuário por cinco resultados seja atendido.
O Agente Elasticsearch
Aqui apresentamos o código-fonte do agente Elasticsearch.
import { Agent } from "@mastra/core/agent";
import { ElasticSearchVector } from '@mastra/elasticsearch';
import { createVectorQueryTool } from '@mastra/rag';
import { ModelRouterEmbeddingModel } from "@mastra/core/llm";
import { Memory } from "@mastra/memory";
const es_url = process.env.ELASTICSEARCH_URL;
const es_apikey = process.env.ELASTICSEARCH_API_KEY;
const es_index_name = process.env.ELASTICSEARCH_INDEX_NAME;
const prompt = 'insert here the previous prompt';
const esVector = new ElasticSearchVector({
id: 'elasticsearch-vector',
url: es_url,
auth: {
apiKey : es_apikey
}
});
const vectorQueryTool = createVectorQueryTool({
vectorStore: esVector,
indexName: es_index_name,
model: new ModelRouterEmbeddingModel("openai/text-embedding-3-small")
});
export const elasticsearchAgent = new Agent({
id: "elasticsearch-agent",
name: "Elasticsearch Agent",
instructions: prompt,
model: 'openai/gpt-5-nano',
tools: { vectorQueryTool },
memory: new Memory(),
});O vectorQueryTool é a ferramenta que é invocada para implementar a parte de recuperação do exemplo RAG. Ele utiliza a implementação ElasticSearchVector que a Elastic contribuiu para o Mastra.
O agente é um objeto da classe agent que utiliza o vectorQueryTool, o prompt e uma memória. Como você pode ver, o código que precisamos colocar em prática para conectar o Elasticsearch a um agente é mínimo.
Conclusão
Este artigo demonstrou a simplicidade e o poder de integrar o Elasticsearch ao framework Mastra para criar aplicações sofisticadas de IA agentiva. Especificamente, detalhamos a criação de um agente RAG capaz de realizar busca semântica em um corpus de dados de filmes de ficção científica indexados no Elasticsearch.
O principal aprendizado é a contribuição direta da Elastic para o projeto open source Mastra, fornecendo suporte nativo para o Elasticsearch como um repositório vetorial. Essa integração reduz significativamente a barreira de entrada, como demonstra o código-fonte do Elasticsearch Agent. Usando o ElasticSearchVector e createVectorQueryTool, a configuração completa para conectar o Elasticsearch ao seu agente exige apenas algumas linhas de código de configuração.
O Elasticsearch oferece vários recursos avançados para aumentar a relevância dos resultados. Por exemplo, a busca híbrida aumenta significativamente a precisão ao combinar a busca lexical com a busca vetorial. Outro recurso interessante é a reclassificação usando os modelos Jina mais recentes, que podem ser aplicados ao final da busca híbrida. Para saber mais sobre essas técnicas, consulte os seguintes artigos do Elasticsearch Labs:
Busca híbrida do Elasticsearch por Valentin Crettaz
Uma introdução aos modelos Jina, sua funcionalidade e seus usos no Elasticsearch por Scott Martens
Também incentivamos você a explorar o exemplo fornecido e começar a construir seus próprios agentes baseados em dados com Mastra e Elasticsearch. Para mais informações sobre o Mastra, você pode consultar a documentação oficial aqui.




