<?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: KOMARI Subheeksh</title>
    <description>The latest articles on DEV Community by KOMARI Subheeksh (@komari_subheeksh_ced2cb4c).</description>
    <link>https://dev.to/komari_subheeksh_ced2cb4c</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%2F4045128%2F36ebc7b3-2b50-4a3b-bab5-94a150be3e85.png</url>
      <title>DEV Community: KOMARI Subheeksh</title>
      <link>https://dev.to/komari_subheeksh_ced2cb4c</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/komari_subheeksh_ced2cb4c"/>
    <language>en</language>
    <item>
      <title>SIGNOZ</title>
      <dc:creator>KOMARI Subheeksh</dc:creator>
      <pubDate>Fri, 24 Jul 2026 08:17:21 +0000</pubDate>
      <link>https://dev.to/komari_subheeksh_ced2cb4c/signoz-8eb</link>
      <guid>https://dev.to/komari_subheeksh_ced2cb4c/signoz-8eb</guid>
      <description>&lt;h1&gt;
  
  
  I built a deterministic verdict engine for AI agents on SigNoz — no LLM in the loop
&lt;/h1&gt;

&lt;p&gt;Your AI agent hallucinates. It loops tool calls. It burns tokens. And you won't know until a customer complains.&lt;/p&gt;

&lt;p&gt;That's the problem Gaze solves. It watches your agent's traces through SigNoz, runs nine deterministic rules, and issues a recomputable verdict. No LLM in the verdict path. Same input always produces the same sha256 hash.&lt;/p&gt;

&lt;p&gt;I built this for the Agents of SigNoz Hackathon 2026. Here's how it works and what I learned.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;Every observability tool tells you what your agent COST. LangSmith, Burnrate, every LLM gateway — they all show dollars spent and tokens consumed. But none of them tell you if the agent was RIGHT.&lt;/p&gt;

&lt;p&gt;An agent can repeat the same wrong answer for hours. It can cite documents that don't exist. It can get stuck in a tool loop burning API credits. Existing SRE tools catch when your service is down. They don't catch when your agent is wrong.&lt;/p&gt;

&lt;p&gt;Gaze sits between your agent and SigNoz. It reads the traces, evaluates behavior, and issues a verdict score from 0 to 100. When the score drops, SigNoz fires an alert.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;p&gt;Your agent emits OpenTelemetry spans with GenAI semantic conventions — prompt, completion, tokens, model name. SigNoz stores them in ClickHouse. Gaze queries ClickHouse directly, runs nine deterministic rules against every span, computes a score, writes the verdict back to SigNoz via OTLP.&lt;/p&gt;

&lt;p&gt;All of this happens inside your deployment. No external service. No API key. You run &lt;code&gt;foundryctl cast --file casting.yaml&lt;/code&gt; and everything comes up: SigNoz, ClickHouse, the ingester, the UI.&lt;/p&gt;

&lt;h3&gt;
  
  
  The nine rules
&lt;/h3&gt;

&lt;p&gt;Every rule is pure Python. No ML models, no embeddings APIs, no external dependencies.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;repetition loop&lt;/strong&gt; — n-gram similarity &amp;gt; 80% across 5+ consecutive spans. Catches agents stuck repeating the same output.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;embedding drift&lt;/strong&gt; — character bigram hashing. Tokenizes output into bigrams, hashes them to a fixed-length vector, compares cosine distance from the agent's baseline. If the distance exceeds 0.40, the agent's output quality is degrading.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;tool loop&lt;/strong&gt; — detects circular tool calls. Same (tool, args) pair repeated 3+ times means the agent is stuck.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;unauthorized tool&lt;/strong&gt; — cross-references tool calls against the agent's registered manifest. Catches jailbreak attempts that try to access unregistered tools.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;prompt injection&lt;/strong&gt; — 47 regex patterns from the verazuo/jailbreak_llms dataset. Matches known injection vectors like "ignore all instructions", "DAN", "developer mode", "system override".&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;cost explosion&lt;/strong&gt; — token usage &amp;gt; 3x the 7-day rolling average for the same agent + model.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;latency degradation&lt;/strong&gt; — P95 span duration &amp;gt; 2x the 7-day rolling baseline.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;empty response&lt;/strong&gt; — agent returned null or empty output.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;hallucinated source&lt;/strong&gt; — agent cited a document not found in the retrieval spans.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  The verdict
&lt;/h3&gt;

&lt;p&gt;Each verdict carries a sha256 hash of (trace snapshot + rule set version + agent ID). Same input always produces the same hash. Anyone can recompute and verify.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://gaze-4fy2.onrender.com/verdict &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"agent_id": "support-bot-01"}'&lt;/span&gt;

&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"verdict_hash"&lt;/span&gt;: &lt;span class="s2"&gt;"sha256:a1b2c3d4..."&lt;/span&gt;,
  &lt;span class="s2"&gt;"score"&lt;/span&gt;: 94,
  &lt;span class="s2"&gt;"status"&lt;/span&gt;: &lt;span class="s2"&gt;"HEALTHY"&lt;/span&gt;,
  &lt;span class="s2"&gt;"rules_evaluated"&lt;/span&gt;: 9
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The verdict spans are written back to SigNoz via OTLP so they appear alongside your agent's traces.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I used SigNoz
&lt;/h2&gt;

&lt;p&gt;This project wouldn't exist without SigNoz. Here's exactly what I used:&lt;/p&gt;

&lt;h3&gt;
  
  
  MCP server
&lt;/h3&gt;

&lt;p&gt;SigNoz exposes an MCP (Model Context Protocol) server that allows external tools to query traces programmatically. Gaze uses this to pull agent spans for evaluation.&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="c1"&gt;# mcp_client.py
&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;query_spans&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;agent_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;window_minutes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;signoz_mcp_client&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute_tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;signoz_list_spans&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;service&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;agent_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;minutes&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;window_minutes&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;h3&gt;
  
  
  ClickHouse direct queries
&lt;/h3&gt;

&lt;p&gt;For deeper analysis, Gaze queries ClickHouse directly. SigNoz stores all trace data in &lt;code&gt;signoz_traces.distributed_signoz_index_v3&lt;/code&gt;. Gaze extracts GenAI-specific attributes:&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;span_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;trace_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;JSONExtractString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tagMap&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'gen_ai.prompt'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;JSONExtractString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tagMap&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'gen_ai.completion'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="k"&gt;completion&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;JSONExtractInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tagMap&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'gen_ai.usage.input_tokens'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;input_tokens&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;signoz_traces&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;distributed_signoz_index_v3&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;serviceName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'support-bot-01'&lt;/span&gt;
  &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="nb"&gt;timestamp&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;INTERVAL&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="k"&gt;MINUTE&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  OTLP verdict export
&lt;/h3&gt;

&lt;p&gt;After evaluation, Gaze creates verdict spans and exports them to SigNoz via OTLP. This means verdicts appear as regular spans in the SigNoz UI, right next to your agent's traces.&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="c1"&gt;# otel_exporter.py
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;opentelemetry.exporter.otlp.proto.grpc.trace_exporter&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OTLPSpanExporter&lt;/span&gt;

&lt;span class="n"&gt;exporter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;OTLPSpanExporter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;endpoint&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://localhost:4317&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;insecure&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;span_processor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;BatchSpanProcessor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;exporter&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Foundry deployment
&lt;/h3&gt;

&lt;p&gt;Everything deploys with one command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;foundryctl cast &lt;span class="nt"&gt;--file&lt;/span&gt; casting.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;casting.yaml&lt;/code&gt; defines the full SigNoz stack — ClickHouse, ingester, query service, UI, alert manager. Judges can re-run Foundry against your &lt;code&gt;casting.yaml.lock&lt;/code&gt; to reproduce the exact deployment.&lt;/p&gt;

&lt;h3&gt;
  
  
  SigNoz dashboard
&lt;/h3&gt;

&lt;p&gt;I built a 6-panel dashboard in &lt;code&gt;dashboards/gaze-verdict.json&lt;/code&gt; that shows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Agent score cards (0-100 for each registered agent)&lt;/li&gt;
&lt;li&gt;Verdict timeline with rule breakdowns&lt;/li&gt;
&lt;li&gt;Evidence explorer linking each violation to the exact span&lt;/li&gt;
&lt;li&gt;Token usage over time vs rolling average&lt;/li&gt;
&lt;li&gt;Latency P95 vs baseline&lt;/li&gt;
&lt;li&gt;Alert rules for score drops&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Import it directly into your SigNoz UI.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I learned
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Deterministic beats probabilistic for observability
&lt;/h3&gt;

&lt;p&gt;Every verdict tool out there uses an LLM to judge agent quality. This is fundamentally wrong for observability. If your monitoring tool can give different answers for the same input, it's not monitoring — it's guessing.&lt;/p&gt;

&lt;p&gt;Gaze uses character bigram hashing for embedding drift detection instead of calling an embedding API. No model variance. No API latency. No cost. Same text always produces the same vector. This was the hardest lesson: resist the urge to use AI for everything. Sometimes a hash function is better.&lt;/p&gt;

&lt;h3&gt;
  
  
  ClickHouse is underrated for trace analysis
&lt;/h3&gt;

&lt;p&gt;Most observability tools abstract ClickHouse behind APIs. But direct queries give you power you can't get otherwise. Gaze's rules use window functions, JSON extraction, and statistical aggregates that would be painful through a REST API. ClickHouse handles them natively.&lt;/p&gt;

&lt;h3&gt;
  
  
  SigNoz MCP is real infrastructure
&lt;/h3&gt;

&lt;p&gt;The MCP server isn't a demo feature — it's a production-grade trace query interface. I built the entire Gaze integration on it. Zero issues with connection stability or query performance.&lt;/p&gt;

&lt;h3&gt;
  
  
  Foundry makes self-hosting trivial
&lt;/h3&gt;

&lt;p&gt;I've set up SigNoz manually before. It's 4+ containers with networking, volumes, and config. Foundry reduces it to one YAML file and one command. For a hackathon deadline, this is the difference between finishing and not.&lt;/p&gt;

&lt;h2&gt;
  
  
  The code
&lt;/h2&gt;

&lt;p&gt;Everything is open source: &lt;a href="https://github.com/subheeksh5599/Gaze" rel="noopener noreferrer"&gt;github.com/subheeksh5599/Gaze&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Backend&lt;/strong&gt;: Python 3.11+, FastAPI, Pydantic v2. 8 endpoints. 35/35 tests passing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Frontend&lt;/strong&gt;: Vite + React 19 + TypeScript + Tailwind — &lt;a href="https://gaze-omega.vercel.app" rel="noopener noreferrer"&gt;gaze-omega.vercel.app&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rules engine&lt;/strong&gt;: 9 deterministic rules. Zero ML dependencies. Pure Python.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deployment&lt;/strong&gt;: Foundry for SigNoz, Render for backend, Vercel for frontend.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Try it yourself:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/subheeksh5599/Gaze
&lt;span class="nb"&gt;cd &lt;/span&gt;Gaze
pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; backend/requirements.txt
&lt;span class="nb"&gt;cd &lt;/span&gt;backend &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; python3 gaze/server.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then visit &lt;code&gt;http://localhost:8000/docs&lt;/code&gt; for the OpenAPI docs.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's next
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Historical replay — recompute verdicts for past trace windows&lt;/li&gt;
&lt;li&gt;Custom rule builder — YAML-based rules, shareable rule packs&lt;/li&gt;
&lt;li&gt;Agent pause integration — auto-pause on CRITICAL verdict&lt;/li&gt;
&lt;li&gt;Slack/Discord bot for querying verdicts from chat&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Built for the Agents of SigNoz Hackathon 2026. MIT licensed.&lt;/p&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>devchallenge</category>
      <category>monitoring</category>
    </item>
  </channel>
</rss>
