Skip to content

Conversation

@aabmass
Copy link
Member

@aabmass aabmass commented Sep 8, 2025

Fixes #2753

Changes

Introduces reference attributes that were held back from #2179 (092db44):

  • gen_ai.system_instructions_ref
  • gen_ai.input.messages_ref
  • gen_ai.output.messages_ref

This makes uploading references to external storage more normative

Prototypes

Merge requirement checklist

  • CONTRIBUTING.md guidelines followed.
  • Change log entry added, according to the guidelines in When to add a changelog entry.
    • If your PR does not need a change log, start the PR title with [chore]
  • Links to the prototypes or existing instrumentations (when adding or changing conventions)

@aabmass aabmass changed the title Genai refs Add gen_ai _ref blob reference attributes Sep 8, 2025
@github-actions github-actions bot added the enhancement New feature or request label Sep 9, 2025
@aabmass aabmass changed the title Add gen_ai _ref blob reference attributes Add gen_ai _ref attributes for referencing external uploaded content Sep 9, 2025
@aabmass aabmass marked this pull request as ready for review September 9, 2025 03:31
@aabmass aabmass requested review from a team as code owners September 9, 2025 03:31
Copy link
Member

@lmolkova lmolkova left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do support this version, just wanted to bring up the reasoning we pushed it away from #2179.

I believe we got stuck on the following question: should we record content on parts in external storage or record the whole json there.

My preference is on recording the whole thing with the following arguments:

  • it's easier and faster (when it comes to P95, more reliable) to upload and download one reasonably sized (megabytes) object than N of smaller ones. Creating an object/blob is time-consuming operation on its own
  • input, output, instructions object are not useful without the content and part's content output is not useful without roles/structure. So when string/binary content is uploaded, but the rest of the message content is not, all consumers always need to do smart joins on the telemetry and object store data.
  • someone who wants to upload individual contents per part can still do so

Leaving it as a comment and not approval only to hear feedback.

@alexmojaki
Copy link
Contributor

alexmojaki commented Sep 9, 2025

someone who wants to upload individual contents per part can still do so

But this will be less useful to do if there isn't a semconv for uploads per part. So this argument doesn't work for me unless we think we might define conventions for both versions.

The ideal I’m imagining for a ref for each part looks like this:

  • For text parts, the value is still stored inline on the JSON up to a character limit. If it’s big enough, a truncated value is stored as well as a URL to the full value. This allows normal querying to some extent, but not always reliably.
  • Binary data like images are always uploaded as a ref and never inlined. They’re not really queryable anyway and are a pain to keep in attributes. This means that if your messages are generally a mix of binary data and short text messages that wouldn’t be truncated, you can always reliably query the text while still getting a lot of benefit from external storage.
    • The data can be stored as raw bytes in the original format, e.g. a PNG, rather than base64 encoded within JSON.
  • The ref URL is based on a hash of the content, meaning that the same content always has the same URL. This way a single part is never uploaded twice. This is great for GenAI where a conversation with many messages leads to the early messages being repeated many times.
    • The client (e.g. OTel SDK) can have an LRU cache of these hashes/URLs so that if a part was uploaded recently it doesn’t even need an HTTP call to know that it doesn’t need to upload it again.
    • Browser caching can maybe save downloading parts sometimes.
    • System instructions and tool definitions are typically repeated verbatim many times in a process lifetime, so this hashing strategy would be very helpful for them. This isn't necessarily an argument in favour of a ref per part since these are whole attributes, but it does mean that there's already motivation to implement uploading to external storage in this way. But a ref per part does help a lot here if system messages are kept at the start of gen_ai.input.messages instead of gen_ai.system_instructions, which is sometimes the case.
  • Each part can be uploaded/downloaded in parallel, which might sometimes be faster and increase the chance that at least some parts are uploaded successfully.

@lmolkova
Copy link
Member

Converting to draft - would like to have some end-to-end impl to proceed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:gen-ai enhancement New feature or request

Development

Successfully merging this pull request may close these issues.

Specify attributes for gen_ai external storage references

3 participants