<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>GenAI on RockB</title><link>https://baeseokjae.github.io/tags/genai/</link><description>Recent content in GenAI on RockB</description><image><title>RockB</title><url>https://baeseokjae.github.io/images/og-default.png</url><link>https://baeseokjae.github.io/images/og-default.png</link></image><generator>Hugo</generator><language>en-us</language><lastBuildDate>Sun, 16 Aug 2026 10:01:56 +0000</lastBuildDate><atom:link href="https://baeseokjae.github.io/tags/genai/index.xml" rel="self" type="application/rss+xml"/><item><title>OpenTelemetry Tracing for DeepSeek Harness: A Complete Setup Guide</title><link>https://baeseokjae.github.io/posts/opentelemetry-tracing-for-deepseek-harness/</link><pubDate>Sun, 16 Aug 2026 10:01:56 +0000</pubDate><guid>https://baeseokjae.github.io/posts/opentelemetry-tracing-for-deepseek-harness/</guid><description>Learn how to add OpenTelemetry tracing to DeepSeek Harness with community plugins, OTLP export, and GenAI semantic conventions.</description><content:encoded><![CDATA[<p>OpenTelemetry tracing for DeepSeek Harness lets you export every agent session, LLM call, and tool invocation as a standard OTLP trace tree to backends like Jaeger, Grafana Tempo, SigNoz, or Langfuse. You add it by installing a community plugin that implements the official <code>@deepseek-ai/dsh-session-telemetry</code> seam, configure an OTLP endpoint and a privacy mode, and then read the GenAI trace tree to debug agent loops, retries, and token usage.</p>
<h2 id="what-is-deepseek-harness-and-why-it-needs-tracing">What is DeepSeek Harness and why it needs tracing</h2>
<p>DeepSeek Harness is the official open-source agent framework from DeepSeek, written in TypeScript with the tagline &ldquo;Everything is a Plugin.&rdquo; Its official repository has roughly 123,000 GitHub stars, making it one of the most popular agent harnesses in the ecosystem. The framework orchestrates multi-step agent loops: it plans, calls LLMs, invokes tools, spawns subagents, and retries failed steps. Each of those steps is a potential failure point, and without tracing you are effectively debugging a black box.</p>
<p>Agent loops are non-deterministic. A single user request can trigger dozens of LLM calls, tool invocations, and retries, and the failure often lives in the interaction between them rather than in any single call. Traditional logging gives you a flat stream of text with no causal structure. OpenTelemetry tracing gives you a hierarchical span tree that shows exactly which step produced which LLM call, which tool ran under which step, and which retries happened along the way.</p>
<p>For DeepSeek Harness specifically, tracing matters because of its plugin architecture. Because &ldquo;everything is a plugin,&rdquo; the harness exposes a public telemetry seam that any plugin can implement. That means you are not locked into a single vendor&rsquo;s exporter. You can swap the official OTLP-logs exporter for a community OTLP-traces plugin without forking the harness, and you can point the output at whichever backend your team already runs.</p>
<h2 id="understanding-the-telemetry-seam-deepseek-aidsh-session-telemetry">Understanding the telemetry seam (@deepseek-ai/dsh-session-telemetry)</h2>
<p>The key architectural fact is that DeepSeek Harness ships a public telemetry seam called <code>@deepseek-ai/dsh-session-telemetry</code>. This is the contract that plugins implement to receive session, agent-loop, LLM-stream, and tool-lifecycle events. The official repository also ships an OTLP-logs exporter that implements this seam.</p>
<p>Community plugins implement the same seam as alternative backends. Instead of exporting logs, they convert the events into OpenTelemetry GenAI traces and metrics. Because they implement the same interface, you can drop them in without modifying the harness source code.</p>
<p>There is one critical gotcha: the telemetry seam accepts exactly one backend per context. If you load a duplicate backend — for example, the official OTLP-logs exporter and a tracing plugin at the same time — the load throws an error. You must choose one backend per context, not stack them.</p>
<h2 id="choosing-an-opentelemetry-backend-jaeger-grafana-tempo-signoz-langfuse">Choosing an OpenTelemetry backend (Jaeger, Grafana Tempo, SigNoz, Langfuse)</h2>
<p>Because the plugins export standard OTLP/HTTP protobuf, you can send traces to any compatible backend. The table below compares the most common choices.</p>
<table>
  <thead>
      <tr>
          <th>Backend</th>
          <th>Best for</th>
          <th>OTLP support</th>
          <th>GenAI semconv</th>
          <th>Notes</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Jaeger</td>
          <td>Lightweight local debugging</td>
          <td>Yes</td>
          <td>Partial</td>
          <td>Fast to spin up with Docker; great for single-node dev</td>
      </tr>
      <tr>
          <td>Grafana Tempo</td>
          <td>Grafana stack users</td>
          <td>Yes</td>
          <td>Yes</td>
          <td>Pairs with Grafana dashboards and Loki logs</td>
      </tr>
      <tr>
          <td>SigNoz</td>
          <td>Open-source APM alternative</td>
          <td>Yes</td>
          <td>Yes</td>
          <td>Full APM with metrics, traces, and logs in one</td>
      </tr>
      <tr>
          <td>Langfuse</td>
          <td>LLM product teams</td>
          <td>Yes</td>
          <td>Yes</td>
          <td>Native LLM features: feedback scores, sessions, prompts</td>
      </tr>
  </tbody>
</table>
<p>The GenAI semantic conventions (semconv) are what make these traces portable. They standardize LLM span attributes — model name, provider, token usage, prompt and completion — so the same trace renders meaningfully in Jaeger, Tempo, SigNoz, and Langfuse alike. If you already run one of these backends, you do not need to stand up a new one.</p>
<h2 id="installing-a-dsh-opentelemetry-tracing-plugin">Installing a dsh OpenTelemetry tracing plugin</h2>
<p>The most popular community options are <code>loongsuite/dsh-plugin</code>, <code>linyp/dsh-plugin-langfuse</code>, <code>CodePrometheus/dsh-observability</code>, and <code>TtTRz/dsh-langfuse</code>. All of them implement the telemetry seam and export OTLP traces. The table below summarizes their differences.</p>
<table>
  <thead>
      <tr>
          <th>Plugin</th>
          <th>Backend target</th>
          <th>Trace shape</th>
          <th>Metrics</th>
          <th>Notable config</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>loongsuite/dsh-plugin</td>
          <td>Any OTLP backend</td>
          <td>ENTRY -&gt; AGENT -&gt; STEP -&gt; LLM/TOOL</td>
          <td>gen_ai.client.operation.duration, gen_ai.client.token.usage</td>
          <td>Standalone, no sidecar or vendor dependency</td>
      </tr>
      <tr>
          <td>linyp/dsh-plugin-langfuse</td>
          <td>Langfuse</td>
          <td>One trace per turn, grouped by session</td>
          <td>No</td>
          <td>Reads LANGFUSE_HOST; feedback as Langfuse Scores</td>
      </tr>
      <tr>
          <td>CodePrometheus/dsh-observability</td>
          <td>Any OTLP backend</td>
          <td>Session span tree, model step to child span</td>
          <td>No</td>
          <td>DSH_OBSERVABILITY_MODE and DSH_OBSERVABILITY_OTLP_URL</td>
      </tr>
      <tr>
          <td>TtTRz/dsh-langfuse</td>
          <td>Langfuse</td>
          <td>One trace tree per session</td>
          <td>No</td>
          <td>Feedback scores and subagent lineage</td>
      </tr>
  </tbody>
</table>
<p>Before installing, verify your environment meets the requirements. The telemetry plugins require Node.js version 22.19.0 or higher and a DeepSeek Harness version of at least 0.1.0-rc.6 and below 0.2.0. If your harness is older or newer than that range, the plugin may not load.</p>
<p>Installation is typically done as a profile bundle. For example, the Langfuse plugin installs via a <code>cordis.patch.yml</code> profile bundle, and it reads the <code>LANGFUSE_HOST</code> environment variable rather than <code>LANGFUSE_BASE_URL</code>. Check each plugin&rsquo;s README for the exact install command, because the bundle mechanism differs slightly between plugins.</p>
<h2 id="configuring-otlp-export-and-privacy-modes-full--feedback_only--disabled">Configuring OTLP export and privacy modes (FULL / FEEDBACK_ONLY / DISABLED)</h2>
<p>Privacy is a first-class concern in these plugins. The design principle is that sharing stays off until a mode explicitly says otherwise, and configuring an endpoint is not consent to upload session content. You must opt in to each level of data sharing.</p>
<p>The <code>CodePrometheus/dsh-observability</code> plugin exposes three modes through the <code>DSH_OBSERVABILITY_MODE</code> environment variable:</p>
<ul>
<li><strong>FULL</strong> — exports the complete session content, including prompts, completions, and tool payloads. Use this only for backends you trust and for data you are allowed to share.</li>
<li><strong>FEEDBACK_ONLY</strong> — exports only feedback and scoring data, without the underlying session content. This is a middle ground for teams that want evaluation signals without shipping raw prompts.</li>
<li><strong>DISABLED</strong> — turns off sharing entirely. This is the safe default.</li>
</ul>
<p>You also configure the OTLP endpoint, typically through a variable such as <code>DSH_OBSERVABILITY_OTLP_URL</code> or the plugin&rsquo;s own endpoint setting. The endpoint points at your chosen backend&rsquo;s OTLP/HTTP receiver. Remember that setting the endpoint alone does not enable content sharing; the mode controls that.</p>
<h2 id="reading-the-genai-trace-tree-entry---agent---step---llmtool">Reading the GenAI trace tree (ENTRY -&gt; AGENT -&gt; STEP -&gt; LLM/TOOL)</h2>
<p>The trace shape is the most valuable part of the setup. The <code>loongsuite/dsh-plugin</code> exports a hierarchy of <code>ENTRY -&gt; AGENT -&gt; STEP -&gt; LLM/TOOL</code>. Here is what each level means:</p>
<ul>
<li><strong>ENTRY</strong> — the root span for a session or a top-level request.</li>
<li><strong>AGENT</strong> — the agent loop that orchestrates the work.</li>
<li><strong>STEP</strong> — a single planning or execution step within the loop.</li>
<li><strong>LLM/TOOL</strong> — the individual LLM call or tool invocation that ran under that step.</li>
</ul>
<p>The critical design detail is that each real LLM attempt gets its own LLM span. If the harness retries a failed LLM call, each retry appears as a separate span under the same step. This keeps retries and tool fallbacks visible under the same step, which is exactly what you need when debugging flaky agent loops. Instead of seeing one opaque &ldquo;LLM call failed&rdquo; message, you see the full sequence of attempts and their individual latencies and token usage.</p>
<p>Subagent sessions create their own trace and carry DeepSeek Harness parent-session and delegation attributes. This preserves fork and subagent lineage, so you can follow a request from the parent session down into each delegated subagent and back.</p>
<p>The plugins also export GenAI metrics. The <code>loongsuite/dsh-plugin</code> exports <code>gen_ai.client.operation.duration</code> and <code>gen_ai.client.token.usage</code>, giving you latency and token-cost telemetry alongside the traces.</p>
<h2 id="troubleshooting-common-issues-duplicate-backend-version-compatibility-restart-required">Troubleshooting common issues (duplicate backend, version compatibility, restart required)</h2>
<p>The most common problems fall into three buckets.</p>
<p><strong>Duplicate backend error.</strong> Because the telemetry seam accepts exactly one backend per context, loading the official OTLP-logs exporter and a tracing plugin together throws an error. Remove or disable the official exporter before loading a tracing plugin. If you need both logs and traces, choose one backend that handles both, or run them in separate contexts.</p>
<p><strong>Version incompatibility.</strong> The plugins require Node.js 22.19.0+ and DSH between 0.1.0-rc.6 and 0.2.0. If the plugin fails to load, check your Node and harness versions first. A harness outside the supported range will reject the plugin.</p>
<p><strong>Restart required.</strong> Telemetry backends are typically loaded at startup. After installing a plugin or changing a mode or endpoint variable, restart the harness so the new backend is picked up. A running session will not hot-reload the telemetry seam.</p>
<p><strong>No traces appearing.</strong> If your backend shows no traces, verify the OTLP endpoint is reachable, confirm the mode is not <code>DISABLED</code>, and check that the plugin actually loaded without a duplicate-backend error. Also confirm the backend&rsquo;s OTLP/HTTP receiver is enabled, since some backends disable it by default.</p>
<h2 id="faq">FAQ</h2>
<p><strong>What is OpenTelemetry tracing for DeepSeek Harness?</strong>
It is a way to export DeepSeek Harness agent sessions, LLM calls, and tool invocations as standard OTLP trace trees to backends like Jaeger, Grafana Tempo, SigNoz, or Langfuse, using community plugins that implement the official telemetry seam.</p>
<p><strong>Which DeepSeek Harness versions support OpenTelemetry tracing plugins?</strong>
The telemetry plugins require Node.js 22.19.0 or higher and a DeepSeek Harness version of at least 0.1.0-rc.6 and below 0.2.0.</p>
<p><strong>Can I use OpenTelemetry tracing with Langfuse?</strong>
Yes. Plugins like <code>linyp/dsh-plugin-langfuse</code> and <code>TtTRz/dsh-langfuse</code> export each session or turn as an OpenTelemetry trace to Langfuse&rsquo;s OTLP endpoint, including feedback scores and subagent lineage.</p>
<p><strong>Why do I get a duplicate backend error when installing a tracing plugin?</strong>
The <code>@deepseek-ai/dsh-session-telemetry</code> seam accepts exactly one backend per context. If you load the official OTLP-logs exporter and a tracing plugin together, the load throws an error. Remove the official exporter before loading a tracing plugin.</p>
<p><strong>How do privacy modes work in DeepSeek Harness tracing plugins?</strong>
Plugins like <code>CodePrometheus/dsh-observability</code> use modes such as FULL, FEEDBACK_ONLY, and DISABLED. Sharing stays off until a mode explicitly enables it, and configuring an endpoint is not consent to upload session content.</p>
]]></content:encoded></item></channel></rss>