Skip to content

Feature: adding additional attributes #14

@wohlgejm

Description

@wohlgejm

It would be nice to have the ability to set custom attributes by passing them into the methods.

For example, something like:

def agent(name, additional_attributes = {})
  @tracer.in_span("#{name}.agent") do |span|
    span.add_attributes({
      OpenTelemetry::SemanticConventionsAi::SpanAttributes::TRACELOOP_SPAN_KIND => "agent",
      OpenTelemetry::SemanticConventionsAi::SpanAttributes::TRACELOOP_ENTITY_NAME => name,
    }.merge(additional_attributes))
    yield
  end
end

agent("test", { "user.id" => 1 }) { agent_work }

One could make the case for the merge to happen the other way around so the default ones cannot be overwritten by the caller.

There's also an option where each of these methods could always yield the span to the caller:

def agent(name)
  @tracer.in_span("#{name}.agent") do |span|
    span.add_attributes({
      OpenTelemetry::SemanticConventionsAi::SpanAttributes::TRACELOOP_SPAN_KIND => "agent",
      OpenTelemetry::SemanticConventionsAi::SpanAttributes::TRACELOOP_ENTITY_NAME => name,
    }
    yield span
  end
end

agent("test") do |span|
  span.set_attributes({"user.id" => 1})
  agent_work
end

In that case, there's a question about how the interface could be the same with llm_call returning an instance of the Tracer class.

It might be better then to have current Tracer methods act on the yielded span, rather than be a class. Something like:

def log_messages(span, messages)
  messages.each_with_index do |message, index|
    content = message[:content].is_a?(Array) ? message[:content].to_json : (message[:content] || "")
    span.add_attributes({
      "#{OpenTelemetry::SemanticConventionsAi::SpanAttributes::LLM_PROMPTS}.#{index}.role" => message[:role] || "user",
      "#{OpenTelemetry::SemanticConventionsAi::SpanAttributes::LLM_PROMPTS}.#{index}.content" => content,
    })
  end
end

log_llm_call('openai', gpt-4o-mini') do |span|
  span.add_attributes({"user.id"} => 1})
  log_messages(span, [])
  response = do_openai_work
  log_response(span, response)
end

LMK what you think. Happy to help contribute if you'd like.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions