Skip to content

Semantic Conventions for Generative AI Tasks (gen_ai.task.*) #37

Open

Description

@dany-moshkovich

Area(s)

area:gen-ai

Propose new conventions

Summary

This proposal introduces semantic conventions for tasks in generative AI agentic systems.
Tasks are the minimal trackable units of work, describing what needs to be done.
They define objectives, can be decomposed into subtasks, and are executed through one or more actions.

Standardizing task-level telemetry will enable consistent observability of goals, lifecycles, inputs, outputs, and feedback across agentic workflows.


Motivation

Tasks represent the anchor concept in agentic systems — defining user/system objectives and structuring how work is divided and executed.
Current OpenTelemetry semantic conventions for LLMs cover completions, but do not capture:

  • High-level objectives and goals of execution
  • Task hierarchies and subtasks
  • Lifecycle states (created, started, in-progress, ended, etc.)
  • Success/failure status and termination conditions
  • Input/output attributes beyond raw LLM prompts
  • Feedback on task performance (human or automatic evaluators)
  • Scheduling context (dependencies, expected times, priorities)
  • Requester context — who or what initiated the task (human, system, role, external request ID).
    Capturing requester information is critical for linking tasks to user journeys, auditing execution, and supporting accountability in multi-tenant or enterprise settings.

Without standardized task attributes, observability is fragmented, making it difficult to trace workflows, debug issues, or evaluate outcomes across multi-agent and multi-action pipelines.


References

Proposed Attributes

Task Identity and Purpose

  • gen_ai.task.id (string) – Unique identifier of the task instance.
  • gen_ai.task.parent.id (string) – Identifier of the parent task (if subtask).
  • gen_ai.task.name (string) – Human-readable display name.
  • gen_ai.task.code.id (string) – Fully qualified reference to task logic/code.
  • gen_ai.task.code.vendor (string) – Vendor/framework name.
  • gen_ai.task.kind (string; enum) – Core intent of the task (planning, retrieval, reasoning, execution, evaluation, delegation, synthesis, coordination, clarification, update_memory, other).
  • gen_ai.task.tags (string[]) – Additional classification tags.

Task Requester

  • gen_ai.task.requester.id (string) – Identifier of requesting entity.
  • gen_ai.task.requester.type (string; enum) – human | system.
  • gen_ai.task.requester.role (string) – Role/profile of the requester.
  • gen_ai.task.request.id (string) – Identifier for the external request.

Task Lifecycle

  • gen_ai.task.state (string; enum) – Lifecycle state (created, submitted, planned, started, in-progress, paused, suspended, ended).
  • gen_ai.task.status (string; enum) – Final outcome of the task (success, failure, timeout, cancelled, unknown).

Task Input Attributes

  • gen_ai.task.input.goal (string) – Description of the desired outcome.
  • gen_ai.task.input.instructions (string[]) – List of execution instructions.
  • gen_ai.task.input.examples (string[]) – Examples guiding execution.
  • gen_ai.task.input.data (string) – Raw input string.
  • gen_ai.task.input.metadata (string; JSON) – Structured metadata about input.

Task Output Attributes

  • gen_ai.task.output.data.values (string[]) – Output values.
  • gen_ai.task.output.data.ranking (double[]) – Ranking/confidence scores.
  • gen_ai.task.output.metadata (string[]; JSON) – Metadata about outputs.

Task Scheduling Attributes

  • gen_ai.task.dependencies.ids (string[]) – List of prerequisite tasks.
  • gen_ai.task.expected_start_time (string; RFC3339) – Scheduled start time.
  • gen_ai.task.expected_end_time (string; RFC3339) – Scheduled end time.
  • gen_ai.task.priority (int) – Task priority (e.g., 0–100).

Task Feedback Attributes

  • gen_ai.task.feedback.source (string; enum) – Feedback source (human, ground_truth, evaluator).
  • gen_ai.task.feedback.source.id (string) – Feedback source identifier.
  • gen_ai.task.feedback.rating (double) – Normalized score (0.0–1.0).
  • gen_ai.task.feedback.value (string) – Explanation of feedback.
  • gen_ai.task.feedback.metric.name (string) – Name of metric (optional).
  • gen_ai.task.feedback.metric.params (string; JSON) – Metric parameters.

