<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Krishnan Srinivasan on Medium]]></title>
        <description><![CDATA[Stories by Krishnan Srinivasan on Medium]]></description>
        <link>https://medium.com/@krish.srinivasans?source=rss-cb9e0b4c6b11------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*BrLtD7zSzq1Lqte1qJSeiA.png</url>
            <title>Stories by Krishnan Srinivasan on Medium</title>
            <link>https://medium.com/@krish.srinivasans?source=rss-cb9e0b4c6b11------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 18 Oct 2026 06:10:37 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@krish.srinivasans/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Agentic AI in Action — Part 30 -Prompt Engineering vs Context Engineering. A Cortex AI Walkthrough]]></title>
            <link>https://pub.towardsai.net/agentic-ai-in-action-part-30-prompt-engineering-vs-context-engineering-a-cortex-ai-walkthrough-0a8b8704f2b8?source=rss-cb9e0b4c6b11------2</link>
            <guid isPermaLink="false">https://medium.com/p/0a8b8704f2b8</guid>
            <category><![CDATA[llm]]></category>
            <category><![CDATA[ai-agent]]></category>
            <category><![CDATA[ai]]></category>
            <category><![CDATA[generative-ai-tools]]></category>
            <category><![CDATA[snowflake]]></category>
            <dc:creator><![CDATA[Krishnan Srinivasan]]></dc:creator>
            <pubDate>Wed, 30 Sep 2026 17:31:02 GMT</pubDate>
            <atom:updated>2026-10-03T01:24:44.422Z</atom:updated>
            <content:encoded><![CDATA[<h3>Prompt Engineering vs Context Engineering. A Hands-on Cortex AI Walkthrough</h3><h4><em>An example demonstrating how the same prompt and instruction return different severity ratings depending on how much context is included.</em></h4><p>Prompt engineering and context engineering solve different problems, though the terms are sometimes used interchangeably. Context engineering describes a real shift in where the hard work moved once teams stopped writing one off prompts and started building agents that run for many turns, call tools, and carry state across a conversation.</p><p>This post lays out the difference with concrete examples, including a couple pulled from the kind of Cortex Agent work I do day to day. The goal is not to declare one discipline obsolete. Prompt engineering still matters. It just stopped being the whole job.</p><h3>What prompt engineering actually is</h3><p>Prompt engineering is the craft of writing the instruction that goes to the model in a single turn. It covers wording, structure, few shot examples, and formatting cues. Done well it reliably improves output for a bounded task where everything the model needs fits inside one well worded request.</p><p>A simple example. Asking a model to summarize a support ticket works better with a structured instruction than a vague one.</p><p><em>Summarize the ticket below in three sentences.<br>Include the customer’s core complaint, any troubleshooting steps already<br>attempted, and the requested resolution. Do not invent steps that were<br>not mentioned.</em></p><p><em>Ticket: {ticket_text}</em></p><p>That is prompt engineering doing its job well. The instruction is specific about format, scope, and what not to do. For a single call with all the information already in front of the model, this is often enough.</p><h3>Where it stops being enough</h3><p>The moment you build an agent that has to remember earlier decisions, pull from a knowledge base, call a tool, and act on the result, a better worded prompt cannot fix what is missing. If the ticket text was never retrieved, or the retrieval pulled the wrong document, no amount of prompt polish recovers the answer. The problem has moved from how you ask to what the model has in front of it when you ask.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*nskRJS2MkPze_0W9DDAyxg.png" /></figure><p>This is the gap context engineering fills. It is the discipline of designing and managing the entire information environment around the model rather than just the instruction. That environment typically includes the system instructions and tool definitions, the task and conversation state built up so far, retrieved knowledge from documents or databases, and the output of any tools already called. Prompt engineering happens inside that context window. Context engineering decides what fills the window in the first place. While prompt engineering works perfectly on its own for simple, single-turn tasks, building agentic workflows subsumes it into the much larger pipeline of context engineering. In such systems, prompt engineering becomes just one component of the larger context engineering ecosystem.</p><h3>A Cortex Agent example</h3><p>Take a helpdesk ticket triage agent built on Cortex Agents. A prompt only version of this agent gets a system instruction describing the triage policy and the ticket text, then asks the model to classify severity and route it.</p><p>That works until the agent needs to check whether the customer is on an enterprise contract before deciding severity, or needs to search for prior tickets from the same account to catch a repeat issue. At that point the design question is no longer about phrasing. It becomes which tools the agent has access to, what is exposed about account tier and ticket history, how much of that history gets pulled into context before it becomes noise, and how the tool’s structured output gets folded back into the next reasoning step.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*6mZ93ZRDfheYuypqyewNYw.png" /></figure><p>Walking through it step by step makes the difference concrete.</p><h3>Step 1. Set up the data</h3><p>A dedicated database ansd schema for maintanability.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/549/1*_tJYkDwDVkxlk448YVmMDA.png" /></figure><p>One table for tickets, one for accounts.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/446/1*WLJYTiEY4gSy-srpXsI81g.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/655/1*3AwykMY5lvwEwVUE4lgu1w.png" /></figure><p>The Accounts table has two entries. However, for this demonstration, we will consider the enterprise customer (ACC-100) on a four hour SLA, with two prior tickets about the same dashboard refresh running late, logged in the last month besides the one just opened.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/388/1*aMByZREaCFAG4HapqEyq0w.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*7EQuAIkTCwTcAkHiqCOpJA.png" /></figure><h3>Step 2. Run the prompt only version</h3><p>Just the ticket text and an instruction, nothing else. The instruction includes an explicit escalation rule, since handing the model facts without telling it what to do with them turned out not to be enough on its own.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/888/1*RCJUDg3Wow5NDIOzQBfwnw.png" /></figure><p>Three things worth flagging in that call. First, the temperature setting. Like most LLM inference, results can vary slightly run to run unless temperature is fixed, so setting it to 0 keeps this comparison deterministic and reproducible. Second, the prompt is wrapped as a single user message rather than passed as a bare string, since the three argument form of Complete that accepts an options object expects a message array for the second argument, not a plain string. Third, once that options argument is present, Complete returns an OBJECT rather than a plain string, with the model’s actual answer nested under choices[0].messages. Path directly into it, do not wrap it in PARSE_JSON, since it is already a parsed OBJECT and not a string to be parsed.</p><p>The escalation rule is in the instruction, but the only field available to test it against is ticket_text. There is no occurrence count and no SLA figure here, so the rule has nothing to fire on.</p><p>So, it evaluates the nature of the ticket purely as a standalone issue based on the prompt text, and without any additional context, ultimately marking it as low.</p><p>Actual output returned for this ticket:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*dLS09oQrKSmhZpvmQ2MXZw.png" /></figure><h3><strong>Step 3.Run the context engineered version</strong></h3><p>First pull together what the prompt alone could never see, account tier, SLA hours, and how many times this account has filed a similar ticket in the last 30 days. That last part matters enough to compute directly in SQL rather than leave for the model to work out by reading a block of ticket history, since asking a model to parse text and count occurrences in one pass is asking it to do arithmetic on unstructured input, and it does not reliably get that right.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*kFgBIi4U2BaUDi7Rv75Jkw.png" /></figure><p>Actual output for the same ticket, with the assembled context in front of it.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/701/1*rZQMgMRjS-L6gWTTbgCDbw.png" /></figure><p>Notice how the output has changed when the complete picture is available. Same escalation rule in both steps. The severity call flips from LOW to HIGH, and what changed between step 2 and step 3 is not just that more facts got added to the context, it is that the fact the rule actually depends on, the occurrence number, got computed upstream in SQL instead of left for the model to derive from raw text. That distinction, what gets precomputed versus what gets handed over raw and left for the model to reason about, is a context engineering decision in its own right.</p><p><em>In a real Cortex Agent deployment, the account tier, SLA hours, and recent history assembled by hand in step 3 would typically be exposed through a Semantic View instead, so the agent queries a governed, reusable definition rather than ad hoc joins baked into each call.</em></p><p>It is also worth being clear that the demo folds everything into a single query for the sake of a runnable example and ease of understanding. In a live agent, that same context could often arrive from several separate tool calls, one for account tier, one for SLA terms, one for ticket history, sometimes backed by different systems entirely, and it is the agent’s job to assemble those separate results into one coherent context before the final classification step. The comparison in this post is never prompt versus a single query. It is prompt versus everything the agent gathers and assembles before it answers (the context), however many calls that takes.</p><h3>The tool selection problem is a context problem in disguise</h3><p>The same agent extended with tools runs into a related problem. Say it also has access to search_prior_tickets and get_account_tier as separate tool calls. If those two tools overlap in what they return, or their descriptions do not make clearly which one to call for which piece of information, the agent can call the wrong one, or call the right one but pass it the wrong ticket or account identifier. The instinct is to rewrite the tool descriptions to be clearer. Sometimes that helps. More often the actual cause is that the tool set itself is ambiguous, two tools doing overlapping jobs, or that the context already in front of the agent buries the identifier it needs to call the tool correctly under unrelated history.</p><p>The fix is curation, not better wording. Keep each tool narrow enough that its purpose is unambiguous, and keep the context in front of the agent limited to what the current decision actually needs, rather than everything retrieved so far. Measuring tool selection accuracy separately from the accuracy of the final answer is what tells you whether a given failure sits in how the tool is described or in what the agent had in front of it when it chose.</p><h3>Where the two disciplines meet</h3><p>Prompt engineering and context engineering are not competitors. Prompt engineering operates at the interaction level, refining how you ask a single question well. Context engineering operates at the infrastructure level, deciding what the agent knows and can act on before it ever answers. A useful way to hold both at once is this. Prompt engineering is what you do inside the context window. Context engineering is the discipline of deciding what belongs in that window and what gets left out.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*FfUq5Bm5rkYzrHfAFfK9OA.png" /></figure><p>For anyone building agents rather than single turn assistants, the practical shift is to stop treating every failure as a wording problem. Before rewriting the system prompt again, it is worth asking whether the agent actually had the right document, the right tool, and the right slice of history in front of it when it produced the wrong answer. If it did not, no prompt could have fixed that.</p><p>The code for this blog can be accessed <a href="https://github.com/Krishsriniv/prompt-vs-context-engineering">here.</a></p><p><em>I share hands-on, implementation-focused perspectives on Generative &amp; Agentic AI, LLMs, Snowflake and Cortex AI, translating advanced capabilities into practical, real-world analytics use cases. Do follow me on </em><a href="https://www.linkedin.com/in/krishsrinivasans/"><em>LinkedIn</em></a><em> and </em><a href="https://medium.com/@krish.srinivasans"><em>Medium</em></a><em> for more such insights.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=0a8b8704f2b8" width="1" height="1" alt=""><hr><p><a href="https://pub.towardsai.net/agentic-ai-in-action-part-30-prompt-engineering-vs-context-engineering-a-cortex-ai-walkthrough-0a8b8704f2b8">Agentic AI in Action — Part 30 -Prompt Engineering vs Context Engineering. A Cortex AI Walkthrough</a> was originally published in <a href="https://pub.towardsai.net">Towards AI</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Agentic AI in Action — Part 29 — Cortex Agent Lineage Walkthrough, Built on Two Agents]]></title>
            <link>https://pub.towardsai.net/agentic-ai-in-action-part-29-cortex-agent-lineage-walkthrough-built-on-two-agents-2a56ff6a88bb?source=rss-cb9e0b4c6b11------2</link>
            <guid isPermaLink="false">https://medium.com/p/2a56ff6a88bb</guid>
            <category><![CDATA[generative-ai-tools]]></category>
            <category><![CDATA[ai-agent]]></category>
            <category><![CDATA[llm]]></category>
            <category><![CDATA[ai]]></category>
            <category><![CDATA[snowflake]]></category>
            <dc:creator><![CDATA[Krishnan Srinivasan]]></dc:creator>
            <pubDate>Tue, 22 Sep 2026 03:54:55 GMT</pubDate>
            <atom:updated>2026-09-22T04:48:58.860Z</atom:updated>
            <content:encoded><![CDATA[<h3>Cortex Agent Lineage Walkthrough, Built on Two Agents</h3><h4><em>Tracing a shared table across two Cortex Analyst agents, from source data to the agents that depend on it</em></h4><p>Every team running agents in production eventually hits the same question. Someone wants to rename a column, drop a table, or reshape a schema, and the room needs to know what depends on it downstream. Dashboards get checked. Pipelines get checked. Now, agents can be checked the same way, thanks to data lineage for Cortex Agents, which Snowflake added on September 2, 2026, tracing the path from a table through a semantic view to the agent that consumes it.</p><p>Rather than standing up a separate tracking system just for agents, Cortex Agents now show up in the same lineage graph that already tracks tables, views, and streams, so there is nothing new to learn if a team is already using lineage elsewhere. A semantic view that a Cortex Analyst tool references appears upstream of the agent, and since that semantic view is itself downstream of the tables it was built on, you get one continuous path from a raw table all the way to the agent consuming it, all inside infrastructure that already existed.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*T6x9O6d1rgrktyPKWDO91Q.png" /></figure><p>This post is a hands on walkthrough of that feature, built around a multi agent scenario rather than a single isolated one, two agents sitting on the same source table instead of just one. A single agent only shows a straight line. Two agents branching off a shared table is what actually makes the governance story visible, since you can watch one table fan out into two separate consumers in the graph rather than just being told it can happen, which is closer to how most accounts actually look once agents move past a first pilot.</p><h3>What You Need Before Starting</h3><p>A Snowflake account with Cortex Agents enabled, a role with CREATE AGENT and CREATE SEMANTIC VIEW privileges, and Enterprise Edition or higher since lineage requires it. The companion SQL file for this post runs top to bottom, so you can follow along here and just execute alongside it.</p><h3>Step 1: Create a Dedicated database and schema</h3><p>It helps to build this demo somewhere self contained, both so it does not clutter an existing database and so the lineage graph you look at later stays free of unrelated objects.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/505/1*gQQUgRVJW_fmBn57ZDHINg.png" /></figure><p>Everything from here on lives inside this schema, which also means the whole exercise can be undone with a single DROP DATABASE once you are done experimenting.</p><h3>Step 2: Create the Shared Source Table</h3><p>This is the table everything else in the post traces back to. Think of it as standing in for whatever fact table your own agents are actually built on, a sales table, a claims table, a ticketing table. The structure barely matters here. What matters is that two different consumers are about to be built on top of it.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/311/1*NnoS1P59sDWXbuG_u4dfFw.png" /></figure><h3>Step 3: Load a Few Rows</h3><p>A handful of rows is all this needs. The point of the walkthrough is the shape of the lineage graph, not the size of the dataset.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/554/1*lQEPhQWJgqPQ9sfTuzO2ng.png" /></figure><p>The table is now the root of two lineage paths that get built out in the steps below, one for a revenue focused agent and one for an operations focused agent.</p><h3>Step 4: Create the Revenue Semantic View</h3><p>The first consumer is shaped around revenue and product questions, the kind a sales leader or account manager would actually ask.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/608/1*XrG4RZ1ad2wev00b_oygEA.png" /></figure><h3>Step 5: Create the Revenue Agent</h3><p>With the semantic view in place, this step wires it up as a Cortex Analyst tool inside an agent a business user could actually talk to.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/857/1*PONU9ju81g8kAO596c95vQ.png" /></figure><p>The first complete path now exists end to end, sales through sales_semantic_view through sales_agent. The next two steps build a second agent (that has nothing to do with the first one, except for sharing the same underlying table).</p><h3>Step 6: Create the Regional Operations Semantic View</h3><p>This second consumer looks at the exact same rows through a different lens entirely, quantities and fulfilment by region rather than revenue.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/630/1*01zM84uw5cuOR0p1GwCr8g.png" /></figure><h3>Step 7: Create the Regional Operations Agent</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/780/1*wdeT1L8Cbz_6xLk2RsKGxw.png" /></figure><p>At this point two agents exist that were likely built by two different teams for two different purposes, and neither one needs to know the other exists. That is exactly the situation lineage is meant to make visible.</p><h3>Step 8: Trace the Fan Out With GET_LINEAGE</h3><p>Now for the payoff. With both agents in place, the whole path, table into semantic view into agent, is queryable in one query through the documented GET_LINEAGE table function.</p><p>The four arguments provided to the function are:<br><strong>object_name: </strong><em>‘sales’</em>, is the object to start from.<br><strong>direction:</strong> <em>‘DOWNSTREAM’</em>, trace forward to what depends on it. <br><strong>object_domain:</strong> <em>TABLE</em><br><strong>max_distance:</strong> <em>3</em>. This defines how many hops to walk. Setting it to 3 is enough to walk past the semantic view hop and reach the agent itself. Distance 1 would stop at the two semantic views. Bumping it to 3 reaches one hop further, to the agents at distance 2.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/828/1*xRPyhoj0mjtBKAmTjOxCOw.png" /></figure><p>Here is what that actually returns.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*H00I8nJ0jhTkYtmX0JFCCA.png" /></figure><p>Four rows are returned, and they tell the whole story on their own.</p><p>At <em>distance 1</em> (see DISTANCE Column), the sales table branches into both sales_semantic_view and regional_ops_semantic_view, confirming the fan out at the semantic view layer. At <em>distance 2</em>, each of those semantic views resolves to its own agent, with TARGET_OBJECT_DOMAIN showing as CORTEX_AGENT, sales_semantic_view leading to sales_agent and regional_ops_semantic_view leading to regional_ops_agent. That CORTEX_AGENT value is fully queryable through GET_LINEAGE, and as the next section shows, the same relationship is just as visible in the Snowsight graph.</p><h3>Step 9: See the Same Fan Out in the Snowsight Graph</h3><p>The query above already tells you everything you need, but the graph view is worth pulling up as well, especially if you are walking a colleague through this rather than reading SQL output on your own.</p><p>Open Catalog, then Explorer, and select the sales table inside cortex_lineage_demo.lineage_demo. Select the Lineage tab.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/285/1*2tFd-38xiTP1rqhGCfFatQ.png" /></figure><p>Look at the lineage tab on the right.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/743/1*Wxc3EsQ-rxnhXwF43pClhQ.png" /></figure><p>The graph mirrors the query results exactly. The sales table sits on the left with its columns listed underneath, and two edges lead out to sales_semantic_view and regional_ops_semantic_view on the right.</p><p>Expanding either semantic view node one level further surfaces its agent, sales_agent on one branch and regional_ops_agent on the other, which is the same relationship the SQL output already showed, just easier to point at in a screen share.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/711/1*mPBNEDFpQd3cB-Nt_caCFA.png" /></figure><p>Note that Snowflake only captures this relationship at the moment an agent is created or a new version is committed, so an agent whose most recent version predates this release won’t show up in lineage until it gets recommitted.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*bks6xINypU8vYLRHZf3VWw.png" /></figure><h3>Where This Actually Comes In Handy</h3><p>The demo above is deliberately small, but the situations it stands in for show up constantly once agents move past a handful of pilots.</p><p><strong>Schema changes before they ship.</strong> A data engineer proposes dropping a column or splitting a table. Instead of pinging every team that might have an agent nearby, they open the table’s lineage graph and see, in seconds, that two semantic views and two agents sit downstream, which gives them a concrete list of owners to loop in before the change goes out.</p><p><strong>Incident response.</strong> An agent starts returning wrong numbers. Rather than guessing which semantic view and which upstream table it depends on, whoever is on call opens the agent’s own lineage entry and reads the path backward, straight to the table that likely changed.</p><p><strong>Onboarding new team members.</strong> A new hire inherits a dozen agents built over the past year by people who have since moved teams. The lineage graph gives them a map of what depends on what without having to read every tool_resources block by hand.</p><p><strong>Access and governance reviews.</strong> A security or platform team auditing what an agent can reach no longer has to trust documentation that may be stale. The graph reflects what the agent’s specification actually declares, which is a more reliable source of truth for an audit than a wiki page.</p><p><strong>Consolidating semantic views.</strong> Once lineage makes it obvious that two semantic views serve two different agents off the same table, as in this walkthrough, it also becomes easier to spot when three or four semantic views are really doing the same job and could be merged.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*BOVFpFyVvQubGoxNRLXVhw.png" /></figure><p>This is really governance catching up to how teams are actually building agents. Once an account has a handful of agents each pointing at different semantic views built on shared tables, tracing blast radius by hand stops being realistic. What this walkthrough demonstrates, one table branching into two agents inside a single graph, is the difference between guessing what might break and knowing exactly what will.</p><p>The notebook for this blog can be accessed <a href="https://github.com/Krishsriniv/cortex_ai_agent_lineage">here.</a></p><p><em>I share hands-on, implementation-focused perspectives on Generative &amp; Agentic AI, LLMs, Snowflake and Cortex AI, translating advanced capabilities into practical, real-world analytics use cases. Do follow me on </em><a href="https://www.linkedin.com/in/krishsrinivasans/"><em>LinkedIn</em></a><em> and </em><a href="https://medium.com/@krish.srinivasans"><em>Medium</em></a><em> for more such insights.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=2a56ff6a88bb" width="1" height="1" alt=""><hr><p><a href="https://pub.towardsai.net/agentic-ai-in-action-part-29-cortex-agent-lineage-walkthrough-built-on-two-agents-2a56ff6a88bb">Agentic AI in Action — Part 29 — Cortex Agent Lineage Walkthrough, Built on Two Agents</a> was originally published in <a href="https://pub.towardsai.net">Towards AI</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Agentic AI in Action — Part 28 — A Geospatial Store Intelligence Agent in Snowflake]]></title>
            <link>https://pub.towardsai.net/agentic-ai-in-action-part-28-a-geospatial-store-intelligence-agent-in-snowflake-d4facffe7a5f?source=rss-cb9e0b4c6b11------2</link>
            <guid isPermaLink="false">https://medium.com/p/d4facffe7a5f</guid>
            <category><![CDATA[snowflake-cortex]]></category>
            <category><![CDATA[llm]]></category>
            <category><![CDATA[snowflake]]></category>
            <category><![CDATA[ai]]></category>
            <category><![CDATA[generative-ai-tools]]></category>
            <dc:creator><![CDATA[Krishnan Srinivasan]]></dc:creator>
            <pubDate>Tue, 08 Sep 2026 04:01:48 GMT</pubDate>
            <atom:updated>2026-09-17T15:00:08.408Z</atom:updated>
            <content:encoded><![CDATA[<h3>A Geospatial Store Intelligence Agent in Snowflake</h3><h4>A look at how Semantic Views and Cortex Analyst answer store performance questions, while native geography functions draw the map.</h4><p>This blog walks through a store intelligence notebook, plain English questions answered through Cortex Analyst and Semantic Views, store locations plotted through native geography functions.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*yl1LsZOSG4Dh2kNbKcZtNA.png" /></figure><p>The use case is straightforward. A retail chain wants store managers and regional planners to ask plain English questions about footfall and location, things like <em>“show me stores in Chicago with footfall below 500 last month”</em>, and get back both the matching rows and a rendered map. The pieces that make this possible, a Semantic View for Cortex Analyst, native geography functions for radius queries, and simple, popular Python packages like matplotlib for the visual layer, already exist inside Snowflake Notebooks. Nothing needs to be stitched together from outside services, and nothing fancy is required to render the output either.</p><p>Along the way this also surfaces a useful design pattern. Cortex Analyst is genuinely good at turning language into SQL over the dimensions and metrics you have exposed to it, and pairing it with native SQL for spatial math gives each piece the job it is best suited for. That division, natural language for attribute filtering, native SQL for geometry, is what it actually comes down to.</p><h3>The architecture</h3><p>A single STORE_LOCATIONS table holds each store&#39;s id, city, footfall for the last month, and a GEOGRAPHY column built from latitude and longitude. A Semantic View sits on top of this table and exposes the dimensions and metrics Cortex Analyst needs to translate a natural language question into SQL. The distance filtering itself uses Snowflake&#39;s native ST_DWITHIN function against the geography column, so radius queries run as ordinary SQL rather than anything bolted on.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*43ugMpL97IQA0VWQ-XXyOg.png" /></figure><p>The notebook is built around four US cities, New York, Chicago, Austin, and Seattle, with roughly eighty synthetic stores jittered around each city center so the points land in realistic locations without needing a real estate dataset.</p><h3>Generating the synthetic data</h3><p>Let’s begin by creating dedicated database and schema.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/818/1*seXMlHkfiaIp95mCMEhiKg.png" /></figure><p>We will generate roughly eighty stores spread across four US cities, New York, Chicago, Austin, and Seattle, each with a footfall reading for the last month.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/581/1*vwL8f_l9z_mPNGA0JXw1AQ.png" /></figure><p>Each city gets twenty stores with footfall figures spread widely enough that a “below 500” style filter returns a meaningful subset rather than an empty result or the whole table.</p><h3>The Semantic View</h3><p>Semantic Views give Cortex Analyst a governed, business friendly layer over raw tables, defining dimensions, metrics, and join logic once so that natural language questions resolve consistently instead of relying on the model to guess at SQL each time.</p><p><strong><em>(For details on how semantic views work, please refer to </em></strong><a href="https://medium.com/towards-artificial-intelligence/agentic-ai-in-action-part-23-snowflake-semantic-views-where-ai-agents-earn-enterprise-trust-17aa8e509d76"><strong><em>Part 23</em></strong></a><strong><em> of my Agentic AI in Action series).</em></strong></p><p>In this cell, STORE_SEMANTIC_VIEW is created over the STORE_LOCATIONS table, keyed on store_id. It exposes city and store_name as dimensions, so questions can be sliced by location or by individual store, and defines two metrics, <em>avg_footfall </em>as the average of footfall_last_month and <em>store_count </em>as a count of store_id. When Cortex Analyst answers a question like which city has the highest average footfall, it resolves it against these definitions rather than improvising the aggregation, and the same city and footfall groupings carry through cleanly into the pydeck map later in the notebook.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/817/1*TGVCrYmwAAu6CdHoQvArdA.png" /></figure><p>This is deliberately narrow. Cortex Analyst only needs enough structure to translate “stores in Chicago with low footfall” into a WHERE clause and an aggregation. Notice what’s missing, latitude, longitude, and anything geography-flavored aren’t in here at all. That’s on purpose, and it matters for what comes next.</p><h3>Splitting the work between Cortex Analyst and native SQL</h3><p>Cortex Analyst is scoped to whatever the Semantic View exposes, city and footfall in this case, so questions about attributes and aggregates go to it directly. Distance is a different kind of question, geometry rather than filtering, and Snowflake already has native functions for that. The cleaner pattern keeps the two separate. Cortex Analyst handles “which stores, filtered by which attributes,” and a direct query against the GEOGRAPHY column built in Cell 2 handles “which stores, within this radius.”</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/632/1*cHOrSd5vd77EpJ-LdXz8Vg.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/826/1*8U78TvwrWemiUXakiryuKQ.png" /></figure><p>This runs on its own using Snowflake’s native ST_DWITHIN function whenever the question genuinely needs distance math, radius searches, nearest neighbor lookups, and so on. Cortex Analyst picks up from there for the attribute filtering that follows.</p><p>Running this against the actual data returns all 20 Chicago stores, footfall ranging from 233 up to 1,379. With the jitter radius used to scatter stores around each city center, a 25 km search from downtown Chicago comfortably covers every store tagged to that city, which is a useful sanity check in itself, the geometry is doing exactly what it should.</p><h3>Asking the question</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*uVWaB0GYruHlUazlMP7www.png" /></figure><p>This cell creates a reusable Python function called ask_cortex_analyst() to send a natural-language question to Snowflake Cortex Analyst. The function takes the user’s question and, by default, the semantic view GEO_DEMO.RETAIL.STORE_SEMANTIC_VIEW, which we just created. It then obtains the Snowflake connection, authentication token, and account host from the existing Snowpark session and constructs the Cortex Analyst REST API endpoint. The question and semantic view are packaged into a JSON payload and sent to the API using an HTTP POST request, with the Snowflake token included for authentication. The function waits up to 60 seconds for a response and checks the HTTP status code to determine whether the request was successful. If an error occurs, it prints the status and part of the error response and raises an exception; otherwise, it converts the API response from JSON into a Python object and returns it. In short, the cell acts as the bridge between a Python notebook and Cortex Analyst, allowing a user to ask business questions in natural language and receive Cortex Analyst’s response programmatically.</p><p>At the bottom of the cell is the question:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/776/1*pONY-KYw_E0jO3SH9jywIw.png" /></figure><p>The question is scoped to city and footfall, since radius search belongs to the native SQL step above rather than to Cortex Analyst. That’s why the phrasing is “stores in Chicago” instead of “stores within 25 km,” and Cortex Analyst returns a clean SQL statement matching exactly that scope. In other words, this demonstrates how you can use Cortex Analyst not just to answer a business question, but to retrieve and inspect the SQL that it generated to answer that question.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/825/1*lYsuWhQWVasBV-oLaSGfQw.png" /></figure><p>That’s the actual SQL Cortex Analyst generated for the question, wrapped in a CTE, filtered on CITY and FOOTFALL_LAST_MONTH, and ordered descending. There are no coordinates or distance calculations involved. It stays exactly within the scope supported by the Semantic View.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/833/1*SlbRnGHKs9E96oDP6o0sOg.png" /></figure><p>Running it returns five stores as seen above.</p><h3>Rendering the map by latitude and longitude</h3><p>One more design detail before the map renders. The Semantic View scopes Cortex Analyst’s output to STORE_ID, STORE_NAME, CITY, and FOOTFALL_LAST_MONTH, the dimensions and metrics defined for it, so coordinates come back in through a join against STORE_LOCATIONS. This is a reasonable pattern in general, the app layer around Cortex Analyst enriches its output with anything outside the semantic model rather than assuming the result already carries everything a downstream step needs.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/764/1*6C_MoiKA4JVMnWY57zf70g.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/537/1*FGzXdXxi1_qjtwsCnbMcJQ.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/724/1*JJVpxDLCA5W2DbbAIHznzA.png" /><figcaption>Five Chicago stores under 500 footfall, plotted by latitude and longitude</figcaption></figure><p>Store 24 sits well north of the other four, at the edge of the jittered coordinate spread, while the rest cluster closer to the city center. This is the payoff. The same question that started as a plain English sentence ends up as pins on a map, and the whole round trip, natural language in, SQL generated, query executed, coordinates joined back in, result rendered, happens inside one Notebook session using only pandas and matplotlib, both of which ship with every Snowflake Notebook by default. If your environment has streamlit and pydeck available through the Packages selector, the same map_df drops into a pdk.Layer and st.pydeck_chart for a more polished interactive map, but the matplotlib version is the one guaranteed to run without any package configuration.</p><h3>An optional layer for territory footfall</h3><p>Individual pins work well for a specific question, but a regional planner usually wants a rollup by territory rather than a list of points. Bucketing stores into H3 cells and summarizing average footfall per cell gives that view.</p><p>H3 cells are Uber’s hexagonal grid system for dividing the map into uniform regions, and H3_POINT_TO_CELL_STRING(location, resolution) is Snowflake’s native function for looking up which hexagon a given point falls into, returning that hexagon’s ID as a string so stores in the same region can be grouped together with GROUP BY. That string is just an identifier, not a shape, so it’s enough to group and aggregate footfall by territory, but drawing the actual hexagon boundaries on a map needs geometry that pydeck’s H3HexagonLayer normally supplies. (Since this notebook stays dependency-light, the output here is a table and bar chart of cell IDs and their average footfall rather than rendered hexagons).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/750/1*Y0p3cQ8US2RReYerjRP8pA.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/753/1*N1rP_8xPdO-_Oou9UV203A.png" /></figure><p>We will go ahead and plot a bar chart summary of footfall by H3 territory.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/772/1*8f_1C-us5_mLW1ibFgb2PA.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/818/1*7e9OVI8yLv33JAl0X-TnkA.png" /><figcaption>Top ten H3 territories by average footfall, one bar per H3 cell</figcaption></figure><p>Each of these top cells holds exactly one store, which tracks with H3 resolution 7 at this scale, eighty stores spread across four metro areas, most stores land in their own cell. A coarser resolution, say H3_POINT_TO_CELL_STRING(LOCATION, 5), groups more stores per cell for a broader density read. This step turns “find nearby stores” into “identify underserved territories,” which tends to land better with a business audience than a list of individual points. (If pydeck is available in your environment, the same h3_df drops into an H3HexagonLayer for an actual hexagon map instead of a bar chart).</p><p>What matters here isn’t the map, it’s where each piece of the work actually happens.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*EdoH-JCy7T_2zvBDnpyvQw.png" /></figure><p>Cortex Analyst handles the part it’s built for, turning a plain English question into SQL over a defined set of dimensions and metrics, and native SQL and Python handle the rest, geometry, joins, and rendering. There is no external service in the loop and no data leaves the account. Swap the underlying table and Semantic View metrics, warehouse footfall for logistics, branch traffic for banking, and the same pattern carries over with the Cortex Analyst and rendering cells unchanged.</p><p>The notebook for this blog can be accessed <a href="https://github.com/Krishsriniv/geospatial-store-intelligence-snowflake">here.</a></p><p><em>I share hands-on, implementation-focused perspectives on Generative &amp; Agentic AI, LLMs, Snowflake and Cortex AI, translating advanced capabilities into practical, real-world analytics use cases. Do follow me on </em><a href="https://www.linkedin.com/in/krishsrinivasans/"><em>LinkedIn</em></a><em> and </em><a href="https://medium.com/@krish.srinivasans"><em>Medium</em></a><em> for more such insights.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d4facffe7a5f" width="1" height="1" alt=""><hr><p><a href="https://pub.towardsai.net/agentic-ai-in-action-part-28-a-geospatial-store-intelligence-agent-in-snowflake-d4facffe7a5f">Agentic AI in Action — Part 28 — A Geospatial Store Intelligence Agent in Snowflake</a> was originally published in <a href="https://pub.towardsai.net">Towards AI</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Agentic AI in Action — Part 27 - Automating Call Center Triage with Cortex AI]]></title>
            <link>https://pub.towardsai.net/agentic-ai-in-action-part-27-automating-call-center-triage-with-cortex-ai-8dc092588628?source=rss-cb9e0b4c6b11------2</link>
            <guid isPermaLink="false">https://medium.com/p/8dc092588628</guid>
            <category><![CDATA[snowflake-cortex]]></category>
            <category><![CDATA[llm]]></category>
            <category><![CDATA[generative-ai-tools]]></category>
            <category><![CDATA[ai]]></category>
            <category><![CDATA[snowflake]]></category>
            <dc:creator><![CDATA[Krishnan Srinivasan]]></dc:creator>
            <pubDate>Wed, 19 Aug 2026 03:54:34 GMT</pubDate>
            <atom:updated>2026-08-20T09:42:40.761Z</atom:updated>
            <content:encoded><![CDATA[<h3>From Raw Audio to Actionable Data, Automating Call Center Triage with Cortex AI</h3><h4><em>Powered by AI_TRANSCRIBE, turning recorded support calls into a structured, queryable feedback table.</em></h4><p>A call center runs on a routine most of us know without ever having worked one. A customer calls in. An agent listens, works the issue, then spends a few minutes after the call typing notes, picking a category from a dropdown, and writing a summary for the next shift or the reporting dashboard. That last part, the typing, is where most of the delay and inconsistency creeps in.</p><p>This post walks through a small pipeline that removes that manual step entirely. Three short support calls go in as raw audio. AI_TRANSCRIBE is the function that makes the whole thing possible, since every downstream step, the categorization, the summary, the resolution log, all exists because the call is now text a query can read.</p><p><strong>On a personal note, I was recently named a Finalist for AI Excellence in the Snowflake Community Awards 2026 (APJ region), and voting is now open. If this series, or any of the work I have shared, has been useful to you, I would genuinely appreciate your </strong><a href="https://docs.google.com/forms/d/e/1FAIpQLSeOvD3T1FmeQel9JhhFgfZFjwoZZP3807Q5SQfct5Ldg75KBg/viewform"><strong>vote here</strong></a><strong>. (<em>You can navigate to Page 7, the last page of the form, and find me, “Krishnan Srinivasan” under APJ region.</em>) Thank you!</strong></p><p>Now, back to the pipeline.</p><p>Snowflake recently <a href="https://docs.snowflake.com/en/release-notes/2026/other/2026-07-15-ai-transcribe-aac-support">extended AI_TRANSCRIBE to accept AAC directly</a>. Most existing transcription demos still stick with WAV or MP3, so this one uses AAC end to end instead.</p><h3>The setup</h3><p>Three recorded calls stand in for a real support queue, each one manually scripted and recorded for the purpose of this demo.</p><p>Call one is a billing dispute. A customer was charged twice for a subscription, and the agent verifies the account before issuing a refund.</p><p>Call two is a technical issue. A customer’s app crashes on photo upload, and the agent logs a bug before offering a workaround.</p><p>Call three is an account access issue. A customer has been locked out since the previous day because a password reset email never arrived, and the agent traces it to a spam filter catching the reset attempts on the company’s end.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*6vLiCYY0LRJuR5-tcts0yg.png" /></figure><p>All three files are AAC audio, a compressed audio format that gets used in most streaming services and modern phone recordings for its smaller file size, at a similar quality to older formats like MP3.</p><p><em>Note: In a real deployment, these recordings would not need a manual upload step at all. A contact center platform typically writes call recordings straight to cloud storage as soon as a call ends, and an external stage or a Snowpipe trigger would pick them up automatically. For this post, uploading through Snowsight keeps the demo self contained and easy for anyone to reproduce without setting up a storage integration first.</em></p><h3><strong>Step 1: </strong>Create the database and schema</h3><p>We will begin by creating the dedicated database and schema for this analysis.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/561/1*m0MsYyJ5mluaUUc98q6ntw.png" /></figure><h3><strong>Step 2: </strong>Create the stage for storing the call recordings</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/374/1*BFIqKMtx3ges8q-YMqNYYA.png" /></figure><h3><strong>Step 3: </strong>Upload the recordings to stage.</h3><p>Click on Add data</p><p>Choose the database, schema and the stage we just created.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/564/1*-nqQS5ApvXq3VhiUTNcmxQ.png" /></figure><p>Click Upload. The three audio files are successfully uploaded to the stage.</p><h3><strong>Step 4: Transcribe calls to searchable text</strong></h3><p>AI_TRANSCRIBE is where the actual work of this pipeline begins, converting spoken audio into a plain transcript a query can act on.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/782/1*Uyz1T8aEOj0WWqBAow8TMw.png" /></figure><p>AI_TRANSCRIBE returns a structured object, not just a string. The transcript text sits under a text key, alongside metadata like audio duration.</p><p>The query below pulls and flattens the transcript and duration out into their own columns, making them easier to reference in the queries that follow.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/821/1*XeA0s2Wn0rUBjBx3eghruQ.png" /></figure><p>We can examine the flattened results by querying the table:</p><p>SELECT * FROM CALL_TRANSCRIPTS_FLAT;</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*O9DGiezEQ3HQe1bJwMyDxw.png" /></figure><p>At this point the raw audio has already done its job. Everything from here forward works on text.</p><h3><strong>Step 5: Classify and Summarize</strong></h3><p>Every unresolved billing dispute or unlogged bug report costs real time and goodwill, and step three is where that cost starts getting recovered, the moment the call becomes searchable text instead of an audio file.</p><p>This step takes the flattened transcripts and produces two AI generated columns for each call, a category and a summary, in a single pass.</p><p>AI_CLASSIFY takes the category list as an argument rather than needing a separate model or lookup table, which keeps this approachable for a team that has not built a custom classifier before. With three calls spanning billing, a technical bug, and account access, all four category labels get a real workout instead of the same one or two showing up every time. It reads the transcript text and picks the best matching label from that list. The result comes back as a structured object containing the labels it assigned, so :labels[0]::STRING pulls out just the first one as a plain string, since that’s the label we want stored as the call’s category.</p><p>AI_SUMMARIZE_AGG(transcript_text) generates a short natural language summary of the transcript, the same kind of note an agent would normally type up by hand after a call. In effect it summarizes the transcript text for each individual call.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/726/1*gzH7uPJ8j3m65kkXquyjwQ.png" /></figure><p>The output is <em>call_analysis</em>, a table where each row now has the original transcript plus a category and a summary sitting right next to it, ready for the next step to layer a resolution status on top.</p><p>SELECT file_name, category, call_summary FROM CALL_ANALYSIS;</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1013/1*sqaeQg45pLSENX2VxjBzow.png" /></figure><p>The results confirm that the pipeline is working end to end, all three calls landed in the right category and got a concise, readable summary out of nothing but raw audio.</p><p><strong>support_call_1.aac, Billing.</strong> The transcript centers on a duplicate subscription charge and Maya issuing a fix, which AI_CLASSIFY correctly reads as a billing issue rather than, say, a general inquiry.</p><p><strong>support_call_2.aac, Technical Support.</strong> The app crashing on photo upload is a product bug report, and the model picked technical support over account access or billing, which is the right call since nothing in that transcript touches billing or login credentials.</p><p><strong>support_call_3.aac, Account Access.</strong> Being locked out because a reset email never arrived is squarely an access issue rather than a technical bug, and the classification reflects that distinction correctly.</p><p>Each summary also reads like something an agent could paste straight into a ticket, naming the actual problem and the specific action taken, rather than a generic restatement of “customer called with an issue.” That’s the practical test for whether AI_SUMMARIZE_AGG is pulling its weight here, a summary someone could act on without listening to the call.</p><h3><strong>Step 6: Logging for feedback and analysis</strong></h3><p>A ticketing system tracks more than just topic and summary, it tracks whether the issue actually got resolved.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/803/1*YppjaLce_TeS7nwZiF_R0Q.png" /></figure><p>This step runs a second classification pass over the same transcripts, this time picking a resolution outcome, <em>Resolved, Escalated,</em> or <em>Follow up required</em>. The result lands in CALL_FEEDBACK_LOG, which carries forward the file name, category, and summary from the previous step and adds the resolution status plus a timestamp, giving you one table that tracks both what each call was about and whether it actually got sorted out. This resolution signal is especially useful for ops reporting.</p><h3>Step 7: Close the loop</h3><p>A rollup query gives a supervisor exactly the kind of view they would ask an analyst for.</p><p>SELECT FILE_NAME, CATEGORY,RESOLUTION_STATUS FROM CALL_FEEDBACK_LOG;</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/557/1*48Eg5OegetzS5cyPVsgbew.png" /></figure><p>Notice that two calls came back as resolved, and the technical support call was correctly classified as escalated, since the agent mentioned logging it as a bug and passing it on to the engineering team.</p><h3>Consistency Is the Real Feature</h3><p>A conventional call center stack would need a transcription vendor, a separate classification model, a summarization step likely run through yet another API, and custom code to stitch the outputs into one table. Cortex AI functions collapse that entire chain into a Snowsight upload and a handful of SQL statements. The billing dispute, the app crash, and the locked account each landed in the right category without any manual tagging, and the resolution pass correctly told the two resolved calls apart from the one that was actually escalated to engineering. It read what the agent and customer actually said and reasoned to the right outcome each time.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*6Wl94R56pJwEO8FAnHK1Ow.png" /></figure><p>Scale this from three calls to three thousand, and the real value comes into focus. Every call already carries signal about what is going wrong for customers, but that signal usually stays locked inside a recording nobody has time to listen to twice. Once it becomes a structured table, patterns that were invisible before become a simple GROUP BY away. A spike in account access issues on a particular day, a category with a disproportionate share of escalations, a category where average call duration keeps creeping up, all of that turns into questions a supervisor can ask directly instead of impressions gathered secondhand from a team lead.</p><p>The bigger shift is what this does to the feedback loop itself. A support team that can see its own patterns clearly, quickly, and consistently is a team that can act on them before they show up as churn or a bad review. That is the real payoff of pushing this kind of pipeline into a customer support operation, not less work for agents, but a much shorter distance between a customer’s problem and the fix that keeps it from happening again.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*bwAEipt0g9-LUmzVG_hvLw.png" /></figure><p>Wire this into a scheduled task or a Snowpipe trigger on the storage stage, and the whole pipeline runs on its own every time a new call lands, with no one needing to remember to kick it off. That consistency is worth as much as the automation itself. A human reviewing calls gets tired, skips some, categorizes similar issues differently depending on the day, and summarizes with varying detail. A pipeline like this applies the same categories and the same summarization approach to every single call, which means the resulting data can actually be trusted for trend analysis over weeks and months, not just a spot check on the ones someone happened to listen to.</p><p>The code for this blog can be accessed <a href="https://github.com/Krishsriniv/cortex-ai-call-center-triage">here.</a></p><p><em>I share hands-on, implementation-focused perspectives on Generative &amp; Agentic AI, LLMs, Snowflake and Cortex AI, translating advanced capabilities into practical, real-world analytics use cases. Do follow me on </em><a href="https://www.linkedin.com/in/krishsrinivasans/"><em>LinkedIn</em></a><em> and </em><a href="https://medium.com/@krish.srinivasans"><em>Medium</em></a><em> for more such insights.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=8dc092588628" width="1" height="1" alt=""><hr><p><a href="https://pub.towardsai.net/agentic-ai-in-action-part-27-automating-call-center-triage-with-cortex-ai-8dc092588628">Agentic AI in Action — Part 27 - Automating Call Center Triage with Cortex AI</a> was originally published in <a href="https://pub.towardsai.net">Towards AI</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Agentic AI in Action — Part 26 -Candidate Screening, Reimagined. A Cortex AISQL Pipeline for HR]]></title>
            <link>https://pub.towardsai.net/agentic-ai-in-action-part-26-candidate-screening-reimagined-a-cortex-aisql-pipeline-for-hr-1eb4ec2b7304?source=rss-cb9e0b4c6b11------2</link>
            <guid isPermaLink="false">https://medium.com/p/1eb4ec2b7304</guid>
            <category><![CDATA[snowflake]]></category>
            <category><![CDATA[snowflake-cortex]]></category>
            <category><![CDATA[llm]]></category>
            <category><![CDATA[generative-ai-tools]]></category>
            <category><![CDATA[ai]]></category>
            <dc:creator><![CDATA[Krishnan Srinivasan]]></dc:creator>
            <pubDate>Tue, 04 Aug 2026 03:47:14 GMT</pubDate>
            <atom:updated>2026-08-04T13:56:20.202Z</atom:updated>
            <content:encoded><![CDATA[<h3>Candidate Screening, Reimagined. A Cortex AISQL Pipeline for HR</h3><p><em>An HR use case using Cortex AISQL where AI_FILTER shortlists on substance, AI_CLASSIFY grades the near misses, AI_AGG writes the summary for the hiring manager.</em></p><p>Every talent acquisition team knows this queue. Multiple applications sit against multiple open requisitions, and the language never lines up cleanly. A resume says “<em>led migration of legacy reporting infrastructure to a cloud data warehouse</em>”. A requisition says “<em>seeking a candidate with Snowflake or BigQuery experience</em>”. Nothing in either string matches the other, and a keyword search has nothing to work with. Worse, keyword search actively misleads you in the other direction, surfacing a resume that happens to share a word with the requisition for reasons that have nothing to do with the job.</p><p>Snowflake’s Cortex AISQL replaces that keyword search with a JOIN condition that reasons instead of matching strings. You write the condition in plain English, and the AI decides row by row whether an applicant genuinely fits a role. This post builds that screening pipeline end to end, from a semantic join that shortlists the real fits, to a graded classification that ranks how strong each match actually is, to an aggregation that turns each shortlist into a paragraph a hiring manager can read in ten seconds.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*KqRSCP1s1oL4AoRs0r_3DA.png" /></figure><p>Let us build it out, starting with the database and schema, and a sample pool of resumes and requisitions that we will be screening throughout this post.</p><p><strong>Step 1: Create database and schema.</strong></p><p>We will start by creating a dedicated database and schema.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/508/1*6gEybnXKxshoQjWg8n4S1A.png" /></figure><p><strong>Step 2: Create the Resume table with ten candidate records</strong></p><p>We will now create the resumes table to store the candidate name along with the content from the resume.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/313/1*_ikyTug71FPaMhffa7q6HA.png" /></figure><p>Let us now insert candidate records. We will load a total of ten applicant resumes spanning data engineering, product design, fraud/streaming engineering, plus two keyword-trap resumes and two clear non-fits, each with a realistic mix of relevant and irrelevant experience.</p><p>Once you run the insert statements from the accompanying sql file, you should have ten records as shown below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/850/1*G2nRM9vGpTBnTpoCyfhusQ.png" /></figure><p><em>Note: In a real pipeline, resumes typically land as PDFs or Word documents on a stage, not as hand typed text. Snowflake has functions built for exactly that. AI_EXTRACT is built for targeted extraction. You provide a schema, key-value pairs, or questions, and it pulls exact, structured data straight from text, tables, or images, no separate parsing step required. Alternatively, AI_PARSE_DOCUMENT and AI_COMPLETE could work together as a two-step pipeline instead: AI_PARSE_DOCUMENT extracts the raw content, structure, and layout from a file like a PDF into a clean, queryable format, then AI_COMPLETE reasons over that parsed output to summarize it or pull out specific insights using a model of your choice. A pipeline might use AI_EXTRACT directly, or pair AI_PARSE_DOCUMENT with AI_COMPLETE when the extraction logic needs more judgment than a fixed schema allows. Previous posts in this series go deep on Snowflake’s multimodal document capabilities. Here, the goal is to show what Cortex AISQL does with resume text once you have it, so the inserts stand in for that upstream step.</em></p><p><strong>Step 3: Create the Jobs table and insert the three Job requisitions.</strong></p><p>We will have three open requisitions: Senior Data Engineer, Product Designer, and Fraud Detection Engineer, each with a short, plain-language description of what the role actually needs.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/273/1*wLNtwzk62mhVode8pec36w.png" /></figure><p>Upon executing the three inserts, the Jobs table will contain these records.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*y5SAsz_fZrDbZBt4jtG6Tg.png" /></figure><p><em>Checkpoint:</em> To summarize, we now have ten applications, three requisitions, and a genuine mix of outcomes hiding in there. Two candidates are a real fit for each role. Two more, Sam Whitfield and Chris Doyle, share a keyword with the Senior Data Engineer requisition for reasons that have nothing to do with the job. Naomi Reyes and Rachel Bennett, are the kind of applications that make up most of any real queue, one with no technical background at all, one close enough to be genuinely ambiguous. A keyword search would handle none of this correctly.</p><p><strong>Step 4: Match jobs on substance and not keywords.</strong></p><p>We will use AI_FILTER to perform a contextual join of resumes with jobs.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/826/1*MOcu2EkodCvfzgG6I59Amg.png" /></figure><p><strong>PROMPT</strong> builds the templated instruction, substituting each resume and job description into the numbered placeholders. AI_FILTER evaluates that instruction per row pair and returns a Boolean, which is exactly what a JOIN condition needs. The output is displayed below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/771/1*Mk8EEjhWkofLdVYZIypWWA.png" /></figure><p>Six matches out of thirty possible pairs, two genuine fits shortlisted per role, based entirely on what each application actually describes. Sam Whitfield, Chris Doyle, Naomi Reyes, and Rachel Bennett all correctly drop out.</p><p>Let us compare with the full roster (displayed below):</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1010/1*d7OgJLIvf5b4nSAP8faAkQ.png" /></figure><p>We can see six real matches, two keyword traps that a string search would have surfaced incorrectly, and two applications that are simply the wrong fit for anything open right now. That last column is what a keyword search cannot produce. It has no concept of “close but not there,” only whether a string appears.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*Xm-Pd7Nwizj8j_tJxnofAg.png" /></figure><p><strong>Step 5: The keyword collision test</strong></p><p>Sam Whitfield and Chris Doyle are the two candidates in this pool who would fool a keyword search. Each resume shares a real word with the requisition, but for reasons that have nothing to do with the job. Sam’s resume says “Snowflake”. Chris&#39;s resume says “warehouse”. The requisition for Senior Data Engineer contains both words.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/811/1*KZSuT9ncSiLCXs5uCbgIFw.png" /></figure><p><em>As expected, no rows are returned.</em></p><p>A keyword search on either “Snowflake” or “warehouse” against this requisition would have returned both resumes as hits. Neither belongs. Sam writes SQL against Snowflake tables but has never touched infrastructure work, and Chris manages a physical distribution warehouse that has nothing to do with cloud data platforms. <strong>That gap between sharing a word and doing the job is exactly what a string match cannot see and a reasoning based condition can.</strong></p><p><strong>Step 6: Grading the fit instead of just a yes or no</strong></p><p>AI_FILTER’s boolean is exactly right for building a shortlist, but real screening decisions are rarely binary. A recruiter wants to know not just who cleared the bar for a requisition, but how close everyone else came, since a hiring manager might still want to glance at a strong near miss. AI_CLASSIFY replaces the yes or no with a tier, and it takes a task_description parameter so you can tell the model explicitly what to weigh, the same thing AI_FILTER&#39;s prompt does.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/892/1*5zMcEAbUpXUuVErdMdTFHw.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/689/1*ige557oyVCzHbU7Do6e1Jg.png" /></figure><p>Sam Whitfield and Aditya Rao are the two candidates whose tier could potentially move. The above run showed up Sam as possible fit. Different runs could produce Sam alone on Possible fit, Aditya alone on Possible fit, and both of them there together on Possible fit, with no changes to the query. Neither candidate’s result is a mistake, and neither is a keyword trap the way Chris Doyle’s would be. Sam Whitfield genuinely writes SQL against Snowflake tables, that part of his resume is real, it just supports Tableau dashboards, not infrastructure work. Aditya Rao’s resume describes designing a streaming pipeline on a distributed event platform, real pipeline architecture work, just built for fraud detection instead of general analytics. Both are legitimate borderline cases, which is exactly why the model doesn’t always land on the same one. What matters here is not which of the two shows up in a given run, it’s that either one can, and that this is ordinary model non-determinism, the same query and the same data producing a different classification depending on when you run it.</p><p>This is also a classic case, where how a light tuning of the prompt changes the results. Tightening the wording turned out to fix both problems at once. <em>Adding a single word, asking the model to weigh fit </em><strong><em>“strictly,”</em></strong><em> changes the result entirely.</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*o-RmBPmqxfjnzfGNosa48Q.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/762/1*Fk5aZ9bpvlAyWaTPqACyPw.png" /></figure><p>Same functions, same dataset, a different task_description depending on whether the goal is casting a wide net or narrowing a flood. This time there are no Possible fit entries.</p><p>The stricter wording does two things at once, and it’s worth being honest about the tradeoff between them rather than calling one version simply better. It collapses the middle tier entirely, so a recruiter using this version never sees Sam Whitfield flagged as worth a second look. He lands in the same bucket as Naomi Reyes, whose background has nothing to do with the role at all. But it also makes the result perfectly repeatable, and very true to the job requisition, which is a real and different kind of value in a hiring context where a classification might need to be defended later. A looser instruction surfaces more nuance but isn’t reliably reproducible. A stricter one gives up that nuance in exchange for an answer you can actually stand behind. Neither wording is the correct one in the abstract, they are two different products, and which one belongs in a real pipeline depends on whether the team wants borderline candidates surfaced for a human to weigh, or a clean, defensible, repeatable line.</p><p>Both of those runs used a task_description loose or strict. Now, wun the same pattern against Fraud Detection Engineer next, this time with no task_description at all, to see whether the parameter was ever necessary there or just good practice.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/805/1*GO-w2ZEr4vlFgpFzpE5v8w.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/740/1*fpvRCzejUgOI3DdM5xq7AQ.png" /></figure><p>The two candidates were correctly flagged as <em>Strong fit</em>. Here, there isn’t any middle tier, no keyword trap, and no error, a clean result straight out of the bare query. Fraud Detection Engineer has no planted vocabulary collision the way Senior Data Engineer does with “Snowflake” and “warehouse,” so there was nothing here for a bare category list to get fooled by. That is the actual lesson from running both requisitions side by side. task_description matters most when a resume pool has surface level vocabulary that could mislead a classifier. It does add token cost, though, so keep it as short as it can be while still doing its job. The safer default is to write it every time regardless.</p><p><strong>Step 7: Generate one summary per shortlist</strong></p><p>Once AI_FILTER has produced a shortlist for each requisition, AI_AGG rolls that shortlist into a single written justification, the paragraph a hiring manager actually wants instead of reading every resume individually.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/877/1*5zkPS4HvDYAVtG2NOslIAQ.png" /></figure><p>Let us examine the output.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/869/1*QaKfifKl4N95PYz42HdJZA.png" /></figure><p>With two matched candidates per role in this dataset, each summary genuinely synthesizes across two different resumes rather than restating one. At real scale, when twenty applications clear the filter for one requisition, AI_AGG turns twenty resumes into one paragraph, and it does this without hitting the context window limit that would eventually break a plain COMPLETE call asked to read all twenty at once. AI_AGG is built specifically to aggregate across rows that would not otherwise fit in a single prompt.</p><p><em>Note: None of this needs to live in a SQL worksheet. The team could build a Streamlit app on top of it. The output of these three queries, who matched, how strong the fit is, and why, is exactly the shape of data a Streamlit app within Snowsight would read straight off a table. A page per requisition listing each shortlisted candidate, their AI_CLASSIFY tier, and the AI_AGG summary justifying the shortlist, so a hiring manager gets a working screening dashboard without touching SQL. The wide-net and tight-shortlist prompt variants above can sit behind a simple toggle in a Streamlit app in Snowsight, “hard to fill” versus “high volume”, with each option mapping to a pre-written task_description behind the scenes. A stored procedure could take the job_id and toggle value, run the function calls, and return the shortlist for Streamlit to render as a table.</em></p><h3>Why this does not fall over at scale</h3><p>The naive way to run this join is a cross join, evaluating the AI condition once for every resume and requisition pair, which grows quadratically. Thirty pairs is nothing, but ninety thousand applications against five hundred open roles is forty five million calls to a language model, and no data team easily signs off on that.</p><p>This is exactly the optimization Snowflake’s engineering team <a href="https://www.snowflake.com/en/blog/engineering/cortex-aisql-query-optimization/">built into</a> Cortex AISQL. When the query optimizer recognizes that a semantic join can be reformulated as a classification problem, it automatically rewrites the execution plan, evaluating each resume once against the full set of job labels instead of once for every resume and job pair. Snowflake’s engineering benchmarks show that this transformation can reduce a <a href="https://arxiv.org/abs/2511.07663">quadratic join to linear complexity</a>, with reported speedups ranging from 15x to 70x depending on the workload, all without requiring any changes to your SQL. You write the query declaratively, and the optimizer determines the most efficient execution strategy.</p><h3>Where this pipeline earns its keep</h3><p>Semantic joins are not a replacement for your existing structured joins. Keep using keys where keys exist. The value here is entirely in the gap that structured joins cannot close, matching entities across different vocabularies, formats, or writing styles where a recruiter would recognize the connection instantly and a WHERE clause cannot. Resume screening is the textbook case, but the same pattern applies to matching invoices to contracts, support tickets to product catalog entries, or building descriptions to compliance requirements.</p><p>Use the three functions for what each is actually good at. AI_FILTER decides who makes the shortlist. AI_CLASSIFY grades how strong a fit is, which is the detail a binary join throws away, and it earns that grading power specifically because of task_description, a bare category list has nothing telling it to weigh substance over shared vocabulary. The wording of task_description changes the shape of the output, not just its accuracy, a looser instruction surfaces borderline candidates, a stricter one doesn&#39;t, and neither is simply the correct choice, they trade recruiter visibility for a cleaner, more repeatable line. That parameter is worth including by default. AI_AGG turns a shortlist into something a person will actually read. Chaining all three like this costs more than a single AI_FILTER call, since you are paying for classification and aggregation on top of the join, so reserve the extra steps for the point in the pipeline where a human is about to make a decision based on the output, not for every application on the way there.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*e1mt6XDjPUMna1jgfm3Uug.png" /></figure><p>Cost is the one thing to watch across all three, and it matters more in an HR context than most, since resumes are personal data and every extra pass is both a compute cost and a governance surface. Every AI_FILTER evaluation, every AI_CLASSIFY call, every AI_AGG rollup is a model call, and none of this is free the way a hash join or a SUM is. Start with a WHERE clause that narrows the candidate set using ordinary SQL first, department, location, seniority level, whatever structured filters your respective Applicant Tracking System already gives you, then let the AI functions work on what is left. Let the low cost deterministic predicates do the heavy lifting before the expensive semantic ones run.</p><p>A string is easy to match. Matching a person to a job has always been the hard part, and it still is, just with a sharper eye for it now.</p><p>The code for this blog can be accessed <a href="https://github.com/Krishsriniv/CortexAISQL-HR-candidate-screening-pipeline">here.</a></p><p><em>I share hands-on, implementation-focused perspectives on Generative &amp; Agentic AI, LLMs, Snowflake and Cortex AI, translating advanced capabilities into practical, real-world analytics use cases. Do follow me on </em><a href="https://www.linkedin.com/in/krishsrinivasans/"><em>LinkedIn</em></a><em> and </em><a href="https://medium.com/@krish.srinivasans"><em>Medium</em></a><em> for more such insights.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=1eb4ec2b7304" width="1" height="1" alt=""><hr><p><a href="https://pub.towardsai.net/agentic-ai-in-action-part-26-candidate-screening-reimagined-a-cortex-aisql-pipeline-for-hr-1eb4ec2b7304">Agentic AI in Action — Part 26 -Candidate Screening, Reimagined. A Cortex AISQL Pipeline for HR</a> was originally published in <a href="https://pub.towardsai.net">Towards AI</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Agentic AI in Action — Part 25 -Extending our CoWork Agent with a Cortex Agent Skill.]]></title>
            <link>https://pub.towardsai.net/agentic-ai-in-action-part-25-extending-your-cowork-agent-with-a-cortex-agent-skill-68720c239035?source=rss-cb9e0b4c6b11------2</link>
            <guid isPermaLink="false">https://medium.com/p/68720c239035</guid>
            <category><![CDATA[snowflake-cortex]]></category>
            <category><![CDATA[snowflake]]></category>
            <category><![CDATA[ai]]></category>
            <category><![CDATA[ai-agent]]></category>
            <category><![CDATA[llm]]></category>
            <dc:creator><![CDATA[Krishnan Srinivasan]]></dc:creator>
            <pubDate>Tue, 14 Jul 2026 03:35:25 GMT</pubDate>
            <atom:updated>2026-08-01T04:05:49.112Z</atom:updated>
            <content:encoded><![CDATA[<h3>Extending our CoWork Agent with a Cortex Agent Skill</h3><h4><em>A step by step guide to adding consistent, auditable domain reasoning to our CoWork agent</em>.</h4><p>The previous <a href="https://medium.com/towards-artificial-intelligence/agentic-ai-in-action-part-24-building-a-fraud-ops-escalation-agent-with-snowflake-cowork-a223cbdeac19">post</a> in the series built a fraud ops agent in Snowflake CoWork from scratch. A Semantic View for structured querying, a stored procedure for writing escalations, and a Cortex Analyst tool. The agent could answer questions and act on the answers.</p><p>This post extends that same agent with a Cortex Agent Skill. Not the procedural SQL kind, but a packaged, reusable set of instructions that tells the agent how to reason through an escalation decision before it takes any action. Without the skill, the agent relies entirely on its orchestration instructions and whatever the user happens to ask. With the skill, it carries a consistent, auditable decision framework that activates every time escalation comes up, regardless of how the question is phrased.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*lVanj0dI9wr3Z9wSLPNu-g.png" /></figure><h3>What a Cortex Agent Skill actually is</h3><p>A skill is a modular, portable package of instructions stored in a named Snowflake stage. At its core it is a single SKILL.md file placed at the root of a skill folder. That file contains a name, a description, and detailed instructions the agent follows when it decides the skill is relevant.</p><p>The discovery mechanism is what makes this useful. When the agent receives a query, it reads the name and description of every skill configured on it. If it judges a skill relevant, it retrieves the full SKILL.md content and follows the instructions inside. It does not persist a copy of the skill file. It reads from the stage on demand each time. This means updating the SKILL.md on the stage updates the agent’s behavior immediately.</p><p>For fraud ops, the skill encodes the escalation logic that would otherwise live perhaps only with a senior analyst, such as which signals matter, in what order, and how to draft a reason that holds up under review. We will now take a closer look at the skill file.</p><h3>The SKILL.md file</h3><p>The SKILL.md file has the following content:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*rHHiu2Kh1S6JJhmdfJ0cMw.png" /></figure><p>The SKILL.md is a plain text file with three parts. A name<em> (Fraud Escalation Guidance)</em> that the agent matches against when deciding whether the skill is relevant, a description that acts as the trigger, telling the orchestrator exactly when to activate it, and a set of instructions that define how the agent should reason and respond when it does. For the fraud escalation skill, the instructions encode the signal priority order, the chargeback rate thresholds that matter, which merchant categories carry inherent risk, and the exact structure the escalation reason should follow. It reads less like code and more like a standard operating procedure that the agent follows to the letter, every time. Below is a pictorial representation of the skill file.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*YFRNwoAkoID0210pBH2uOg.png" /></figure><p>The description is what the agent reads to decide whether to activate the skill at all. Keep it precise: <em>“use this skill whenever the user asks about escalating a transaction”</em> gives the orchestrator a clear trigger. Vague descriptions like “helps with fraud” leave the agent guessing.</p><p>Let us dive into the code.</p><p><strong><em>Note: The dataset </em></strong><em>(Customers, Merchants and Transactions)</em><strong><em> and the agent from the previous </em></strong><a href="https://medium.com/towards-artificial-intelligence/agentic-ai-in-action-part-24-building-a-fraud-ops-escalation-agent-with-snowflake-cowork-a223cbdeac19"><strong><em>post</em></strong></a><strong><em> are assumed to already be in place. Everything here builds on top of this data.</em></strong></p><h3>Creating the stage and uploading the skill</h3><p>Save the accompanying SKILL.md file to your local machine.</p><p>Run the below commands in a Snowsight SQL worksheet against the fraud ops database that we created in the previous post.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/316/1*dr4TNlMa0U_fBz7E91C4XA.png" /></figure><p>Now navigate to the stage we just created:</p><p>Catalog -&gt; Database Explorer -&gt; FRAUD_OPS_DB-&gt;CORE-&gt;Stages-&gt; SKILLS_STAGE</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/353/1*bJ1zzfvFHugifSThAZ1WbA.png" /></figure><p>Use the <strong>+ Files</strong> option at the top right, and upload the SKILL.md file to this stage.</p><p>Specify the path as /<em>fraud_escalation/</em></p><p>This will create a new folder called fraud_escalation in the stage and store the SKILL.md file within the folder.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/602/1*rTtqoTmNJoTZmhQBfo6Vuw.png" /></figure><p>Click Upload.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/851/1*evnMePMkmiTQYvl4k9WA9Q.png" /></figure><p>Verify that the file landed:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/551/1*SwDCU26KLU-0a1sORbnyEw.png" /></figure><h3>Adding the skill to the agent</h3><p>We will now attach this skill to our Fraud Ops agent.</p><p>In Snowsight, go to <strong>AI &amp; ML &gt; Agents</strong> and open the FRAUDOPS agent that we built in the previous post. Select <strong>Configuration</strong>, then navigate to the <strong>Skills</strong> tab.</p><p>i. Select Add Skill -&gt; Add from Stage<br>ii. For the stage, select FRAUD_OPS_DB.CORE.SKILLS_STAGE <br>iii. For the skill folder path, choose “<em>fraud_escalation</em>” <br>iv. Enter Skill name as “<em>SKILL.md</em>” <br>v. Click Add</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/458/1*7ImM8jdEi-DPPBx3wPA4Xw.png" /></figure><p>You should now see the skill added to the agent.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/645/1*7vTG4xwhcqgt4TQJMb940A.png" /></figure><p>Click<strong> Save.</strong></p><p>Let us now navigate to CoWork and ask a question. Navigate to <em>AI &amp; ML-&gt; Snowflake CoWork.</em> CoWork opens in a new window.</p><h3>What changes in CoWork</h3><p>Without the skill, asking the agent to evaluate a transaction for escalation produces a reasonable but generic response.</p><p>With the skill active, the agent follows the priority order defined in the SKILL.md every time escalation comes up, regardless of phrasing. Ask it this:</p><p><em>Look at the largest flagged transaction from a crypto exchange merchant in the last 30 days. Should I escalate it?</em></p><p>Let us break down the output from CoWork.</p><ol><li><strong>CoWork identifies and displays the transaction:</strong></li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/772/1*fdh3b56F2HNZK-9Jda28Tg.png" /></figure><p><strong>2. Performs the Risk Assessment:</strong></p><p>The agent queries the Semantic View through Cortex Analyst to find the transaction, then activates the “Fraud Escalation Guidance” skill to evaluate it. It works through the signals in order: customer risk tier first, then merchant chargeback rate, then any country mismatch, and drafts a structured reason before asking for confirmation. The skill invocation is visible in the thinking steps panel in CoWork, so you can see exactly when it was selected and what input it received.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/803/1*swRq0_1KrawUftxdBg9GEg.png" /></figure><p><strong>3. Provides the Recommendation and asks for confirmation to escalate:</strong></p><p>The agent provides its final recommendation and asks for confirmation to escalate. Notice how it reasons and proactively suggests escalation.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/825/1*cMv7OMps99j_NS7MdTPj4A.png" /></figure><p><strong>4. Escalates the Transaction after receiving user confirmation</strong></p><p>Upon user confirmation, the transaction is successfully escalated.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/798/1*0JsbG9Jf_RXD-ErcU2gZeQ.png" /></figure><p>The agent calls the <em>Escalate_Transaction</em> procedure with the transaction ID and the drafted reason. The record is written to the Escalation table for further review. Check the <em>Escalations</em> table to confirm.</p><p>SELECT * FROM ESCALATIONS order by escalated_at desc;</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/539/1*OvwnhA2AX6B9PFKf4c08AQ.png" /></figure><p>The <strong>ESCALATION_REASON</strong> column will reflect the skill’s structured format: risk tier, merchant category, chargeback rate, country mismatch if any, and amount, not a freeform sentence the LLM improvised.</p><p>Expand the the column and view the content to confirm.</p><p><em>“High-risk customer (tier: high) transacting $2,430.64 with a UAE-based crypto exchange (8% chargeback rate) from India at 3:15 AM — cross-border mismatch and unusual timing suggest potential fraud/money laundering”.</em></p><p>Compare this to the earlier escalation record from our previous <a href="https://medium.com/towards-artificial-intelligence/agentic-ai-in-action-part-24-building-a-fraud-ops-escalation-agent-with-snowflake-cowork-a223cbdeac19">blog</a>. The reason column was a short sentence then and whatever the agent improvised from the question asked. The reason now follows the exact structure defined in the SKILL.md, customer risk tier first, then merchant category and chargeback rate, country mismatch if present, and transaction amount to close.<em> The output is noticeably more structured and auditable.</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*uixY7SqaasDYq5eLf-9OPg.png" /></figure><h3>Why a skill and not just an instruction</h3><p>The skill does two things the orchestration instructions alone cannot. First, it encodes domain knowledge in a form that is versioned and auditable. The SKILL.md lives on a stage, which means it can be governed by Snowflake roles, updated without touching the agent configuration, and reviewed the same way you would review a SQL change. Second, it makes the agent’s reasoning reproducible. Two different analysts asking the same question in different ways will get escalation drafts built on the same signal hierarchy.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Pt14qpUcv2N9FdlVCc9HSQ.png" /></figure><p>Orchestration instructions are best kept for routing decisions, telling the agent to use Cortex Analyst for structured data questions and Cortex Search for policy or document questions. The moment domain reasoning gets detailed enough to need its own structure, its own version history, and its own owner, it belongs in a skill. That separation keeps the agent configuration clean and the domain logic maintainable as it grows.</p><p>(The code and the SKILL.md file for this walkthrough can be accessed <a href="https://github.com/Krishsriniv/snowflake-cowork-with-agent-skill">here</a>. The code for this blog is built on top of the previous <a href="https://medium.com/towards-artificial-intelligence/agentic-ai-in-action-part-24-building-a-fraud-ops-escalation-agent-with-snowflake-cowork-a223cbdeac19">blog</a> where we created the objects and built the agent).</p><p><em>I share hands-on, implementation-focused perspectives on Generative &amp; Agentic AI, LLMs, Snowflake and Cortex AI, translating advanced capabilities into practical, real-world analytics use cases. Do follow me on </em><a href="https://www.linkedin.com/in/krishsrinivasans/"><em>LinkedIn</em></a><em> and </em><a href="https://medium.com/@krish.srinivasans"><em>Medium</em></a><em> for more such insights.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=68720c239035" width="1" height="1" alt=""><hr><p><a href="https://pub.towardsai.net/agentic-ai-in-action-part-25-extending-your-cowork-agent-with-a-cortex-agent-skill-68720c239035">Agentic AI in Action — Part 25 -Extending our CoWork Agent with a Cortex Agent Skill.</a> was originally published in <a href="https://pub.towardsai.net">Towards AI</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Agentic AI in Action — Part 24 - Building a Fraud Ops Escalation Agent with Snowflake CoWork]]></title>
            <link>https://pub.towardsai.net/agentic-ai-in-action-part-24-building-a-fraud-ops-escalation-agent-with-snowflake-cowork-a223cbdeac19?source=rss-cb9e0b4c6b11------2</link>
            <guid isPermaLink="false">https://medium.com/p/a223cbdeac19</guid>
            <category><![CDATA[snowflake]]></category>
            <category><![CDATA[ai-agent]]></category>
            <category><![CDATA[agentic-ai]]></category>
            <category><![CDATA[llm]]></category>
            <category><![CDATA[ai]]></category>
            <dc:creator><![CDATA[Krishnan Srinivasan]]></dc:creator>
            <pubDate>Tue, 07 Jul 2026 03:34:30 GMT</pubDate>
            <atom:updated>2026-07-08T16:01:40.839Z</atom:updated>
            <content:encoded><![CDATA[<h3>From Question to Escalation: Building a Fraud Ops Agent with Snowflake CoWork</h3><h4><em>Standing up a working CoWork agent with governed data, structured metrics, and a write action for escalation.</em></h4><p>At Summit 2026, Snowflake rebranded Snowflake Intelligence as Snowflake CoWork and significantly expanded its capabilities. While it retains the conversational interface and Cortex Agent foundation, CoWork is positioned as a personal work agent for every knowledge worker. New capabilities include Deep Research for multi-step investigations, Artifacts for persistent and shareable outputs, MCP connectors that let the agent interact with enterprise tools such as Slack, Google Workspace, and Salesforce, and User Skills that allow reusable multi-step workflows to be captured and shared.</p><p><a href="https://medium.com/towards-artificial-intelligence/agentic-ai-in-action-part-23-snowflake-semantic-views-where-ai-agents-earn-enterprise-trust-17aa8e509d76">Part 23</a> of the Agentic AI series went deep on Semantic Views as the layer that keeps an agent’s metrics consistent instead of drifting across handwritten SQL. This time we put one to work. We will stand up a small fraud ops dataset, wire that Semantic View into a CoWork agent, give the agent a tool that can actually do something beyond answering questions. By the end, a natural language question will have turned into a governed escalation record.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*lQosq5tTtIJpBHVBQypvRg.png" /></figure><p>The blog contains the complete SQL walkthrough plus UI screenshots woven in to show what CoWork actually looks and feels like compared to Snowflake Intelligence. By the end you will have a working agent you can open in CoWork and ask real questions of.</p><h3>The dataset</h3><p>A fraud ops team needs three things to investigate a flagged transaction. The transaction itself, the merchant it ran against, and the customer’s recent history. We will build all three as plain tables and load synthetic data.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/875/1*Uv8c3o23Sf8HIVtNJSnFAQ.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/610/1*JgjOhCZi7TQ9KAOhUJIdpw.png" /></figure><p>We will load these tables with synthetic rows. A small generator is enough for this to feel real without needing an external file.</p><p><strong>Customers:</strong> 500 customers spread across five countries, each assigned a risk tier weighted so roughly twenty percent are high risk, thirty percent medium, and the rest low, creating a realistic distribution for a consumer fintech portfolio.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/689/1*oTJ7LZSblAf3kAz4gffLQA.png" /></figure><p><strong>Merchants: </strong>80 merchants across six categories including crypto exchange, which sits alongside groceries and electronics to give the flagged rate analysis something interesting to surface. Each merchant carries a randomly assigned chargeback rate between 0 and 25 percent, simulating the spectrum from low risk grocery stores to volatile high-chargeback operators.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/665/1*mXHlU2qwFpX4GRK4TGu-Ig.png" /></figure><p><strong>Transactions: </strong>20,000 transactions spanning the last two months, with amounts ranging from five dollars to twenty-five hundred. The transaction country is randomized independently of the customer’s home country, which creates cross-border transaction patterns that a fraud model would typically flag as signals worth investigating.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/691/1*LElJ8tMC0wHDq6s5Wj2Psw.png" /></figure><p>Notice the last column. About six percent of transactions come in flagged, which gives the agent something worth investigating instead of a uniformly boring table.</p><h3>The Semantic View:</h3><p>A Cortex Analyst tool needs a Semantic View to understand what “flagged transaction rate” or “high risk merchant” actually means against these tables. Same idea as <a href="https://medium.com/towards-artificial-intelligence/agentic-ai-in-action-part-23-snowflake-semantic-views-where-ai-agents-earn-enterprise-trust-17aa8e509d76">Part 23</a>, just pointed at a new dataset. The full DDL is in the companion script and here is what it defines.</p><p>There are three logical tables with primary keys and synonyms so CoWork resolves “clients” and “vendors” to the right table without guessing. Two explicit relationships wiring the join paths from transactions to customers and merchants, so the agent never has to infer how the tables connect. Facts capture the row-level measures before aggregation: amount_usd, is_flagged, and chargeback_rate. Dimensions provide the categorical slicing context: risk_tier, category, transaction_country, and a few others. Metrics are where the business logic lands: total_volume, flagged_count, and total_count as base aggregations, and flagged_rate as a derived metric that divides flagged_count by total_count, following the pattern for a typical ratio metric.</p><p>Run a quick sanity check.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/697/1*jxgj8rhEmRrNZQHXwLFr5g.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/753/1*xa1sUVmDev5wZwPyMuhydQ.png" /></figure><p><em>(Note: The null values in category and risk_tier are expected. The synthetic data uses uniform(1, 80, random()) for merchant IDs and uniform(1, 500, random()) for customer IDs in the transactions table, which occasionally generates IDs that do not exist in the merchants or customers lookup tables. Those unmatched rows surface as nulls in the joined output. In a production dataset with referential integrity enforced this would never happen).</em></p><h3>Closing the Loop with a Write Action</h3><p>Answering questions is half the point. The other half is acting on the answer. We will give the agent a stored procedure that can escalate a transaction, something a real fraud analyst would otherwise do by hand in a case management tool.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/652/1*Y2qzxEyXGCttBt8N_DiiyA.png" /></figure><p>This is a simplified version for easy reproducibility. A production version would route to a case management system through an MCP connector, but the pattern of giving the agent a write action, not just a read path, is the part worth demonstrating.</p><h3>Building the Agent</h3><p>We will now build the agent. The steps below mirror the exact sequence in Snowsight, so it is easy to follow along and replicate.</p><p><strong>Step 1- Create the Agent: </strong>In Snowsight, go to AI &amp; ML &gt; Agents and click Create agent. Name it FraudOps.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/514/1*QfUECsmuGgWXP1ZakuayYA.png" /></figure><p><strong>Step 2 — Add Semantic View:</strong> Open the Agent. Navigate to Configuration -&gt;Tools and Choose the <em>Add semantic view</em> option</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/903/1*etlA7kGFCfVllHBX_nJxCg.png" /></figure><p><strong>Step 3 — Define Cortex Analyst:</strong> The previous step will open the Cortex Analyst window. Choose the database and pick the semantic view. Name the tool as “Fraud_Transaction_Data”.You could either enter a description manually or let Cortex generate one.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/820/1*zR-QWtYsgoyF8QPXgNXcyg.png" /></figure><p><strong>Step 4 — Define the stored procedure as a custom tool: </strong>Navigate to Configuration -&gt; Tools and scroll to the Custom tools section. Add our escaltion stored procedure, as a custom tool as shown below. Let’s call this “Escalate_Transaction”</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/739/1*YhWArQHJe_cqPrchAESPLw.png" /></figure><p><strong>Step 5 — Verify that the semantic view and the custom tool are defined.</strong></p><p>Now that we have configured the semantic view and a custon tool, navigate to the Agent and check the Tools section to confirm.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/608/1*F-pBmLdXqMlwovqJN4VxWA.png" /></figure><p><strong>Step 6 — Provide Orchestration Instructions:</strong> Under orchestration instructions, add a line so the agent does not escalate silently. <em>“always confirm the transaction ID and reason with the user before calling Escalate_Transaction”. </em>This is where you build human in the loop into the agent by design. The agent will surface the decision, draft the reason, and wait for your approval before it escalates anything.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/728/1*kEYiRxs9T7rdFv4hLE73kg.png" /></figure><p><strong>Step 7 — Add Agent to Cowork:</strong> Navigate to AI &amp; ML -&gt;Agents and choose the Snowflake CoWork tab</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/448/1*HywOkgHrmDIH-AgUkYbgXg.png" /></figure><p>Now add the FraudOps agent to CoWork.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/870/1*naGBUZP_3a7c1QCyhAdRKA.png" /></figure><p><strong>Step 8 — Verify and Choose the Agent in CoWork:</strong> Navigate to AI &amp; ML -&gt; Snowflake CoWork. This will open CoWork in a new tab. Now choose the FraudOps Agent.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*EBnvNKoIU8ciQpdK47lgjg.png" /></figure><p><strong>Step 9— Ask a question: </strong>Let us start with a simple question. <em>“Which merchant categories have the highest flagged transaction rate?”</em></p><p>CoWork displays a chart, followed by a Key Findings section that contains tabular representation along with an explanation of findings.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/665/1*Fmc7PmcABwjpCFH6vwClxg.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/702/1*vHja44JUBqUYsVhnb3xHVQ.png" /></figure><p>We will ask another question. “<em>Show me flagged transactions from high risk customers against crypto exchange merchants in the last 30 days.”</em></p><p>This is the kind of compound filter that would normally take a few minutes to write by hand. The Semantic View’s relationships mean the agent can join across customers, merchants, and transactions without being told how those tables connect. The response presents a detailed tabular breakdown followed by a summarized analysis, making it easy to interpret the results without additional manual effort.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/681/1*ibVm7dzLlcD5izLr3PW_cw.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/730/1*C4RlfqaaSqNjYczoCCJyiA.png" /></figure><p><strong>Step 10 — Escalate a Transaction and Verify:</strong></p><p>Let us close the loop with an action. We will ask CoWork a question regarding high chargeback rates and escalate one such transaction.</p><p><em>“List the top 10 flagged transactions by amount from high risk customers, with the merchant category and chargeback rate”.</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/596/1*UMrhxF-rVZNngwb4aHhs1Q.png" /></figure><p>Notice what happened here. Without being asked about escalation at all, CoWork surfaces the highest-concern transactions with chargeback rates and cross-border signals highlighted, and closes with <em>“Would you like me to escalate any of these, or investigate the merchants with the highest chargeback rates further?” </em>The agent is not just answering the question. It is reasoning about what a fraud analyst would logically want to do next and offering it proactively. That is the orchestration instruction and the tool descriptions doing their job, and not a pre-scripted response.</p><p>Let us now go ahead and escalate one such transaction.</p><p><em>“Escalate Transaction 19955 as it has a very high chargeback rate”</em></p><p>Because of the orchestration instruction, the agent comes back with a confirmation step before it calls the procedure. This is human in the loop in practice. Not a checkbox on a slide or a side note, but a real approval gate built into the agent’s reasoning, where the decision stays with you and the agent handles the execution.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Ec7FOcLGXQdTW5fXzY_Vzg.png" /></figure><p>Confirm, and it writes a row to the escalations table.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/809/1*mwnTjw6K10InICYNyyiK2w.png" /></figure><p>We will now run a query and verify that the write landed.</p><p>SELECT * FROM ESCALATIONS;</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/857/1*QYRQuGNbLx0n7tr_xANVOg.png" /></figure><p>Your username will be in the escalated_by column, with the transaction ID, escalation time and the reason the agent drafted alongside it. That is the full loop closed, with a natural language question that crossed three tables, a ranked result that surfaced the right transaction, and a governed write action that left an audit trail.</p><p>In a real deployment, the escalations table becomes the source of record for downstream workflows. A manager’s daily review report would query it to track high frequency escalation patterns. Such patterns against a particular merchant or customer segment would surface as a risk signal in their own right, and perhaps triggering a merchant review process. What started as a single natural language question now has a traceable, queryable audit trail that the rest of the organisation can act on.</p><h3>From Question to Escalation</h3><p>The agent here had two tools. A Semantic View backed Cortex Analyst tool for understanding the data, and a custom procedure for acting on it. That is the entire shape of a useful CoWork agent. The questions get answered through the Semantic View. The action lands through the procedure. The orchestration instruction keeps a human in the loop before anything is written.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*CRCVxMzFwOEZpfnH69KoIQ.png" /></figure><p>The Semantic View and the procedure above are both fairly simple. What decides whether the agent reaches for them at the right moment is the description text written into the agent configuration. This is the main signal the orchestrator has about when a tool applies. The proactive escalation offer you saw in the previous step came entirely from precise tool descriptions, not from any special logic in the SQL. Spend the extra ten minutes writing those descriptions well and the agent reasons predictably, surfaces the right signals, and knows when to act. That investment in plain language pays more dividends than anything else in the configuration.</p><h3>Beyond Fraud Ops. The Pattern Applies Everywhere.</h3><p>The loop this agent closes, surface the right signal, reason about it, prompt a human for approval, write a governed action, is not specific to fraud. It is a pattern that applies anywhere an organization needs to move from data insight to a recorded decision without losing the human in the middle.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*bMlpjB4i8wSz0L0-HP0jGg.png" /></figure><p><strong>Customer service:</strong> Support interactions carry frustration signals that are easy to miss at volume. Sentiment trends, unresolved ticket age, and repeated contacts on the same issue surface the customers most likely to escalate publicly or churn. The agent prompts a supervisor to personally reach out before it gets there, and once approved, logs the intervention against the customer record with the approving agent’s name and reason attached.</p><p><strong>Supply chain:</strong> Supplier delivery performance drifts before it breaches. Tracking actuals against contracted SLAs in real time means the agent surfaces vendors approaching threshold and prompts a procurement lead to trigger a penalty clause or open a renegotiation at the right moment, not after the fact. The approved decision lands on the supplier record with full context.</p><p><strong>Healthcare operations:</strong> Bed occupancy and patient wait times tell a story before a ward hits capacity. The agent identifies the pressure points early and prompts a duty manager to authorise a diversion or resource reallocation while there is still time to act, with every approval timestamped and attributed.</p><p><strong>IT operations:</strong> Recurring failures in a service tier rarely announce themselves as a pattern until it is too late. The agent surfaces the trend early, gives an on-call engineer the context to escalate to a vendor or trigger a runbook, and once confirmed, creates a tracked incident record with the full reasoning attached.</p><p>The common thread across all of these is the same three-part structure used in this post. A Semantic View that gives the agent a consistent, governed understanding of the domain metrics. A Cortex Analyst tool that queries it in natural language. A custom write action that records the decision with a human approval step baked in. Pick any domain where data signals drive decisions and the same three-part structure applies.</p><p><em>This is CoWork at its best, a governed intelligent workspace where the agent does not just retrieve data but reasons about it, connects the dots across tools, prompts you for the next action, and escalates with your approval.</em></p><p>The code for this blog can be accessed <a href="https://github.com/Krishsriniv/snowflake-cowork-fraud-ops">here</a>.</p><p><em>I share hands-on, implementation-focused perspectives on Generative &amp; Agentic AI, LLMs, Snowflake and Cortex AI, translating advanced capabilities into practical, real-world analytics use cases. Do follow me on </em><a href="https://www.linkedin.com/in/krishsrinivasans/"><em>LinkedIn</em></a><em> and </em><a href="https://medium.com/@krish.srinivasans"><em>Medium</em></a><em> for more such insights.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a223cbdeac19" width="1" height="1" alt=""><hr><p><a href="https://pub.towardsai.net/agentic-ai-in-action-part-24-building-a-fraud-ops-escalation-agent-with-snowflake-cowork-a223cbdeac19">Agentic AI in Action — Part 24 - Building a Fraud Ops Escalation Agent with Snowflake CoWork</a> was originally published in <a href="https://pub.towardsai.net">Towards AI</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Agentic AI in Action — Part 23 — Snowflake Semantic Views: Where AI Agents Earn Enterprise Trust]]></title>
            <link>https://pub.towardsai.net/agentic-ai-in-action-part-23-snowflake-semantic-views-where-ai-agents-earn-enterprise-trust-17aa8e509d76?source=rss-cb9e0b4c6b11------2</link>
            <guid isPermaLink="false">https://medium.com/p/17aa8e509d76</guid>
            <category><![CDATA[snowflake-cortex]]></category>
            <category><![CDATA[ai-agent]]></category>
            <category><![CDATA[data-engineering]]></category>
            <category><![CDATA[ai]]></category>
            <category><![CDATA[snowflake]]></category>
            <dc:creator><![CDATA[Krishnan Srinivasan]]></dc:creator>
            <pubDate>Tue, 30 Jun 2026 03:22:17 GMT</pubDate>
            <atom:updated>2026-07-01T14:26:30.587Z</atom:updated>
            <content:encoded><![CDATA[<h3>Snowflake Semantic Views: Where AI Agents Earn Enterprise Trust</h3><h4><strong><em>A working demo of how semantic views stop your AI agents from getting it wrong</em></strong></h4><p>Your head of sales asks an agent for Q3 revenue and gets $14.2 million. Your CFO asks the same agent the same question an hour later and gets $12.8 million. Nobody made an error. Both numbers are correct, according to the system that produced them.</p><p>That sentence is the whole problem. Two correct numbers for one question is not a precision issue, it is a trust issue. And as agents take over more of the asking, this stops being a quarterly footnote and starts being the reason a perfectly good AI initiative quietly loses executive confidence.</p><p>Snowflake Semantic Views exist for exactly this moment. Instead of revenue being defined separately in a dashboard, a notebook, and an agent’s prompt, it gets defined once, inside the database, and every one of those consumers reads from that same definition. One number, agreed upon once, shown to everyone, whether the question comes from the CFO, the head of sales, or anyone else asking.</p><h3>This used to be a BI problem. Now it is an Agent problem</h3><p>Metric drift is not new. Sales has always had a slightly different definition of an active customer than finance. A dashboard built two years ago calculates revenue one way, a notebook a data scientist wrote last month calculates it another way, and a spreadsheet somewhere calculates it a third way. For years this was survivable, because a human was in the loop. An analyst would notice the gap, ask around, reconcile it, move on.</p><p>Agents remove that checkpoint. An agent does not pause to wonder why its number looks different from the one in last week’s board deck. It queries whatever table or view it has access to, applies whatever logic that object encodes, and answers with full confidence. Multiply that by a few dozen agents running continuously across a business, each one happily computing its own version of the truth, and drift stops being an occasional embarrassment. It becomes the default state.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*SUV65piZewmlTsLlzlf-5g.png" /></figure><p>The root cause is almost always the same. A metric gets defined once, somewhere reasonable, and then gets recreated by hand everywhere it is needed next. A BI model here. A dbt model there. A hardcoded calculation buried inside a prompt. Every recreation is a fresh opportunity for the definition to drift or diverge a little, and nothing forces those copies to stay in sync.</p><p><em>(Note: Worth being precise about the term “drift” here</em>, <em>since it’s easy to confuse with data drift or model drift in the typical machine learning sense. What follows is not always a metric quietly changing over time. More often it is two definitions that never matched in the first place, built independently by two teams who each made a reasonable call about something like refunds. Nothing drifted away from a shared baseline, because there was never a shared baseline to begin with. The industry calls both situations drift, so this blog does too, but it is really a divergence problem as much as a decay problem).</em></p><p>We will smulate a metric divergence scenario and address it by creating a single version of truth by leveraging Semantic views.</p><h3>What a Semantic view actually is</h3><p>A semantic view is a schema level object in Snowflake that holds the business meaning of your data alongside the data itself, rather than leaving that meaning to live in a dashboard config, a dbt model, or someone’s memory. Instead of a raw table full of columns like gross_amount and refund_amount, a semantic view defines tables, dimensions, facts, and metrics together, so revenue is not just a column, it is a named, documented, single definition that anyone, or anything, can query consistently.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Z_of6dZrN-nr6UkTchRlIw.png" /></figure><p>Business logic and metrics get defined once, in SQL, but expressed in business terms rather than raw column math, sitting on top of governed Snowflake tables. From there, that same definition gets used everywhere, BI tools, notebooks, dbt models, applications, and AI agents alike, all reading from the same object instead of each maintaining their own copy. The business impact of that is straightforward too, consistent KPIs, faster time to insight, and decisions people can actually trust, because the analyst, the dashboard, and the agent are no longer capable of disagreeing with each other.</p><p>The example at the bottom of the diagram above is really the whole point of this article in four steps. A business analyst defines a metric once. That definition becomes a semantic view. Everyone, BI tools and agents included, reads from that same definition. One number, one truth. CREATE SEMANTIC VIEW is the SQL command that builds one, and once it exists, both plain SQL and Cortex Analyst’s natural language queries read from the same object. That is the entire mechanism behind everything in the rest of this article.</p><h3>Initial Setup</h3><p>Before we begin, let us create a dedicated database and schema.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/457/1*x1P0oZL2mKNM2UIzvKCzvQ.png" /></figure><p>We will now import the accompanying notebook.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/423/1*1WtP04_Y3REBgm706UOLUw.jpeg" /></figure><h3>Reproducing the problem, step by step</h3><p>It is worth seeing this fail before talking about how to fix it. The companion notebook to this article walks through four steps inside a Snowflake Notebook. Here is each step, what the code does, and what it shows.</p><h3>Step 1: Build a small synthetic sales dataset</h3><p>This sets up a small ORDERS table, ten rows, two regions, a mix of products, and a refund flag on a few of the rows. The only column that matters for the rest of this is REFUND_AMOUNT, because that is where the drift gets seeded. Real metric drift almost never comes from bad data. It comes from a perfectly reasonable column that two teams choose to treat differently, and this step sets up that exact fork in miniature.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/733/1*EEXJmcPsM-L7hgRxJqzYjQ.png" /></figure><h3>Step 2: Reproduce the drift</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/761/1*gpMW7ndCVYmTT2ntJQ3ClA.png" /></figure><p>This creates two views over the same ten rows. REVENUE_VIEW_BI models an old dashboard that defines revenue as the gross order amount, full stop, because refunds were rare when it was built. REVENUE_VIEW_FINANCE models finance’s own query, which always nets out refunds, because that is what actually lands in the general ledger. Query both and the regional totals disagree, even though both queries are correct SQL against correct data. Neither team did anything wrong, they just never agreed on a single definition. Now picture an agent answering “what was AMER revenue last month” by querying whichever of these two views it happens to have access to. It will not pause to flag the discrepancy. It will just answer, confidently, with one half of the truth.</p><p>Upon executing this cell, the below output is returned.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/494/1*whjV78aUcGegtwwUM0rang.png" /></figure><p>We see that AMER and EMEA totals disagree across the two outputs. That gap is metric drift, reproduced with ten rows of data.</p><h3>Step 3: Fix it with a governed Semantic View</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/799/1*dckeiN27GGAQgAEjaJeLDg.png" /></figure><p>Instead of a third view with a third opinion, this defines revenue exactly once, net of refunds, as a Snowflake Semantic View. CREATE SEMANTIC VIEW is a schema level object, that holds tables, facts, dimensions, and metrics together as one governed definition rather than scattering that logic across views, notebooks, and dashboards. This is one of the more quietly powerful additions to the platform, because it moves business meaning into the database itself rather than leaving it to live in a dashboard config or a person’s memory. There is now exactly one place where what counts as revenue gets decided, and everything after this is just different ways of asking that same object the same question.</p><p>Querying it is standard SQL, through the SEMANTIC_VIEW() table function introduced alongside semantic views:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/417/1*bE9g4A48ozfPI5MKSF6RKg.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/613/1*OPZ093wVak9lXJWlAj6Sxg.png" /></figure><p>This pulls total revenue by region straight out of the semantic view using ordinary SQL, no special client or library required. The result matches finance’s number exactly, because finance’s definition is now the only definition that exists. Any new BI panel or new agent built from this point forward points at the semantic view, and the discrepancy from Step 2 structurally cannot recur there. The same semantic view can also be attached to a Snowflake CoWork agent as its Cortex Analyst tool, so business users get this in a chat window instead of opening Cortex Analyst directly.</p><h3>What just got fixed</h3><p>Step 2 left us with two views, two definitions of revenue, and two different answers to the same question. Step 3 closed that gap, but it is worth being precise about how. The semantic view did not average the two numbers or pick a winner between BI and finance. It removed the choice entirely by giving revenue exactly one definition, net of refunds, inside the database itself. AMER and EMEA revenue now have one number each, and that number holds regardless of whether the question arrives as a SQL query, a BI dashboard refresh, or eventually a natural language prompt. The two old views still exist and still disagree with each other if you query them directly, but nothing new gets built on top of them anymore. The drift stops spreading even before anyone gets around to cleaning up the old views.</p><h3>Step 4: Hand the semantic view to Cortex Analyst</h3><p>The query from the previous cell proves the semantic view returns the governed number through plain SQL. The next step, asking the same question in natural language, happens in Snowsight , because Cortex Analyst is a conversational interface, not a SQL call.</p><p>The cell below generates a direct Cortex Analyst (Snowsight) link to the semantic view created in Step 3. The link is built from a few pieces, your organization name, account name, and database, pulled live from the session so it resolves correctly no matter whose account is running it, stitched onto the fixed path that opens the Cortex Analyst editor for SALES_SEMANTIC_VIEW specifically.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/794/1*_GFzKiifB0JaETQzSSvBmg.png" /></figure><p>Paste the output of this cell to a browser, and Snowsight drops you straight into the Cortex Analyst interface with that exact semantic view already selected, with no manual navigation required.</p><p>Now, ask “what was total revenue by region” in plain English, and Cortex Analyst generates SQL against that same governed object, and returns the precise result as expected.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/826/1*VTW4VqQrpdx-5MeVdfnV1Q.jpeg" /></figure><p>This is the part that actually closes the loop on the opening scenario. The head of sales and the CFO were not asking SQL questions, they were asking an agent a question in plain English, and this step is where the natural language path produces the same number as the SQL path in Step 3, both tracing back to the one definition created there, instead of either of the two conflicting views from Step 2. In essence, Semantic views close the trust gap between your data and your AI agents.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*lFaJ-01N-ZfrRinVAqmCCw.png" /></figure><h3>Where this is heading next</h3><p>A semantic view fixes drift inside Snowflake, for anything that actually queries it. The gap is everything that does not, a Tableau workbook built before the semantic view existed, a dbt model with its own version of the same logic, a calculation that nobody ever repointed. <a href="https://www.snowflake.com/en/product/features/horizon-context/">Horizon Context</a>, announced at Summit 2026, is built to close that gap in three stages. It collects metadata from external systems like Postgres, Tableau, Power BI, and dbt, separately enriches that metadata with lineage and documentation, and activates that enriched context through search so AI agents such as CoCo can discover and prioritize the appropriate governed semantic view rather than relying solely on inferred business meaning. The piece that connects to those external systems, Metadata Connectors, is the part still in private preview as of this writing. Other pieces carry different status tags, so it is worth checking Snowflake’s release notes for the specific capability you care about rather than treating Horizon Context as one single release.</p><h3>Takeaways</h3><ul><li><strong>The failure is structural, not statistical.</strong> Two views over the same ten rows produced two different correct answers. No model was involved in that disagreement, and no model will fix it either.</li><li><strong>The fix is removal, not addition.</strong> The win is not the semantic view itself. It is deleting the second and third copies of the same metric logic that used to live elsewhere.</li><li><strong>Check the natural language answer too.</strong> Most teams stop after fixing the SQL. Step 4 matters because an agent answering in plain English needs to hit the same governed definition, or the drift just moves from BI to chat.</li><li><strong>Start by counting, not building.</strong> Pick your three or four most asked about metrics, revenue, active customers, churn, and count how many places each one is defined. That number is almost always higher than expected. Fix the highest traffic one first, not the hardest one.</li><li><strong>Horizon Context extends this further.</strong> Once a metric is governed inside Snowflake, Horizon Context is built to carry that same consistency across BI tools and systems outside Snowflake too. Worth tracking as it rolls out.</li></ul><h3>The Question worth asking clients</h3><p>Most conversations about AI accuracy start in the wrong place. Someone asks whether the agent is hallucinating, whether the model needs fine tuning, whether a better prompt would help. Those questions matter, but they are not always where the answer lives. Just as often, the real question is less interesting and more important. “<em>Is there one definition of this metric, or are there multiple?”</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/768/1*-78v89XdN0rHqdNbcm-5mw@2x.jpeg" /></figure><p>An agent that confidently hands you one of two correct numbers is not making a mistake. It is just answering from whichever definition it happened to land on. That is not a model problem, it is a single source of truth problem wearing an AI costume. Fix the source of truth, and the agent stops getting it wrong, because it no longer has two different truths to choose from. That’s exactly where semantic views come in. <em>Give the truth one home, and every agent that visits, finds the same one.</em></p><p>The companion Jupyter notebook for this blog can be accessed <a href="https://github.com/Krishsriniv/agent-trust-with-snowflake-semantic-views">here.</a></p><p><em>I share hands-on, implementation-focused perspectives on Generative &amp; Agentic AI, LLMs, Snowflake and Cortex AI, translating advanced capabilities into practical, real-world analytics use cases. Do follow me on </em><a href="https://www.linkedin.com/in/krishsrinivasans/"><em>LinkedIn</em></a><em> and </em><a href="https://medium.com/@krish.srinivasans"><em>Medium</em></a><em> for more such insights.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=17aa8e509d76" width="1" height="1" alt=""><hr><p><a href="https://pub.towardsai.net/agentic-ai-in-action-part-23-snowflake-semantic-views-where-ai-agents-earn-enterprise-trust-17aa8e509d76">Agentic AI in Action — Part 23 — Snowflake Semantic Views: Where AI Agents Earn Enterprise Trust</a> was originally published in <a href="https://pub.towardsai.net">Towards AI</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Model Experiment Tracking, Natively in Snowflake: A Practical Walkthrough using Snowflake Notebook]]></title>
            <link>https://pub.towardsai.net/model-experiment-tracking-natively-in-snowflake-a-practical-walkthrough-using-snowflake-notebook-dd63cc4ebf85?source=rss-cb9e0b4c6b11------2</link>
            <guid isPermaLink="false">https://medium.com/p/dd63cc4ebf85</guid>
            <category><![CDATA[snowflake]]></category>
            <category><![CDATA[mlops]]></category>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[ai]]></category>
            <category><![CDATA[snowflake-data-cloud]]></category>
            <dc:creator><![CDATA[Krishnan Srinivasan]]></dc:creator>
            <pubDate>Tue, 23 Jun 2026 03:48:08 GMT</pubDate>
            <atom:updated>2026-06-25T08:21:34.033Z</atom:updated>
            <content:encoded><![CDATA[<p>As machine learning adoption accelerates across enterprises, the challenge is no longer limited to building models. It is increasingly about managing them responsibly. Organizations routinely train multiple models, test various algorithms, and iterate through numerous parameter combinations. Without a structured way to track these experiments, it becomes difficult to answer fundamental questions such as which model performed best, what parameters were used, and why a particular model was ultimately selected for production.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*iY-aZfz1yseXUJ7yksUsdA.png" /></figure><p>Experiment tracking addresses this gap by providing a systematic way to record, compare, and reproduce machine learning runs. Snowflake’s native Model Experiment Tracking feature, allows organizations to manage machine learning development directly inside the AI Data Cloud, eliminating the need for external tools such as maintaining a separate ML tracking server or external interfaces. By integrating experiment tracking natively with data, compute, and governance, Snowflake enables teams to build, evaluate, and promote models within a unified and controlled environment, significantly simplifying the operationalization of enterprise machine learning.</p><h3>The Use Case: Predicting Customer Lifetime Value</h3><p>To illustrate this capability, this notebook demonstrates a complete experiment tracking workflow inside Snowflake Native Notebook. The use case chosen is Customer Lifetime Value (CLV) prediction, a common business problem that helps organizations estimate the long-term value of customers based on behavioral and transactional attributes.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*3__ID876VGZKCkyv7H-Vgw.png" /></figure><p>The primary objective here is not to build a production-grade predictive system, but to demonstrate Snowflake’s experiment tracking capability end-to-end. To keep the focus on the experiment tracking feature itself, a small synthesized dataset is created directly within the notebook.This ensures the entire lifecycle, from data creation to model registration, occurs inside Snowflake.</p><h3>Initial Setup</h3><p>We start by creating a dedicated database.</p><p>CREATE DATABASE CLV_DB;</p><p>Now navigate to the Projects -&gt; Notebook option in Snowsight and click on the +Notebook option and choose “Import .ipynb file”</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/196/1*d6xIzyyd0muw8Fzkw1mn7A.png" /></figure><p>Now import the <em>Snowflake Experiment Tracking CLV Notebook.ipynb </em>file that is provided. Ensure that you choose the CLV_DB database, that we just created.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/426/1*O0VRz4rdoqlSOJ6SaXwLog.jpeg" /></figure><p><strong><em>(Please note that if you are using the new Snowsight UI, you could directly upload or drag and drop the notebook from your local machine. The above screen capture corresponds to the legacy notebook interface)</em></strong></p><p>We will proceed with the steps in the notebook.</p><p>We start by installing the required packages.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/929/1*78xJeyEW94SRq7F5eySWpQ.png" /></figure><h4>Step 1: Initialize the Snowflake Session</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*1mDJqnB2BfJ5vYzeM8_WhA.png" /></figure><h4>Step 2: Import ML and Experiment Tracking Libraries</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/925/1*ujh7GQkWd8GjE5HPexyDig.png" /></figure><h4>Step 3: Create the Customer Lifetime Value Dataset</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/916/1*e-1BuIKrKh09T3hdeNl4dQ.png" /></figure><p>We will insert realistic business sample data.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/882/1*Vh618gJldJsFoYm8N4bsgg.png" /></figure><h4>Step 4: Load Data into Snowpark DataFrame</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*IwOSmQ2iUoRBip94Xc5Nyg.png" /></figure><h4>Step 5: Define the Features and Target</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/838/1*li99zcqOZjLcRjBgj0YmOA.png" /></figure><h4>Step 6: Initialize Experiment Tracking</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*M0J5bMWMDNkKddDJ6DiNmg.png" /></figure><h4>Step 7: Run Experiment — Linear Regression</h4><p>This run sets the baseline. LinearRegression is fit on the same features and target as every other model in this notebook, predicting PREDICTED_CLV. It’s simple and interpretable by design, the point isn’t to win on accuracy, it’s to confirm the features behave sensibly before reaching for anything heavier. The run is wrapped in exp.start_run(), with the model type and R² logged as a parameter and metric, and the fitted model itself registered via log_model(), so this baseline becomes a permanent, queryable reference point for every run that follows.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/914/1*oLcNgQj5zHdGv_k1NLqUGQ.png" /></figure><p>It will run for a few seconds as it starts to log the model:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/707/1*-CSKl_5ZuTcosfqs34YMxQ.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/770/1*gLxCdgaVdVZEwp1lmQ52bw.jpeg" /></figure><h4>Step 8: Run Experiment — XGBoost</h4><p>This run repeats the exact same pattern, same features, same target, same r2_score call, only swapping LinearRegression for XGBRegressor. The same log_param, log_metric, and log_model calls fire here as well.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/955/1*f72w34628KJIeO_qj1Fugw.png" /></figure><h4>Step 9: Compare Experiments in Snowsight</h4><p>Both runs are now sitting in the same experiment, so comparing them is just selecting and clicking Compare in Snowsight.</p><p>Navigate to:</p><p>AI &amp; ML → Experiments → CUSTOMER_LIFETIME_VALUE_EXPERIMENT</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*7Hnt5nbvkx-DajaZ4B2rCw.jpeg" /></figure><p>Select runs and click Compare.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/891/1*y3DUu2JWGKYb_wiBsr8WGA.jpeg" /></figure><p>Noe examine the Chart and Details tabs.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/513/1*6e2TRe-c2p-5NJPB-Dax9Q.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/384/1*rC5YqT5HULFNERpnDiFRGg.png" /></figure><p>Since the dataset used in this demonstration was small and synthesized, the models were evaluated on the same data they were trained on. This resulted in perfect R² scores, which is expected in such controlled scenarios. However, in real-world applications, models are evaluated on separate test datasets to ensure unbiased performance measurement. Snowflake’s experiment tracking capability supports such workflows seamlessly, allowing teams to compare models based on realistic evaluation metrics.</p><p>For the purposes of this demonstration, we will proceed with the XGBoost model as our best model.</p><h4>Step 10: Register Best Model</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/833/1*Lt5zogmnOHCLapRMZxic5w.png" /></figure><h4>Step 11: Create a Small Inference Dataset</h4><p>We create a small synthetic dataset of new customers, ones the model has never seen, to test inference.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/860/1*PdfVHON6jpgk-tJ62-fHQw.png" /></figure><h4>Step 12: Load the Registered Model and run Inference</h4><p>This step imports the registered model from the Model Registry by name along with the latest version, loads it, and runs it against the fresh data.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/930/1*oxTQrXnmiSb0GEi0GQd2KQ.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/987/1*w4Oeq-9GMle0-cZ4LetOhw.png" /></figure><p>This closes the complete loop. The model trained, logged, compared, and registered earlier in the notebook now predicts CLV on data it has never seen, with no separate deployment step or external serving layer required.</p><h4>Cleanup (Optional) — Delete the Experiment and drop the Model</h4><p>Running these commands removes the experiment and the registered model once you are done exploring.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/880/1*2-7TV8InwXMQULtv9uomrQ.png" /></figure><p>Predicting Customer Lifetime Value (CLV) requires transforming raw transactional and behavioral data, such as recency, frequency, and monetary value, into actionable business foresight. As demonstrated, applying native experiment tracking to this use case allows us to seamlessly evaluate and promote models entirely within the AI Data Cloud, ensuring these critical predictions are accurate, reproducible, and securely governed.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*QDzAzwIeFfgo9TAzF6ABVw.png" /></figure><h3>From Experimentation to Operational Confidence</h3><p>Machine learning development is fundamentally an iterative process. Models evolve through experimentation, comparison, and refinement before they are ready for operational use. Without a structured way to track these iterations, organizations risk losing visibility into how models were developed, what alternatives were considered, and why a particular model was ultimately selected. This lack of traceability can undermine reproducibility, governance, and confidence in machine learning systems.</p><p>Snowflake’s native Experiment Tracking capability addresses this challenge by bringing experiment management directly into the platform. As demonstrated in this notebook, experiments can be created, tracked, and compared entirely within Snowflake, with each run capturing its associated parameters, metrics, and model artifacts. This provides a persistent and governed record of model development, ensuring that decisions are transparent and reproducible.</p><p>Equally important, experiment tracking does not exist in isolation. It integrates seamlessly with Snowflake’s Model Registry, enabling models that emerge from experimentation to be registered, versioned, and operationalized. The final inference step illustrates this continuity — from training and tracking experiments, to registering the selected model, and ultimately applying it to new data. This completes the full machine learning lifecycle within a single, unified platform.</p><p>By eliminating the need for external tracking infrastructure such as standalone MLflow servers and embedding experiment tracking natively within Snowflake, organizations can simplify their machine learning workflows while strengthening governance and reliability. Experiment tracking becomes not just a development aid, but a foundational capability that enables machine learning to scale responsibly.</p><p>The true power of native experiment tracking lies in its continuity. As shown below, once the winning XGBoost model is selected and registered, it transitions smoothly from a data science experiment into an operationalized asset, ready to drive measurable business value across retail, marketing, and finance workflows within a fully governed framework.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*gIra8idgdHRHU1m8FxnUIQ.png" /></figure><p>As machine learning continues to play a critical role in enterprise decision-making, the ability to track, compare, and operationalize models with confidence becomes essential for realizing business value. Snowflake’s native Experiment Tracking capability provides exactly this by transforming machine learning from a collection of isolated experiments into a structured, governed, and enterprise-ready discipline within the AI Data Cloud.</p><p>The code files associated with this blog can be accessed <a href="https://github.com/Krishsriniv/snowflake-model-experiment-tracking">here</a>.</p><p><em>I share hands-on, implementation-focused perspectives on Generative &amp; Agentic AI, LLMs, Snowflake and Cortex AI, translating advanced capabilities into practical, real-world analytics use cases. Do follow me on </em><a href="https://www.linkedin.com/in/krishsrinivasans/"><em>LinkedIn</em></a><em> and </em><a href="https://medium.com/@krish.srinivasans"><em>Medium</em></a><em> for more such insights.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=dd63cc4ebf85" width="1" height="1" alt=""><hr><p><a href="https://pub.towardsai.net/model-experiment-tracking-natively-in-snowflake-a-practical-walkthrough-using-snowflake-notebook-dd63cc4ebf85">Model Experiment Tracking, Natively in Snowflake: A Practical Walkthrough using Snowflake Notebook</a> was originally published in <a href="https://pub.towardsai.net">Towards AI</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Agentic AI in Action — Part — 22 — Memory in Agentic AI on Snowflake]]></title>
            <link>https://pub.towardsai.net/memory-in-agentic-ai-on-snowflake-how-memory-transforms-ai-from-tool-to-teammate-b6518a7d926a?source=rss-cb9e0b4c6b11------2</link>
            <guid isPermaLink="false">https://medium.com/p/b6518a7d926a</guid>
            <category><![CDATA[ai-agent]]></category>
            <category><![CDATA[llm]]></category>
            <category><![CDATA[snowflake]]></category>
            <category><![CDATA[generative-ai-tools]]></category>
            <category><![CDATA[ai]]></category>
            <dc:creator><![CDATA[Krishnan Srinivasan]]></dc:creator>
            <pubDate>Wed, 17 Jun 2026 03:52:55 GMT</pubDate>
            <atom:updated>2026-06-17T06:51:32.266Z</atom:updated>
            <content:encoded><![CDATA[<h3>Memory in Agentic AI on Snowflake: How Memory Transforms AI from Tool to Teammate</h3><p>Most AI models today are inherently stateless. While systems can introduce memory through external storage and retrieval, the model itself does not persist experience across interactions. Every interaction depends on what is explicitly provided in the moment, rather than what the system has accumulated over time. Context can be passed. Experience cannot. This distinction is subtle, but important.</p><p>A stateless system can respond intelligently within a moment, but it does not naturally improve from one interaction to the next. It does not remember recurring issues. It does not recognize patterns unless they are explicitly retrieved and supplied again. Without persistent memory, intelligence exists only within the boundary of a single request.</p><p>Agentic AI changes this model. An agent does not simply respond. It observes, reasons, acts, and critically, remembers. Memory allows the system to carry forward experience, build continuity, and refine its behavior over time. Each interaction becomes part of a growing internal context that influences future decisions. This is what transforms an AI system from a reactive tool into an adaptive participant.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*3FISZpITUrWxAVNHQP3CBQ.png" /></figure><p>When a customer support agent remembers prior complaints, resolution patterns, and customer preferences, its responses evolve from generic to precise. When a data engineering agent remembers schema changes, pipeline failures, and data anomalies, it prevents recurring issues instead of repeatedly reacting to them. When an enterprise AI system remembers organizational context, it stops behaving like an external assistant and starts behaving like an internal teammate.</p><p>Memory transforms AI from reactive to adaptive.</p><p>The reason is simple. Intelligence is not defined by reasoning alone. It is defined by the ability to accumulate experience.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/929/1*A2iuCYBt7fIrJsMawfM24g.png" /></figure><p>Agentic systems operate in a continuous loop. They observe inputs, reason about them, take actions, evaluate outcomes, and update their internal state. Memory is the persistence layer of this loop. It carries forward the system’s accumulated understanding, ensuring that every future decision benefits from past experience.</p><p>Without memory, the loop collapses into repetition. With memory, the loop becomes evolution.</p><p>This memory exists in multiple forms. Some memory is short-term, preserving context within a session. Some memory is long-term, persisting across sessions and workflows. Some memory is structured, such as events, decisions, and system states. Some memory is semantic, capturing meaning through embeddings that allow agents to retrieve relevant past knowledge even when the wording differs. Together, these layers create continuity.</p><p>Modern data platforms make this architecture practical. Snowflake’s AI Data Cloud provides a unified foundation where agent memory, reasoning, and execution coexist securely and scalably. Memory can be stored as structured records, enriched with semantic embeddings, and retrieved dynamically using Cortex functions. This allows agents to access relevant historical knowledge in real time, without introducing external complexity or fragmentation.</p><p>The architecture becomes both intelligent and governed within the AI data cloud.</p><p>The lifecycle begins when the agent observes an interaction. This interaction is converted into both structured and semantic memory. <strong>Structured memory</strong> captures explicit attributes such as timestamps, users, actions, and outcomes. <strong>Semantic memory</strong> captures meaning using embeddings, enabling contextual retrieval later. When the agent encounters a new situation, it queries its memory store to retrieve the most relevant prior experiences. These retrieved memories inform reasoning, enabling more accurate decisions. After the action is completed, the outcome itself becomes new memory, continuously improving the agent.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/939/1*LdL_v3cvNxcL1qwprcZLAA.png" /></figure><p>This creates a self-reinforcing cycle.</p><p>The implementation of this architecture can be achieved entirely within Snowflake using Cortex capabilities. In this implementation, the agent combines structured and semantic long-term memory, allowing it not only to store experiences, but to retrieve and apply them intelligently when needed.</p><p>We begin by establishing the environment where agent memory will live.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/566/1*Gh0FV4n-kixHnlTqQlYXZQ.png" /></figure><p>This creates a governed, centralized memory layer inside Snowflake. Memory itself consists of two components. The event itself, and the semantic representation of that event. The event captures what happened. The embedding captures what it means.</p><p>We now create the memory table.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/796/1*KQcnPV6GlUC8Igxmk2FZ7Q.png" /></figure><p>This table becomes the persistent memory of the agent. Every time the agent observes an interaction, it converts that interaction into semantic memory and stores it.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/769/1*ydQPtUe0Jttylf8NvEcS7w.png" /></figure><p>This insert statement stores a customer interaction in the agent’s memory table and generates a semantic embedding of the interaction using an embedding model. The embedding converts the text into a numerical vector that captures its meaning, allowing the agent to later retrieve this memory based on contextual similarity rather than exact wording.</p><p>At this moment, the agent has learned something. The interaction is no longer transient. It has become persistent experience.</p><p>As more interactions occur, the memory grows. Let us insert another row.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/782/1*EyPnQSLTW6YehkgyAwIQYQ.png" /></figure><p>The power of memory emerges during retrieval. When a new query arrives, the agent searches its memory for relevant prior experiences using semantic similarity.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/843/1*Pv5HCXRXMBxOz7Rd0se06g.png" /></figure><p>This query converts the new customer issue into an embedding and compares it with stored memory embeddings using cosine similarity to find the most contextually relevant past events. It allows the agent to retrieve prior experiences that are semantically similar, enabling more informed and context-aware responses. This allows the agent to retrieve experiences based on meaning, not keywords. Even if the wording differs, the context remains accessible.</p><p>This retrieved memory now becomes input to reasoning.</p><p>Now, the query below retrieves the agent’s memory events and provides them as context to the Cortex LLM (claude-3–5-sonnet) enabling it to generate a response that is informed by prior interactions rather than responding in isolation. In effect, it allows the agent to use its stored memory to produce a more context-aware and intelligent response.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/839/1*WgB90KBaNVXcCMkrYvz7SQ.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*s3AQgXMb4P0nxyfE1llbYw.png" /></figure><p>This response is fundamentally different from a stateless answer. It incorporates accumulated experience. It reflects continuity. The agent is no longer reacting in isolation. It is responding with context.</p><p>It allows the agent to convert multiple past experiences into a higher-level understanding, helping it recognize patterns instead of treating each event independently.</p><p><em>(Note: If the model claude-sonnet-4–5, is not supported in your region, you may get an error during the execution. To resolve this, please enable the CROSS_REGION_INFERENCE parameter.Setting the parameter to </em><em>ANY_REGION provides access to the full set of supported models and Cortex products, with the highest available capacity. Snowflake routes requests to the optimal region automatically. Refer </em><a href="https://docs.snowflake.com/en/user-guide/snowflake-cortex/cross-region-inference"><em>here</em></a><em> for details on the same.</em></p><p><em>ALTER ACCOUNT SET CORTEX_ENABLED_CROSS_REGION = ‘ANY_REGION’;)</em></p><p>Moving ahead, the query below combines all support-related memory events into a single text using LISTAGG, and then uses the Cortex SUMMARIZE function to generate a concise summary of those interactions. Over time, memory itself evolves. Individual events can be summarized into higher-level understanding. Cortex enables this consolidation.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/605/1*e3ySwWSWOD3GCMqEwm6xAA.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/811/1*cwEr59rvIWw2bSbpuiwZNQ.png" /></figure><p>This allows the agent to move beyond remembering individual events and begin understanding patterns.</p><p>In a production setup, this architecture expands beyond a single memory table into a fully managed memory lifecycle integrated with governance, performance optimization, and operational reliability. Memory is typically separated into short-term operational memory and long-term semantic memory, with automated pipelines that continuously ingest interactions from applications, support systems, or data platforms. Retrieval is optimized using vector indexes and relevance filtering to ensure low-latency access even at scale. Memory is periodically summarized, consolidated, and pruned to prevent uncontrolled growth and preserve only high-value knowledge. Guardrails and access controls ensure that sensitive memory is only accessible to authorized agents, maintaining enterprise security and compliance. Observability layers track what memory was retrieved, how it influenced decisions, and whether outcomes improved, enabling continuous evaluation and refinement. Over time, this transforms the agent from a reactive responder into a continuously learning system that becomes more accurate, efficient, and context-aware as it operates.</p><p>Memory transforms the nature of the system itself. Without memory, the agent behaves like a calculator, producing outputs without awareness of history. With memory, the agent behaves like a participant, continuously refining its understanding of its environment. This is the true shift introduced by Agentic AI.</p><p>While this demonstrates how easily you can implement this loop using the Snowflake AI Data Cloud, the fundamental concept of architectural memory is entirely generic and can be applied to any data ecosystem.</p><p>The future of enterprise AI will not be defined by models alone. Models provide reasoning, but memory provides continuity. Models generate responses, but memory enables learning. Models create intelligence in isolation, but memory creates intelligence over time. Agentic systems are not defined by their ability to respond. They are defined by their ability to remember. And through memory, to improve.</p><p>The code associated with this blog can be accessed <a href="https://github.com/Krishsriniv/Snowflake-Agentic-Memory">here.</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b6518a7d926a" width="1" height="1" alt=""><hr><p><a href="https://pub.towardsai.net/memory-in-agentic-ai-on-snowflake-how-memory-transforms-ai-from-tool-to-teammate-b6518a7d926a">Agentic AI in Action — Part — 22 — Memory in Agentic AI on Snowflake</a> was originally published in <a href="https://pub.towardsai.net">Towards AI</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>