Skip to content

Commit 8953cd3

Browse files
authored
Merge pull request #246 from Integration-Automation/feat/agent-trace-batch
Add GenAI OpenTelemetry-convention agent tracing
2 parents 187f313 + 243b3aa commit 8953cd3

15 files changed

Lines changed: 529 additions & 1 deletion

File tree

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
## Table of Contents
1515

16+
- [What's new (2026-06-19) — Agent Observability (GenAI OpenTelemetry Spans)](#whats-new-2026-06-19--agent-observability-genai-opentelemetry-spans)
1617
- [What's new (2026-06-19) — Compliance Control Report (SOC2 / ISO 27001)](#whats-new-2026-06-19--compliance-control-report-soc2--iso-27001)
1718
- [What's new (2026-06-19) — Agent Trajectory Evaluation](#whats-new-2026-06-19--agent-trajectory-evaluation)
1819
- [What's new (2026-06-19) — Approval Testing (Golden-Master Baselines)](#whats-new-2026-06-19--approval-testing-golden-master-baselines)
@@ -90,6 +91,12 @@
9091

9192
---
9293

94+
## What's new (2026-06-19) — Agent Observability (GenAI OpenTelemetry Spans)
95+
96+
OTel GenAI-convention spans for LLM runs. Full reference: [`docs/source/Eng/doc/new_features/v38_features_doc.rst`](docs/source/Eng/doc/new_features/v38_features_doc.rst).
97+
98+
- **`AgentTrace`** (`AC_trace_record` / `AC_trace_summary` / `AC_trace_export` / `AC_trace_reset`, `ac_*`): records spans whose attributes follow the OpenTelemetry **GenAI semantic conventions** (`gen_ai.operation.name`, `gen_ai.system`, `gen_ai.request.model`, `gen_ai.usage.input_tokens`/`output_tokens`, `gen_ai.tool.name`) and the `"{operation} {model}"` span name. `to_otel()` drops into an OTLP exporter; `summary()` rolls up token cost and latency; an `operation()` context manager times live blocks and marks errors. Pure-stdlib (no `opentelemetry` dep), injectable clock; pairs with trajectory evaluation (record here, score there).
99+
93100
## What's new (2026-06-19) — Compliance Control Report (SOC2 / ISO 27001)
94101

95102
Map governance evidence to named controls. Full reference: [`docs/source/Eng/doc/new_features/v37_features_doc.rst`](docs/source/Eng/doc/new_features/v37_features_doc.rst).

README/README_zh-CN.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
## 目录
1414

15+
- [本次更新 (2026-06-19) — Agent 可观测性(GenAI OpenTelemetry Spans)](#本次更新-2026-06-19--agent-可观测性genai-opentelemetry-spans)
1516
- [本次更新 (2026-06-19) — 合规控制报告(SOC2 / ISO 27001)](#本次更新-2026-06-19--合规控制报告soc2--iso-27001)
1617
- [本次更新 (2026-06-19) — Agent 轨迹评估](#本次更新-2026-06-19--agent-轨迹评估)
1718
- [本次更新 (2026-06-19) — 核准式测试(Golden-Master 基准)](#本次更新-2026-06-19--核准式测试golden-master-基准)
@@ -89,6 +90,12 @@
8990

9091
---
9192

93+
## 本次更新 (2026-06-19) — Agent 可观测性(GenAI OpenTelemetry Spans)
94+
95+
LLM 运行的 OTel GenAI 惯例 spans。完整参考:[`docs/source/Zh/doc/new_features/v38_features_doc.rst`](../docs/source/Zh/doc/new_features/v38_features_doc.rst)
96+
97+
- **`AgentTrace`**(`AC_trace_record` / `AC_trace_summary` / `AC_trace_export` / `AC_trace_reset``ac_*`):记录的 span 其属性遵循 OpenTelemetry **GenAI 语意惯例**(`gen_ai.operation.name``gen_ai.system``gen_ai.request.model``gen_ai.usage.input_tokens`/`output_tokens``gen_ai.tool.name`)与 `"{operation} {model}"` span 名称。`to_otel()` 可送入 OTLP exporter;`summary()` 汇整 token 成本与延迟;`operation()` 上下文管理器为实时区块计时并标记错误。纯标准库(无 `opentelemetry` 依赖)、可注入时钟;与轨迹评估互补(在此记录、在那里评分)。
98+
9299
## 本次更新 (2026-06-19) — 合规控制报告(SOC2 / ISO 27001)
93100

94101
将治理证据映射到具名控制项。完整参考:[`docs/source/Zh/doc/new_features/v37_features_doc.rst`](../docs/source/Zh/doc/new_features/v37_features_doc.rst)

README/README_zh-TW.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
## 目錄
1414

15+
- [本次更新 (2026-06-19) — Agent 可觀測性(GenAI OpenTelemetry Spans)](#本次更新-2026-06-19--agent-可觀測性genai-opentelemetry-spans)
1516
- [本次更新 (2026-06-19) — 合規控制報告(SOC2 / ISO 27001)](#本次更新-2026-06-19--合規控制報告soc2--iso-27001)
1617
- [本次更新 (2026-06-19) — Agent 軌跡評估](#本次更新-2026-06-19--agent-軌跡評估)
1718
- [本次更新 (2026-06-19) — 核准式測試(Golden-Master 基準)](#本次更新-2026-06-19--核准式測試golden-master-基準)
@@ -89,6 +90,12 @@
8990

9091
---
9192

93+
## 本次更新 (2026-06-19) — Agent 可觀測性(GenAI OpenTelemetry Spans)
94+
95+
LLM 執行的 OTel GenAI 慣例 spans。完整參考:[`docs/source/Zh/doc/new_features/v38_features_doc.rst`](../docs/source/Zh/doc/new_features/v38_features_doc.rst)
96+
97+
- **`AgentTrace`**(`AC_trace_record` / `AC_trace_summary` / `AC_trace_export` / `AC_trace_reset``ac_*`):記錄的 span 其屬性遵循 OpenTelemetry **GenAI 語意慣例**(`gen_ai.operation.name``gen_ai.system``gen_ai.request.model``gen_ai.usage.input_tokens`/`output_tokens``gen_ai.tool.name`)與 `"{operation} {model}"` span 名稱。`to_otel()` 可送入 OTLP exporter;`summary()` 彙整 token 成本與延遲;`operation()` 情境管理器為即時區塊計時並標記錯誤。純標準函式庫(無 `opentelemetry` 相依)、可注入時鐘;與軌跡評估互補(在此記錄、在那裡評分)。
98+
9299
## 本次更新 (2026-06-19) — 合規控制報告(SOC2 / ISO 27001)
93100

94101
將治理證據對應到具名控制項。完整參考:[`docs/source/Zh/doc/new_features/v37_features_doc.rst`](../docs/source/Zh/doc/new_features/v37_features_doc.rst)
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
Agent Observability (GenAI OpenTelemetry Spans)
2+
===============================================
3+
4+
When automation drives an LLM agent, you want the same observability an
5+
OpenTelemetry backend gives a service: per-operation spans carrying token usage,
6+
model, and status. ``AgentTrace`` records spans whose attributes follow the
7+
OpenTelemetry **GenAI semantic conventions** — ``gen_ai.operation.name``,
8+
``gen_ai.system``, ``gen_ai.request.model``, ``gen_ai.usage.input_tokens`` /
9+
``gen_ai.usage.output_tokens``, ``gen_ai.tool.name`` — and the convention span
10+
name ``"{operation} {model}"``. :meth:`AgentTrace.to_otel` output drops straight
11+
into an OTLP exporter, while :meth:`AgentTrace.summary` rolls up cost and latency
12+
for a run.
13+
14+
It pairs with :doc:`trajectory evaluation <v36_features_doc>` — record the run
15+
here, score it there. Pure standard library (no ``opentelemetry`` dependency);
16+
the clock is injectable so durations are deterministically testable. Imports no
17+
``PySide6``.
18+
19+
Headless API
20+
------------
21+
22+
.. code-block:: python
23+
24+
from je_auto_control import AgentTrace
25+
26+
trace = AgentTrace()
27+
# one-shot record of a completed call:
28+
trace.record("chat", model="claude-opus-4-8", system="anthropic",
29+
input_tokens=1200, output_tokens=180, duration_s=0.9)
30+
31+
# or time a live block; set token counts on the yielded dict:
32+
with trace.operation("tool", tool_name="search") as fields:
33+
result = run_tool()
34+
fields["output_tokens"] = 42 # error inside marks the span error
35+
36+
print(trace.summary()) # {span_count, error_count, input_tokens, ...}
37+
exporter.export(trace.to_otel()) # OTLP-friendly span dicts
38+
39+
``summary`` aggregates ``span_count``, ``error_count``, ``input_tokens``,
40+
``output_tokens``, and total ``duration_s``. ``to_otel`` returns each span as
41+
``{name, kind, attributes, duration_s, status:{code}}`` with an OTel status code.
42+
43+
Executor commands
44+
-----------------
45+
46+
A module-level default trace backs the executor/MCP surfaces so a flow can build
47+
a trace across steps:
48+
49+
================================ ===================================================
50+
Command Effect
51+
================================ ===================================================
52+
``AC_trace_record`` Record a GenAI span (operation/model/tokens/…).
53+
``AC_trace_summary`` Roll up the default trace.
54+
``AC_trace_export`` Export the default trace as OTLP spans.
55+
``AC_trace_reset`` Clear the default trace.
56+
================================ ===================================================
57+
58+
The same operations are exposed as MCP tools (``ac_trace_record`` /
59+
``ac_trace_summary`` / ``ac_trace_export`` / ``ac_trace_reset``) and as Script
60+
Builder commands under **Agent**.

docs/source/Eng/eng_index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ Comprehensive guides for all AutoControl features.
6060
doc/new_features/v35_features_doc
6161
doc/new_features/v36_features_doc
6262
doc/new_features/v37_features_doc
63+
doc/new_features/v38_features_doc
6364
doc/ocr_backends/ocr_backends_doc
6465
doc/observability/observability_doc
6566
doc/operations_layer/operations_layer_doc
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
Agent 可觀測性(GenAI OpenTelemetry Spans)
2+
==========================================
3+
4+
當自動化驅動 LLM agent 時,你會想要 OpenTelemetry 後端給服務的那種可觀測性:每個操作
5+
一個 span,帶有 token 用量、模型與狀態。``AgentTrace`` 記錄的 span 其屬性遵循
6+
OpenTelemetry **GenAI 語意慣例** —— ``gen_ai.operation.name``、``gen_ai.system``、
7+
``gen_ai.request.model``、``gen_ai.usage.input_tokens`` /
8+
``gen_ai.usage.output_tokens``、``gen_ai.tool.name`` —— 以及慣例 span 名稱
9+
``"{operation} {model}"``。:meth:`AgentTrace.to_otel` 的輸出可直接送入 OTLP
10+
exporter,而 :meth:`AgentTrace.summary` 則彙整一次執行的成本與延遲。
11+
12+
它與 :doc:`軌跡評估 <v36_features_doc>` 互補 —— 在此記錄執行,在那裡評分。純標準函式
13+
庫(無 ``opentelemetry`` 相依);時鐘可注入,因此持續時間可被確定性地測試。不匯入
14+
``PySide6``。
15+
16+
無頭 API
17+
--------
18+
19+
.. code-block:: python
20+
21+
from je_auto_control import AgentTrace
22+
23+
trace = AgentTrace()
24+
# 一次性記錄已完成的呼叫:
25+
trace.record("chat", model="claude-opus-4-8", system="anthropic",
26+
input_tokens=1200, output_tokens=180, duration_s=0.9)
27+
28+
# 或為即時區塊計時;在 yield 出的 dict 上設定 token 數:
29+
with trace.operation("tool", tool_name="search") as fields:
30+
result = run_tool()
31+
fields["output_tokens"] = 42 # 區塊內若拋出例外則標記為 error
32+
33+
print(trace.summary()) # {span_count, error_count, input_tokens, ...}
34+
exporter.export(trace.to_otel()) # OTLP 友善的 span dict
35+
36+
``summary`` 彙整 ``span_count``、``error_count``、``input_tokens``、
37+
``output_tokens`` 與總 ``duration_s``。``to_otel`` 將每個 span 回傳為
38+
``{name, kind, attributes, duration_s, status:{code}}``,帶有 OTel 狀態碼。
39+
40+
執行器指令
41+
----------
42+
43+
模組層級的預設 trace 支撐 executor/MCP 介面,讓流程可跨步驟建立一條 trace:
44+
45+
================================ ===================================================
46+
指令 效果
47+
================================ ===================================================
48+
``AC_trace_record`` 記錄一個 GenAI span(operation/model/tokens/…)。
49+
``AC_trace_summary`` 彙整預設 trace。
50+
``AC_trace_export`` 將預設 trace 匯出為 OTLP spans。
51+
``AC_trace_reset`` 清除預設 trace。
52+
================================ ===================================================
53+
54+
相同操作亦提供為 MCP 工具(``ac_trace_record`` / ``ac_trace_summary`` /
55+
``ac_trace_export`` / ``ac_trace_reset``),以及 Script Builder 中 **Agent** 分類下的
56+
指令。

docs/source/Zh/zh_index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ AutoControl 所有功能的完整使用指南。
6060
doc/new_features/v35_features_doc
6161
doc/new_features/v36_features_doc
6262
doc/new_features/v37_features_doc
63+
doc/new_features/v38_features_doc
6364
doc/ocr_backends/ocr_backends_doc
6465
doc/observability/observability_doc
6566
doc/operations_layer/operations_layer_doc

je_auto_control/__init__.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,10 @@
222222
from je_auto_control.utils.compliance import (
223223
build_compliance_report, render_compliance_html, write_compliance_report,
224224
)
225+
# Agent observability: OpenTelemetry GenAI-convention spans
226+
from je_auto_control.utils.agent_trace import (
227+
AgentTrace, default_trace, reset_trace,
228+
)
225229
# Background popup/interrupt watchdog (unattended automation)
226230
from je_auto_control.utils.watchdog import (
227231
PopupWatchdog, WatchdogRule, default_popup_watchdog,
@@ -665,6 +669,7 @@ def start_autocontrol_gui(*args, **kwargs):
665669
"evaluate_trajectory",
666670
"build_compliance_report", "render_compliance_html",
667671
"write_compliance_report",
672+
"AgentTrace", "default_trace", "reset_trace",
668673
# MCP server
669674
"AuditLogger", "HttpMCPServer", "MCPContent", "MCPPrompt",
670675
"MCPPromptArgument", "MCPResource", "MCPServer", "MCPTool",

je_auto_control/gui/script_builder/command_schema.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -824,6 +824,37 @@ def _add_misc_specs(specs: List[CommandSpec]) -> None:
824824
),
825825
description="Map governance evidence to SOC2/ISO 27001 controls.",
826826
))
827+
specs.append(CommandSpec(
828+
"AC_trace_record", "Agent", "Trace: Record Span",
829+
fields=(
830+
FieldSpec("operation", FieldType.STRING, placeholder="chat"),
831+
FieldSpec("model", FieldType.STRING, optional=True),
832+
FieldSpec("system", FieldType.STRING, optional=True),
833+
FieldSpec("input_tokens", FieldType.INT, optional=True),
834+
FieldSpec("output_tokens", FieldType.INT, optional=True),
835+
FieldSpec("tool_name", FieldType.STRING, optional=True),
836+
FieldSpec("duration_s", FieldType.FLOAT, optional=True,
837+
default=0.0),
838+
FieldSpec("status", FieldType.ENUM, optional=True, default="ok",
839+
choices=("ok", "error")),
840+
),
841+
description="Record a GenAI-convention span on the default trace.",
842+
))
843+
specs.append(CommandSpec(
844+
"AC_trace_summary", "Agent", "Trace: Summary",
845+
fields=(),
846+
description="Roll up the default agent trace (count/tokens/duration).",
847+
))
848+
specs.append(CommandSpec(
849+
"AC_trace_export", "Agent", "Trace: Export (OTLP)",
850+
fields=(),
851+
description="Export the default agent trace as OTLP-friendly spans.",
852+
))
853+
specs.append(CommandSpec(
854+
"AC_trace_reset", "Agent", "Trace: Reset",
855+
fields=(),
856+
description="Clear the default agent trace.",
857+
))
827858
specs.append(CommandSpec(
828859
"AC_generate_sop", "Report", "Generate SOP Document",
829860
fields=(
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
"""Agent observability: OpenTelemetry GenAI-convention spans for LLM runs."""
2+
from je_auto_control.utils.agent_trace.agent_trace import (
3+
AgentTrace, default_trace, reset_trace,
4+
)
5+
6+
__all__ = ["AgentTrace", "default_trace", "reset_trace"]

0 commit comments

Comments
 (0)