Prior Art

  • Existing gen_ai.* attributes for LLM completions in the OTEL specification
  • Early proposals for gen_ai.agent.* attributes
  • Vendor implementations (e.g., LangFuse, Arize, OpenInference) track partial task information but lack a standard schema

Next Steps

  • Discuss scope and alignment with existing gen_ai.* conventions
  • Collect feedback on attribute set, naming, and lifecycle states
  • Submit PRs adding gen_ai.task.* attributes to the OTEL semantic conventions repo:
    • Identity & Purpose attributes
    • Requester attributes
    • Lifecycle attributes
    • Input attributes
    • Output attributes
    • Scheduling attributes
    • Feedback attributes

Tip

React with 👍 to help prioritize this issue. Please use comments to provide useful context, avoiding +1 or me too, to help us triage it. Learn more here.

Activity

  1. Cirilla-zmh commented on Nov 4, 2025

    @Cirilla-zmh
    Member

    Hey! Thanks for your proposal! We are adding instrumentation for the memory framework (such as mem0), which is a framework that provides memory capabilities for Agents. We've noticed that there is currently a lack of defined semantic specifications related to memory, and we've seen some relevant discussions in this issue.

    There are a few issues:

    • According to the definition "Tasks are the minimal trackable units of work, describing what needs to be done.", it seems that any operation could be considered a task. Strictly speaking, even an LLM call could be seen as a kind of task. So, how should we treat calls that represent task-like operations? Should they include all undefined types of calls in the GenAI scenario, or should they have more specific characteristics?
    • Is a memory-related call — such as retrieve memory or search memory — considered a task?
  2. marisaSim commented on May 12, 2026

    @marisaSim

    Happy to see task feedback options being brought up here. One gap from production experience: in agentic systems that produce work products (not just responses), the actionable signal from a human reviewer isn't a score, it's a structured correction.

    We operate a reliability layer for an agentic AI system in a regulated industry. When an expert reviews agent output, their response is an action: they correct a detail, replace the output, escalate because the failure may affect other workstreams, or stop trusting the agent for that task type. These are different signals with different remediation paths, and a normalized score doesn't distinguish between them.

    What we needed was a structured correction record: what the agent produced, what the expert produced instead, the evidence that justified the change, and the response type (correct, override, escalate, reclassify, work around, withdraw trust). The response type matters because "expert fixed a detail" and "expert stopped trusting the agent for this task type" require completely different follow-up, even if both would score 0.2.

    Like gen_ai.task.feedback.source, this is application-emitted telemetry: the convention standardizes the shape so downstream tooling can consume corrections consistently across systems. This is consistent with the application-emitted approach reflected in several other proposals in this repo, including #72, #79, and #80.

    We have a working implementation and would be interested in contributing, either extending the feedback attributes or drafting a companion convention for structured correction events.

  3. added
    area:agent-orchestrationComposition above single agent: workflow execution, handoffs, delegation across agents
    on May 28, 2026
  4. agorokh commented on Jun 27, 2026

    @agorokh

    Field evidence plus a concrete identifier sub-proposal for Task

    Sharing production experience from operating a multi-harness fleet of autonomous coding agents, in support of the Task direction here. The main operational metric we needed was cost-to-outcome: dollars and tokens per merged PR, per issue. That requires binding each agent run to the external work item it serves, such as a GitHub issue or ticket.

    We implemented this twice, and the failure modes may be useful signal for why a standardized identifier matters.

    What failed concretely:

    1. Reconstruction from incidental signals is lossy. Inferring the work item after the fact from branch names, PR text, logs, or commit shape breaks on squash, rebase, detached HEAD/worktrees, multi-issue branches, and runs that error before producing a PR. This matches the existing instinct in GenAI semconv not to derive identifiers from unstable implementation details.
    2. Capture-at-source is right, but an unstandardized value convention silently zeroed the metric. We captured intent at the source, but one dashboard counted a literal capture while the stamped value was capture:gh_issue, so the metric read 0 despite capture working. A standard attribute with a defined value shape would have turned that into a conformance issue instead of a production incident.
    3. Lifecycle ambiguity matters. Without a clear "set at run start" semantic, an early implementation stamped on the wrong event and attributed nothing.

    The gap I hit: gen_ai.conversation.id can carry run identity, gen_ai.workflow.name can label an orchestration, and gen_ai.agent.id identifies the agent, but nothing clearly carries the external work item the run is for. The Task concept here captures the right level. The missing concrete piece is a stable external reference for it.

    Concrete sub-proposal, with naming deferred to the SIG:

    • Attribute: a stable work-item reference under the Task umbrella, for example gen_ai.task.reference or gen_ai.work_item.id.
    • Type: string.
    • Value shape: stable external reference, for example org/repo#123, PROJ-456, or another system-native ticket identifier.
    • Requirement level: conditionally required when available. Instrumentations should not fabricate it. A UUID, branch name, or content hash is not a fallback.
    • Optional companions: task URL, task type (issue, pull_request, ticket, epic), and task system (github, jira, linear, etc.).
    • Carriage: set at run start, propagated via W3C Baggage, and surfaced as a span attribute. For agent-to-tool boundaries, the MCP _meta trace-context direction looks like the right adjacent carrier.

    This is field input, not a finished PR. I would be happy to contribute wording and validate it against a running fleet if the SIG finds the direction useful. Whatever final name the group chooses, the load-bearing parts are the set-at-source semantic, the do-not-fabricate rule, and a defined value shape. Those are exactly where the silent failures showed up in practice.

  5. Jaegeonyoon commented on Jul 3, 2026

    @Jaegeonyoon

    Small clarification question on gen_ai.task.parent.id.

    The issue summary describes this attribute as the identifier of the parent task "if subtask". In the linked task draft, I also saw it described as required while allowing no parent for root tasks.

    Is the intended model that root tasks omit gen_ai.task.parent.id, or should they emit a specific placeholder value (or, sentinel/null-like value) to make the absence of a parent explicit?

  6. steverao commented on Sep 1, 2026

    @steverao
    Contributor

    We have a concrete multi-agent use case where a stable task identifier is essential for correlating telemetry across workflows, agent invocations, and traces. A task originates from an external system, such as a GitHub issue, ticket, coding harness, or user-provided task-management component, and already has a stable identifier. Multiple agents—potentially running in separate OpenClaw instances—may collaborate on that task over several rounds and produce multiple traces.

    For example:

    External Tasker
    └── task.id = "org/repo#123"
        │
        │ propagated through OpenTelemetry Context / Baggage
        │
        ├── Trace A: trace_id = aaa
        │   └── invoke_workflow "triage"
        │       ├── gen_ai.task.id = "org/repo#123"
        │       │
        │       └── invoke_agent "triage-agent"
        │           ├── gen_ai.task.id = "org/repo#123"
        │           │
        │           └── inference "gpt-5"
        │               └── gen_ai.task.id = "org/repo#123"
        │
        ├── Trace B: trace_id = bbb
        │   └── invoke_agent "coding-agent"
        │       ├── gen_ai.task.id = "org/repo#123"
        │       │
        │       ├── inference "claude"
        │       │   └── gen_ai.task.id = "org/repo#123"
        │       │
        │       └── execute_tool "write_file"
        │           └── gen_ai.task.id = "org/repo#123"
        │
        └── Trace C: trace_id = ccc
            └── invoke_agent "review-agent"
                ├── gen_ai.task.id = "org/repo#123"
                │
                └── inference "gpt-5"
                    └── gen_ai.task.id = "org/repo#123"
    

    Each trace still uses its own trace_id and span_id to represent causal relationships within that execution, while gen_ai.task.id provides the logical correlation across traces and agent instances. gen_ai.conversation.id cannot replace this identifier because a conversation correlates messages and may not share the lifecycle of an externally managed task. Similarly, gen_ai.workflow.name identifies a workflow definition rather than a task instance.

    We therefore suggest starting with a minimal gen_ai.task.id attribute, applicable to relevant workflow, agent, inference, and tool spans. Similar to gen_ai.conversation.id, it should be recorded only when the instrumented library has a task identifier readily available or the application provides one through OpenTelemetry context or library-specific mechanisms. Instrumentations should not derive fallback values from trace IDs, conversation IDs, request hashes, branch names, or other implementation details.

    Would the maintainers prefer this identifier under gen_ai.task.id, or under a more generic namespace such as workflow.task.id as discussed in #55? Would you be open to a focused PR covering only the task identifier, its applicable spans?

  7. moved this from No status to Post-stability in Stable GenAI Semantic Conventionson Sep 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:agent-orchestrationComposition above single agent: workflow execution, handoffs, delegation across agentsenhancementNew feature or request

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions