diff --git a/quickstart-agent-typescript.md b/quickstart-agent-typescript.md new file mode 100644 index 0000000..94c47cf --- /dev/null +++ b/quickstart-agent-typescript.md @@ -0,0 +1,333 @@ +--- +title: Quickstart - AI Agent with Vector Search in TypeScript +description: Learn how to build an AI agent using TypeScript with vector search in Azure DocumentDB. Create intelligent hotel recommendation agents that use semantic search with LangChain. +ms.date: 02/06/2026 +ms.topic: quickstart-sdk +ms.custom: devx-track-ts +ai-usage: ai-assisted +# CustomerIntent: As a developer, I want to learn how to build AI agents with vector search in TypeScript applications with Azure DocumentDB. +--- + +# Quickstart: AI Agent with vector search in Azure DocumentDB using TypeScript + +Build an intelligent AI agent by using TypeScript and Azure DocumentDB. This quickstart demonstrates a two-agent architecture that performs semantic hotel search and generates personalized recommendations. + +> [!IMPORTANT] +> This sample uses LangChain, a popular framework for building AI applications. LangChain provides abstractions for agents, tools, and prompts that simplify agent development. + +## Prerequisites + +You can use the Azure Developer CLI to create the required Azure resources by running the `azd` commands in the sample repository. For more information, see [Deploy Infrastructure with Azure Developer CLI](https://github.com/Azure-Samples/documentdb-samples/). + +### Azure resources + +- **Azure OpenAI resource** with the following model deployments in Microsoft Azure AI Foundry: + - `gpt-4o` deployment (Synthesizer Agent) - Recommended: **50,000 tokens per minute (TPM)** capacity + - `gpt-4o-mini` deployment (Planner Agent) - Recommended: **30,000 tokens per minute (TPM)** capacity + - `text-embedding-3-small` deployment (Embeddings) - Recommended: **10,000 tokens per minute (TPM)** capacity + - **Token quotas**: Configure sufficient TPM for each deployment to avoid rate limiting + - See [Manage Azure OpenAI quotas](/azure/ai-services/openai/how-to/quota) for quota management + - If you encounter 429 errors, increase your TPM quota or reduce request frequency + +- **Azure DocumentDB (with MongoDB compatibility) cluster** with vector search support: + - **Cluster tier requirements** based on vector index algorithm: + - **IVF (Inverted File Index)**: M10 or higher (default algorithm) + - **HNSW (Hierarchical Navigable Small World)**: M30 or higher (graph-based) + - **DiskANN**: M40 or higher (optimized for large-scale) + - **Firewall configuration**: REQUIRED. Without proper firewall configuration, connection attempts fail + - Add your client IP address to the cluster's firewall rules. For more information, see [Grant access from your IP address](/azure/documentdb/how-to-configure-firewall#grant-access-from-your-ip-address). + - For passwordless authentication, Role Based Access Control (RBAC) enabled + +### Development tools + +- [Node.js](https://nodejs.org/) 18 or later +- [TypeScript](https://www.typescriptlang.org/) 5.0 or later +- [Azure CLI](/cli/azure/install-azure-cli) for authentication + +## Architecture + +The sample uses a two-agent architecture where each agent has a specific role. + +:::image type="content" source="media/quickstart-agent-typescript/agent-architecture-typescript.svg" alt-text="Architecture diagram showing the two-agent workflow with planner agent, vector search tool, and synthesizer agent." border="false"::: + +This sample uses LangChain's agent framework with the OpenAI SDK. It leverages LangChain's function calling abstractions for tool integration and follows a linear workflow between the agents and the search tool. The execution is stateless with no conversation history, making it suitable for single-turn query and response scenarios. + +## Get the sample code + +1. Clone or download the repository [Azure DocumentDB Samples](https://github.com/Azure-Samples/documentdb-samples/) to your local machine to follow the quickstart. + +1. Navigate to the project directory: + + ```bash + cd ai/vector-search-agent-ts + ``` + +## Configure environment variables + +Create a `.env` file in your project root to configure environment variables. You can create a copy of the `.env.sample` file from the repository. + +Edit the `.env` file and replace these placeholder values: + +This quickstart uses a two-agent architecture (planner + synthesizer) with three model deployments (two chat models + embeddings). The environment variables are configured for each model deployment. + +- `AZURE_OPENAI_PLANNER_DEPLOYMENT`: Your gpt-4o-mini deployment name +- `AZURE_OPENAI_SYNTH_DEPLOYMENT`: Your gpt-4o deployment name +- `AZURE_OPENAI_EMBEDDING_MODEL`: Your text-embedding-3-small deployment name (for passwordless) or `AZURE_OPENAI_EMBEDDING_DEPLOYMENT` (for API key) + +You can choose between two authentication methods: passwordless authentication using Azure Identity (recommended) or traditional connection string and API key. + +### Option 1: Passwordless authentication + +Use passwordless authentication with both Azure OpenAI and Azure DocumentDB. Set `USE_PASSWORDLESS=true`, `AZURE_OPENAI_ENDPOINT`, and `AZURE_DOCUMENTDB_CLUSTER`. + +```.env +# Enable passwordless authentication +USE_PASSWORDLESS=true + +# Azure OpenAI Configuration (passwordless) +AZURE_OPENAI_ENDPOINT=your-openai-endpoint +AZURE_OPENAI_PLANNER_DEPLOYMENT=gpt-4o-mini +AZURE_OPENAI_PLANNER_API_VERSION=2024-08-01-preview +AZURE_OPENAI_SYNTH_DEPLOYMENT=gpt-4o +AZURE_OPENAI_SYNTH_API_VERSION=2024-08-01-preview +AZURE_OPENAI_EMBEDDING_MODEL=text-embedding-3-small +AZURE_OPENAI_EMBEDDING_API_VERSION=2023-05-15 + +# Azure DocumentDB (passwordless) +AZURE_DOCUMENTDB_CLUSTER=your-mongo-cluster-name +AZURE_DOCUMENTDB_DATABASENAME=Hotels +AZURE_DOCUMENTDB_COLLECTION=hotel_data + +# Data Configuration +DATA_FILE_WITHOUT_VECTORS=../data/Hotels.json + +# Vector Index Configuration +VECTOR_INDEX_ALGORITHM=vector-ivf +EMBEDDING_DIMENSIONS=1536 +``` + +**Prerequisites for passwordless authentication:** +- Ensure you're signed in to Azure: `az login` +- Grant your identity the following roles: + - `Cognitive Services OpenAI User` on the Azure OpenAI resource + - `DocumentDB Account Contributor` and `Cosmos DB Account Reader Role` on the Azure DocumentDB resource + + For more information about assigning roles, see [Assign Azure roles using the Azure portal](/azure/role-based-access-control/role-assignments-portal). + +### Option 2: Connection string and API key authentication + +Use key-based authentication by setting `USE_PASSWORDLESS=false` (or omitting it) and providing `AZURE_OPENAI_API_KEY` and `AZURE_DOCUMENTDB_CONNECTION_STRING` values in your `.env` file. + +```.env +# Disable passwordless authentication +USE_PASSWORDLESS=false + +# Azure OpenAI Configuration (API key) +AZURE_OPENAI_ENDPOINT=your-openai-endpoint +AZURE_OPENAI_API_KEY=your-azure-openai-api-key +AZURE_OPENAI_PLANNER_DEPLOYMENT=gpt-4o-mini +AZURE_OPENAI_PLANNER_API_VERSION=2024-08-01-preview +AZURE_OPENAI_SYNTH_DEPLOYMENT=gpt-4o +AZURE_OPENAI_SYNTH_API_VERSION=2024-08-01-preview +AZURE_OPENAI_EMBEDDING_DEPLOYMENT=text-embedding-3-small +AZURE_OPENAI_EMBEDDING_API_VERSION=2023-05-15 + +# Azure DocumentDB (connection string) +AZURE_DOCUMENTDB_CLUSTER=your-mongo-cluster-name +AZURE_DOCUMENTDB_CONNECTION_STRING=mongodb+srv://username:password@cluster.mongocluster.cosmos.azure.com/ +AZURE_DOCUMENTDB_DATABASENAME=Hotels +AZURE_DOCUMENTDB_COLLECTION=hotel_data + +# Data Configuration +DATA_FILE_WITHOUT_VECTORS=../data/Hotels.json + +# Vector Index Configuration +VECTOR_INDEX_ALGORITHM=vector-ivf +EMBEDDING_DIMENSIONS=1536 +``` + +## Project structure + +The project follows a standard Node.js/TypeScript project layout. Your directory structure should look like the following structure: + +``` +vector-search-agent-ts/ +├── src/ +│ ├── agent.ts # Main agent application +│ ├── upload-documents.ts # Data upload utility +│ ├── cleanup.ts # Database cleanup utility +│ ├── vector-store.ts # Vector store and tool implementation +│ ├── utils/ +│ │ ├── clients.ts # Azure OpenAI and DocumentDB client setup +│ │ ├── prompts.ts # System prompts and tool definitions +│ │ ├── types.ts # TypeScript type definitions +│ │ └── mongo.ts # MongoDB utility functions +│ └── scripts/ # Additional utility scripts +├── .env # Environment variable configuration +├── package.json # npm dependencies and scripts +└── tsconfig.json # TypeScript configuration +``` + +## Explore the code + +This section walks through the core components of the AI agent workflow. It highlights how the agents process requests, how tools connect the AI to the database, and how prompts guide the AI's behavior. + +### Agent application + +The `src/agent.ts` file orchestrates an AI-powered hotel recommendation system. + +The application uses two Azure services: + +- Azure OpenAI that uses AI models that understand queries and generate recommendations +- Azure DocumentDB that stores hotel data and performs vector similarity searches + +#### Agent and tool components + +The three components work together to process the hotel search request: + +- **Planner agent** - Interprets the request and decides how to search +- **Vector search tool** - Finds hotels similar to what the planner agent describes +- **Synthesizer agent** - Writes a helpful recommendation based on search results + +#### Application workflow + +The application processes a hotel search request in two steps: + +- **Planning:** The workflow calls the planner agent, which analyzes the user's query (like "hotels near running trails") and searches the database for matching hotels. +- **Synthesizing:** The workflow calls the synthesizer agent, which reviews the search results and writes a personalized recommendation explaining which hotels best match the request. + +:::code language="typescript" source="~/documentdb-samples/ai/vector-search-agent-ts/src/agent.ts" range="72-96"::: + +### Agents + +The `src/agent.ts` source file implements the planner and synthesizer agents that work together to process hotel search requests. + +#### Planner agent + +The planner agent is the *decision maker* that determines how to search for hotels. + +The planner agent receives the user's natural language query and sends it to an AI model using LangChain's agent framework along with available tools it can use. The AI decides to call the vector search tool and provides search parameters. LangChain handles the tool execution automatically and returns the matching hotels. Instead of hardcoding search logic, the AI interprets what the user wants and chooses how to search, making the system flexible for different types of queries. + +:::code language="typescript" source="~/documentdb-samples/ai/vector-search-agent-ts/src/agent.ts" range="12-45"::: + +#### Synthesizer agent + +The synthesizer agent is the *writer* that creates helpful recommendations. + +The synthesizer agent receives the original user query along with the hotel search results. It sends everything to an AI model with instructions for writing recommendations. It returns a natural language response that compares hotels and explains the best options. This approach matters because raw search results aren't user-friendly. The synthesizer transforms database records into a conversational recommendation that explains why certain hotels match the user's needs. + +:::code language="typescript" source="~/documentdb-samples/ai/vector-search-agent-ts/src/agent.ts" range="48-69"::: + +### Agent tools + +The `src/vector-store.ts` source file defines the vector search tool that the planner agent uses. + +The tools file defines a search tool that the AI agent can use to find hotels. This tool is how the agent connects to the database. The AI doesn't search the database directly. It asks to use the search tool, and the tool executes the actual search. + +#### Tool definition + +LangChain's `tool` function creates a tool from a regular TypeScript function. The tool definition includes the name, description, and schema (using Zod for validation). This definition lets the AI know the tool exists and how to use it correctly. + +:::code language="typescript" source="~/documentdb-samples/ai/vector-search-agent-ts/src/vector-store.ts" range="144-176"::: + +#### Tool execution + +When the AI calls the tool, the function body runs. It generates an embedding by converting the text query into a numeric vector using Azure OpenAI's embedding model. Then it searches the database by sending the vector to Azure DocumentDB, which finds hotels with similar vectors meaning similar descriptions. Finally, it formats results by converting the database records into readable text that the synthesizer agent can understand. + +The implementation leverages LangChain's `AzureCosmosDBMongoDBVectorStore` for seamless integration with Azure DocumentDB. + +#### Why use this pattern? + +Separating the tool from the agent provides flexibility. The AI decides when to search and what to search for, while the tool handles how to search. You can add more tools without changing the agent logic. + +### Prompts + +The `src/utils/prompts.ts` source file contains system prompts and tool definitions for the agents. + +The prompts file defines the instructions and context given to the AI models for both the planner and synthesizer agents. These prompts guide the AI's behavior and ensure it understands its role in the workflow. + +The quality of AI responses depends heavily on clear instructions. These prompts set boundaries, define the output format, and focus the AI on the user's goal of making a decision. You can customize these prompts to change how the agents behave without modifying any code. + +:::code language="typescript" source="~/documentdb-samples/ai/vector-search-agent-ts/src/utils/prompts.ts" range="30-75"::: + +## Prepare the data + +The sample uses hotel data from a JSON file. The repository includes two versions: + +- `Hotels.json` - Hotel data without vector embeddings (used by this sample) +- `Hotels_Vector.json` - Hotel data with pre-computed embeddings (used by other samples) + +The upload script automatically generates embeddings from the `Hotels.json` file using the Azure OpenAI embedding model, so you don't need to pre-compute them. + +## Run the sample + +1. Install dependencies: + + ```bash + npm install + ``` + +1. Before running the agent, upload hotel data with embeddings. The `upload-documents.ts` command loads hotels from the JSON file, generates embeddings for each hotel using `text-embedding-3-small`, inserts documents into Azure DocumentDB, and creates a vector index. + + ```bash + npm run upload + ``` + +1. Run the hotel recommendation agent by using the `agent.ts` command. The agent calls the planner agent, the vector search, and the synthesizer agent. The output includes similarity scores, and the synthesizer agent's comparative analysis with recommendations. + + ```bash + npm start + ``` + + ```output + DEBUG mode is OFF + DEBUG_CALLBACKS length: 0 + Connected to existing vector store: Hotels.hotel_data + + --- PLANNER --- + Found 5 documents from vector store + Hotel: Nordick's Valley Motel, Score: 0.49866509437561035 + Hotel: White Mountain Lodge & Suites, Score: 0.48731985688209534 + Hotel: Trails End Motel, Score: 0.47985398769378662 + Hotel: Country Comfort Inn, Score: 0.47431993484497070 + Hotel: Lakefront Captain Inn, Score: 0.45787304639816284 + + --- SYNTHESIZER --- + Context size is 3233 characters + Output: 812 characters of final recommendation + + --- FINAL ANSWER --- + 1. COMPARISON SUMMARY: + • Nordick's Valley Motel has the highest rating (4.5) and offers free parking, air conditioning, and continental breakfast. It is located in Washington D.C., near historic attractions and trails. + • White Mountain Lodge & Suites is a resort with unique amenities like a pool, restaurant, and meditation gardens, but has the lowest rating (2.4). It is located in Denver, surrounded by forest trails. + • Trails End Motel is budget-friendly with a moderate rating (3.2), free parking, free wifi, and a restaurant. It is close to downtown Scottsdale and eateries. + + Key tradeoffs: + - Nordick's Valley Motel excels in rating and proximity to historic attractions but lacks a pool or free wifi. + - White Mountain Lodge & Suites offers resort-style amenities and forest trails but has the lowest rating. + - Trails End Motel balances affordability and essential amenities but has fewer unique features compared to the others. + + 2. BEST OVERALL: + Nordick's Valley Motel is the best choice for its high rating, proximity to trails and attractions, and free parking. + + 3. ALTERNATIVE PICKS: + • Choose White Mountain Lodge & Suites if you prioritize resort amenities and forest trails over rating. + • Choose Trails End Motel if affordability and proximity to downtown Scottsdale are your main concerns. + ``` + +## View and manage data in Visual Studio Code + +1. Select the [DocumentDB extension](https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-documentdb) in Visual Studio Code to connect to your Azure DocumentDB account. + +1. View the data and indexes in the Hotels database. + + :::image type="content" source="media/quickstart-agent-typescript/documentdb-view-data.png" alt-text="Visual Studio Code DocumentDB extension showing the vector search index and hotel documents."::: + +## Clean up resources + +Use the cleanup command to delete the test database when you're done. Run the following command: + +```bash +npm run cleanup +``` +Delete the resource group, DocumentDB account, and Azure OpenAI resource when you don't need them to avoid extra costs. diff --git a/typescript-agent-article-questions.md b/typescript-agent-article-questions.md new file mode 100644 index 0000000..f128a12 --- /dev/null +++ b/typescript-agent-article-questions.md @@ -0,0 +1,110 @@ +# TypeScript Agent Article - Questions and Issues + +This document lists questions and issues encountered while creating the TypeScript agent article for Azure DocumentDB. + +## Successfully Resolved + +The following items were successfully addressed in the article: + +1. **Architecture diagram reference** - Updated the image source to reference `media/quickstart-agent-typescript/agent-architecture-typescript.svg` (needs to be created separately in the docs repo) +2. **Code file links** - All code references point to the correct location: `~/documentdb-samples/ai/vector-search-agent-ts/` +3. **Authentication patterns** - Both passwordless and API key authentication methods documented based on the TypeScript implementation +4. **LangChain framework** - Documented the use of LangChain instead of custom implementation (key difference from Go version) +5. **Environment variables** - Adapted environment variable names to match TypeScript implementation: + - `AZURE_OPENAI_EMBEDDING_MODEL` for passwordless auth + - `AZURE_OPENAI_EMBEDDING_DEPLOYMENT` for API key auth +6. **npm scripts** - Updated commands to use npm instead of Go commands (`npm start`, `npm run upload`, `npm run cleanup`) + +## Questions and Issues + +### 1. Architecture Diagram +**Issue**: The article references `media/quickstart-agent-typescript/agent-architecture-typescript.svg` which doesn't exist yet. + +**Resolution needed**: +- Create a TypeScript-specific architecture diagram in the MicrosoftDocs repo +- OR reuse the Go diagram if the architecture is identical (just with different language) +- The diagram should show: User Query → Planner Agent → Vector Search Tool → Synthesizer Agent → Final Response + +### 2. Screenshot for Visual Studio Code +**Issue**: The article references `media/quickstart-agent-typescript/documentdb-view-data.png` which doesn't exist yet. + +**Resolution needed**: +- Take a screenshot of VS Code showing the Hotels database with the DocumentDB extension +- OR reuse the Go screenshot if the view is identical +- Ensure it shows the vector index and hotel documents + +### 3. Data File Path ✅ RESOLVED +**Previous Issue**: The TypeScript sample uses `DATA_FILE_WITHOUT_VECTORS` environment variable but the article didn't specify where this data file should come from. + +**Resolution**: +- Added `DATA_FILE_WITHOUT_VECTORS=../data/Hotels.json` to both .env examples +- Added "Prepare the data" section explaining the difference between `Hotels.json` and `Hotels_Vector.json` +- Clarified that the upload script generates embeddings automatically from `Hotels.json` + +### 4. Vector Index Algorithm Configuration +**Issue**: The TypeScript sample supports multiple vector index algorithms (IVF, HNSW, DiskANN) via `VECTOR_INDEX_ALGORITHM` environment variable. + +**Current situation**: +- Article mentions this in the .env examples with `VECTOR_INDEX_ALGORITHM=vector-ivf` +- But doesn't explain the different options or when to use each + +**Resolution needed**: +- Consider adding a section explaining the different vector index algorithms +- OR reference the vector search article that explains these options +- The Go article doesn't seem to cover this level of detail + +### 5. LangChain Dependencies +**Issue**: The TypeScript version uses specific LangChain packages that have version requirements. + +**Current package.json**: +```json +"@langchain/azure-cosmosdb": "^1.0.0", +"@langchain/core": "^1.0.6", +"@langchain/openai": "^1.1.2", +"langchain": "^1.0.6" +``` + +**Resolution needed**: +- Consider mentioning LangChain version requirements in prerequisites +- OR note that package.json manages dependencies automatically + +### 6. Debug Mode +**Issue**: The TypeScript sample has a DEBUG environment variable and debug callbacks, but this isn't documented in the article. + +**Current situation**: +- The code shows: `console.log(\`DEBUG mode is \${process.env.DEBUG === 'true' ? 'ON' : 'OFF'}\`);` +- Could be useful for developers troubleshooting + +**Resolution needed**: +- Optionally add a troubleshooting section mentioning DEBUG=true +- OR keep it as an undocumented feature + +### 7. API Version Differences +**Issue**: The API versions in the TypeScript sample differ from what might be standard. + +**Current versions in code**: +- Planner/Synth: `2024-08-01-preview` +- Embedding: `2023-05-15` + +**Resolution needed**: +- Verify these are the recommended API versions +- Update if newer stable versions are available + +## Differences from Go Version + +Key differences that were intentionally adapted for TypeScript: + +1. **Framework**: LangChain vs custom implementation +2. **Package manager**: npm vs Go modules +3. **Type system**: TypeScript types vs Go interfaces +4. **Async handling**: async/await vs Go goroutines +5. **Client creation**: LangChain clients vs OpenAI SDK directly +6. **Tool definition**: LangChain's `tool()` function vs custom implementation + +## Recommendations + +1. **Test the article**: Have someone follow the quickstart from scratch to identify any gaps +2. **Create visual assets**: Generate the architecture diagram and screenshot +3. **Verify code references**: Ensure all code snippets compile and line ranges are correct +4. **Update .env documentation**: Add the missing `DATA_FILE_WITHOUT_VECTORS` variable +5. **Cross-reference**: Link to the vector search TypeScript article for additional context on vector indexes