Para agentes de IA: hay un índice de documentación disponible en https://www.mongodb.com/es/docs/llms.txt; las versiones en Markdown de todas las páginas están disponibles agregando .md a cualquier ruta URL.
Make the MongoDB docs better! We value your opinion. Share your feedback for a chance to win $100.
MongoDB Branding Shape
Click here >
Docs Menu

Compila agentes de IA con MongoDB

MongoDB ofrece varias características para desarrollar agentes de IA. Como base de datos tanto de vectores como de documentos, MongoDB admite varios métodos de búsqueda para RAG agéntica, así como el almacenamiento de interacciones de agentes en la misma base de datos para la memoria a corto y largo plazo de los agentes.

Empezar

En el contexto de la IA generativa, un agente de IA generalmente se refiere a un sistema que puede completar una tarea de forma autónoma o semiautónoma al combinar modelos de IA, como los LLM, con un conjunto de herramientas predefinidas.

Los agentes de IA pueden utilizar herramientas para recopilar contexto, interactuar con sistemas externos y realizar acciones. Ellos pueden definir su propio flujo de ejecución (planificación) y recordar las interacciones anteriores para informar sus respuestas (memoria). Por lo tanto, los agentes de IA son los más adecuados para tareas complejas que requieren razonamiento, planificación y toma de decisiones.

Diagrama que muestra una arquitectura de agente único con MongoDB

Un agente de IA suele incluir una combinación de los siguientes componentes:

Percepción

Su entrada para el agente. Las entradas de texto son el mecanismo de percepción más común para los agentes de IA, pero las entradas también pueden ser de audio, imágenes o datos multimodales.

Planificación

Cómo el agente determina qué hacer a continuación. Este componente típicamente incluye LLMs y prompts, utilizando bucles de retroalimentación y varias técnicas de ingeniería de prompts como chain-of-thought y reAct, para ayudar al LLM a razonar a través de tareas complejas.

Los agentes de IA pueden consistir en un solo LLM como responsable de la toma de decisiones, un LLM con múltiples indicaciones, múltiples LLM trabajando juntos, o cualquier combinación de estos enfoques.

Herramientas

Cómo el agente recopila el contexto para una tarea. Las herramientas permiten la interacción de los agentes con sistemas externos y realizar acciones como la búsqueda vectorial, la búsqueda en la web o la llamada a APIs de otros servicios.

Memoria

Un sistema para almacenar interacciones de agentes, de modo que el agente pueda aprender de experiencias pasadas para informar sus respuestas. La memoria puede ser de corto plazo (para la sesión actual) o de largo plazo (persistente a través de las sesiones).

Nota

Los agentes de IA varían en el patrón de diseño, la función y la complejidad. Para aprender sobre otras arquitecturas de agentes, incluidos los sistemas multiagente, consultar Patrones de diseño Agentic.

MongoDB admite los siguientes componentes para desarrollar agentes de IA:

  • Herramientas: aprovechar las funcionalidades de búsqueda de MongoDB como herramientas para que el agente recupere información relevante e implemente el RAG agente.

  • Memoria: almacenar las interacciones del agente en colecciones de MongoDB para la memoria a corto y largo término.

En el contexto de los agentes de IA, una herramienta es cualquier cosa que pueda ser definida e invocada programáticamente por el agente. Las herramientas amplían las capacidades del agente más allá de generar texto, permitiéndole la interacción con sistemas externos, recuperar información y realizar acciones. Las herramientas suelen definirse con una interfaz específica que incluye:

  • Un nombre y una descripción que ayuden al agente a comprender cuándo debe usar la herramienta.

  • Parámetros requeridos y sus formatos esperados.

  • Una función que lleva a cabo la operación real al ser invocada.

El agente utiliza sus capacidades de razonamiento para determinar qué herramienta debe usar, cuándo debe usarla y qué parámetros debe proporcionar, basándose en la entrada del usuario y la tarea en cuestión.

Además de las queries estándar de MongoDB, MongoDB proporciona varias capacidades de búsqueda que se pueden implementar como herramientas para el agente.

  • MongoDB búsqueda vectorial: realiza una búsqueda vectorial para recuperar el contexto relevante basado en el significado semántico y la similitud. Para obtener más información, consulta MongoDB búsqueda vectorial Overview.

  • MongoDB Search: Realiza una búsqueda de texto completo para recuperar contextos relevantes en función de la coincidencia de palabras clave y la puntuación de relevancia. Para obtener más información, consulte Descripción general de MongoDB Search.

  • Búsqueda híbrida: combina la Búsqueda Vectorial de MongoDB con MongoDB Search para aprovechar los puntos fuertes de ambos enfoques. Para saber más, consulte Cómo realizar búsquedas híbridas.

Puedes definir herramientas manualmente o utilizando frameworks como LangChain y LangGraph, que proporcionan abstracciones con funcionalidad incorporada para la creación y el uso de herramientas.

Las herramientas se definen como funciones que el agente puede llamar para llevar a cabo tareas específicas. Por ejemplo, la siguiente sintaxis ilustra cómo podría definir una herramienta que ejecute una query de búsqueda vectorial:

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

Las llamadas a herramientas son lo que el agente utiliza para ejecutar las herramientas. Se puede definir cómo procesar las llamadas a herramientas en el agente, o usar un framework para la gestión. Por lo general, se definen como objetos JSON que incluyen el nombre de la herramienta y otros argumentos para pasar a la herramienta, de modo que el agente pueda llamar a la herramienta con los parámetros adecuados. Por ejemplo, la siguiente sintaxis muestra cómo un agente podría llamar a la herramienta de búsqueda vectorial:

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

Al utilizar MongoDB como base de datos vectorial, se pueden crear herramientas de recuperación que implementan RAG agéntica, que es una forma avanzada de RAG que permite orquestar dinámicamente el proceso de recuperación y generación a través de un agente de IA.

Diagrama que muestra una arquitectura RAG agentic con MongoDB

Este enfoque permite flujos de trabajo e interacciones de usuario más complejas. Por ejemplo, se puede configurar el agente de IA para determinar la herramienta óptima de recuperación según la tarea, como usar MongoDB Vector Search para búsqueda semántica y MongoDB Search para búsqueda en texto completo. También se puede definir distintas herramientas de recuperación para diferentes colecciones para personalizar aún más las capacidades de recuperación del agente.

La memoria de los agentes implica almacenar información sobre interacciones anteriores, para que el agente pueda aprender de experiencias pasadas y proporcionar respuestas más relevantes y personalizadas. Esto es particularmente importante para tareas que requieren contexto, como los agentes conversacionales, donde el agente necesita recordar los turnos anteriores de la conversación para proporcionar respuestas coherentes y contextualmente relevantes. Existen dos tipos primarios de memoria de agente:

  • Memoria a corto plazo: almacena información para la sesión actual, como los turnos recientes de conversación y el contexto de la tarea activa.

  • Memoria a largo plazo: persiste la información entre las sesiones, lo que puede incluir conversaciones pasadas y preferencias personalizadas a lo largo del tiempo.

Dado que MongoDB también es una base de datos de documentos, puedes implementar memoria para agentes almacenando tus interacciones en una colección de MongoDB. El agente puede entonces query o actualizar esta colección según sea necesario. Existen varias maneras de implementar la memoria del agente con MongoDB:

  • Para la memoria a corto plazo, se podría incluir un campo session_id para identificar una sesión específica al almacenar las interacciones y luego ejecutar una query para las interacciones con el mismo ID para pasarlas al agente como contexto.

  • Para la memoria a largo plazo, se podrían procesar varias interacciones con un LLM para extraer información relevante, como las preferencias del usuario o un contexto importante, y luego almacenar esta información en una colección separada que el agente pueda realizar una query cuando sea necesario.

  • Para crear sistemas de gestión de memoria sólidos que permitan una recuperación más eficiente y compleja de historiales de conversación, utiliza MongoDB Search o MongoDB Vector Search para almacenar, indexar y consultar interacciones importantes entre sesiones.

