Skip to content

Metadata

Metadata lets you store arbitrary structured data alongside any trace or observation. Unlike tags (which are simple string labels), metadata is a JSON object that can hold nested values — making it suitable for request IDs, model parameters, retrieval context, or any application-specific state you want to preserve alongside a trace.

Adding Metadata

Set metadata via propagate_attributes() or directly on an observation:

from xeroml import observe, propagate_attributes
@observe()
def handle_request(query: str) -> str:
with propagate_attributes(metadata={
"request_id": "req_abc123",
"retriever": "pinecone",
"index": "knowledge-base-v2",
"filters": {"category": "technical", "lang": "en"}
}):
return run_pipeline(query)

TypeScript:

import { propagateAttributes } from "@xeroml/tracing";
await propagateAttributes({
metadata: {
requestId: "req_abc123",
retriever: "pinecone",
filters: { category: "technical" }
}
}, async () => {
await runPipeline(query);
});

Metadata on Individual Observations

You can also set metadata directly when creating or updating an observation:

with xeroml.start_as_current_observation(name="retrieval", type="span") as obs:
results = retrieve_documents(query)
obs.update(metadata={
"num_results": len(results),
"top_score": results[0].score if results else None,
})

Querying Metadata

Metadata is searchable in the XeroML UI and queryable via the Public API. Use it to filter traces by application-specific fields that don’t fit the standard tag model.

Best Practices

  • Keep metadata keys consistent across traces — inconsistent naming makes filtering difficult
  • Use metadata for structured data; use tags for simple categorical labels used in filtering
  • Avoid storing PII in metadata unless your XeroML deployment is configured for it