<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Akshay Sharma</title>
    <description>The latest articles on DEV Community by Akshay Sharma (@akshaysharma10).</description>
    <link>https://dev.to/akshaysharma10</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4236411%2Fc46144be-804d-41c7-bf93-1e34b96af9d9.png</url>
      <title>DEV Community: Akshay Sharma</title>
      <link>https://dev.to/akshaysharma10</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/akshaysharma10"/>
    <language>en</language>
    <item>
      <title>Beyond Sentiment: Customer Intelligence with Snowflake Cortex AI and Streamlit</title>
      <dc:creator>Akshay Sharma</dc:creator>
      <pubDate>Tue, 10 Nov 2026 06:56:09 +0000</pubDate>
      <link>https://dev.to/akshaysharma10/beyond-sentiment-customer-intelligence-with-snowflake-cortex-ai-and-streamlit-280m</link>
      <guid>https://dev.to/akshaysharma10/beyond-sentiment-customer-intelligence-with-snowflake-cortex-ai-and-streamlit-280m</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fe7falaeh3fh59sakwar1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fe7falaeh3fh59sakwar1.png" alt="Snowflake Cortex 200-case resolution intelligence dashboard" width="800" height="367"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A customer says, “Thanks for the update. I appreciate your efforts, but my account is still locked.” A sentiment model may reasonably interpret that as neutral or courteous. But a support operations dashboard needs to surface a more consequential fact: &lt;strong&gt;the issue remains unresolved&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This distinction motivated a small open-source project I built with &lt;strong&gt;Snowflake Cortex AI, SQL, and Streamlit in Snowflake&lt;/strong&gt;. Instead of reducing a support conversation to positive or negative sentiment, the implementation asks a different question: &lt;em&gt;What evidence does the customer's message provide about the status of the issue?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The repository includes reproducible SQL, synthetic case data, stored Cortex outputs, evaluation queries, a Streamlit dashboard, and a short presentation video. You can inspect the observed results without needing a Snowflake account.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Project:&lt;/strong&gt; &lt;a href="https://github.com/akshaysharma1088/snowflake-cortex-customer-intelligence" rel="noopener noreferrer"&gt;Snowflake Cortex Customer Intelligence on GitHub&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Archived project:&lt;/strong&gt; &lt;a href="https://doi.org/10.5281/zenodo.24098765" rel="noopener noreferrer"&gt;Zenodo DOI 10.5281/zenodo.24098765&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;90-second presentation:&lt;/strong&gt; &lt;a href="https://github.com/akshaysharma1088/snowflake-cortex-customer-intelligence/blob/main/Snowflake_Cortex_90s_Presentation_NEW.mp4" rel="noopener noreferrer"&gt;Watch the implementation walkthrough&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Why sentiment doesn't answer the resolution question
&lt;/h2&gt;

&lt;p&gt;Customer support language is often polite, indirect, or incomplete. Consider four hypothetical messages:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Customer message&lt;/th&gt;
&lt;th&gt;What we can infer&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;“I tested the fix and can now sign in.”&lt;/td&gt;
&lt;td&gt;The customer confirms resolution.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;“I tried again, but sign-in still fails.”&lt;/td&gt;
&lt;td&gt;The problem persists.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;“Your ticket says resolved, but I still cannot sign in.”&lt;/td&gt;
&lt;td&gt;The customer disputes a claimed resolution.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;“Can you send me the sign-in documentation?”&lt;/td&gt;
&lt;td&gt;There isn't enough evidence of resolution status.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A sentiment score does not reliably distinguish these operational situations. In particular, &lt;strong&gt;an unresolved issue is not necessarily a disputed resolution&lt;/strong&gt;. A dispute requires a prior assertion that the problem was fixed or closed and a customer response contradicting it.&lt;/p&gt;

&lt;p&gt;I therefore separated the demonstration into three concepts: sentiment polarity, expressed dissatisfaction, and &lt;strong&gt;resolution evidence&lt;/strong&gt;. The 200-case experiment discussed below evaluates only the third concept. It does not establish accuracy for dissatisfaction or sentiment classification.&lt;/p&gt;
&lt;h2&gt;
  
  
  A Snowflake-native architecture
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/akshaysharma1088/snowflake-cortex-customer-intelligence/blob/main/docs/images/snowflake-cortex-architecture.svg" rel="noopener noreferrer"&gt;View the complete Snowflake Cortex architecture diagram on GitHub&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The implementation has five parts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Input tables:&lt;/strong&gt; Store synthetic customer messages and their authored reference labels.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cortex inference:&lt;/strong&gt; Classify the message into a resolution-evidence state with &lt;code&gt;AI_CLASSIFY&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Versioned results:&lt;/strong&gt; Persist raw model responses as &lt;code&gt;VARIANT&lt;/code&gt; with a run version and timestamp.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Evaluation view:&lt;/strong&gt; Compare extracted model labels with the constructed references.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Streamlit in Snowflake:&lt;/strong&gt; Read stored results and let users inspect cohort metrics, the confusion matrix, and individual cases.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;An important design choice is separating &lt;strong&gt;inference from presentation&lt;/strong&gt;. Streamlit doesn't invoke the AI function on each refresh. Instead, it reads a saved comparison view. That makes the application easier to audit and helps prevent repeated inference charges when someone changes a filter.&lt;/p&gt;

&lt;p&gt;The broader repository also includes a bounded enrichment pipeline that demonstrates &lt;code&gt;AI_SENTIMENT&lt;/code&gt;, &lt;code&gt;AI_EXTRACT&lt;/code&gt;, and issue-category &lt;code&gt;AI_CLASSIFY&lt;/code&gt;. The resolution experiment is a separate, focused evaluation.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 1: Define resolution evidence explicitly
&lt;/h2&gt;

&lt;p&gt;I used four labels with operational meanings:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Label&lt;/th&gt;
&lt;th&gt;Definition&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;confirmed_resolved&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The customer explicitly verifies the desired outcome or a working fix.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;reported_unresolved&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The customer says an issue is ongoing or an attempted fix failed, without contradicting a prior claim of completion.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;disputed&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The customer explicitly challenges a previous statement or ticket status that the problem was resolved.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;unknown&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The message offers insufficient current resolution evidence.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;These definitions matter as much as the model call. For example, “I tried your suggestion and it failed” is not automatically a &lt;code&gt;disputed&lt;/code&gt; case. It may be only &lt;code&gt;reported_unresolved&lt;/code&gt; unless the earlier suggestion was explicitly declared to have solved the problem.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 2: Run four-class classification with Cortex AI_CLASSIFY
&lt;/h2&gt;

&lt;p&gt;The experiment stores cases in &lt;code&gt;RESOLUTION_V3_CASES&lt;/code&gt; and writes model outputs to &lt;code&gt;RESOLUTION_V3_RESULTS&lt;/code&gt;. The central classification call uses label descriptions and task-level instructions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
  &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="no"&gt;CASE_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s1"&gt;'resolution-v3.0'&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="no"&gt;VERSION&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="kc"&gt;CURRENT_TIMESTAMP&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="no"&gt;RUN_AT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="no"&gt;AI_CLASSIFY&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="no"&gt;TRANSCRIPT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'label'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s1"&gt;'confirmed_resolved'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="s1"&gt;'description'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s1"&gt;'The customer explicitly confirms they tested a fix or received the desired outcome and the problem is resolved.'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'label'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s1"&gt;'reported_unresolved'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="s1"&gt;'description'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s1"&gt;'The customer reports the problem is ongoing or an attempted fix failed, without explicitly contradicting a previous declaration that it was resolved.'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'label'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s1"&gt;'disputed'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="s1"&gt;'description'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s1"&gt;'The customer explicitly challenges another actor''s statement or ticket status asserting the issue is resolved, completed, or fixed.'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'label'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s1"&gt;'unknown'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="s1"&gt;'description'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s1"&gt;'There is insufficient evidence about current resolution status: a procedural question, future promise, documentation request, or polite closing.'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s1"&gt;'task_description'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="s1"&gt;'Classify resolution evidence only, not sentiment or courtesy. '&lt;/span&gt;
        &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="s1"&gt;'Choose disputed only for explicit contradiction of a prior '&lt;/span&gt;
        &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="s1"&gt;'completion claim. For future plans or questions without '&lt;/span&gt;
        &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="s1"&gt;'current issue evidence, choose unknown. Return one label.'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s1"&gt;'output_mode'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s1"&gt;'single'&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="no"&gt;RESOLUTION_RAW&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="no"&gt;RESOLUTION_V3_CASES&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Illustrative excerpt adapted from the project's executable script. Use the complete versioned SQL file to rerun the experiment; the excerpt above is not a substitute for its schema, idempotency and persistence logic.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The runnable script avoids reclassifying case/version pairs that already have a successful result. This is valuable when rerunning a notebook or working in a time-limited trial environment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Full SQL:&lt;/strong&gt; &lt;a href="https://github.com/akshaysharma1088/snowflake-cortex-customer-intelligence/blob/main/sql/09_resolution_v3_200_benchmark.sql" rel="noopener noreferrer"&gt;&lt;code&gt;sql/09_resolution_v3_200_benchmark.sql&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Persist predictions and compare evidence
&lt;/h2&gt;

&lt;p&gt;Cortex responses are stored in a &lt;code&gt;VARIANT&lt;/code&gt; column instead of immediately discarded after extracting a label. A versioned comparison view then exposes both the raw response and a normalized prediction:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
  &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="no"&gt;CASE_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="no"&gt;GOLD_RESOLUTION&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="no"&gt;RESOLUTION_RAW&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="no"&gt;RESOLUTION_RAW&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="kt"&gt;VARCHAR&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="no"&gt;CORTEX_RESOLUTION&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="no"&gt;IFF&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="no"&gt;RESOLUTION_RAW&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;IS&lt;/span&gt; &lt;span class="kc"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="kc"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="no"&gt;IFF&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="no"&gt;RESOLUTION_RAW&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="kt"&gt;VARCHAR&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="no"&gt;GOLD_RESOLUTION&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="no"&gt;EXACT_MATCH&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="no"&gt;RESOLUTION_V3_CASES&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;
&lt;span class="k"&gt;LEFT&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="no"&gt;RESOLUTION_V3_RESULTS&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;
  &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="no"&gt;CASE_ID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="no"&gt;CASE_ID&lt;/span&gt;
 &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="no"&gt;VERSION&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'resolution-v3.0'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Simplified excerpt; the committed comparison view also selects the latest run per case and includes product, domain, cohort, and timestamp.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Preserving the raw responses helps with debugging, schema changes, audits of unexpected labels, and more nuanced evaluation than a single aggregate percentage.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Show the observed outcomes in Streamlit
&lt;/h2&gt;

&lt;p&gt;The Streamlit application uses an active Snowflake session to read &lt;code&gt;CORTEX_CI_DEMO.APP.V_RESOLUTION_V3_COMPARISON&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="n"&gt;streamlit&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;st&lt;/span&gt;
&lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;snowflake&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;snowpark&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="n"&gt;get_active_session&lt;/span&gt;

&lt;span class="nd"&gt;@st&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cache_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ttl&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;load_predictions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_active_session&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sql&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"""
        SELECT CASE_ID, PRODUCT, DOMAIN, COHORT,
               TRANSCRIPT, GOLD_RESOLUTION,
               CORTEX_RESOLUTION, EXACT_MATCH,
               TO_VARCHAR(RESOLUTION_RAW) AS RESOLUTION_RAW_TEXT
        FROM CORTEX_CI_DEMO.APP.V_RESOLUTION_V3_COMPARISON
        WHERE CASE_ID LIKE 'R3-%'
        ORDER BY CASE_ID
    """&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_pandas&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a read-only data retrieval path—&lt;strong&gt;no Cortex inference runs when a dashboard user reloads the page&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fe7falaeh3fh59sakwar1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fe7falaeh3fh59sakwar1.png" alt="Actual Streamlit dashboard in Snowflake showing the 200-case synthetic evaluation and confusion matrix" width="800" height="367"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Actual Snowsight screenshot of the 200-case dashboard. The agreement metric reflects controlled synthetic examples, not field accuracy.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The dashboard exposes per-class counts, a confusion matrix, filters by reference label and domain, and an individual-case explorer that displays the message, expected label, Cortex prediction, and stored raw response.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fd0c2gw9nzw8r4aetwc5l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fd0c2gw9nzw8r4aetwc5l.png" alt="Actual Snowflake Streamlit case explorer showing the reference labels, predictions and customer messages" width="800" height="385"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Actual case-level explorer from the working application.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Streamlit source:&lt;/strong&gt; &lt;a href="https://github.com/akshaysharma1088/snowflake-cortex-customer-intelligence/blob/main/streamlit_resolution_v3.py" rel="noopener noreferrer"&gt;&lt;code&gt;streamlit_resolution_v3.py&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What did the experiments show?
&lt;/h2&gt;

&lt;p&gt;I ran three small exercises during the November 2026 Snowflake trial:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Exercise&lt;/th&gt;
&lt;th&gt;Observed outcome&lt;/th&gt;
&lt;th&gt;Interpretation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;8-case enrichment smoke test&lt;/td&gt;
&lt;td&gt;8/8 enriched; 6/8 sentiment-label and 5/8 issue-label matches&lt;/td&gt;
&lt;td&gt;Validated the initial end-to-end pipeline, not general model quality.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;24-case resolution v2&lt;/td&gt;
&lt;td&gt;20/24 exact matches (83.33%)&lt;/td&gt;
&lt;td&gt;Exposed confusion around unresolved versus disputed resolution.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;200-case resolution v3&lt;/td&gt;
&lt;td&gt;200/200 exact matches (100%)&lt;/td&gt;
&lt;td&gt;Consistent behavior on an intentionally structured synthetic set.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The &lt;strong&gt;24-case experiment was more informative than the perfect-looking final percentage&lt;/strong&gt;. Of the four mismatches, three ongoing-issue messages were classified as disputes, while a future-oriented request was interpreted as unresolved. That pointed to a semantic boundary that needed more explicit treatment: &lt;strong&gt;a failed fix is not always a challenge to a claimed resolution&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;After revising the label instructions, I ran a 200-case synthetic demonstration. The dataset was balanced across four reference categories: 50 examples per category. Every model prediction matched its constructed reference label.&lt;/p&gt;

&lt;p&gt;But the important caveat is that the &lt;strong&gt;200 examples were generated from 20 sentence templates across 10 product/feature contexts&lt;/strong&gt;. They are not 200 independent, naturally occurring support conversations; labels were authored as part of dataset creation. Both the instructions and datasets changed between v2 and v3, so the difference in observed agreement &lt;strong&gt;cannot&lt;/strong&gt; be attributed solely to better instructions.&lt;/p&gt;

&lt;p&gt;That means &lt;strong&gt;200/200 is not evidence of 100% real-world accuracy&lt;/strong&gt;. It is a controlled implementation and taxonomy demonstration. A rigorous next benchmark would require diverse, independently annotated, multi-turn messages, including ambiguous closures, partial fixes, indirect complaints and contrastive examples that differ by only one important clause.&lt;/p&gt;

&lt;p&gt;The project preserves the full observed output for inspection: &lt;a href="https://github.com/akshaysharma1088/snowflake-cortex-customer-intelligence/blob/main/data/resolution_v3_observed.csv" rel="noopener noreferrer"&gt;200-row CSV&lt;/a&gt; and &lt;a href="https://github.com/akshaysharma1088/snowflake-cortex-customer-intelligence/blob/main/docs/resolution-v3-observed-results.md" rel="noopener noreferrer"&gt;evaluation notes&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to reproduce the implementation
&lt;/h2&gt;

&lt;p&gt;With compatible Snowflake Cortex access and a suitable warehouse:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Review the repository's setup instructions, role privileges, and potential Cortex inference charges.&lt;/li&gt;
&lt;li&gt;Create the expected &lt;code&gt;CORTEX_CI_DEMO&lt;/code&gt; database, &lt;code&gt;APP&lt;/code&gt; schema, and &lt;code&gt;CORTEX_CI_WH&lt;/code&gt; warehouse, or adjust those names in the script.&lt;/li&gt;
&lt;li&gt;Run the complete &lt;a href="https://github.com/akshaysharma1088/snowflake-cortex-customer-intelligence/blob/main/sql/09_resolution_v3_200_benchmark.sql" rel="noopener noreferrer"&gt;&lt;code&gt;09_resolution_v3_200_benchmark.sql&lt;/code&gt;&lt;/a&gt; in Snowsight. It seeds synthetic examples, performs bounded classification, stores outputs, and creates &lt;code&gt;V_RESOLUTION_V3_COMPARISON&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Create a Streamlit in Snowflake application using &lt;a href="https://github.com/akshaysharma1088/snowflake-cortex-customer-intelligence/blob/main/streamlit_resolution_v3.py" rel="noopener noreferrer"&gt;&lt;code&gt;streamlit_resolution_v3.py&lt;/code&gt;&lt;/a&gt; and grant the app role read access to the view.&lt;/li&gt;
&lt;li&gt;Inspect class counts, the confusion matrix, and individual messages. Export results or read the checked-in CSV to audit the outputs offline.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you don't have a Snowflake account, you can still inspect the CSV, architecture, code and screenshots on GitHub. The repository also documents the security and responsible-use considerations required before exposing customer data to a model-driven process.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I would change for a production system
&lt;/h2&gt;

&lt;p&gt;A working prototype is not a finished support decision engine. Before using this architecture on real conversations, I would add &lt;strong&gt;transcript authorization and PII protection, role-based access, cost controls, retention limits, drift monitoring, independently labeled evaluation sets, and human review for consequential actions&lt;/strong&gt;. I'd also test longer multi-turn dialogue histories and conflicts between an agent's claimed resolution and a customer's later observations.&lt;/p&gt;

&lt;p&gt;More fundamentally, I'd resist turning &lt;code&gt;unknown&lt;/code&gt; into a forced prediction. If a customer asks for documentation or says they will test later, there may simply be no evidence that a fix succeeded or failed. Keeping that uncertainty visible is an operational feature rather than a defect.&lt;/p&gt;

&lt;h2&gt;
  
  
  The takeaway
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Sentiment tells us something about tone. Resolution evidence tells us something about whether the customer actually got an outcome.&lt;/strong&gt; Those signals overlap, but they are not interchangeable.&lt;/p&gt;

&lt;p&gt;This project shows one way to make that distinction concrete with Snowflake-native SQL, Cortex classification, persisted model responses, and a read-only Streamlit dashboard. The most useful next step isn't a bigger template dataset; it's a harder and more independent evaluation of the boundary between ongoing issues, challenged resolutions and insufficient evidence.&lt;/p&gt;

&lt;p&gt;If you're building customer-service analytics with Snowflake Cortex, I'd welcome feedback on the taxonomy, evaluation design, and edge cases worth testing next.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Explore the open-source implementation:&lt;/strong&gt; &lt;a href="https://github.com/akshaysharma1088/snowflake-cortex-customer-intelligence" rel="noopener noreferrer"&gt;GitHub repository&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Persistent archive:&lt;/strong&gt; &lt;a href="https://doi.org/10.5281/zenodo.24098765" rel="noopener noreferrer"&gt;10.5281/zenodo.24098765&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Implementation presentation:&lt;/strong&gt; &lt;a href="https://github.com/akshaysharma1088/snowflake-cortex-customer-intelligence/blob/main/Snowflake_Cortex_90s_Presentation_NEW.mp4" rel="noopener noreferrer"&gt;90-second video&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This is an independent educational project using synthetic conversations. No employer or real-customer transcripts were used. Reported runs were observed by the project author and have not been independently replicated in a second Snowflake environment.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>snowflake</category>
      <category>ai</category>
      <category>dataengineering</category>
      <category>streamlit</category>
    </item>
  </channel>
</rss>
