Repository navigation
Closed
Labels
enhancementNew feature or requestNew feature or request
Description
Summary
Support for Ollama traces that still emit legacy GenAI semantic convention attributes (gen_ai.prompt.* and gen_ai.completion.*), so conversations and invocation tool trajectories are correctly reconstructed.
Context
Ollama instrumentation emit legacy attributes instead
gen_ai.prompt.<idx>.<field>gen_ai.completion.<idx>.<field>
Reference: OpenTelemetry semantic conventions changelog
Example
Resource SchemaURL:
Resource attributes:
-> telemetry.sdk.language: Str(python)
-> telemetry.sdk.name: Str(opentelemetry)
-> telemetry.sdk.version: Str(1.38.0)
-> agentevals.eval_set_id: Str(langchain_local_ollama_eval)
-> agentevals.session_name: Str(langchain-ollama-zero-code)
-> service.name: Str(unknown_service)
ScopeSpans #0
ScopeSpans SchemaURL:
InstrumentationScope opentelemetry.instrumentation.ollama 0.57.0
Span #0
Trace ID : d43842922319fd9cbf9829e702e4124d
Parent ID :
ID : 2b7263989e73c210
Name : ollama.chat
Kind : Client
Start time : 2026-04-01 07:28:42.293099 +0000 UTC
End time : 2026-04-01 07:28:44.170246 +0000 UTC
Status code : Unset
Status message :
DroppedAttributesCount: 0
DroppedEventsCount: 0
DroppedLinksCount: 0
Attributes:
-> llm.request.type: Str(chat)
-> gen_ai.request.model: Str(llama3.2:3b)
-> llm.is_streaming: Bool(true)
-> gen_ai.prompt.0.role: Str(user)
-> gen_ai.prompt.0.content: Str(Hi! Can you help me?)
-> llm.request.functions.0.name: Str(roll_die)
-> llm.request.functions.0.description: Str(Roll a die with a specified number of sides.)
-> llm.request.functions.0.parameters: Str({"type": "object", "properties": {"sides": {"type": "integer"}}})
-> llm.request.functions.1.name: Str(check_prime)
-> llm.request.functions.1.description: Str(Check if numbers are prime.)
-> llm.request.functions.1.parameters: Str({"type": "object", "required": ["nums"], "properties": {"nums": {"type": "array", "items": {"type": "integer"}}}})
-> gen_ai.completion.0.role: Str(assistant)
-> gen_ai.response.model: Str(llama3.2:3b)
-> llm.usage.total_tokens: Int(210)
-> gen_ai.usage.output_tokens: Int(18)
-> gen_ai.usage.input_tokens: Int(192)
-> gen_ai.system: Str(Ollama)
{"resource": {"service.instance.id": "5ae43280-e76f-4df3-8226-64ee9b933e45", "service.name": "otelcol-contrib", "service.version": "0.147.0"}, "otelcol.component.id": "debug", "otelcol.component.kind": "exporter", "otelcol.signal": "traces"}
2026-04-01T07:28:45.403Z info Traces {"resource": {"service.instance.id": "5ae43280-e76f-4df3-8226-64ee9b933e45", "service.name": "otelcol-contrib", "service.version": "0.147.0"}, "otelcol.component.id": "debug", "otelcol.component.kind": "exporter", "otelcol.signal": "traces", "resource spans": 1, "spans": 1}
2026-04-01T07:28:45.403Z info ResourceSpans #0
Resource SchemaURL:
Resource attributes:
-> telemetry.sdk.language: Str(python)
-> telemetry.sdk.name: Str(opentelemetry)
-> telemetry.sdk.version: Str(1.38.0)
-> agentevals.eval_set_id: Str(langchain_local_ollama_eval)
-> agentevals.session_name: Str(langchain-ollama-zero-code)
-> service.name: Str(unknown_service)
ScopeSpans #0
ScopeSpans SchemaURL:
InstrumentationScope opentelemetry.instrumentation.ollama 0.57.0
Span #0
Trace ID : 5cb2f7c18e78f026e15cf0ced4d6904e
Parent ID :
ID : bb8ef41e144b2679
Name : ollama.chat
Kind : Client
Start time : 2026-04-01 07:28:44.173369 +0000 UTC
End time : 2026-04-01 07:28:44.760511 +0000 UTC
Status code : Unset
Status message :
DroppedAttributesCount: 0
DroppedEventsCount: 0
DroppedLinksCount: 0
Attributes:
-> llm.request.type: Str(chat)
-> gen_ai.request.model: Str(llama3.2:3b)
-> llm.is_streaming: Bool(true)
-> gen_ai.prompt.0.role: Str(user)
-> gen_ai.prompt.0.content: Str(Hi! Can you help me?)
-> gen_ai.prompt.1.role: Str(assistant)
-> gen_ai.prompt.1.tool_calls.0.name: Str(roll_die)
-> gen_ai.prompt.1.tool_calls.0.arguments: Str({"sides": 6})
-> gen_ai.prompt.2.role: Str(tool)
-> gen_ai.prompt.2.content: Str({"sides": 6, "result": 4, "message": "Rolled a 4 on a 6-sided die"})
-> llm.request.functions.0.name: Str(roll_die)
-> llm.request.functions.0.description: Str(Roll a die with a specified number of sides.)
-> llm.request.functions.0.parameters: Str({"type": "object", "properties": {"sides": {"type": "integer"}}})
-> llm.request.functions.1.name: Str(check_prime)
-> llm.request.functions.1.description: Str(Check if numbers are prime.)
-> llm.request.functions.1.parameters: Str({"type": "object", "required": ["nums"], "properties": {"nums": {"type": "array", "items": {"type": "integer"}}}})
-> gen_ai.completion.0.content: Str(You rolled a 4 on a 6-sided die. Would you like to roll again?)
-> gen_ai.completion.0.role: Str(assistant)
-> gen_ai.response.model: Str(llama3.2:3b)
-> llm.usage.total_tokens: Int(140)
-> gen_ai.usage.output_tokens: Int(20)
-> gen_ai.usage.input_tokens: Int(120)
-> gen_ai.system: Str(Ollama)
{"resource": {"service.instance.id": "5ae43280-e76f-4df3-8226-64ee9b933e45", "service.name": "otelcol-contrib", "service.version": "0.147.0"}, "otelcol.component.id": "debug", "otelcol.component.kind": "exporter", "otelcol.signal": "traces"}
2026-04-01T07:28:46.416Z info Traces {"resource": {"service.instance.id": "5ae43280-e76f-4df3-8226-64ee9b933e45", "service.name": "otelcol-contrib", "service.version": "0.147.0"}, "otelcol.component.id": "debug", "otelcol.component.kind": "exporter", "otelcol.signal": "traces", "resource spans": 1, "spans": 2}
2026-04-01T07:28:46.417Z info ResourceSpans #0
Resource SchemaURL:
Resource attributes:
-> telemetry.sdk.language: Str(python)
-> telemetry.sdk.name: Str(opentelemetry)
-> telemetry.sdk.version: Str(1.38.0)
-> agentevals.eval_set_id: Str(langchain_local_ollama_eval)
-> agentevals.session_name: Str(langchain-ollama-zero-code)
-> service.name: Str(unknown_service)
ScopeSpans #0
ScopeSpans SchemaURL:
InstrumentationScope opentelemetry.instrumentation.ollama 0.57.0
Span #0
Trace ID : f9ea7d4ad69153bbc66417c5a1895ab2
Parent ID :
ID : f247050084ab6286
Name : ollama.chat
Kind : Client
Start time : 2026-04-01 07:28:44.762914 +0000 UTC
End time : 2026-04-01 07:28:45.412878 +0000 UTC
Status code : Unset
Status message :
DroppedAttributesCount: 0
DroppedEventsCount: 0
DroppedLinksCount: 0
Attributes:
-> llm.request.type: Str(chat)
-> gen_ai.request.model: Str(llama3.2:3b)
-> llm.is_streaming: Bool(true)
-> gen_ai.prompt.0.role: Str(user)
-> gen_ai.prompt.0.content: Str(Hi! Can you help me?)
-> gen_ai.prompt.1.role: Str(assistant)
-> gen_ai.prompt.1.tool_calls.0.name: Str(roll_die)
-> gen_ai.prompt.1.tool_calls.0.arguments: Str({"sides": 6})
-> gen_ai.prompt.2.role: Str(tool)
-> gen_ai.prompt.2.content: Str({"sides": 6, "result": 4, "message": "Rolled a 4 on a 6-sided die"})
-> gen_ai.prompt.3.role: Str(assistant)
-> gen_ai.prompt.3.content: Str(You rolled a 4 on a 6-sided die. Would you like to roll again?)
-> gen_ai.prompt.4.role: Str(user)
-> gen_ai.prompt.4.content: Str(Roll a 20-sided die for me)
-> llm.request.functions.0.name: Str(roll_die)
-> llm.request.functions.0.description: Str(Roll a die with a specified number of sides.)
-> llm.request.functions.0.parameters: Str({"type": "object", "properties": {"sides": {"type": "integer"}}})
-> llm.request.functions.1.name: Str(check_prime)
-> llm.request.functions.1.description: Str(Check if numbers are prime.)
-> llm.request.functions.1.parameters: Str({"type": "object", "required": ["nums"], "properties": {"nums": {"type": "array", "items": {"type": "integer"}}}})
-> gen_ai.completion.0.role: Str(assistant)
-> gen_ai.response.model: Str(llama3.2:3b)
-> llm.usage.total_tokens: Int(303)
-> gen_ai.usage.output_tokens: Int(18)
-> gen_ai.usage.input_tokens: Int(285)
-> gen_ai.system: Str(Ollama)
Span #1
Trace ID : d411e5438ecc53d13f8e110cfc5ee807
Parent ID :
ID : 7e4cf21d1e06b6ab
Name : ollama.chat
Kind : Client
Start time : 2026-04-01 07:28:45.415016 +0000 UTC
End time : 2026-04-01 07:28:45.990931 +0000 UTC
Status code : Unset
Status message :
DroppedAttributesCount: 0
DroppedEventsCount: 0
DroppedLinksCount: 0
Attributes:
-> llm.request.type: Str(chat)
-> gen_ai.request.model: Str(llama3.2:3b)
-> llm.is_streaming: Bool(true)
-> gen_ai.prompt.0.role: Str(user)
-> gen_ai.prompt.0.content: Str(Hi! Can you help me?)
-> gen_ai.prompt.1.role: Str(assistant)
-> gen_ai.prompt.1.tool_calls.0.name: Str(roll_die)
-> gen_ai.prompt.1.tool_calls.0.arguments: Str({"sides": 6})
-> gen_ai.prompt.2.role: Str(tool)
-> gen_ai.prompt.2.content: Str({"sides": 6, "result": 4, "message": "Rolled a 4 on a 6-sided die"})
-> gen_ai.prompt.3.role: Str(assistant)
-> gen_ai.prompt.3.content: Str(You rolled a 4 on a 6-sided die. Would you like to roll again?)
-> gen_ai.prompt.4.role: Str(user)
-> gen_ai.prompt.4.content: Str(Roll a 20-sided die for me)
-> gen_ai.prompt.5.role: Str(assistant)
-> gen_ai.prompt.5.tool_calls.0.name: Str(roll_die)
-> gen_ai.prompt.5.tool_calls.0.arguments: Str({"sides": 20})
-> gen_ai.prompt.6.role: Str(tool)
-> gen_ai.prompt.6.content: Str({"sides": 20, "result": 13, "message": "Rolled a 13 on a 20-sided die"})
-> llm.request.functions.0.name: Str(roll_die)
-> llm.request.functions.0.description: Str(Roll a die with a specified number of sides.)
-> llm.request.functions.0.parameters: Str({"type": "object", "properties": {"sides": {"type": "integer"}}})
-> llm.request.functions.1.name: Str(check_prime)
-> llm.request.functions.1.description: Str(Check if numbers are prime.)
-> llm.request.functions.1.parameters: Str({"type": "object", "required": ["nums"], "properties": {"nums": {"type": "array", "items": {"type": "integer"}}}})
-> gen_ai.completion.0.content: Str(You rolled a 13 on a 20-sided die. Would you like to roll again?)
-> gen_ai.completion.0.role: Str(assistant)
-> gen_ai.response.model: Str(llama3.2:3b)
-> llm.usage.total_tokens: Int(233)
-> gen_ai.usage.output_tokens: Int(20)
-> gen_ai.usage.input_tokens: Int(213)
-> gen_ai.system: Str(Ollama)
{"resource": {"service.instance.id": "5ae43280-e76f-4df3-8226-64ee9b933e45", "service.name": "otelcol-contrib", "service.version": "0.147.0"}, "otelcol.component.id": "debug", "otelcol.component.kind": "exporter", "otelcol.signal": "traces"}
2026-04-01T07:28:47.224Z info Traces {"resource": {"service.instance.id": "5ae43280-e76f-4df3-8226-64ee9b933e45", "service.name": "otelcol-contrib", "service.version": "0.147.0"}, "otelcol.component.id": "debug", "otelcol.component.kind": "exporter", "otelcol.signal": "traces", "resource spans": 1, "spans": 2}
2026-04-01T07:28:47.225Z info ResourceSpans #0
Resource SchemaURL:
Resource attributes:
-> telemetry.sdk.language: Str(python)
-> telemetry.sdk.name: Str(opentelemetry)
-> telemetry.sdk.version: Str(1.38.0)
-> agentevals.eval_set_id: Str(langchain_local_ollama_eval)
-> agentevals.session_name: Str(langchain-ollama-zero-code)
-> service.name: Str(unknown_service)
ScopeSpans #0
ScopeSpans SchemaURL:
InstrumentationScope opentelemetry.instrumentation.ollama 0.57.0
Span #0
Trace ID : 5aabd1ead1df7f200ffc99368443797d
Parent ID :
ID : 80072804a3bdb611
Name : ollama.chat
Kind : Client
Start time : 2026-04-01 07:28:45.994496 +0000 UTC
End time : 2026-04-01 07:28:46.647071 +0000 UTC
Status code : Unset
Status message :
DroppedAttributesCount: 0
DroppedEventsCount: 0
DroppedLinksCount: 0
Attributes:
-> llm.request.type: Str(chat)
-> gen_ai.request.model: Str(llama3.2:3b)
-> llm.is_streaming: Bool(true)
-> gen_ai.prompt.0.role: Str(user)
-> gen_ai.prompt.0.content: Str(Hi! Can you help me?)
-> gen_ai.prompt.1.role: Str(assistant)
-> gen_ai.prompt.1.tool_calls.0.name: Str(roll_die)
-> gen_ai.prompt.1.tool_calls.0.arguments: Str({"sides": 6})
-> gen_ai.prompt.2.role: Str(tool)
-> gen_ai.prompt.2.content: Str({"sides": 6, "result": 4, "message": "Rolled a 4 on a 6-sided die"})
-> gen_ai.prompt.3.role: Str(assistant)
-> gen_ai.prompt.3.content: Str(You rolled a 4 on a 6-sided die. Would you like to roll again?)
-> gen_ai.prompt.4.role: Str(user)
-> gen_ai.prompt.4.content: Str(Roll a 20-sided die for me)
-> gen_ai.prompt.5.role: Str(assistant)
-> gen_ai.prompt.5.tool_calls.0.name: Str(roll_die)
-> gen_ai.prompt.5.tool_calls.0.arguments: Str({"sides": 20})
-> gen_ai.prompt.6.role: Str(tool)
-> gen_ai.prompt.6.content: Str({"sides": 20, "result": 13, "message": "Rolled a 13 on a 20-sided die"})
-> gen_ai.prompt.7.role: Str(assistant)
-> gen_ai.prompt.7.content: Str(You rolled a 13 on a 20-sided die. Would you like to roll again?)
-> gen_ai.prompt.8.role: Str(user)
-> gen_ai.prompt.8.content: Str(Is the number you rolled prime?)
-> llm.request.functions.0.name: Str(roll_die)
-> llm.request.functions.0.description: Str(Roll a die with a specified number of sides.)
-> llm.request.functions.0.parameters: Str({"type": "object", "properties": {"sides": {"type": "integer"}}})
-> llm.request.functions.1.name: Str(check_prime)
-> llm.request.functions.1.description: Str(Check if numbers are prime.)
-> llm.request.functions.1.parameters: Str({"type": "object", "required": ["nums"], "properties": {"nums": {"type": "array", "items": {"type": "integer"}}}})
-> gen_ai.completion.0.role: Str(assistant)
-> gen_ai.response.model: Str(llama3.2:3b)
-> llm.usage.total_tokens: Int(395)
-> gen_ai.usage.output_tokens: Int(18)
-> gen_ai.usage.input_tokens: Int(377)
-> gen_ai.system: Str(Ollama)
Span #1
Trace ID : de7b7280a2191e770fe3c533144172a6
Parent ID :
ID : 5e496bf799b99568
Name : ollama.chat
Kind : Client
Start time : 2026-04-01 07:28:46.649387 +0000 UTC
End time : 2026-04-01 07:28:47.16431 +0000 UTC
Status code : Unset
Status message :
DroppedAttributesCount: 0
DroppedEventsCount: 0
DroppedLinksCount: 0
Attributes:
-> llm.request.type: Str(chat)
-> gen_ai.request.model: Str(llama3.2:3b)
-> llm.is_streaming: Bool(true)
-> gen_ai.prompt.0.role: Str(user)
-> gen_ai.prompt.0.content: Str(Hi! Can you help me?)
-> gen_ai.prompt.1.role: Str(assistant)
-> gen_ai.prompt.1.tool_calls.0.name: Str(roll_die)
-> gen_ai.prompt.1.tool_calls.0.arguments: Str({"sides": 6})
-> gen_ai.prompt.2.role: Str(tool)
-> gen_ai.prompt.2.content: Str({"sides": 6, "result": 4, "message": "Rolled a 4 on a 6-sided die"})
-> gen_ai.prompt.3.role: Str(assistant)
-> gen_ai.prompt.3.content: Str(You rolled a 4 on a 6-sided die. Would you like to roll again?)
-> gen_ai.prompt.4.role: Str(user)
-> gen_ai.prompt.4.content: Str(Roll a 20-sided die for me)
-> gen_ai.prompt.5.role: Str(assistant)
-> gen_ai.prompt.5.tool_calls.0.name: Str(roll_die)
-> gen_ai.prompt.5.tool_calls.0.arguments: Str({"sides": 20})
-> gen_ai.prompt.6.role: Str(tool)
-> gen_ai.prompt.6.content: Str({"sides": 20, "result": 13, "message": "Rolled a 13 on a 20-sided die"})
-> gen_ai.prompt.7.role: Str(assistant)
-> gen_ai.prompt.7.content: Str(You rolled a 13 on a 20-sided die. Would you like to roll again?)
-> gen_ai.prompt.8.role: Str(user)
-> gen_ai.prompt.8.content: Str(Is the number you rolled prime?)
-> gen_ai.prompt.9.role: Str(assistant)
-> gen_ai.prompt.9.tool_calls.0.name: Str(check_prime)
-> gen_ai.prompt.9.tool_calls.0.arguments: Str({"nums": [13]})
-> gen_ai.prompt.10.role: Str(tool)
-> gen_ai.prompt.10.content: Str({"results": {"13": true}, "prime_count": 1, "prime_numbers": [13]})
-> llm.request.functions.0.name: Str(roll_die)
-> llm.request.functions.0.description: Str(Roll a die with a specified number of sides.)
-> llm.request.functions.0.parameters: Str({"type": "object", "properties": {"sides": {"type": "integer"}}})
-> llm.request.functions.1.name: Str(check_prime)
-> llm.request.functions.1.description: Str(Check if numbers are prime.)
-> llm.request.functions.1.parameters: Str({"type": "object", "required": ["nums"], "properties": {"nums": {"type": "array", "items": {"type": "integer"}}}})
-> gen_ai.completion.0.content: Str(Yes, the number 13 is a prime number. Would you like to roll again?)
-> gen_ai.completion.0.role: Str(assistant)
-> gen_ai.response.model: Str(llama3.2:3b)
-> llm.usage.total_tokens: Int(317)
-> gen_ai.usage.output_tokens: Int(19)
-> gen_ai.usage.input_tokens: Int(298)
-> gen_ai.system: Str(Ollama)
{"resource": {"service.instance.id": "5ae43280-e76f-4df3-8226-64ee9b933e45", "service.name": "otelcol-contrib", "service.version": "0.147.0"}, "otelcol.component.id": "debug", "otelcol.component.kind": "exporter", "otelcol.signal": "traces"}
Reproduction
Running the following example code
Proposed solution
Support legacy GenAI attributes gen_ai.prompt.*, gen_ai.completion.*
Alternatives considered
Update Ollama OTel Instrumentation to use the latest GenAI semantic convention
Human confirmation
- I am a human (not a bot, agent, or AI) filing this issue.
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or request
Activity
krisztianfekete commentedon Apr 1, 2026
IIRC this gap is not specific to ollama itself, but to the format traceloop/openllmetry supports today. There's no official ollama OTel SDK, so the only way to have full coverage for ollama traces is via that SDK. Supporting that format however, would likely mean that agentevals could support all openllmetry instrumentations right away.
Do you agree with this assessment?
ajimenez1503 commentedon Apr 1, 2026
I see your point. I have test with Zero Code instrumentation. I will give a try using OTel SDK.
Sure, that will improve the coverage of agentevals
I have done some exploration. We can review it together if you want :)
[-]Support Ollama legacy GenAI attributes (`gen_ai.prompt.*`, `gen_ai.completion.*`)[/-][+]Support legacy GenAI attributes (`gen_ai.prompt.*`, `gen_ai.completion.*`)[/+]moezdil commentedon May 5, 2026
Working on this in #136.