Para agentes de IA: um índice de documentação está disponível em https://www.mongodb.com/pt-br/docs/llms.txt — as versões de marcação de todas as páginas estão disponíveis anexando .md a qualquer caminho de URL .
Make the MongoDB docs better! We value your opinion. Share your feedback for a chance to win $100.
MongoDB Branding Shape
Click here >
Menu Docs

Crie agentes de AI com o MongoDB

O MongoDB oferece vários recursos para criar agentes de IA. Como um banco de dados de vetores e documento , o MongoDB oferece suporte a vários métodos de pesquisa para RAG de agentes, além de armazenar interações de agente no mesmo banco de dados para memória de agente de curto e longo prazo.

Começar

No contexto da IA generativa, um agente de IA geralmente se refere a um sistema que pode realizar uma tarefa de forma autônoma ou semiautônoma, combinando modelos de IA, como LLMs, com um conjunto de ferramentas predefinidas.

Agentes de AI podem usar ferramentas para reunir contexto, realizar interação com sistemas externos e executar ações. Eles podem definir seu próprio fluxo de execução (planejamento) e lembrar interações anteriores para informar suas respostas (memória). Portanto, os agentes de AI são mais adequados para tarefas complexas que exigem raciocínio, planejamento e tomada de decisões.

Diagrama mostrando uma arquitetura de agente único com MongoDB

Um agente de AI normalmente inclui uma combinação dos seguintes componentes:

Percepção

Sua informação para o agente. Informações em texto são o mecanismo de percepção mais comum para agentes de AI, mas também podem ser de áudio, imagens ou dados multimodais.

Planejamento

Como o agente determina o que fazer a seguir. Este componente normalmente inclui LLMs e prompts, utilizando ciclos de feedback e várias técnicas de engenharia de prompts, como cadeia de pensamento e React, para ajudar o LLM a raciocinar sobre tarefas complexas.

Os agentes de AI podem consistir em um único LLM como tomador de decisões, um LLM com vários prompts, múltiplos LLMs trabalhando juntos ou qualquer combinação dessas abordagens.

Ferramentas

Como o agente reúne contexto para uma tarefa. As ferramentas permitem que os agentes interajam com sistemas externos e realizem ações como pesquisa vetorial, pesquisa na web ou chamadas de APIs de outros serviços.

Memória

Um sistema para armazenar interações do agente, de forma que ele possa aprender com experiências passadas para informar suas respostas. A memória pode ser de curto termo (para a sessão atual) ou de longo termo (persistida entre as sessões).

Observação

Os agentes de AI variam em padrão de design, função e complexidade. Para aprender mais sobre outras arquiteturas de agentes, incluindo sistemas multiagentes, consulte Padrões de design de agentes.

O MongoDB é compatível com os seguintes componentes para criar agentes de IA:

  • Ferramentas: aproveite os recursos de pesquisa do MongoDB como ferramentas para seu agente recuperar informações relevantes e implementar RAG de agente.

  • Memória: armazene interações de agentes em coleções MongoDB para memória de curto e longo prazo.

No contexto de agentes de AI, uma ferramenta é qualquer recurso que possa ser definido e invocado programaticamente pelo agente. As ferramentas ampliam as funcionalidades do agente além da geração de textos, permitindo a interação com sistemas externos, a recuperação de informações e a execução de ações. As ferramentas são tipicamente definidas com uma interface específica que inclui:

  • Um nome e uma descrição que ajudam o agente a entender quando usar a ferramenta.

  • Parâmetros obrigatórios e seus formatos esperados.

  • Uma função que realiza a operação efetiva quando chamada.

O agente utiliza suas capacidades de raciocínio para determinar qual ferramenta empregar, quando utilizá-la e quais parâmetros fornecer, com base na entrada do usuário e na tarefa em questão.

Além das queries padrão do MongoDB , o MongoDB fornece vários recursos de pesquisa que você pode implementar como FERRAMENTAS para seu agente.

  • Vector Search do MongoDB: execute pesquisa vetorial para recuperar o contexto relevante com base no significado e similaridade semântica. Para saber mais, consulte Visão geral da Vector Search do MongoDB.

  • MongoDB Search: realize pesquisas de texto completo para recuperar o contexto relevante com base na correspondência de palavras-chave e na pontuação de relevância. Para saber mais, consulte Visão geral da pesquisa do MongoDB.

  • Pesquisa híbrida: combine a pesquisa vetorial do MongoDB com a MongoDB Search para aproveitar os pontos fortes de ambas as abordagens. Para saber mais, consulte Como realizar pesquisas híbridas.

Você pode definir ferramentas manualmente ou usando frameworks como LangChain e LangGraph, que fornecem abstrações integradas para criação e chamada de ferramentas.

As ferramentas são definidas como funções que o agente pode chamar para executar tarefas específicas. Por exemplo, a sintaxe a seguir ilustra como você pode definir uma ferramenta que executa uma query de pesquisa vetorial:

async function vectorSearchTool(query) {
const pipeline = [
{
$vectorSearch: {
// Vector search query pipeline...
}
}
];
const results = await collection.aggregate(pipeline).toArray();
return results;
}
def vector_search_tool(query: str) -> str:
pipeline = [
{
"$vectorSearch": {
# Vector search query pipeline...
}
}
]
results = collection.aggregate(pipeline)
array_of_results = []
for doc in results:
array_of_results.append(doc)
return array_of_results

As chamadas de ferramenta são o que o agente usa para executar o FERRAMENTAS. Você pode definir como processar chamadas de ferramentas em seu agente ou usar uma estrutura para lidar com isso para você. Eles normalmente são definidos como objetos JSON que incluem o nome da ferramenta e outros argumentos a serem passados para a ferramenta, para que o agente possa chamar a ferramenta com os parâmetros apropriados. Por exemplo, a seguinte sintaxe ilustra como um agente pode chamar a ferramenta de pesquisa vetorial:

{
"tool": "vector_search_tool",
"args": { "query": "What is MongoDB?" },
"id": "call_H5TttXb423JfoulF1qVfPN3m"
}

Ao usar o MongoDB como um banco de dados vetorial, você pode criar FERRAMENTAS de recuperação que implementam o RAG agente, que é uma forma avançada de RAG que permite orquestrar dinamicamente o processo de recuperação e geração por meio de um agente de IA.

Diagrama mostrando uma arquitetura RAG de agente com MongoDB

Essa abordagem permite fluxos de trabalho e interações com o usuário mais complexos. Por exemplo, você pode configurar seu agente de IA para determinar a ferramenta de recuperação ideal com base na tarefa, como usar o MongoDB Vector Search para pesquisa semântica e o MongoDB Search para pesquisa de texto completo. Você também pode definir diferentes FERRAMENTAS de recuperação para diferentes coleções para personalizar ainda mais os recursos de recuperação do agente.

A memória para agentes envolve armazenar informações sobre interações anteriores, para que o agente possa aprender com experiências passadas e fornecer respostas mais relevantes e personalizadas. Isso é particularmente importante para tarefas que exigem contexto, como agentes conversacionais, em que o agente precisa se lembrar das interações anteriores na conversa para fornecer respostas coerentes e relevantes ao contexto. Existem dois tipos primários de memória de agente:

  • Memória de curto prazo: armazena informações para a sessão atual, como as últimas interações e o contexto da tarefa ativa.

  • Memória de longo prazo: persiste informações entre sessões, podendo incluir conversas passadas e preferências personalizadas ao longo do tempo.

Como o MongoDB também é um banco de dados de documento , você pode implementar memória para agentes armazenando suas interações em uma coleção do MongoDB . O agente pode então consultar ou atualizar essa coleção conforme necessário. Há várias maneiras de implementar a memória do agente com o MongoDB:

  • Para a memória de curto prazo, você pode incluir um campo session_id para identificar uma sessão específica ao armazenar interações e, em seguida, consultar as interações com o mesmo ID para passá-las ao agente como contexto.

  • Para memória de longo prazo, você pode processar várias interações com um LLM para extrair informações relevantes, como preferências do usuário ou contexto importante, e então armazenar essas informações em uma coleção separada que o agente pode consultar quando necessário.

  • Para criar sistemas robustos de gerenciamento de memória que permitam uma recuperação mais eficiente e complexa de histórico de conversas, aproveite o MongoDB Search ou o MongoDB pesquisa vetorial para armazenar, indexar e consultar interações importantes entre sessões.

Um documento em uma coleção que armazena memória de curto prazo pode ser semelhante ao seguinte:

{
"session_id": "123",
"user_id": "jane_doe",
"interactions":
[
{
"role": "user",
"content": "What is MongoDB?",
"timestamp": "2025-01-01T12:00:00Z"
},
{
"role": "assistant",
"content": "MongoDB is the world's leading modern database.",
"timestamp": "2025-01-01T12:00:05Z"
}
]
}

Um documento em uma coleção que armazena memória de longo prazo pode ser semelhante ao seguinte:

{
"user_id": "jane_doe",
"last_updated": "2025-05-22T09:15:00Z",
"preferences": {
"conversation_tone": "casual",
"custom_instructions": [
"I prefer concise answers."
],
},
"facts": [
{
"interests": ["AI", "MongoDB"],
}
]
}

As estruturas a seguir também fornecem abstrações diretas para a memória do agente com o MongoDB:

Framework
Características

LangChain

  • MongoDBChatMessageHistory: componente de histórico de mensagens de chat

  • MongoDBAtlasSemanticCache: componente de cache semântico

Para saber mais, consulte o tutorial.

LangGraph

  • MongoDBSaver: checkpointer de memória de curto prazo que pode ser usado para persistência

  • MongoDBStore: armazenamento de documento de longo prazo para armazenamento de memória no MongoDB (disponível somente na integração do Python)

Para saber mais, consulte LangGraph e LangGraph.js.

O tutorial a seguir demonstra como criar um agente de IA usando o MongoDB para RAG e memória de agente, sem uma estrutura de agente .


➤ Use o menu suspenso Selecione seu idioma para definir o idioma para este tutorial.


Trabalhe com uma versão executável deste tutorial como um notebook Python.

Para concluir este tutorial, você deve ter o seguinte:

  • Um dos seguintes tipos de cluster MongoDB :

  • Uma chave de API do Voyage AI.

  • Uma chave de API OpenAI.

Observação

Este tutorial usa modelos da Voyage AI e da OpenAI, mas você pode alterar o código para utilizar os modelos de sua preferência.

Esse agente de AI pode ser usado para responder a perguntas sobre uma fonte de dados personalizada e realizar cálculos. Ele também pode lembrar de interações anteriores para informar suas respostas. Ele usa os seguintes componentes:

  • Percepção: entradas de texto.

  • Planejamento: um LLM e várias instruções para raciocinar sobre a tarefa.

  • Ferramentas: uma ferramenta de pesquisa vetorial e uma ferramenta de cálculo.

  • Memória: armazena as interações em uma coleção do MongoDB.

1
  1. Inicialize o projeto e instale dependências.

    Crie um novo diretório de projeto e, em seguida, instale as dependências necessárias:

    mkdir mongodb-ai-agent
    cd mongodb-ai-agent
    npm init -y
    npm install --quiet dotenv mongodb voyageai openai langchain @langchain/community @langchain/core mathjs pdf-parse@1

    Observação

    Seu projeto usará a seguinte estrutura:

    mongodb-ai-agent
    ├── .env
    ├── config.js
    ├── ingest-data.js
    ├── tools.js
    ├── memory.js
    ├── planning.js
    └── index.js
  2. Configure o ambiente.

    Crie um arquivo de ambiente denominado .env em seu projeto. Esse arquivo conterá suas chaves de API para o agente , a string de conexão do MongoDB e os nomes do banco de dados e da collection do MongoDB .

    Copie e cole o seguinte código em seu .env arquivo.

    Substitua os valores do espaço reservado por sua string de conexão do MongoDB e suas chaves de API Voyage AI e OpenAI.

    MONGODB_URI="<mongodb-connection-string>"
    VOYAGE_API_KEY="<voyage-api-key>"
    OPENAI_API_KEY= "<openai-api-key>"

    Observação

    Substitua <connection-string> pela string de conexão do seu cluster do Atlas ou da implantação local do Atlas.

    Sua string de conexão deve usar o seguinte formato:

    mongodb+srv://<db_username>:<db_password>@<clusterName>.<hostname>.mongodb.net

    Para aprender mais, consulte Conectar-se a um cluster por meio de bibliotecas de clientes.

    Sua string de conexão deve usar o seguinte formato:

    mongodb://localhost:<port-number>/?directConnection=true

    Para saber mais, consulte Connection strings.

2

Crie um arquivo denominado config.js em seu projeto. Este arquivo lerá em suas variáveis de ambiente e conectará o aplicação a serviços como o banco de dados do MongoDB e o OpenAI.

Copie e cole o seguinte código no seu arquivo config.js.

import dotenv from 'dotenv';
import { MongoClient } from 'mongodb';
import OpenAI from "openai";
// Load environment variables from .env file
dotenv.config();
// MongoDB cluster configuration
export const MONGODB_URI = process.env.MONGODB_URI;
export const mongoClient = new MongoClient(MONGODB_URI);
export const agentDb = mongoClient.db("ai_agent_db");
export const vectorCollection = agentDb.collection("embeddings");
export const memoryCollection = agentDb.collection("chat_history");
// Model Configuration
export const OPENAI_MODEL = "gpt-4o";
export const VOYAGE_MODEL = "voyage-3-large";
export const VOYAGE_API_KEY = process.env.VOYAGE_API_KEY;
// Initialize OpenAI Client
export const openAIClient = new OpenAI({ apiKey: process.env.OPENAI_API_KEY,});
3

Crie um arquivo denominado ingest-data.js em seu projeto. Esse script ingere um PDF de amostra que contém um relatório de rendimentos recente do MongoDB em uma collection no MongoDB usando o modelo de incorporação voyage-3-large. Este código também inclui uma função para criar um índice de pesquisa vetorial em seus dados, se eles ainda não existirem.

Para aprender mais, consulte Ingestão.

Copie e cole o seguinte código no seu arquivo ingestão-data.js.

import { PDFLoader } from "@langchain/community/document_loaders/fs/pdf";
import { RecursiveCharacterTextSplitter } from "langchain/text_splitter";
import { vectorCollection } from "./config.js";
import { VOYAGE_API_KEY, VOYAGE_MODEL } from "./config.js";
import { VoyageAIClient } from "voyageai";
import { MONGODB_URI } from "./config.js";
import * as fs from 'fs';
import fetch from 'node-fetch';
console.log("Connecting to MongoDB:", MONGODB_URI);
const EMBEDDING_DIMENSIONS = 1024;
// Use Voyage AI Client SDK to get embeddings
export async function getEmbedding(data, input_type) {
if (!VOYAGE_API_KEY) {
throw new Error("VOYAGE_API_KEY is not set in environment variables.");
}
try {
const client = new VoyageAIClient({ apiKey: VOYAGE_API_KEY });
const response = await client.embed({
input: [data],
model: VOYAGE_MODEL,
input_type: input_type // "document" or "query"
});
if (response.data && response.data.length > 0) {
return response.data[0].embedding;
}
throw new Error("No embedding data found from Voyage AI response.");
}
catch (error) {
console.error("Error generating Voyage AI embedding:", error);
return null;
}
}
// Ingest data from a PDF, generate embeddings, and store in MongoDB
export async function ingestData() {
try {
// download PDF
const rawData = await fetch("https://investors.mongodb.com/node/13176/pdf");
const pdfBuffer = await rawData.arrayBuffer();
fs.writeFileSync("investor-report.pdf", Buffer.from(pdfBuffer));
// load and split PDF
const loader = new PDFLoader("investor-report.pdf");
const data = await loader.load();
const textSplitter = new RecursiveCharacterTextSplitter({
chunkSize: 400,
chunkOverlap: 20,
});
const docs = await textSplitter.splitDocuments(data);
console.log(`Chunked PDF into ${docs.length} documents.`);
// generate embeddings and insert
const insertDocuments = await Promise.all(docs.map(async doc => ({
document: doc,
embedding: await getEmbedding(doc.pageContent, "document"),
})));
const result = await vectorCollection.insertMany(insertDocuments, { ordered: false });
console.log("Inserted documents:", result.insertedCount);
} catch (err) {
console.error("Ingestion error:", err);
}
}
// Create a vector search index
export async function createVectorIndex() {
try {
// check if the index already exists
const existingIndexes = await vectorCollection.listSearchIndexes().toArray();
if (existingIndexes.some(index => index.name === "vector_index")) {
console.log("Vector index already exists. Skipping creation.");
return;
}
// define your Vector Search index
const index = {
name: "vector_index",
type: "vectorSearch",
definition: {
"fields": [
{
"type": "vector",
"path": "embedding",
"numDimensions": EMBEDDING_DIMENSIONS,
"similarity": "cosine",
}
]
}
}
// run the helper method to ensure the index is created
const result = await vectorCollection.createSearchIndex(index);
console.log(`New index named ${result} is building.`);
// wait for the index to be ready to query
console.log("Polling to check if the index is ready. This may take up to a minute.")
let isQueryable = false;
while (!isQueryable) {
const cursor = vectorCollection.listSearchIndexes();
for await (const index of cursor) {
if (index.name === result) {
if (index.queryable) {
console.log(`${result} is ready for querying.`);
isQueryable = true;
} else {
await new Promise(resolve => setTimeout(resolve, 5000));
}
}
}
}
} catch (err) {
console.error("Error creating vector index:", err);
throw err;
}
}
4

Crie um arquivo chamado tools.js em seu projeto. Esse arquivo define as ferramentas que o agente pode usar para dar resposta às perguntas. Neste exemplo, você define as seguintes ferramentas:

  • vectorSearchTool: executa uma query de pesquisa vetorial para recuperar documentos relevantes da sua coleção.

  • calculatorTool: usa a biblioteca mathjs para operações matemáticas básicas.

Copie e cole o seguinte código no seu arquivo Tools.js.

import { getEmbedding } from './ingest-data.js';
import { vectorCollection } from './config.js';
import { evaluate } from 'mathjs';
// Vector search tool
export async function vectorSearchTool(userInput) {
const queryEmbedding = await getEmbedding(userInput, "query");
const pipeline = [
{
$vectorSearch: {
index: "vector_index",
queryVector: queryEmbedding,
path: "embedding",
exact: true,
limit: 5
}
},
{
$project: {
_id: 0,
"document.pageContent": 1
}
}
];
const cursor = vectorCollection.aggregate(pipeline);
const results = await cursor.toArray();
return results;
}
// Simple calculator tool
export function calculatorTool(userInput) {
try {
const result = evaluate(userInput);
return String(result);
} catch (e) {
return `Error: ${e.message}`;
}
}
5

Crie um arquivo chamado memory.js em seu projeto. Esse arquivo define o sistema que o agente utiliza para armazenar suas interações. Neste exemplo, você implementa a memória de curto prazo ao definir as seguintes funções:

  • storeChatMessage: para armazenar informações sobre uma interação em uma coleção do MongoDB.

  • retrieveSessionHistory: para obter todas as interações de uma sessão específica usando o campo session_id.

Copie e cole o seguinte código em seu arquivo memory.js.

import { memoryCollection } from './config.js';
/**
* Store a chat message in the memory collection.
* @param {string} sessionId - unique identifier for the chat session
* @param {string} role - role of the sender (user or system)
* @param {string} content - content of the message
*/
export async function storeChatMessage(sessionId, role, content) {
const message = {
session_id: sessionId,
role,
content,
timestamp: new Date(), // use JS date for timestamp
};
await memoryCollection.insertOne(message);
}
/**
* Retrieve the chat history for a session.
* @param {string} sessionId - unique identifier for the chat session
* @returns {Promise<Array<{role: string, content: string}>>}
*/
export async function retrieveSessionHistory(sessionId) {
const cursor = memoryCollection
.find({ session_id: sessionId })
.sort({ timestamp: 1 });
const messages = [];
await cursor.forEach(msg => {
messages.push({ role: msg.role, content: msg.content });
});
return messages;
}
6

Crie um arquivo chamado planning.js em seu projeto. Esse arquivo incluirá vários prompts e chamadas LLM para determinar o fluxo de execução do agente. Neste exemplo, você define as seguintes funções:

  • openAIChatCompletion: Função auxiliar para chamar a API OpenAI para gerar respostas.

  • toolSelector: determina como o LLM seleciona a ferramenta apropriada para uma tarefa.

  • generateAnswer: orquestra o fluxo de execução do agente utilizando ferramentas, chamando o LLM e processando os resultados.

  • getLLMResponse: função de assistente para geração de resposta LLM.

Copie e cole o seguinte código em seu arquivo planning.js.

import { vectorSearchTool, calculatorTool } from './tools.js';
import { storeChatMessage, retrieveSessionHistory } from './memory.js';
import { openAIClient, OPENAI_MODEL } from './config.js';
// OpenAI chat completion helper
export async function openAIChatCompletion(messages) {
try {
const completion = await openAIClient.chat.completions.create({
model: OPENAI_MODEL,
messages,
max_tokens: 1024,
});
return completion.choices[0].message.content;
} catch (error) {
console.error("Error in openAIChatCompletion:", error);
throw error;
}
}
// Tool selector function to determine which tool to use based on user input and session history
export async function toolSelector(userInput, sessionHistory = []) {
const systemPrompt = `
Select the appropriate tool from the options below. Consider the full context of the conversation before deciding.
Tools available:
- vector_search_tool: Retrieve specific context about recent MongoDB earnings and announcements
- calculator_tool: For mathematical operations
- none: For general questions without additional context
Process for making your decision:
1. Analyze if the current question relates to or follows up on a previous vector search query
2. For follow-up questions, incorporate context from previous exchanges to create a comprehensive search query
3. Only use calculator_tool for explicit mathematical operations
4. Default to none only when certain the other tools won't help
When continuing a conversation:
- Identify the specific topic being discussed
- Include relevant details from previous exchanges
- Formulate a query that stands alone but preserves conversation context
Return a JSON object only: {"tool": "selected_tool", "input": "your_query"}
`.trim();
const messages = [
{ role: "system", content: systemPrompt },
...sessionHistory,
{ role: "user", content: userInput }
];
try {
const response = await openAIChatCompletion(messages);
let toolCall;
try {
toolCall = JSON.parse(response);
} catch {
try {
toolCall = eval(`(${response})`);
} catch {
return { tool: "none", input: userInput };
}
}
return {
tool: toolCall.tool || "none",
input: toolCall.input || userInput
};
} catch (err) {
console.error("Error in toolSelector:", err);
return { tool: "none", input: userInput };
}
}
// Function to get LLM response based on messages and system message content
async function getLlmResponse(messages, systemMessageContent) {
const systemMessage = { role: "system", content: systemMessageContent };
let fullMessages;
if (messages.some(msg => msg.role === "system")) {
fullMessages = [...messages, systemMessage];
} else {
fullMessages = [systemMessage, ...messages];
}
const response = await openAIChatCompletion(fullMessages);
return response;
}
// Function to generate response based on user input
export async function generateResponse(sessionId, userInput) {
await storeChatMessage(sessionId, "user", userInput);
const sessionHistory = await retrieveSessionHistory(sessionId);
const llmInput = [...sessionHistory, { role: "user", content: userInput }];
const { tool, input: toolInput } = await toolSelector(userInput, sessionHistory);
console.log("Tool selected:", tool);
let response;
if (tool === "vector_search_tool") {
const contextResults = await vectorSearchTool(toolInput);
const context = contextResults.map(doc => doc.document?.pageContent || JSON.stringify(doc)).join('\n---\n');
const systemMessageContent = `
Answer the user's question based on the retrieved context and conversation history.
1. First, understand what specific information the user is requesting
2. Then, locate the most relevant details in the context provided
3. Finally, provide a clear, accurate response that directly addresses the question
If the current question builds on previous exchanges, maintain continuity in your answer.
Only state facts clearly supported by the provided context. If information is not available, say 'I DON'T KNOW'.
Context:
${context}
`.trim();
response = await getLlmResponse(llmInput, systemMessageContent);
} else if (tool === "calculator_tool") {
response = calculatorTool(toolInput);
} else {
const systemMessageContent = "You are a helpful assistant. Respond to the user's prompt as best as you can based on the conversation history.";
response = await getLlmResponse(llmInput, systemMessageContent);
}
await storeChatMessage(sessionId, "system", response);
return response;
}
7

Por fim, crie um arquivo chamado index.js em seu projeto. Esse arquivo executa o agente e permite a interação com ele.

Copie e cole o seguinte código no seu arquivo index.js.

import readline from 'readline';
import { mongoClient } from './config.js';
import { ingestData, createVectorIndex } from './ingest-data.js';
import { generateResponse } from './planning.js';
// Prompt for user input
async function prompt(question) {
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
return new Promise(resolve => rl.question(question, answer => {
rl.close();
resolve(answer);
}));
}
async function main() {
try {
await mongoClient.connect();
const runIngest = await prompt("Ingest sample data? (y/n): ");
if (runIngest.trim().toLowerCase() === 'y') {
await ingestData();
console.log("\nAttempting to create/verify Vector Search Index...");
await createVectorIndex();
} else {
await createVectorIndex(); // ensure index exists even if not ingesting data
}
const sessionId = await prompt("Enter a session ID: ");
while (true) {
const userQuery = await prompt("\nEnter your query (or type 'quit' to exit): ");
if (userQuery.trim().toLowerCase() === 'quit') break;
if (!userQuery.trim()) {
console.log("Query cannot be empty. Please try again.");
continue;
}
const answer = await generateResponse(sessionId, userQuery);
console.log("\nAnswer:");
console.log(answer);
}
} finally {
await mongoClient.close();
}
}
main();

Salve seu projeto e execute o seguinte comando. Quando você executar o agente:

  • Caso ainda não tenha feito, instrua o agente a ingerir os dados de amostra.

  • Digite um ID de sessão para começar uma nova sessão ou continuar uma já existente.

  • Faça perguntas. O agente gera uma resposta com base nas suas ferramentas, nas interações anteriores e nos prompts definidos na fase de planejamento.

Consulte o exemplo de saída para uma interação de amostra:

node index.js
Ingest sample data? (y/n): y
Chunked PDF into 100 documents.
Inserted documents: 100
Attempting to create/verify Vector Search Index...
New index named vector_index is building.
Polling to check if the index is ready. This may take up to a minute.
vector_index is ready for querying.
Enter a session ID: 123
Enter your query (or type 'quit' to exit): What was MongoDB's latest acquisition?
Tool selected: vector_search_tool
Answer:
MongoDB recently acquired Voyage AI, a pioneer in embedding and reranking models that power next-generation AI applications.
Enter your query (or type 'quit' to exit): What do they do?
Tool selected: vector_search_tool
Answer: Voyage AI is a company that specializes in
state-of-the-art embedding and reranking models designed to
power next-generation AI applications. These technologies help
organizations build more advanced and trustworthy AI
capabilities.
Enter your query (or type 'quit' to exit): What is 123+456?
Tool selected: calculator_tool
Answer:
579

Dica

Se estiver usando o Atlas, você poderá verificar suas embeddings e interações navegando até o namespace ai_agent_db.embeddings na IU do Atlas.

8

Agora que você possui um agente básico de AI, você pode continuar a desenvolvê-lo da seguinte maneira:

  • Melhorando o desempenho das suas ferramentas de pesquisa vetorial e pelo ajuste fino dos seus pipelines RAG.

  • Adicionar mais ferramentas ao agente, como ferramentas de pesquisa híbridas ou de texto completo.

  • Aprimorando a fase de planejamento ao utilizar prompts mais avançados e chamadas de LLM.

  • Implementar memória de longo prazo e sistemas de memória mais avançados usando o MongoDB Search e o MongoDB pesquisa vetorial para armazenar e recuperar interações importantes entre sessões.

1
  1. Inicialize o projeto e instale dependências.

    Crie um novo diretório de projeto e, em seguida, instale as dependências necessárias:

    mkdir mongodb-ai-agent
    cd mongodb-ai-agent
    pip install --quiet --upgrade pymongo voyageai openai langchain langchain-mongodb
    langchain-community python-dotenv

    Observação

    Seu projeto usará a seguinte estrutura:

    mongodb-ai-agent
    ├── .env
    ├── config.py
    ├── ingest_data.py
    ├── tools.py
    ├── memory.py
    ├── planning.py
    ├── main.py
  2. Configure o ambiente.

    Crie um arquivo de ambiente denominado .env em seu projeto. Esse arquivo conterá suas chaves de API para o agente , a string de conexão do MongoDB e os nomes do banco de dados e da collection do MongoDB .

    Copie e cole o seguinte código em seu .env arquivo.

    Substitua os valores do espaço reservado por sua string de conexão do MongoDB e suas chaves de API Voyage AI e OpenAI.

    MONGODB_URI="<mongodb-connection-string>"
    VOYAGE_API_KEY="<voyage-api-key>"
    OPENAI_API_KEY= "<openai-api-key>"

    Observação

    Substitua <connection-string> pela string de conexão do seu cluster do Atlas ou da implantação local do Atlas.

    Sua string de conexão deve usar o seguinte formato:

    mongodb+srv://<db_username>:<db_password>@<clusterName>.<hostname>.mongodb.net

    Para aprender mais, consulte Conectar-se a um cluster por meio de bibliotecas de clientes.

    Sua string de conexão deve usar o seguinte formato:

    mongodb://localhost:<port-number>/?directConnection=true

    Para saber mais, consulte Connection strings.

2

Crie um arquivo denominado config.py em seu projeto. Este arquivo lerá em suas variáveis de ambiente e conectará o aplicação a serviços como o banco de dados do MongoDB e o OpenAI.

Copie e cole o seguinte código no seu arquivo config.py.

from pymongo import MongoClient
from openai import OpenAI
import voyageai
from dotenv import load_dotenv
import os
# Load environment variables from .env file
load_dotenv()
# Environment variables (private)
MONGODB_URI = os.getenv("MONGODB_URI")
VOYAGE_API_KEY = os.getenv("VOYAGE_API_KEY")
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
# MongoDB cluster configuration
mongo_client = MongoClient(MONGODB_URI)
agent_db = mongo_client["ai_agent_db"]
vector_collection = agent_db["embeddings"]
memory_collection = agent_db["chat_history"]
# Model configuration
voyage_client = voyageai.Client(api_key=VOYAGE_API_KEY)
openai_client = OpenAI(api_key=OPENAI_API_KEY)
VOYAGE_MODEL = "voyage-3-large"
OPENAI_MODEL = "gpt-4o"
3

Crie um arquivo denominado ingest_data.py em seu projeto. Esse script ingere um PDF de amostra que contém um relatório de rendimentos recente do MongoDB em uma collection no MongoDB usando o modelo de incorporação voyage-3-large. Este código também inclui uma função para criar um índice de pesquisa vetorial em seus dados, se eles ainda não existirem.

Para aprender mais, consulte Ingestão.

Copie e cole o seguinte código no seu arquivo ingestão_data.py.

from config import vector_collection, voyage_client, VOYAGE_MODEL
from pymongo.operations import SearchIndexModel
from langchain_community.document_loaders import PyPDFLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
import time
# Define a function to generate embeddings
def get_embedding(data, input_type = "document"):
embeddings = voyage_client.embed(
data, model = VOYAGE_MODEL, input_type = input_type
).embeddings
return embeddings[0]
# --- Ingest embeddings into MongoDB ---
def ingest_data():
# Chunk PDF data
loader = PyPDFLoader("https://investors.mongodb.com/node/13176/pdf")
data = loader.load()
text_splitter = RecursiveCharacterTextSplitter(chunk_size=400, chunk_overlap=20)
documents = text_splitter.split_documents(data)
print(f"Successfully split PDF into {len(documents)} chunks.")
# Ingest chunked documents into collection
print("Generating embeddings and ingesting documents...")
docs_to_insert = []
for i, doc in enumerate(documents):
embedding = get_embedding(doc.page_content)
if embedding:
docs_to_insert.append({
"text": doc.page_content,
"embedding": embedding
})
if docs_to_insert:
result = vector_collection.insert_many(docs_to_insert)
print(f"Inserted {len(result.inserted_ids)} documents into the collection.")
else:
print("No documents were inserted. Check embedding generation process.")
# --- Create the vector search index ---
index_name = "vector_index"
search_index_model = SearchIndexModel(
definition = {
"fields": [
{
"type": "vector",
"numDimensions": 1024,
"path": "embedding",
"similarity": "cosine"
}
]
},
name=index_name,
type="vectorSearch"
)
try:
vector_collection.create_search_index(model=search_index_model)
print(f"Search index '{index_name}' creation initiated.")
except Exception as e:
print(f"Error creating search index: {e}")
return
# Wait for initial sync to complete
print("Polling to check if the index is ready. This may take up to a minute.")
predicate=None
if predicate is None:
predicate = lambda index: index.get("queryable") is True
while True:
indices = list(vector_collection.list_search_indexes(index_name))
if len(indices) and predicate(indices[0]):
break
time.sleep(5)
print(index_name + " is ready for querying.")
4

Crie um arquivo chamado tools.py em seu projeto. Esse arquivo define as ferramentas que o agente pode usar para dar resposta às perguntas. Neste exemplo, você define as seguintes ferramentas:

  • vector_search_tool: executa uma query de pesquisa vetorial para recuperar documentos relevantes da sua coleção.

  • calculator_tool: usa a função eval() para operações matemáticas básicas.

Copie e cole o seguinte código no seu arquivo tools.py.

from config import vector_collection
from ingest_data import get_embedding
# Define a vector search tool
def vector_search_tool(user_input: str) -> str:
query_embedding = get_embedding(user_input)
pipeline = [
{
"$vectorSearch": {
"index": "vector_index",
"queryVector": query_embedding,
"path": "embedding",
"exact": True,
"limit": 5
}
}, {
"$project": {
"_id": 0,
"text": 1
}
}
]
results = vector_collection.aggregate(pipeline)
array_of_results = []
for doc in results:
array_of_results.append(doc)
return array_of_results
# Define a simple calculator tool
def calculator_tool(user_input: str) -> str:
try:
result = eval(user_input)
return str(result)
except Exception as e:
return f"Error: {str(e)}"
5

Crie um arquivo chamado memory.py em seu projeto. Esse arquivo define o sistema que o agente utiliza para armazenar suas interações. Neste exemplo, você implementa a memória de curto prazo ao definir as seguintes funções:

  • store_chat_message: para armazenar informações sobre uma interação em uma coleção do MongoDB.

  • retrieve_session_history: para obter todas as interações de uma sessão específica usando o campo session_id.

Copie e cole o seguinte código no seu arquivo memory.py.

from config import memory_collection
from datetime import datetime
from typing import List
def store_chat_message(session_id: str, role: str, content: str) -> None:
message = {
"session_id": session_id, # Unique identifier for the chat session
"role": role, # Role of the sender (user or system)
"content": content, # Content of the message
"timestamp": datetime.now(), # Timestamp of when the message was sent
}
memory_collection.insert_one(message)
def retrieve_session_history(session_id: str) -> List:
# Query the collection for messages with a specific "session_id" in ascending order
cursor = memory_collection.find({"session_id": session_id}).sort("timestamp", 1)
# Iterate through the cursor and return a JSON object with the message role and content
if cursor:
messages = [{"role": msg["role"], "content": msg["content"]} for msg in cursor]
else:
messages = []
return messages
6

Crie um arquivo chamado planning.py em seu projeto. Esse arquivo incluirá vários prompts e chamadas LLM para determinar o fluxo de execução do agente. Neste exemplo, você define as seguintes funções:

  • tool_selector: determina como o LLM seleciona a ferramenta apropriada para uma tarefa.

  • generate_answer: orquestra o fluxo de execução do agente utilizando ferramentas, chamando o LLM e processando os resultados.

  • get_llm_response: função de assistente para geração de resposta LLM.

Copie e cole o seguinte código no seu arquivo planning.py.

from config import openai_client, OPENAI_MODEL
from tools import vector_search_tool, calculator_tool
from memory import store_chat_message, retrieve_session_history
# Define a tool selector function that decides which tool to use based on user input and message history
def tool_selector(user_input, session_history=None):
messages = [
{
"role": "system",
"content": (
"Select the appropriate tool from the options below. Consider the full context of the conversation before deciding.\n\n"
"Tools available:\n"
"- vector_search_tool: Retrieve specific context about recent MongoDB earnings and announcements\n"
"- calculator_tool: For mathematical operations\n"
"- none: For general questions without additional context\n"
"Process for making your decision:\n"
"1. Analyze if the current question relates to or follows up on a previous vector search query\n"
"2. For follow-up questions, incorporate context from previous exchanges to create a comprehensive search query\n"
"3. Only use calculator_tool for explicit mathematical operations\n"
"4. Default to none only when certain the other tools won't help\n\n"
"When continuing a conversation:\n"
"- Identify the specific topic being discussed\n"
"- Include relevant details from previous exchanges\n"
"- Formulate a query that stands alone but preserves conversation context\n\n"
"Return a JSON object only: {\"tool\": \"selected_tool\", \"input\": \"your_query\"}"
)
}
]
if session_history:
messages.extend(session_history)
messages.append({"role": "user", "content": user_input})
response = openai_client.chat.completions.create(
model=OPENAI_MODEL,
messages=messages
).choices[0].message.content
try:
tool_call = eval(response)
return tool_call.get("tool"), tool_call.get("input")
except:
return "none", user_input
# Define the agent workflow
def generate_response(session_id: str, user_input: str) -> str:
# Store the user input in the chat history collection
store_chat_message(session_id, "user", user_input)
# Initialize a list of inputs to pass to the LLM
llm_input = []
# Retrieve the session history for the current session and add it to the LLM input
session_history = retrieve_session_history(session_id)
llm_input.extend(session_history)
# Append the user message in the correct format
user_message = {
"role": "user",
"content": user_input
}
llm_input.append(user_message)
# Call the tool_selector function to determine which tool to use
tool, tool_input = tool_selector(user_input, session_history)
print("Tool selected: ", tool)
# Process based on selected tool
if tool == "vector_search_tool":
context = vector_search_tool(tool_input)
# Construct the system prompt using the retrieved context and append it to the LLM input
system_message_content = (
f"Answer the user's question based on the retrieved context and conversation history.\n"
f"1. First, understand what specific information the user is requesting\n"
f"2. Then, locate the most relevant details in the context provided\n"
f"3. Finally, provide a clear, accurate response that directly addresses the question\n\n"
f"If the current question builds on previous exchanges, maintain continuity in your answer.\n"
f"Only state facts clearly supported by the provided context. If information is not available, say 'I DON'T KNOW'.\n\n"
f"Context:\n{context}"
)
response = get_llm_response(llm_input, system_message_content)
elif tool == "calculator_tool":
# Perform the calculation using the calculator tool
response = calculator_tool(tool_input)
else:
system_message_content = "You are a helpful assistant. Respond to the user's prompt as best as you can based on the conversation history."
response = get_llm_response(llm_input, system_message_content)
# Store the system response in the chat history collection
store_chat_message(session_id, "system", response)
return response
# Helper function to get the LLM response
def get_llm_response(messages, system_message_content):
# Add the system message to the messages list
system_message = {
"role": "system",
"content": system_message_content,
}
# If the system message should go at the end (for context-based queries)
if any(msg.get("role") == "system" for msg in messages):
messages.append(system_message)
else:
# For general queries, put system message at beginning
messages = [system_message] + messages
# Get response from LLM
response = openai_client.chat.completions.create(
model=OPENAI_MODEL,
messages=messages
).choices[0].message.content
return response
7

Por fim, crie um arquivo chamado main.py em seu projeto. Esse arquivo executa o agente e permite a interação com ele.

Copie e cole o seguinte código no seu arquivo principal.py.

from config import mongo_client
from ingest_data import ingest_data
from planning import generate_response
if __name__ == "__main__":
try:
run_ingest = input("Ingest sample data? (y/n): ")
if run_ingest.lower() == 'y':
ingest_data()
session_id = input("Enter a session ID: ")
while True:
user_query = input("\nEnter your query (or type 'quit' to exit): ")
if user_query.lower() == 'quit':
break
if not user_query.strip():
print("Query cannot be empty. Please try again.")
continue
answer = generate_response(session_id, user_query)
print("\nAnswer:")
print(answer)
finally:
mongo_client.close()

Salve seu projeto e execute o seguinte comando. Quando você executar o agente:

  • Caso ainda não tenha feito, instrua o agente a ingerir os dados de amostra.

  • Digite um ID de sessão para começar uma nova sessão ou continuar uma já existente.

  • Faça perguntas. O agente gera uma resposta com base nas suas ferramentas, nas interações anteriores e nos prompts definidos na fase de planejamento.

Consulte o exemplo de saída para uma interação de amostra:

python main.py
Ingest sample data? (y/n): y
Successfully split PDF into 104 chunks.
Generating embeddings and ingesting documents...
Inserted 104 documents into the collection.
Search index 'vector_index' creation initiated.
Polling to check if the index is ready. This may take up to a minute.
vector_index is ready for querying.
Enter a session ID: 123
Enter your query (or type 'quit' to exit): What was MongoDB's latest acquisition?
Tool selected: vector_search_tool
Answer:
MongoDB's latest acquisition was Voyage AI.
Enter your query (or type 'quit' to exit): What do they do?
Tool selected: vector_search_tool
Answer:
Voyage AI is a company that specializes in state-of-the-art embedding and reranking models designed to power next-generation AI applications. These technologies help organizations build more advanced and trustworthy AI capabilities.
Enter your query (or type 'quit' to exit): What is 123+456?
Tool selected: calculator_tool
Answer:
579

Dica

Se estiver usando o Atlas, você poderá verificar suas embeddings e interações navegando até o namespace ai_agent_db.embeddings na IU do Atlas.

8

Agora que você possui um agente básico de AI, você pode continuar a desenvolvê-lo da seguinte maneira:

  • Melhorando o desempenho das suas ferramentas de pesquisa vetorial e pelo ajuste fino dos seus pipelines RAG.

  • Adicionar mais ferramentas ao agente, como ferramentas de pesquisa híbridas ou de texto completo.

  • Aprimorando a fase de planejamento ao utilizar prompts mais avançados e chamadas de LLM.

  • Implementar memória de longo prazo e sistemas de memória mais avançados usando o MongoDB Search e o MongoDB pesquisa vetorial para armazenar e recuperar interações importantes entre sessões.

Para mais tutoriais sobre a construção de agentes de AI com o MongoDB, consulte a tabela a seguir: