Skip to content

Conversation

@codefromthecrypt
Copy link
Contributor

@codefromthecrypt codefromthecrypt commented Sep 28, 2025

Aligns embedding spans with semantic conventions by removing LLM-specific attributes that don't apply to embedding operations and standardizing embedding data structure:

  • Removes llm.system and llm.provider from embedding spans
  • Adds EMBEDDING_INVOCATION_PARAMETERS constant to semantic conventions
  • Adds OPENINFERENCE_HIDE_EMBEDDINGS_VECTORS environment variable
    • Deprecates OPENINFERENCE_HIDE_EMBEDDING_VECTORS
  • Adds OPENINFERENCE_HIDE_EMBEDDINGS_TEXT environment variable
    • There was no ENV before
  • Updates spec documentation with rationale for attribute exclusions

Benefits:

  • Clearer semantic conventions: embedding.model_name is sufficient for model identification
  • Avoids ambiguity: llm.system definition unclear when applied to embeddings
  • Consistent with established patterns: embedding spans use embedding.* prefix exclusively

Breaking changes:

openinference-instrumentation-openai:

  • llm.system attribute removed from embedding spans
  • llm.provider attribute removed from embedding spans

openinference-instrumentation-litellm:

  • Attribute names change from embedding.textembedding.embeddings.{i}.embedding.text
  • Attribute names change from embedding.vectorembedding.embeddings.{i}.embedding.vector
  • embedding.vector now captures all embeddings (not just first) as tuples (not JSON strings)

openinference-instrumentation (TraceConfig):

  • hide_embedding_vectors behavior changed: now returns "__REDACTED__" instead of removing attribute (None)
    • This aligns with documented spec behavior for redacted content

Deprecations:

openinference-instrumentation (TraceConfig):

  • OPENINFERENCE_HIDE_EMBEDDING_VECTORS deprecated → use OPENINFERENCE_HIDE_EMBEDDINGS_VECTORS
  • hide_embedding_vectors deprecated → use hide_embeddings_vectors
  • Both old and new continue to work via OR logic for backwards compatibility

Note

Standardizes embedding spans across SDKs: use CreateEmbeddings, embed invocation params and per-item text/vector, drop LLM system/provider for embeddings, and add new embedding redaction config; updates specs and tests accordingly.

  • Embedding Semantics & Specs:
    • Add SpanAttributes.EMBEDDING_INVOCATION_PARAMETERS; update docs to use span name CreateEmbeddings, record per-item embedding.embeddings.{i}.embedding.text/vector, and clarify no llm.system/provider for embeddings.
    • Revise spec for text vs token inputs and vector handling; update configuration docs with new redaction env vars and deprecations.
  • Config (TraceConfig):
    • Add OPENINFERENCE_HIDE_EMBEDDINGS_VECTORS (deprecates OPENINFERENCE_HIDE_EMBEDDING_VECTORS) and OPENINFERENCE_HIDE_EMBEDDINGS_TEXT; masking now uses "__REDACTED__".
  • OpenAI Instrumentation:
    • Embedding spans: name CreateEmbeddings, emit embedding.invocation_parameters, exclude llm.system/provider.
  • LiteLLM Instrumentation:
    • Embeddings: name CreateEmbeddings; capture invocation params; record input texts and all vectors under embedding.embeddings.{i}.*; set embedding.model_name from response when present.
  • Tests & Cassettes:
    • Add embedding tests (single/batch, model name override), update assertions to new keys and span names; adjust token count/instrumentation fixtures.

Written by Cursor Bugbot for commit b9dc097. This will update automatically on new commits. Configure here.

@codefromthecrypt codefromthecrypt requested a review from a team as a code owner September 28, 2025 01:53
@dosubot dosubot bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Sep 28, 2025
@codefromthecrypt
Copy link
Contributor Author

so this is the same as #2210, and a FAQ might be why return an indexed list? The reason is that if you have a mixed batch request, you'll get multiple embedding vectors back, index correlated with the input text. one example recorded from the openai instrumentation is this one https://github.com/envoyproxy/ai-gateway/blob/main/tests/internal/testopeninference/spans/embeddings-mixed-batch.json

@codefromthecrypt codefromthecrypt force-pushed the feat/litellm-align-embedding-instrumentation-with-spec branch from c0c6750 to dc87863 Compare October 11, 2025 16:52
@dosubot dosubot bot added size:XL This PR changes 500-999 lines, ignoring generated files. and removed size:L This PR changes 100-499 lines, ignoring generated files. labels Oct 11, 2025
@codefromthecrypt
Copy link
Contributor Author

@axiomofjoy I updated this PR including the specs along with your rationale about why embeddings spans should have no system/provider attributes. If I got anything wrong, lemme know and I'll bump it!

cursor[bot]

This comment was marked as outdated.

Aligns embedding spans with semantic conventions by removing LLM-specific attributes that don't apply to embedding operations and standardizing embedding data structure:

  - Removes llm.system and llm.provider from embedding spans (LLM spans unchanged)
  - Adds EMBEDDING_INVOCATION_PARAMETERS constant to semantic conventions
  - Adds OPENINFERENCE_HIDE_EMBEDDINGS_VECTORS environment variable
  - Adds OPENINFERENCE_HIDE_EMBEDDINGS_TEXT environment variable (new functionality)
  - Deprecates OPENINFERENCE_HIDE_EMBEDDING_VECTORS (use OPENINFERENCE_HIDE_EMBEDDINGS_VECTORS)
  - Updates spec documentation with rationale for attribute exclusions
  - Fixes security flaw: api_key excluded from embedding.invocation_parameters

  **Key benefits:**
  - Clearer semantic conventions: embedding.model_name is sufficient for model identification
  - Avoids ambiguity: llm.system definition unclear when applied to embeddings
  - Consistent with established patterns: embedding spans use embedding.* prefix exclusively
  - Backwards compatible: deprecated hide_embedding_vectors continues to work

  **Breaking changes:**

  **openinference-instrumentation-openai:**
  - `llm.system` attribute removed from embedding spans
  - `llm.provider` attribute removed from embedding spans

  **openinference-instrumentation-litellm:**
  - Attribute names change from `embedding.text` → `embedding.embeddings.{i}.embedding.text`
  - Attribute names change from `embedding.vector` → `embedding.embeddings.{i}.embedding.vector`
  - `embedding.vector` now captures all embeddings (not just first) as tuples (not JSON strings)

  **openinference-instrumentation (TraceConfig):**
  - `hide_embedding_vectors` behavior changed: now returns `"__REDACTED__"` instead of removing attribute (None)
    - This aligns with documented spec behavior for redacted content

  **Deprecations:**

  **openinference-instrumentation (TraceConfig):**
  - `OPENINFERENCE_HIDE_EMBEDDING_VECTORS` deprecated → use `OPENINFERENCE_HIDE_EMBEDDINGS_VECTORS`
  - `hide_embedding_vectors` deprecated → use `hide_embeddings_vectors`
  - Both old and new continue to work via OR logic for backwards compatibility

Signed-off-by: Adrian Cole <adrian@tetrate.io>
Signed-off-by: Adrian Cole <adrian@tetrate.io>
@codefromthecrypt codefromthecrypt force-pushed the feat/litellm-align-embedding-instrumentation-with-spec branch from dc87863 to b9dc097 Compare October 11, 2025 18:31
@codefromthecrypt
Copy link
Contributor Author

#2295 for the unrelated inspector test failures

Comment on lines 14 to -18
) -> Iterator[None]:
LiteLLMInstrumentor().instrument(tracer_provider=tracer_provider)
yield
LiteLLMInstrumentor().uninstrument()
Copy link
Contributor

Choose a reason for hiding this comment

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

Was this pattern causing an issue?

Comment on lines +44 to +55
## Attributes Not Used in Embedding Spans

The following attributes that are used in LLM spans are **not applicable** to embedding spans:

- `llm.system`: Not used for embedding spans
- `llm.provider`: Not used for embedding spans

### Rationale

The `llm.system` attribute is defined as "the AI product as identified by the client or server instrumentation." While this definition has been reserved for API providers in LLM spans (e.g., "openai", "anthropic"), it is ambiguous when applied to embedding operations.

In terms of conceptualization, `llm.system` describes the shape of the API, while `llm.provider` describes the owner of the physical hardware that runs those APIs. For observability products like Arize and Phoenix, these conventions are primarily consumed in playground features, allowing re-invocation of LLM calls.
Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks for taking a stab at this. I'm not sure we need to proscribe using llm.system and llm.provider for embedding spans. Only that we've never used these attributes to describe a client interface like litellm before. In the case of the OpenAI SDK, I think it could make sense to set them. It might make less sense to set them if we don't know the specific API being hit, as is the case for LiteLLM.

Let me chat with @RogerHYang to see if he has the same understanding.

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

Labels

size:XL This PR changes 500-999 lines, ignoring generated files.

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

2 participants