Cortex Agents simplify AI-powered data interactions via a REST API, combining hybrid search and accurate SQL generation. They streamline workflows by managing context retrieval, natural language to SQL conversion, and LLM orchestration. Response quality is enhanced with in-line citations, answer abstention, and multi-message context handling. Developers benefit from a single API call integration, real-time streamed responses, and reduced latency for optimized applications.
In this guide, we will see how to integrate the Cortex Agents (in Public Preview as of 01/12/2025) with Microsoft Teams.
Business users have typically relied on BI dashboards and reports for data insights, but these tools often lack flexibility, requiring users to wait on busy data analysts for updates. Cortex Agents addresses this with a natural language interface allowing organizations to develop conversational applications. This enables business users to query data in natural language and get accurate answers in near real time.
Under the hood it is a stateless REST API that unifies Cortex Search's hybrid search and Cortex Analyst's SQL generation (with 90%+ accuracy). It streamlines complex workflows by handling context retrieval, converting natural language to SQL via semantic models, and managing LLM orchestration and prompts. Enhanced with in-line citations, answer abstention for irrelevant queries, and multi-message conversation context management, it offers single API call integration, real-time streamed responses, and reduced latency. Together, these capabilities allow you to search sales conversations, translate text into SQL for analytical queries, and blend structured and unstructured data for natural language interactions.
Learn more about Cortex Agents, Cortex Analyst, and Cortex Search.
Microsoft Teams is a communication and collaboration platform designed to streamline workplace interactions. It allows teams to organize conversations by channels, send direct messages, share files, and integrate with other tools for a seamless workflow. Microsoft Teams also supports the deployment of bots and apps, making it a hub for productivity, quick information sharing, and team alignment across projects.
A conversationl interface using Cortex Agents REST API integrated with Microsoft Teams
Step 1: In Snowsight, create a SQL Worksheet and open setup.sql to execute all statements in order from top to bottom. This is to to create a database, schema, and tables SUPPORT_TICKETS and SUPPLY_CHAIN with data loaded from AWS S3 for both tables. And also to create Snowflake managed internal stages for storing the semantic model specification files and PDF documents.
Step 2: Use Snowsight to upload the support tickets semantic model spec file and the supply chain semantic model spec file to the DASH_SEMANTIC_MODELS stage.
Step 3: Use Snowsight to upload six PDF documents to the DASH_PDFS stage.
Step 4: In Snowsight, create a SQL Worksheet and open cortex_search_service.sql to execute all statements in order from top to bottom. This is to create a Cortex Search service for getting insights from the PDF documents. NOTE: PARSE_DOCUMENT is in Public Preview as of 01/12/2025.
Step 1. Select the Teams Toolkit extension icon on the left in the VS Code toolbar.
Step 2. Click on Create a New App
Step 3. Select Bot from the dropdown menu and then select Basic Bot
Step 4. Select JavaScript as the language
Step 5. Select location and give your application a name. For example, CortexBot
At this point, you should have a folder structure similar to the one shown below.
Click on Run > Start Debugging which launches your app in Teams App Test Tool in a web browser.
If all goes well, you will see an application that you can interact with in Teams App Test Tool as shown below. You will receive a welcome message from the bot, and you can send anything to the bot to get an echoed response.
Step 1: Download package.json and overwrite/copy-paste the contents in your package.json.
Step 2: Download index.js and overwrite/copy-paste the contents in your index.js.
Step 3: Download teamsBot.js and overwrite/copy-paste the contents in your teamsBot.js.
Step 4: Download new cortexChat.js and copy the file in the same folder.
Step 5: Download new snowflakeQueryExecutor.js and copy the file in the same folder.
Step 6: Download new jwtGenerator.js and copy the file in the same folder.
Step 7: Configure key-pair authentication and assign the public key to your user in Snowflake and store/save/copy the private key file (.p8) in the same folder.
Step 8: Set the following variables in existing env/.env.dev file:
DEMO_DATABASE='DASH_DB'
DEMO_SCHEMA='DASH_SCHEMA'
WAREHOUSE='DASH_S'
DEMO_USER='<your-user-name>'
DEMO_USER_ROLE='<your-user-role>'
DEMO_USER_PASSWORD='<your-user-pwd>'
SUPPORT_SEMANTIC_MODEL='@DASH_DB.DASH_SCHEMA.DASH_SEMANTIC_MODELS/support_tickets_semantic_model.yaml'
SUPPLY_CHAIN_SEMANTIC_MODEL='@DASH_DB.DASH_SCHEMA.DASH_SEMANTIC_MODELS/supply_chain_semantic_model.yaml'
SEARCH_SERVICE='DASH_DB.DASH_SCHEMA.vehicles_info'
ACCOUNT='<your-account-name>'
HOST='<your-org>.snowflakecomputing.com'
AGENT_ENDPOINT='https://<your-org>-<your-account>.snowflakecomputing.com/api/v2/cortex/agent:run'
# You may NOT edit below values
RSA_PRIVATE_KEY_PATH='rsa_key.p8'
MODEL = 'claude-3-5-sonnet'
At this point, you should have an updated folder structure similar to the one shown below.
In VS Code, click on Run > Start Debugging which launches your app in Teams App Test Tool in a web browser. If all goes well, you will see an application that you can interact with in Teams App Test Tool.
Let's ask the following questions.
These questions are correctly routed via the support tickets semantic model.
Question: Can you show me a breakdown of customer support tickets by service type cellular vs business internet?
In a few moments, you should see the following response:
Now let's ask this question.
Question: How many unique customers have raised a support ticket with a ‘Cellular' service type and have ‘Email' as their contact preference?
In a few moments, you should see the following response:
These questions are correctly routed to the vehicles info search service.
Question: What are the payment terms for Snowtires?
In a few moments, you should see the following response:
Now let's ask this question.
Question: What's the latest, most effective way to recycle rubber tires?
In a few moments, you should see the following response:
As you can see, now (business) users can directly get answers to their questions written in natural language using the Microsoft Teams app.
This question is correctly routed via the supply chain semantic model.
Question: What is the average shipping time for tires from Snowtires Automotive compared to average of our other suppliers?
As you may have noticed, there are four main classes teamsBot.js, cortexChat.js, snowflakeQueryExecutor.js and jwtGenerator.js.
Here are some things you should make a note of in case you'd like to extend or modify the application.
class TeamsBot extends TeamsActivityHandler
This is the main handler that orchestrates the interaction between the user and the application. When user enters a prompt/message/question, it first creates and instance of CortexChat class, then calls _retrieveResponse method. Then, if the response includes a SQl, then it creates an instance of SnowflakeQueryExecutor class and calls runQuery method to execute the query and convert the results in a dataframe that can be displayed to the user. In other cases, the response is displayed to the user which may also include citations.
class CortexChat
An instance of this class is constructed using parameters jwtGenerator, agentUrl, model, searchService, semanticModels and it has method _retrieveResponse() that calls the Cortex Agents REST API – which inturn calls other class methods to parse the response.
async _retrieveResponse(query, limit = 1) {
const headers = {
'X-Snowflake-Authorization-Token-Type': 'KEYPAIR_JWT',
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': `Bearer ${this.jwt}`
};
const data = {
model: this.model,
messages: [{ role: "user", content: [{ type: "text", text: query }] }],
tools: [
{ tool_spec: { type: "cortex_search", name: "vehicles_info_search" } },
{ tool_spec: { type: "cortex_analyst_text_to_sql", name: "support" } },
{ tool_spec: { type: "cortex_analyst_text_to_sql", name: "supply_chain" } }
],
tool_resources: {
vehicles_info_search: {
name: this.searchService,
max_results: limit,
title_column: "title",
id_column: "relative_path"
},
support: { semantic_model_file: this.semanticModels[0] },
supply_chain: { semantic_model_file: this.semanticModels[1] }
}
};
try {
const response = await fetch(this.agentUrl, { method: "POST", headers, body: JSON.stringify(data) });
if (!response.ok) throw new Error(`Response status: ${response.status}`);
return await this._parseResponse(response);
} catch (error) {
console.error("Error fetching response:", error);
return { text: "An error occurred." };
}
}
class JWTGenerator
This class is responsible for generating a Java Web Token (JWT) for authenticating Cortex Agents REST API calls.
class SnowflakeQueryExecutor
The response from Cortex Agents REST API can include SQL query for questions served by Cortex Analyst. This class is responsible for executing that SQL on the client and returning the response as a dataframe.
As next steps, follow these links to extend the Bot's functionality.
Congratulations! You've sucessfully integrated Cortex Agents with Microsoft Teams. I hope you found this guide both educational and inspiring.