Un documento en una colección que almacena memoria a corto plazo podría parecerse a lo siguiente:

{
"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"
}
]
}

Un documento en una colección que almacena memoria a largo plazo podría parecerse a lo siguiente:

{
"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"],
}
]
}

Los siguientes frameworks también proporcionan abstracciones directas para la memoria del agente con MongoDB:

Marco
Características

LangChain

  • MongoDBChatMessageHistory: componente de historial de mensajes de chat

  • MongoDBAtlasSemanticCache: componente de caché semántico

Para obtener más información, consulta el tutorial.

LangGraph

  • MongoDBSaver: un verificador de memoria a corto plazo que se puede utilizar para la persistencia

  • MongoDBStore: almacén de documento a largo plazo para almacenar datos en MongoDB (disponible solo en la integración con Python)

Para obtener más información, consulta LangGraph y LangGraph.js.

El siguiente tutorial demuestra cómo compilar un agente de IA utilizando MongoDB para RAG agentic y memoria, sin un marco de agentes.


➤ Utiliza el menú desplegable Seleccionar su lenguaje para establecer el lenguaje de este tutorial.


Trabaja con una versión ejecutable de este tutorial como un cuaderno interactivo de Python.

Para completar este tutorial, debes tener lo siguiente:

  • Uno de los siguientes tipos de clúster de MongoDB:

  • Una clave API de Voyage IA.

  • Una clave de API de OpenAI.

Nota

Este tutorial utiliza modelos de Voyage IA y OpenAI, pero se puede modificar el código para usar los modelos que se prefieran.

Este agente de IA puede utilizarse para responder preguntas sobre una fuente de datos personalizada y realizar cálculos. También puede recordar anteriores interacciones para informar sus respuestas. Utiliza los siguientes componentes:

  • Percepción: entradas de texto.

  • Planificación: un LLM y varios prompts para razonar a través de la tarea.

  • Herramientas: una herramienta de búsqueda vectorial y una herramienta de calculadora.

  • Memoria: almacena las interacciones en una colección de MongoDB.

1
  1. Inicialice el proyecto e instale las dependencias.

    Cree un nuevo directorio de proyecto y luego instale las dependencias necesarias:

    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

    Nota

    Su proyecto utilizará la siguiente estructura:

    mongodb-ai-agent
    ├── .env
    ├── config.js
    ├── ingest-data.js
    ├── tools.js
    ├── memory.js
    ├── planning.js
    └── index.js
  2. Configura el entorno.

    Se debe crear un archivo de entorno llamado .env en el proyecto. Este archivo contendrá claves API para el agente, la cadena de conexión de MongoDB y los nombres de la base de datos y la colección de MongoDB.

    Se debe copiar y pegar el siguiente código en el archivo .env.

    Se deben reemplazar los valores de marcador con la cadena de conexión de MongoDB y las claves de API de Voyage AI y OpenAI.

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

    Nota

    Se debe sustituir <connection-string> por la cadena de conexión del clúster Atlas o de la implementación local de Atlas.

    Su cadena de conexión debe usar el siguiente formato:

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

    Para obtener más información, consulte Conéctese a un clúster mediante Librerías de clientes.

    Su cadena de conexión debe usar el siguiente formato:

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

    Para obtener más información, consulta Cadenas de conexión.

2

Cree un archivo llamado config.js en su proyecto. Este archivo leerá sus variables de entorno y conectará la aplicación a servicios como la base de datos MongoDB y OpenAI.

Se debe copiar y pegar el siguiente código en el archivo 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

Se debe crear un archivo llamado ingest-data.js en el proyecto. Este script ingiere un PDF de muestra que contiene un informe de ganancias reciente de MongoDB en una colección en MongoDB utilizando el modelo de incrustación voyage-3-large. Este código también incluye una función para crear un índice de búsqueda vectorial sobre los datos si aún no existe.

Para aprender más, consulta Ingestión.

Copie y pegue el siguiente código en su archivo ingest-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

Se debe crear un archivo llamado tools.js en el proyecto. Este archivo define las herramientas que el agente puede usar para responder preguntas. En este ejemplo, el usuario define las siguientes herramientas:

  • vectorSearchTool: se ejecuta una query de búsqueda vectorial para recuperar documentos relevantes de su colección.

  • calculatorTool: usa la biblioteca mathjs para operaciones matemáticas básicas.

Se debe copiar y pegar el siguiente código en el archivo 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

Se debe crear un archivo llamado memory.js en el proyecto. Este archivo define el sistema que el agente utiliza para almacenar sus interacciones. En este ejemplo, se implementa la memoria a corto plazo definiendo las siguientes funciones:

  • storeChatMessage: para almacenar información sobre una interacción en una colección de MongoDB.

  • retrieveSessionHistory: para obtener todas las interacciones de una sesión específica usando el campo session_id.

Copie y pegue el siguiente código en su archivo 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

Se debe crear un archivo llamado planning.js en el proyecto. Este archivo incluirá varias indicaciones y llamadas de LLM para determinar el flujo de ejecución del agente. En este ejemplo, se debe definir las siguientes funciones:

  • openAIChatCompletion: función asistente para llamar la API de OpenAI y generar respuestas.

  • toolSelector: Determina cómo el LLM selecciona la herramienta adecuada para una tarea.

  • generateAnswer: orquesta el flujo de ejecución del agente utilizando herramientas, llamando al LLM y procesando los resultados.

  • getLLMResponse: función de asistencia para la generación de respuestas de LLM.

Copie y pegue el siguiente código en su archivo 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 último, se debe crear un archivo llamado index.js en el proyecto. Este archivo ejecuta el agente y permite interactuar con él.

Se debe copiar y pegar el siguiente código en el archivo 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();

Guardar el proyecto y luego ejecutar el siguiente comando. Cuando se ejecute el agente:

  • Si aún no lo ha hecho, instruya al agente para que ingiera los datos de muestra.

  • Introducir un ID de sesión para iniciar una nueva sesión o continuar una sesión existente.

  • Haz preguntas. El agente genera una respuesta basada en tus herramientas, las interacciones anteriores y las indicaciones definidas en la fase de planificación.

Consulte el ejemplo de salida para una interacción de muestra:

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

Tip

Si utilizas Atlas, puedes verificar tus incrustaciones e interacciones navegando al espacio de nombres ai_agent_db.embeddings en la Interfaz de Usuario de Atlas.

8

Ahora que tiene un agente de IA básico, puede seguir desarrollándolo mediante:

  • Mejorando el rendimiento de las herramientas de búsqueda vectorial y ajustando sus pipelines de RAG.

  • Añadir más herramientas al agente, como herramientas híbridas o de búsqueda de texto completo.

  • Se refine la fase de planificación mediante el uso de indicaciones más avanzadas y llamadas de LLM.

  • Implementación de la memoria a largo plazo y sistemas de memoria más avanzados utilizando MongoDB Search y MongoDB búsqueda vectorial para almacenar y recuperar interacciones importantes entre sesiones.

1
  1. Inicialice el proyecto e instale las dependencias.

    Cree un nuevo directorio de proyecto y luego instale las dependencias necesarias:

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

    Nota

    Su proyecto utilizará la siguiente estructura:

    mongodb-ai-agent
    ├── .env
    ├── config.py
    ├── ingest_data.py
    ├── tools.py
    ├── memory.py
    ├── planning.py
    ├── main.py
  2. Configura el entorno.

    Se debe crear un archivo de entorno llamado .env en el proyecto. Este archivo contendrá claves API para el agente, la cadena de conexión de MongoDB y los nombres de la base de datos y la colección de MongoDB.

    Se debe copiar y pegar el siguiente código en el archivo .env.

    Se deben reemplazar los valores de marcador con la cadena de conexión de MongoDB y las claves de API de Voyage AI y OpenAI.

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

    Nota

    Se debe sustituir <connection-string> por la cadena de conexión del clúster Atlas o de la implementación local de Atlas.

    Su cadena de conexión debe usar el siguiente formato:

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

    Para obtener más información, consulte Conéctese a un clúster mediante Librerías de clientes.

    Su cadena de conexión debe usar el siguiente formato:

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

    Para obtener más información, consulta Cadenas de conexión.

2

Cree un archivo llamado config.py en su proyecto. Este archivo leerá sus variables de entorno y conectará la aplicación a servicios como la base de datos MongoDB y OpenAI.

Se debe copiar y pegar el siguiente código en el archivo 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

Se debe crear un archivo llamado ingest_data.py en el proyecto. Este script ingiere un PDF de muestra que contiene un informe de ganancias reciente de MongoDB en una colección en MongoDB utilizando el modelo de incrustación voyage-3-large. Este código también incluye una función para crear un índice de búsqueda vectorial sobre los datos si aún no existe.

Para aprender más, consulta Ingestión.

Copie y pegue el siguiente código en su archivo ingest_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

Se debe crear un archivo llamado tools.py en el proyecto. Este archivo define las herramientas que el agente puede usar para responder preguntas. En este ejemplo, el usuario define las siguientes herramientas:

  • vector_search_tool: se ejecuta una query de búsqueda vectorial para recuperar documentos relevantes de su colección.

  • calculator_tool: se usa la función eval() para operaciones matemáticas básicas.

Se debe copiar y pegar el siguiente código en el archivo 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

Se debe crear un archivo llamado memory.py en el proyecto. Este archivo define el sistema que el agente utiliza para almacenar sus interacciones. En este ejemplo, se implementa la memoria a corto plazo definiendo las siguientes funciones:

  • store_chat_message: para almacenar información sobre una interacción en una colección de MongoDB.

  • retrieve_session_history: para obtener todas las interacciones de una sesión específica usando el campo session_id.

Se debe copiar y pegar el siguiente código en el archivo 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

Se debe crear un archivo llamado planning.py en el proyecto. Este archivo incluirá varias indicaciones y llamadas de LLM para determinar el flujo de ejecución del agente. En este ejemplo, se debe definir las siguientes funciones:

  • tool_selector: Determina cómo el LLM selecciona la herramienta adecuada para una tarea.

  • generate_answer: orquesta el flujo de ejecución del agente utilizando herramientas, llamando al LLM y procesando los resultados.

  • get_llm_response: función de asistencia para la generación de respuestas de LLM.

Se debe copiar y pegar el siguiente código en el archivo 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 último, se debe crear un archivo llamado main.py en el proyecto. Este archivo ejecuta el agente y permite interactuar con él.

Se debe copiar y pegar el siguiente código en el archivo main.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()

Guardar el proyecto y luego ejecutar el siguiente comando. Cuando se ejecute el agente:

  • Si aún no lo ha hecho, instruya al agente para que ingiera los datos de muestra.

  • Introducir un ID de sesión para iniciar una nueva sesión o continuar una sesión existente.

  • Haz preguntas. El agente genera una respuesta basada en tus herramientas, las interacciones anteriores y las indicaciones definidas en la fase de planificación.

Consulte el ejemplo de salida para una interacción de muestra:

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

Tip

Si utilizas Atlas, puedes verificar tus incrustaciones e interacciones navegando al espacio de nombres ai_agent_db.embeddings en la Interfaz de Usuario de Atlas.

8

Ahora que tiene un agente de IA básico, puede seguir desarrollándolo mediante:

  • Mejorando el rendimiento de las herramientas de búsqueda vectorial y ajustando sus pipelines de RAG.

  • Añadir más herramientas al agente, como herramientas híbridas o de búsqueda de texto completo.

  • Se refine la fase de planificación mediante el uso de indicaciones más avanzadas y llamadas de LLM.

  • Implementación de la memoria a largo plazo y sistemas de memoria más avanzados utilizando MongoDB Search y MongoDB búsqueda vectorial para almacenar y recuperar interacciones importantes entre sesiones.

Para obtener más tutoriales sobre la creación de agentes de IA con MongoDB, consulte la siguiente tabla: