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