# Fiddler Google ADK SDK Source: https://docs.fiddler.ai/changelog/adk-sdk Fiddler's Google ADK SDK release history. Contains ADK SDK release highlights, deprecation notices, and more. [![PyPI](https://img.shields.io/pypi/v/fiddler-adk)](https://pypi.org/project/fiddler-adk/) ## 1.0 * **Initial PyPI Release** * First version of `fiddler-adk` published to PyPI (`pip install fiddler-adk`). * `GoogleADKInstrumentor`: sets up an isolated Fiddler tracing pipeline via `FiddlerClient` and promotes it to the global tracer provider so ADK's `gcp.vertex.agent` tracer resolves to it. * `ADKSpanProcessor`: backfills `gen_ai.conversation.id` from child spans onto the parent `invocation` root span, fixing orphan-root rendering in the Fiddler UI. * Span-type classification, content extraction, and attribute normalization are delegated to the Fiddler backend's `GoogleADKSpanMapper`. * Supported versions: `google-adk >= 1.34.2` (1.x and 2.x lines), `opentelemetry-api >= 1.37.0`, Python 3.10-3.14. # Compatibility Matrix Source: https://docs.fiddler.ai/changelog/compatibility-matrix Compatibility guidance between the Fiddler platform and Python client. Find the recommended Python client version to use with your Fiddler platform version. This table summarizes the compatibility between the Fiddler Python client and the Fiddler application. You can find: * **Corresponding Fiddler Platform(s)**: Exactly the same features / API objects in both python client and the Fiddler Platform version * **Lower Fiddler Platform**: Python client has features or API objects that may not be present in the Fiddler Platform, either due to that python client has additional new methods, or that the server has removed old APIs. However, everything they have in common (i.e., most APIs) will work. * **Higher Fiddler Platform**: The Fiddler Platform has features the python client can't use, either due to the server has additional new APIs, or that python client has removed old API. However, everything they share in common (i.e., most APIs) will work. This matrix maps Python **client** versions to Fiddler **platform** versions. To see which **Python language** versions Fiddler's SDKs support, see the [Python version support policy](/reference/python-support-policy). | Client version | Corresponding Fiddler Platform(s) ✅ | Lower Fiddler Platform | Higher Fiddler Platform | | -------------- | ------------------------------------------------------------------ | ----------------------- | ----------------------- | | 3.13 | 26.13 | Between 26.12 and 26.11 | 26.14 or above | | 3.12 | 26.11, 26.12 | 26.10 | 26.13 or above | | 3.11 | 25.22, 26.1, 26.2, 26.3, 26.4, 26.5, 26.6, 26.7, 26.8, 26.9, 26.10 | Between 25.21 and 25.13 | 26.11 or above | | 3.10 | 25.13 | Between 25.12 and 25.9 | 25.14 or above | | 3.9 | 25.9 | Between 25.8 and 25.2 | 25.10 or above | | 3.8 | 25.2 | Between 25.1 and 24.19 | 25.3 or above | | 3.7 | 24.18, 24.19, 25.0, 25.1 | Between 24.17 and 24.4 | 25.2 or above | | 3.6 | 24.17 | Between 24.16 and 24.4 | 24.18 or above | | 3.5 | 24.16 | Between 24.15 and 24.4 | 24.17 or above | | 3.4 | 24.13, 24.14, 24.15 | Between 24.12 and 24.4 | 24.16 or above | | 3.3 | 24.10, 24.11, 24.12 | Between 24.9 and 24.4 | 24.13 or above | | 3.2 | 24.8, 24.9 | Between 24.7 and 24.4 | 24.10 or above | | 3.1 | 24.5, 24.6, 24.7 | 24.4 | 24.8 or above | | 3.0 | 24.4 | Not compatible | 24.5 or above | # Fiddler Evals SDK Source: https://docs.fiddler.ai/changelog/evals-sdk Fiddler's Evals SDK release history. Contains Evals SDK release highlights, SDK deprecation notices, and more. [![PyPI](https://img.shields.io/pypi/v/fiddler-evals)](https://pypi.org/project/fiddler-evals/) ## 0.5 * **Fixes** * **Experiment runner threading**: Fixed an issue where the experiment runner could fail when executed inside a thread. ## 0.4 * **Breaking Changes** * **Experiment result models renamed**: The experiment item data models were refactored. `ExperimentItem` is now `ExperimentResultItem` and `ExperimentItemResult` is now `ScoredExperimentItem` (with a new `ExperimentResultScore` model). `Experiment.get_items()` now returns `Iterator[ExperimentResultItem]`. Update imports from `fiddler_evals.pydantic_models.experiment` accordingly. * **Enhancements** * **CustomJudge alignment**: `CustomJudge` now aligns with Fiddler's internal PromptSpecV2 model for consistent custom LLM-as-a-Judge evaluation. * **Fixes** * Fixed a URL construction issue affecting API requests. ## 0.3 * **New Evaluators** * **Context Relevance** (New): Measures whether retrieved documents are relevant to the user query. Ordinal scoring — High (1.0), Medium (0.5), Low (0.0) with detailed reasoning. * **RAG Faithfulness** (New): LLM-as-a-Judge evaluator that assesses whether the response is grounded in the retrieved documents. Binary scoring — Yes (1.0) / No (0.0) with detailed reasoning. * **CustomJudge** (New): Build custom LLM-as-a-Judge evaluators using `prompt_template` with Jinja `{{ placeholder }}` syntax and `output_fields` for structured evaluation results. * **Enhancements** * **Answer Relevance 2.0**: Upgraded from binary to ordinal scoring — High (1.0), Medium (0.5), Low (0.0) with detailed reasoning. * **Ordinal Score Bounding**: Ordinal scores from the scoring API are now bounded to \[0, 1]. * **Enhancements** * **Model and Credential Parameters**: `model` and `credential` are now parameters on LLM-as-a-Judge evaluators, enabling configuration of the LLM used for evaluation. * **Evaluator-Level Score Function Mapping**: Evaluators now support `score_fn_kwargs_mapping` at the evaluator level for more flexible parameter binding. * **Score Name Prefix**: Added support for custom score name prefixes on evaluators. * **Evals API Error Handling**: Improved error handling and messaging for Evals API responses. * **Coherence Prompt Input Required**: The `prompt` input for the Coherence evaluator is now required. * **Removed Pandas Core Dependency**: Pandas moved from core to optional dependency, reducing install footprint. * **Docstring Standardization**: Fixed docstring errors and standardized documentation format across all evaluators. * **Removals** * **Toxicity Evaluator Removed**: The Toxicity evaluator has been removed from the SDK. * **Initial Release** * Core SDK with HTTP client, entity management (Project, Application, Dataset, Experiment), and the `evaluate()` function for running experiments. * **Evaluators**: AnswerRelevance, Coherence, Conciseness, Sentiment, TopicClassification, FTLPromptSafety, FTLResponseFaithfulness, RegexSearch, and support for user-defined function evaluators. * **Data Input**: Load test cases from pandas DataFrames, CSV files, or JSONL files. * **Concurrent Processing**: Parallel evaluation with ThreadPoolExecutor and tqdm progress tracking. * **PyPI Publishing**: Available as `pip install fiddler-evals`. # Changelog Source: https://docs.fiddler.ai/changelog/index Release notes for the Fiddler AI Observability Platform and supported SDKs. Track new features, fixes, and deprecations across the Fiddler platform and its SDKs. Each section below has its own page and its own RSS feed. **Latest platform release: Release 26.14 — July 14, 2026.** Curated PII defaults for the Sensitive Information guardrail, faster pre-built LLM-as-a-Judge evaluators, OAuth 2.0 for Databricks in the LLM Gateway, and evaluator downsampling for GenAI applications (private preview). See [Product releases](/changelog/product-releases#july-14-2026) for full notes. ## Platform Platform features, enhancements, and fixes for Fiddler AI Observability. Recommended `fiddler-client` version for each Fiddler platform release. ## SDKs Releases of `fiddler-client` — model onboarding, publishing, baselines, alerts, and custom metrics. Releases of `fiddler-evals` — built-in and custom LLM-as-a-judge evaluators for experiments and regression tests. Releases of `fiddler-langgraph` — auto-instrumentation and tracing for LangGraph agents. Releases of `fiddler-strands` — instrumentation and tracing for Strands Agents. Releases of `fiddler-langchain` — middleware-based instrumentation for LangChain V1 agents. Releases of `fiddler-otel` — the shared OpenTelemetry foundation used by the agentic SDKs. ## Subscribe Every changelog page exposes an RSS feed at the same URL with `/rss.xml` appended — for example, `https://docs.fiddler.ai/changelog/product-releases/rss.xml`. Look for the RSS icon at the top of any release-notes page, or add the feed directly to Slack, email, or your reader of choice. # Fiddler LangChain SDK Source: https://docs.fiddler.ai/changelog/langchain-sdk Fiddler's LangChain SDK release history. Contains LangChain SDK release highlights, SDK deprecation notices, and more. [![PyPI](https://img.shields.io/pypi/v/fiddler-langchain)](https://pypi.org/project/fiddler-langchain/) ## 1.1 ### **1.1.2** *May 25, 2026* * **Bug Fixes** * **Suppressed `gen_ai.llm.context` on routing-only LLM spans**: When an LLM span's output is purely `tool_calls` (a routing decision with no text content), the SDK now blanks `gen_ai.llm.context` on that span. Previously, RAG context set earlier in the same turn via `set_llm_context()` leaked onto these routing spans, triggering faithfulness evaluation on spans that produce no answer text. *** ### **1.1.1** *May 12, 2026* * **Bug Fixes** * **Fixed `wrapt` 2.x compatibility**: `wrapt` 2.0 renamed the first parameter of `wrap_function_wrapper()` from `module` to `target`. The SDK passed it as a keyword argument (`module='...'`), which raised `TypeError: wrap_function_wrapper() got an unexpected keyword argument 'module'` on `wrapt >= 2.0`. Fixed with a version-detecting helper that dispatches the correct keyword argument name based on the installed `wrapt` major version (`module=` for 1.x, `target=` for 2.x). * **Dependencies** * Bumps `fiddler-otel` dependency to `1.2.0`. *** ### **1.1.0** *April 14, 2026* * **New Features** * **`clear_llm_context()` function**: New convenience function to explicitly remove RAG context from an LLM instance, preventing faithfulness evaluation on subsequent non-RAG spans. In multi-step agent workflows, context set after a RAG retrieval step previously leaked into later non-RAG LLM calls (tool planning, routing, etc.), causing unintended faithfulness evaluation. `set_llm_context(llm, None)` also now clears context. ```python theme={null} from fiddler_langchain import set_llm_context, clear_llm_context # After RAG retrieval set_llm_context(model, retrieved_documents) response = model.invoke(rag_prompt) # faithfulness evaluated # Before non-RAG steps clear_llm_context(model) plan = model.invoke(planning_prompt) # no faithfulness evaluation ``` * **Python 3.14 support**: Added Python 3.14 to CI test matrix and PyPI classifiers. All runtime dependencies have compatible wheels. *** ## 1.0 ### **1.0.1** *March 20, 2026* * **Bug Fixes** * **Fixed `fiddler-otel` dependency constraint**: Relaxed the `fiddler-otel` upper bound from `<1.0.0` to `<2.0.0`, resolving a dependency conflict when installing alongside `fiddler-otel 1.x`. *** ### **1.0.0** *March 18, 2026* Initial release of the Fiddler LangChain SDK. * **Added** * **`FiddlerLangChainInstrumentor`**: Auto-instrumentor for LangChain V1 agents. Monkey-patches `langchain.agents.create_agent` so every subsequent call automatically receives a `FiddlerAgentMiddleware`. Idempotent — calling `instrument()` multiple times is safe. * `instrument()`: Enable automatic instrumentation of all `create_agent` calls. * `uninstrument()`: Restore the original `create_agent` function. Does not affect already-created agents. * `is_instrumented_by_opentelemetry`: Property indicating whether instrumentation is currently active. * **`FiddlerAgentMiddleware`**: LangChain V1 `AgentMiddleware` that instruments agents with Fiddler tracing. Produces a clean, flat trace hierarchy: agent → LLM calls → tool calls, with no noisy Chain wrappers. * `before_agent()`: Opens a root Agent span (`TYPE=agent`) at the start of each invocation. * `after_agent()`: Closes the root Agent span. * `wrap_model_call()` / `awrap_model_call()`: Wraps synchronous and asynchronous model calls with LLM spans (`TYPE=llm`). Captures model name, provider, system prompt, user prompt, full message history, output messages, token usage, LLM context, and tool definitions. * `wrap_tool_call()` / `awrap_tool_call()`: Wraps synchronous and asynchronous tool calls with Tool spans (`TYPE=tool`). Captures tool name, input, and output. * **`set_llm_context()`**: Attach a context string to a `BaseLanguageModel` or `RunnableBinding`. The middleware reads this at invocation time and sets `gen_ai.llm.context` on the LLM span. * **`add_span_attributes(**kwargs)`**: Attach custom metadata to a specific LangChain component (model, tool, or retriever). Emitted as `fiddler.span.user.{key}` only on the span for that component — scoped, unlike `add_session_attributes`. * **`set_conversation_id()`**: Re-exported from `fiddler_otel` for convenience. Propagates conversation ID to all spans in the current execution context. * **`add_session_attributes()`**: Re-exported from `fiddler_otel`. Attaches session-level metadata to all spans in the current context. * **Full async support**: `awrap_model_call` and `awrap_tool_call` hooks fully support `agent.ainvoke()`. * **Error handling**: Failing LLM or tool spans are marked `StatusCode.ERROR` with the exception recorded. The root Agent span is always closed cleanly, preventing dangling open spans. Exceptions are re-raised so normal application error handling is unaffected. * **Multi-agent single-trace nesting**: When a sub-agent is invoked from within a delegation tool, its root Agent span is automatically created as a child of the active tool span — the entire multi-agent flow appears in one trace. Top-level agents (no active parent span) start a new trace as usual. * **Retriever-as-tool**: Retrievers wrapped with `@tool` are automatically traced as `TYPE=tool` spans. * **JSONL local capture**: Inherited from `fiddler-otel`. Use `jsonl_capture_enabled=True` on `FiddlerClient`. The `FIDDLER_JSONL_FILE` environment variable overrides the output file path. ## 0.1 ### **0.1.1** *March 18, 2026* Pre-release. # Fiddler LangGraph SDK Source: https://docs.fiddler.ai/changelog/langgraph-sdk Fiddler's LangGraph SDK release history. Contains LangGraph SDK release highlights, SDK deprecation notices, and more. [![PyPI](https://img.shields.io/pypi/v/fiddler-langgraph)](https://pypi.org/project/fiddler-langgraph/) ## Deprecation notices ### Re-exported `fiddler-otel` symbols Importing core `fiddler-otel` symbols directly from `fiddler_langgraph` is deprecated and will be removed in a future major release. This affects the following imports: ```python theme={null} # Deprecated — will be removed in a future release from fiddler_langgraph import FiddlerClient from fiddler_langgraph import FiddlerSpan, FiddlerGeneration, FiddlerChain, FiddlerTool from fiddler_langgraph import trace, get_current_span, get_client, set_conversation_id ``` **Recommended migration:** Import these symbols from `fiddler_otel` directly: ```python theme={null} # Correct — import from fiddler_otel from fiddler_otel import FiddlerClient from fiddler_otel import FiddlerSpan, FiddlerGeneration, FiddlerChain, FiddlerTool from fiddler_otel import trace, get_current_span, get_client, set_conversation_id ``` `LangGraphInstrumentor`, `add_session_attributes`, `add_span_attributes`, `set_llm_context`, and `clear_llm_context` remain in `fiddler_langgraph` and are not affected. *** ## 1.5 * **Bug Fixes** * **Suppressed `gen_ai.llm.context` on routing-only LLM spans**: When an LLM span's output is purely `tool_calls` (a routing decision with no text content), the SDK now blanks `gen_ai.llm.context` on that span. Previously, RAG context set earlier in the same turn via `set_llm_context()` leaked onto these routing spans, triggering faithfulness evaluation on spans that produce no answer text. * **Bug Fixes** * **Fixed `wrapt` 2.x compatibility**: `wrapt` 2.0 renamed the first parameter of `wrap_function_wrapper()` from `module` to `target`. The SDK passed it as a keyword argument (`module='...'`), which raised `TypeError: wrap_function_wrapper() got an unexpected keyword argument 'module'` on `wrapt >= 2.0`. Fixed with a version-detecting helper that dispatches the correct keyword argument name based on the installed `wrapt` major version (`module=` for 1.x, `target=` for 2.x). * **Dependencies** * Bumps `fiddler-otel` dependency to `1.2.0`. * **New Features** * **`clear_llm_context()` function**: New convenience function to explicitly remove RAG context from an LLM instance, preventing faithfulness evaluation on subsequent non-RAG spans. In multi-step agent workflows, context set after a RAG retrieval step previously leaked into later non-RAG LLM calls (tool planning, routing, etc.), causing unintended faithfulness evaluation. `set_llm_context(llm, None)` also now clears context. ```python theme={null} from fiddler_langgraph import set_llm_context, clear_llm_context # After RAG retrieval set_llm_context(llm, retrieved_documents) response = llm.invoke(rag_prompt) # faithfulness evaluated # Before non-RAG steps clear_llm_context(llm) plan = llm.invoke(planning_prompt) # no faithfulness evaluation ``` * **Python 3.14 support**: Added Python 3.14 to CI test matrix and PyPI classifiers. All runtime dependencies have compatible wheels. OpenTelemetry minimum bumped to `>= 1.28.0` (protobuf 4.x is incompatible with Python 3.14 due to metaclass `tp_new` changes; OTel `>= 1.28.0` resolves to protobuf 5.x). * **Bug Fixes** * **Fixed `@trace` nesting inside auto-instrumented LangGraph tools**: `@trace` decorated functions running inside LangGraph tools now correctly nest their spans under the callback handler's tool span instead of creating disconnected root traces. The root cause was that `_CallbackHandler` created OTel spans but never called `context.attach()`, making them invisible to Python's OTel context system. All start/end handlers now call `context.attach()`/`context.detach()` so that `start_as_current_span()` inside a tool finds the correct active parent span. * **Improvements** (via `fiddler-otel 1.1.1`) * **`add_session_attributes()` now accepts all OTel primitive value types**: Previously restricted to `str`, forcing callers to convert numeric metadata to strings. Now supports `str`, `bool`, `int`, `float`, and homogeneous sequences of these (per the OpenTelemetry attribute specification). *** ## 1.4 **Breaking change released as a patch version.** If you are upgrading from 1.4.1 or earlier, see the migration steps below. * **Breaking Changes** * **Module restructure — `fiddler_langgraph.tracing` removed and instrumentor class renamed**: The internal `tracing` sub-package has been removed and the instrumentor class has been renamed from `FiddlerLangChainInstrumentor` to `LangGraphInstrumentor`. All existing code using the old import path must be updated. **Old import (1.4.1 and earlier):** ```python theme={null} from fiddler_langgraph.tracing.instrumentation import FiddlerLangChainInstrumentor instrumentor = FiddlerLangChainInstrumentor(client=client) instrumentor.instrument() ``` **New import (1.4.2+):** ```python theme={null} from fiddler_langgraph import LangGraphInstrumentor instrumentor = LangGraphInstrumentor(client=client) instrumentor.instrument() ``` **Migration:** Update the import path and rename `FiddlerLangChainInstrumentor` to `LangGraphInstrumentor`. The constructor signature and all methods (`instrument()`, `uninstrument()`) are identical — no other code changes required. **Impact:** Upgrading to 1.4.2 without updating the import raises `ModuleNotFoundError: No module named 'fiddler_langgraph.tracing'`. If you cannot upgrade immediately, pin to `fiddler-langgraph==1.4.1`. * **Other functions relocated from `fiddler_langgraph.tracing.instrumentation`**: The following utility functions were also in the removed `tracing` sub-package. They are now importable directly from `fiddler_langgraph`: | Function | Old import (1.4.1 and earlier) | New import (1.4.2+) | | ------------------------ | ------------------------------------------------------------------------------ | ------------------------------------------------------ | | `add_session_attributes` | `from fiddler_langgraph.tracing.instrumentation import add_session_attributes` | `from fiddler_langgraph import add_session_attributes` | | `add_span_attributes` | `from fiddler_langgraph.tracing.instrumentation import add_span_attributes` | `from fiddler_langgraph import add_span_attributes` | | `set_llm_context` | `from fiddler_langgraph.tracing.instrumentation import set_llm_context` | `from fiddler_langgraph import set_llm_context` | | `set_conversation_id` | `from fiddler_langgraph.tracing.instrumentation import set_conversation_id` | `from fiddler_otel import set_conversation_id` | **Impact:** Any of these imports using the `fiddler_langgraph.tracing.instrumentation` path will raise `ModuleNotFoundError: No module named 'fiddler_langgraph.tracing'` when upgrading to 1.4.2. * **`is_fiddler_span` utility relocated to `fiddler_otel.utils`**: The `is_fiddler_span()` function has moved from `fiddler_langgraph.core.utils` to `fiddler_otel.utils`. Update the import if you are using this utility directly. **Old import (1.4.1 and earlier):** ```python theme={null} from fiddler_langgraph.core.utils import is_fiddler_span ``` **New import (1.4.2+):** ```python theme={null} from fiddler_otel.utils import is_fiddler_span ``` **Impact:** Upgrading to 1.4.2 without updating the import raises `ModuleNotFoundError: No module named 'fiddler_langgraph.core'`. * **New features** (via `fiddler-otel 1.1.0`) * **Offline / S3 routing mode**: `FiddlerClient` now accepts two new parameters for writing traces to local files instead of sending them directly to Fiddler. This enables deployments where security or network policies require data to pass through a controlled intermediary (such as Amazon S3) before reaching Fiddler. | Parameter | Type | Default | Description | | --------------------------- | ------ | ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `otlp_enabled` | `bool` | `True` | Set to `False` to disable direct OTLP export. `api_key` and `url` are not required when `False`. | | `otlp_json_capture_enabled` | `bool` | `False` | When `True`, writes traces to local `.json` files in standard OTLP JSON format (`ExportTraceServiceRequest` envelope) compatible with the Fiddler S3 connector. | | `otlp_json_output_dir` | `str` | `'fiddler_traces'` | Output directory for OTLP JSON files. Created automatically if it does not exist. Each span batch is written to a separate timestamped file. | ```python theme={null} from fiddler_langgraph import LangGraphInstrumentor from fiddler_otel import FiddlerClient # No api_key or url needed — traces written to local files only client = FiddlerClient( application_id='YOUR_APPLICATION_ID', # Required — used by S3 connector to route traces otlp_enabled=False, otlp_json_capture_enabled=True, otlp_json_output_dir='./fiddler_traces', ) instrumentor = LangGraphInstrumentor(client=client) instrumentor.instrument() # Traces are written to ./fiddler_traces/*.json — upload these files to S3 ``` See [Offline and S3 Routing Mode](/integrations/agentic-ai/langgraph-sdk#offline-and-s3-routing-mode) in the integration guide for full details. * **Documentation** * Updated the [LangGraph SDK integration guide](/integrations/agentic-ai/langgraph-sdk) to use `LangGraphInstrumentor` throughout — all code examples, quick start, configuration, and troubleshooting sections now reflect the new import path. * **Bug Fixes** * **Fixed `set_conversation_id()` ignored after first LangGraph invocation**: When using `LangGraphInstrumentor`, calling `set_conversation_id()` between agent invocations had no effect — every span after the first run carried the conversation ID from the initial call. The root cause was a `@cached_property` on the internal `_CallbackHandler` that read the conversation ID contextvar once on first access and froze that value for the lifetime of the `_CallbackHandler` instance. The cached property has been replaced with a direct contextvar read on every span, matching the behaviour of `FiddlerSpanProcessor`. `set_conversation_id()` now takes effect immediately for all subsequent invocations. * **Added** * **Decorator-based instrumentation**: New `@trace()` decorator for automatic function instrumentation. * `@trace()` decorator for instrumenting any Python function with minimal boilerplate. * `get_current_span()` to access the current span inside decorated functions. * Support for span types: `span`, `generation`, `chain`, `tool`, with type-specific wrappers and helpers (e.g. `set_user_prompt()`, `set_tool_input()`). * Automatic parent-child relationship from call stack. * Decorator arguments for metadata: `model`, `system`, `user_id`, `version`. * `capture_input` and `capture_output` arguments for controlling automatic argument/return value capture. * Automatic async function detection — `@trace()` works with both sync and async functions. * **Manual instrumentation**: Context managers and explicit control. * `client.start_as_current_span(name, as_type=...)` for context-manager usage with automatic lifecycle and exception recording. * `client.start_span(name, as_type=...)` for explicit control; caller must call `span.end()`. * Support for all span types with both patterns. * **Span wrapper classes**: Typed wrappers with semantic convention helpers. * `FiddlerSpan` (base), `FiddlerGeneration`, `FiddlerChain`, `FiddlerTool` — returned by `start_as_current_span()`, `start_span()`, and `get_current_span()`. * `FiddlerGeneration` helpers: `set_model()`, `set_system()`, `set_user_prompt()`, `set_completion()`, `set_usage()`, `set_messages()`, `set_output_messages()`, `set_tool_definitions()`. * `FiddlerTool` helpers: `set_tool_name()`, `set_tool_input()`, `set_tool_output()`. * Common helpers on all wrappers: `set_input()`, `set_output()`, `set_attribute()`, `set_agent_name()`, `set_conversation_id()`. * **Global client accessor**: `get_client()` retrieves the active `FiddlerClient` singleton for use in decorators and utility functions. * **Context isolation**: Isolation from other OpenTelemetry tracers. * Each `FiddlerClient` uses its own isolated `Context`. * `is_fiddler_span()` utility to verify span ownership. * **Enhancements** * **Automatic Span Flush on Exit**: `FiddlerClient` now registers an `atexit` handler to automatically flush and shut down the tracer provider when the process exits, reducing span loss from in-memory buffering. * **Explicit Flush and Shutdown Methods**: New `force_flush(timeout_millis)` and `shutdown()` methods on `FiddlerClient` for explicit control over span export. `shutdown()` is idempotent and safe to call multiple times. * **Asyncio Support**: New `aflush()` and `ashutdown()` async methods run flush and shutdown in a thread pool, avoiding event loop blocking in asyncio applications. * **Context Manager Support**: `FiddlerClient` can now be used as a context manager (`with FiddlerClient(...) as client:`) to ensure automatic shutdown on exit. * **Bug Fixes** * **Fixed Pydantic Double-Encoding**: Corrected JSON serialization of Pydantic models to use `model_dump()` instead of `model_dump_json()`, preventing double-encoded JSON strings in span attributes. * **Deduplicated Retriever Span Attributes**: Removed duplicate `TYPE` and `TOOL_NAME` attribute assignments in the `on_retriever_start` callback. * **Replaced `print()` with `logging`**: All `print()` calls in `jsonl_capture.py` now use the standard `logging` module for proper log management. * **Enhancements** * **OpenTelemetry Version Upgrade**: Updated OpenTelemetry dependencies to version 1.39.1/0.60b1 for improved performance and compatibility: * `opentelemetry-api`: now supports up to 1.39.1 * `opentelemetry-sdk`: now supports up to 1.39.1 * `opentelemetry-instrumentation`: now supports up to 0.60b1 * `opentelemetry-exporter-otlp-proto-http`: now supports up to 1.39.1 * **Enhancements** * **Removed Hardcoded OpenTelemetry Limits**: Removed hardcoded default values for span limits and batch span processor configuration. The SDK now relies on OpenTelemetry SDK's built-in defaults, simplifying configuration and ensuring consistency with standard OpenTelemetry defaults. * **Enhanced LangGraph Tracing with Full Message History**: Introduced comprehensive message lifecycle tracking with two new span attributes: * `gen_ai.input.messages`: Captures the complete message history provided as input to the LLM, including system, user, assistant, and tool messages * `gen_ai.output.messages`: Captures the output messages generated by the LLM, including tool calls and finish\_reason when available * Both attributes are aligned with GenAI semantic conventions for standardized observability * **Extracted Message History from Strands Span Events**: Added support for extracting `gen_ai.input.messages` and `gen_ai.output.messages` from Strands span events (emitted as events rather than attributes) and storing them as span-level attributes in ClickHouse for unified querying and analysis. * **Breaking Changes** * **Moved `add_session_attributes` to Tracing Module**: The `add_session_attributes()` method has been relocated from the Core module to the Tracing module to co-locate session management functions with related tracing utilities. * **Old import**: `from fiddler_langgraph.core.attributes import add_session_attributes` * **New import**: `from fiddler_langgraph.tracing.instrumentation import add_session_attributes` * **Migration**: Update import statements in your code. No functional changes—all behavior remains identical. * **Impact**: Existing code using the old import path will fail with ImportError Initial release of Fiddler LangGraph SDK. # Fiddler OTel SDK Source: https://docs.fiddler.ai/changelog/otel-sdk Fiddler's OTel SDK release history. Contains OTel SDK release highlights, SDK deprecation notices, and more. [![PyPI](https://img.shields.io/pypi/v/fiddler-otel)](https://pypi.org/project/fiddler-otel/) ## 1.3 ### **1.3.0** *June 2026* #### New features * **`FIDDLER_OTLP_DEBUG` debug flag** — Set `FIDDLER_OTLP_DEBUG=true` to log OTLP trace exports for troubleshooting. Failed exports are logged at `WARNING` (with bearer tokens scrubbed) and successful exports at `DEBUG`, and wire-level HTTP logging is elevated for the underlying HTTP libraries and the OpenTelemetry HTTP exporter. #### Bug fixes * **Thread-safe lazy tracer initialization** — `FiddlerClient` now guards lazy tracer initialization with double-checked locking. Concurrent first-span creation from multiple threads no longer registers the OTLP `BatchSpanProcessor` twice, which would previously have doubled trace ingest volume. *** ## 1.2 ### **1.2.0** *May 2026* #### New features * **Multimodal content normalization** — Large inline base64 content (images, PDFs) in span attributes can now be automatically uploaded to S3 and replaced with lightweight `fiddler-file://` URIs before OTLP export. This prevents trace loss at the 10 MB Kafka span limit. Enable with `normalize_multimodal=True` on `FiddlerClient`: ```python theme={null} from fiddler_otel import FiddlerClient client = FiddlerClient( application_id='YOUR_APPLICATION_ID', api_key='YOUR_API_KEY', url='https://your-instance.fiddler.ai', normalize_multimodal=True, # opt-in, default False ) ``` | Detail | Value | | ------------------ | ------------------------------------------------- | | Upload threshold | \~100 KB base64 (\~75 KB raw) | | Supported content | `image_url` parts in content arrays | | Upload endpoint | `POST /v3/files/upload` | | Failure behavior | Warning logged, inline base64 kept (no data loss) | | Requires | `otlp_enabled=True`, valid `api_key` and `url` | | Server requirement | `ENABLE_MULTIMODAL_UPLOAD` enabled | * **Multimodal content setters** — `set_user_prompt()` now accepts `str | list[dict]`, allowing users to pass OpenAI-format multimodal content arrays directly without manual JSON serialization. ```python theme={null} generation.set_user_prompt([ {'type': 'text', 'text': 'Describe this image'}, {'type': 'image_url', 'image_url': {'url': 'data:image/png;base64,...'}}, ]) ``` #### Dependencies * Added `httpx>=0.24.0,<1.0` — used by `MediaUploader` for file uploads with thread-safe connection pooling. *** ## 1.1 ### **1.1.1** *April 2026* #### Bug fixes * **`add_session_attributes()` now accepts all OTel primitive value types** — Previously, `value` was restricted to `str`, forcing callers to convert numeric metadata to strings before attaching it to a session. Numeric values now flow through unchanged, so downstream charts and filters that expect numeric types (e.g. integer counts, floating-point scores) work as intended. Supported value types: `str`, `bool`, `int`, `float`, and homogeneous sequences of these (per the OpenTelemetry attribute specification). ```python theme={null} from fiddler_otel import add_session_attributes add_session_attributes(key='user_id', value='user_12345') # str add_session_attributes(key='request_count', value=42) # int add_session_attributes(key='confidence', value=0.87) # float add_session_attributes(key='is_premium', value=True) # bool ``` ### **1.1.0** *April 2026* #### New features * **Offline / S3 routing mode** — Traces can now be written to local `.json` files in standard OTLP JSON format and routed through an intermediate store (e.g. Amazon S3) instead of being sent directly to Fiddler. This enables deployment in environments where security or network policies require all data to pass through a controlled intermediary before reaching Fiddler. New `FiddlerClient` constructor parameters: | Parameter | Type | Default | Description | | --------------------------- | ------ | ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `otlp_enabled` | `bool` | `True` | Set to `False` to disable direct OTLP export to Fiddler. When `False`, `api_key` and `url` are not required. | | `otlp_json_capture_enabled` | `bool` | `False` | When `True`, writes traces to local `.json` files in standard OTLP JSON format (`ExportTraceServiceRequest` envelope) compatible with the Fiddler S3 connector. | | `otlp_json_output_dir` | `str` | `'fiddler_traces'` | Directory for OTLP JSON output files. Created automatically if absent. Each span batch is written to a separate timestamped file. | Usage example: ```python theme={null} from fiddler_otel import FiddlerClient # No api_key or url needed in offline mode client = FiddlerClient( application_id='YOUR_APPLICATION_ID', # Required — used by S3 connector to route traces otlp_enabled=False, otlp_json_capture_enabled=True, otlp_json_output_dir='./fiddler_traces', ) ``` Upload the generated `.json` files from `otlp_json_output_dir` to S3. The Fiddler S3 connector ingests them directly with no reformatting required. * **`application_id` as first positional parameter** — `FiddlerClient.__init__` now accepts `application_id` as the first (and only strictly required) argument. `api_key` and `url` default to `''` and are only validated when `otlp_enabled=True`. #### Clarifications (no functional change) * `console_tracer=True` has always been **additive** — it prints spans to stdout alongside the existing OTLP export. It does **not** suppress export to Fiddler. The documentation has been updated to reflect this clearly. * `jsonl_capture_enabled=True` has always been **additive** — it writes spans to a local JSONL file alongside the existing OTLP export. It does **not** suppress export to Fiddler. Note: the JSONL format is Fiddler's custom format and is **not** compatible with the S3 connector; use `otlp_json_capture_enabled=True` for S3 ingestion. #### Breaking changes * **Parameter reordering in `FiddlerClient.__init__`**: `application_id` is now the first parameter, before `api_key` and `url`. Code using **keyword arguments** (the recommended pattern) is unaffected. Code passing arguments **positionally** will break — update to use keyword arguments. *** ## 1.0 ### **1.0.0** *March 18, 2026* Initial release of the Fiddler OTel SDK as a standalone package. The core OpenTelemetry instrumentation functionality has been extracted from `fiddler-langgraph` into this independent package, which now serves as the foundation for all Fiddler framework integrations. #### Core classes * **`FiddlerClient`**: Main client that configures and manages the OTel tracer. Handles OTLP authentication, compression, span limits, sampling, and lifecycle (flush/shutdown). Registers an `atexit` handler for automatic span flushing. * **`@trace` decorator**: Automatic function tracing with input/output capture. Supports sync and async functions, all four span types (`span`, `generation`, `chain`, `tool`), and decorator parameters for `model`, `system`, `user_id`, and `version`. * **`get_current_span()`**: Retrieve the active Fiddler span inside a `@trace`-decorated function as a typed wrapper. * **`get_client()`**: Retrieve the global `FiddlerClient` singleton. #### Span wrappers `FiddlerSpan` (base), `FiddlerGeneration`, `FiddlerChain`, `FiddlerTool` — typed wrappers with semantic convention helpers. * `FiddlerGeneration`: `set_model()`, `set_system()`, `set_system_prompt()`, `set_user_prompt()`, `set_completion()`, `set_usage()`, `set_context()`, `set_messages()`, `set_output_messages()`, `set_tool_definitions()` * `FiddlerTool`: `set_tool_name()`, `set_tool_input()`, `set_tool_output()`, `set_tool_definitions()` * All wrappers: `set_input()`, `set_output()`, `set_attribute()`, `set_agent_name()`, `set_agent_id()`, `set_conversation_id()`, `record_exception()`, `end()` #### Context and session * **`set_conversation_id()`**: Set the conversation ID as a `ContextVar` that propagates to all spans in the current thread or async task. * **`add_session_attributes(key, value)`**: Attach session-level metadata to all spans in the current thread or async coroutine. Emitted as `fiddler.session.user.{key}` and automatically propagated from parent to child spans. * **`FiddlerSpanProcessor`**: OTel `SpanProcessor` that auto-propagates `gen_ai.agent.name`, `gen_ai.agent.id`, `gen_ai.conversation.id`, `session.id`, and `user.id` from parent to child spans. * **Context isolation**: Each `FiddlerClient` uses its own isolated OTel `Context`, preventing interference with any existing global tracer in the application. #### Configuration and debugging * **JSONL local capture**: `jsonl_capture_enabled` and `jsonl_file_path` constructor parameters for local span capture. The `FIDDLER_JSONL_FILE` environment variable overrides the file path when `jsonl_file_path` is not set explicitly. * **Console tracing**: `console_tracer=True` parameter to print spans to stdout during development. * **Flush and shutdown**: `force_flush()`, `shutdown()`, `aflush()`, `ashutdown()`, and context manager support. #### Constants * **`FiddlerSpanAttributes`**: Constants for all Fiddler OTel span attribute keys. * **`FiddlerResourceAttributes`**: Constants for Fiddler OTel resource attribute keys. * **`SpanType`**: Constants for valid `fiddler.span.type` values. ## 0.1 ### **0.1.1** *March 17, 2026* Pre-release. # Product Releases Source: https://docs.fiddler.ai/changelog/product-releases Discover the latest updates to Fiddler's AI observability platform - new features for ML, LLM, GenAI, and agentic observability. ### Release 26.14 #### What's New and Improved **Sensitive Information Guardrail: Curated PII Defaults and Score Normalization** The Sensitive Information guardrail now ships with a curated default PII entity set and per-entity score normalization for more consistent detection across entity types. * **`PII` (default)** — 12 high-precision entities benchmarked across multiple datasets: person, address, email, phone number, credit card number, and more. * **`PII_ALL` (new)** — All 28 supported PII entities for maximum coverage. * **`PHI`** — 7 protected health information entities (unchanged). * Per-entity score normalization ensures a single confidence threshold works uniformly across all entity types. * If you need the full 28-entity set, use `entity_categories='PII_ALL'`. **Explorer: Resource Attributes in Single-Trace View** The single-trace (RCA) view now displays **resource attributes** for each span in a dedicated collapsible section. OTel resource-level attributes such as `service.name`, `deployment.environment`, and SDK info are shown inline, helping identify the origin of any span directly in the trace details view. **Faster and More Consistent Pre-built LLM-as-a-Judge Evaluators** All pre-built LLM-as-a-Judge evaluators now run faster and more consistently across all supported models, with no accuracy impact. Fiddler-hosted Ministral sees the largest improvement: 50–81% latency reduction depending on evaluator. * *Scope*: Answer Relevance, Context Relevance, RAG Faithfulness, Conciseness, and Coherence evaluators * *Benefit*: Evaluations complete faster with more predictable latency regardless of which LLM model is used **LLM Gateway: OAuth 2.0 Authentication for Databricks** You can now connect a **Databricks** provider in the LLM Gateway using **OAuth 2.0 (client-credentials / machine-to-machine)** authentication — a Databricks **service principal** instead of a static personal access token. * Add a Databricks credential of type **OAuth Client Credentials** with your service principal's **Token URL**, **Client ID**, **Client Secret**, and **Scope**. Fiddler exchanges these for a short-lived bearer token and refreshes it automatically — no long-lived tokens to manage or rotate. * *Availability*: Databricks only. * *Benefit*: Use enterprise machine-to-machine auth for Databricks model serving instead of static, time-limited access tokens. **Evaluator Downsampling for GenAI Applications** This capability is currently in [private preview](/reference/feature-maturity-definitions#private-preview) and is not yet available to all customers. Contact your Fiddler Customer Success Manager to request access. Evaluator rules can now score a representative sample of spans instead of every span, cutting evaluator cost and latency on high-volume GenAI applications. Set a `sampling_rate` greater than 0 and up to `1.0` (default `1.0` — no sampling) on any evaluator rule. * Configure via the v3 evaluator-rules REST API, the evaluator rule UI, or MCP tools. * A soft cap of 100 evaluator rules per application provides an early guardrail against rule sprawl. * *Benefit*: Keep evaluator coverage on high-volume applications without paying to score every span. #### What's Fixed * **Charts: custom `token_count` configurations are preserved on edit** — Charts now retain their original metric parameters through a token-count round-trip, so custom token-count chart configurations are no longer silently dropped when charts are edited and saved. * **Trace queries: out-of-memory failures on large GenAI applications are resolved** — Trace fetches now paginate attribute and evaluator lookups by span ID, preventing out-of-memory failures on large trace queries and stabilizing trace fetches under heavy load. * **Ingestion: intermittent SSL connection errors are resolved** — Ingestion workers now dispose of their database engine after forking, correcting a connection-sharing defect that caused intermittent SSL errors and could destabilize ingestion. * **ClickHouse: transient read failures are retried automatically** — A transient ClickHouse read error (`ATTEMPT_TO_READ_AFTER_EOF`) is now treated as retryable, so momentary read hiccups no longer surface as hard errors. ### Release 26.13 #### What's New and Improved **Explorer: Span Events and Links in Single-Trace View** The single-trace (RCA) view now displays **events** and **links** for each span in dedicated collapsible sections. * **Events** — OTel span events (e.g., exceptions, log entries, `gen_ai.content.prompt` events) are shown with their timestamp, name, and attributes. Timestamps are formatted in your local timezone. * **Links** — Links to related spans in the same or different trace are shown with Trace ID, Span ID, and optional trace state and attributes. Copy buttons allow quick extraction of IDs. * Both sections are collapsed by default when empty, keeping the view clean for spans without events or links. * *Benefit*: Access the full OTel span context — exceptions, cross-trace references, and structured event data — directly in the RCA view without needing to export traces to another tool. **GenAI Traces TTL Can Now Be Configured via the Config Manager API** This capability is currently in [private preview](/reference/feature-maturity-definitions#private-preview) and is not yet available to all customers. Contact your Fiddler Customer Success Manager to request access. The retention window for GenAI trace, span, session, and evaluator data (introduced in 26.9) can now be configured at the organization level at runtime through the Config Manager APIs, without redeployment. Platform administrators can set the retention window to a minimum of 7 days. New data adopts the configured retention immediately. **Fiddler Centor Model for Safety v2.7.23** [Fiddler Centor Model for Safety](/observability/llm/enrichments#safety) has been updated with improved detection and calibrated scoring. * **Stronger Jailbreak Detection**: Significantly improved recall on jailbreak and prompt-injection attempts * **Fewer False Positives**: Reduced false flags on benign content such as technical jargon and roleplay * **Calibrated Scoring**: Scores are calibrated so a single decision threshold of `0.5` currently applies across all eleven safety categories — no per-label threshold tuning required * *Note*: No changes to the model interface or API/SDK identifiers (`ftl_prompt_safety`); existing integrations should adopt the new `0.5` decision threshold #### What's Changed **Custom Evaluator Output Description Field Removed** The "Description" field on Custom Judge (LLM-as-a-Judge) output definitions has been removed from the UI. This field had no measurable impact on evaluator response. If you were using it for evaluation instructions, move those instructions into the prompt template instead. **GenAI Monitoring Dashboards Under the v2 OTel Schema** Attribute-based GenAI metrics — token counts and other numeric and categorical attributes — could return empty results on monitoring dashboards when the v2 OTel schema was enabled, because attribute lookups did not account for the stripped `fiddler.span.` name prefix. Attribute queries and filters now resolve correctly, restoring affected charts. ### Release 26.12 #### What's New and Improved **Bulk Trace and Session Deletion for GenAI Applications** You can now delete individual traces and sessions from GenAI applications via the REST API, enabling granular data cleanup without deleting the entire application. * **Delete traces**: `DELETE /v3/traces` accepts an `application_id` and up to 1,000 `trace_ids` per request. All associated data within the specified traces are removed. * **Delete sessions**: `DELETE /v3/sessions` accepts an `application_id` and up to 1,000 `session_ids` per request. All associated data within the specified sessions are removed. * **Idempotent**: Requests succeed even if some or all of the specified IDs do not exist — no errors for already-deleted or non-existent data. * **Authorization**: Deletion requires `DELETE` permission on the project that owns the application. Each request is scoped to a single application. * **Rate limited**: Per-token rate limits apply to protect against accidental bulk data loss. See [REST API Rate Limiting](/sdk-api/rest-api#rate-limiting). * *Use cases*: Designed for ad-hoc removal of test data or PII traces, rather than a programmatic cleanup workflow. * *Scope*: Available for all GenAI Applications. Deletion is synchronous — data is invisible to subsequent queries immediately after the request returns. **Explorer: Complete Span Attributes in Single-Trace View** The single-trace (RCA) view in the Explorer now displays **all** attributes for **every** span type, grouped by semantic concept. * Previously, span attributes were only shown for LLM spans, using a fixed set of curated fields, so many attributes — and entire span types such as tool and chain spans — never surfaced their details. * Attributes are now resolved against the global semantic-mappings table and grouped under human-readable categories (Input, Output, Tool Input, Tool Output, and more), with any unmapped attributes collected under an **Unmapped Attributes** group. Empty categories are hidden. * Custom-integration spans (for example, Claude Code) that previously showed empty System Input / User Input / Output now populate correctly. * *Benefit*: Inspect the full set of attributes on any span — not just LLM spans — for faster, more complete root-cause investigation. **Agentic Alert Backtesting in the Alert Chart Preview** When you create a GenAI (agentic) alert rule, the Chart Preview now backtests your thresholds against historical data so you can validate an alert before saving it. * The preview plots your selected metric over a chosen time range with the **critical** and **warning** thresholds overlaid as mark-lines, so you can see exactly where past data would have breached. * The preview updates as you adjust the metric, thresholds, and comparison operator in the rule form. * *Benefit*: Tune alert thresholds with confidence by seeing how they would have behaved on real historical data, reducing noisy or missed alerts. **Date-Time Range Picker for Alert Backtesting** The Chart Preview header now includes an interactive date-time range picker, replacing the previous fixed "Last 30 days" view. * Choose from preset ranges or a custom date range to control the backtest window. * Defaults to the last 30 days; the chart x-axis follows the selected range. * *Benefit*: Backtest alert thresholds over the exact time period you care about — a recent incident, a seasonal window, or a longer historical baseline. **Breach Summary in the Alert Chart Preview** A breach summary now appears below the Chart Preview, quantifying how often your thresholds would have triggered over the selected range. * Shows the count of **critical** and **warning** breaches out of the total number of data points in the range. * A data point that breaches both thresholds is counted once, as critical. * *Benefit*: Get an at-a-glance sense of how sensitive an alert configuration is before saving it. **Trace Explorer is Now "Explorer"** We renamed the Trace Explorer to the Explorer — a simpler name that better reflects the view's purpose. * Page names and routes no longer include the word "trace." * Existing bookmarks redirect automatically to the new Explorer URLs. * *Benefit*: A clearer, shorter name for the view, with no disruption to your saved links. **Add Spans to an Evaluation Dataset from the Explorer** You can now select spans directly in the Explorer and add them to an evaluation dataset, turning real production traffic into test data without leaving the page. * Select spans with the new per-row checkboxes, then choose **Add to dataset** in the toolbar. * A guided dialog walks you through choosing the target dataset and mapping span fields — Input, Output, Tools & Retrieval, and Attributes — to dataset columns by drag-and-drop, with a final review step before you confirm. * *Benefit*: Build and grow evaluation datasets from the traces you are already investigating, so your test cases reflect real user traffic. **Secret Detection in Prompts and Responses** Fiddler can now detect leaked credentials — API keys, tokens, and other secrets — in LLM prompts and responses, both in real time and in offline scans. * **Real-time guardrail**: Fiddler Guardrails block or redact secrets before a request reaches the model. * **Offline evaluation**: The new [`FTLSecretDetection`](/sdk-api/evals/ftl-secret-detection) evaluator scans datasets for credentials, returning one score per detected secret with its type label. * Detection combines 42 known credential formats with Shannon-entropy analysis to catch custom or unknown secrets. It runs as a CPU-only, sub-millisecond pipeline — no GPU required. * *Benefit*: Catch credential leakage in agent and LLM traffic before it is stored or sent downstream. See the [Secret Detection tutorial](/developers/tutorials/guardrails/guardrails-secrets) to get started. **Kong AI Gateway Integration** You can now capture LLM observability data through the [Kong AI Gateway](/integrations/agentic-ai/kong-integration) (v3.13+) using Kong's OpenTelemetry plugin. * Point your application at Kong instead of the provider, and Kong exports traces — prompts, responses, token usage, and latency — directly to Fiddler over OTLP. * Supports OpenAI, Anthropic, Cohere, Azure OpenAI, Google Gemini, and other providers via Kong's `ai-proxy` plugin. * *Benefit*: Get full LLM observability with zero application instrumentation — no SDK to add to your code. **Executive Dashboard** This capability is currently in [private preview](/reference/feature-maturity-definitions#private-preview) and is not yet available to all customers. Contact your Fiddler Customer Success Manager to request access. A new cross-project Executive Dashboard gives organization leadership a single, at-a-glance overview of GenAI and ML health across every application. * **Top-line KPIs** — Total Apps, Active Apps, Total Traces, Errors, and Sessions over a selectable 7-day, 14-day, or 30-day window. * **Evaluator Scores** — Average Quality alongside Answer Relevance, Context Relevance, Faithfulness, Prompt Safety, and PII Detection, aggregated across all applications. * **Traffic and Token Usage** trends, plus an **Application Health Overview** table (traces, average latency, tokens, and average quality per app) with drill-down links into each application. * *Benefit*: Give leadership a cross-project view of GenAI adoption, quality, and cost in one place — without stitching together per-application dashboards. #### Improvements **Score Distribution in Experiment Results** Each score column in the Experiment Details results grid now shows a mini distribution chart in its header — a histogram for numeric evaluators, a stacked bar for categorical ones — with a `Mean · Pass %` summary below it. The pass rate is computed from each evaluator's configured thresholds, so it stays consistent with the color-coded scores in the cells. *Benefit*: See the shape of your results at a glance, without scrolling the grid. **Evaluator Rule Limit** Each application now supports up to 100 evaluator rules by default, keeping evaluation and monitoring responsive as rule counts grow. Creating a rule beyond the limit returns a `422` error; delete unused rules to make room. On self-hosted deployments, an administrator can adjust the limit. See [Evaluator Rules](/evaluate-and-test/evaluator-rules#rule-limit). ### Release 26.11 #### What's New and Improved **Trace Explorer Filtering Improvements** * Introduced a new filtering sidebar/persistent drawer to the Trace Explorer UI with more robust filtering options. * Search for any column to filter from the search input, with options to sort and filter the results. * Filter settings persist in local storage and as URL params, making it easier to save and share views. **Long-Running Jobs Alert on Jobs In Progress** The Jobs In Progress tab now surfaces jobs that have been queued or running for more than 2 hours, helping you spot stalled ingestion and processing work sooner. * A warning banner appears when one or more jobs have been queued or running for over 2 hours. * Click **Show long-running jobs** in the banner to filter the grid to just those jobs; an info banner indicates the filter is active and can be cleared with one click. * The Duration column is now filterable by elapsed running time (in hours) directly from the column filter menu (for example, `Duration > 2`). * The grid defaults to sorting by Duration so the longest-running jobs appear at the top. * *Benefit*: Detect stuck or slow jobs at a glance and drill into them without manually scanning the list. #### Client Versions | Component | Version | | --------------------- | ------- | | Fiddler Python Client | 3.12.0 | | Fiddler Evals SDK | 0.3.0 | | Fiddler LangChain SDK | 1.1.2 | | Fiddler LangGraph SDK | 1.5.2 | | Fiddler Strands SDK | 0.6.0 | | Fiddler OTel SDK | 1.2.0 | The Fiddler Python client 3.12.0 migrates to **Pydantic v2** (`pydantic>=2.0`) and adds **Python 3.13 and 3.14** support. Environments pinned to Pydantic v1 must upgrade. Refer to the [Python client changelog](/changelog/python-sdk) for version-specific details. #### Deprecations and Removals **`Model.publish()` is deprecated (Python client 3.12.0)** The implicit-dispatch `Model.publish()` method is deprecated in favor of two explicit methods; calling it now emits a `DeprecationWarning`. * **Replacement**: Use `Model.publish_stream(events=...)` for streaming/live events, or `Model.publish_batch(source=...)` for batch files (Parquet/CSV) and pandas DataFrames. * *Action Required*: Update calls to `model.publish(...)`. Pass `update=True` to either method to update previously published events. * See the [Python Client SDK changelog](/changelog/python-sdk) and [Publishing production data](/developers/client-library-reference/publishing-production-data). ### Release 26.10 #### What's New and Improved **Fiddler Centor Models — Product Rebrand** Fiddler's purpose-built LLM evaluators are now called **Fiddler Centor Models**. This release updates all documentation and UI labels to reflect the new name. * **Fiddler Trust Models** → **Fiddler Centor Models** (product family name) * **Fast Safety** → **Centor Safety** * **Fast Faithfulness** → **Centor Faithfulness** * **Fast PII** → **Centor PII** * API field names and SDK identifiers (`ftl_prompt_safety`, `ftl_response_faithfulness`, etc.) are **unchanged** — no code changes are required. * Alongside this rename, Fiddler has launched the [Fiddler Evals TCO calculator](https://www.fiddler.ai/evals-tco-calculator), which lets you compare the cost of Centor Models to third-party LLM evaluators. **RCA Column Filtering for Predictive/LLM Monitoring Charts** You can now filter by any column in the RCA chart for Predictive and LLM Monitoring charts. * Click the filter icon in the upper-right corner of the chart, or open the column header menu on any column. * Specify up to 10 filter conditions; data is filtered server-side. * Column filters combine with existing saved segments or ad-hoc segments; all conditions are joined with AND. * Must be enabled with feature flag: `enableRCAColumnFilteringUI` * *Scope*: Applies to Predictive and LLM Monitoring charts. Not available for GenAI Application charts. * *Benefit*: Narrow the RCA view to a specific data slice without leaving the chart, and layer column filters on top of saved or ad-hoc segments for targeted root-cause investigation. **Project Admin Access for Org Admins** This feature is currently in [private preview](/reference/feature-maturity-definitions#private-preview) and not yet available to all customers. Contact your Customer Success Manager to enable. When enabled, Org Admins automatically receive Project Admin access on every project in their organization, without needing to be explicitly assigned to each one. * Org Admins get Project Admin permissions on all projects, models, alerts, dashboards, and charts in their organization. * Org Admins can no longer be assigned a project role while the feature is enabled. * Any existing project role assignments for Org Admins are no longer shown in project member listings; those Org Admins automatically have Project Admin access instead. * Per-project role assignments for non-admin users are unaffected. * Org Admins can still be added to teams; their effective access on a team's projects is always Project Admin (the higher permission wins). * If an Org Admin is later demoted to Org Member, they lose implicit Project Admin access immediately and revert to whatever direct or team-mediated project roles (if any) were assigned to them previously. * Must be enabled with feature flag: `enableOrgAdminImplicitProjectAdmin` * *Benefit*: Eliminates per-project role-assignment overhead for organizations where Org Admins are expected to have full platform access. **Enhanced API Rate Limiting** The REST API now exposes rate limit information through standard HTTP response headers (`X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`, `Retry-After`) on every request, making it straightforward for clients to implement graceful retry handling. Per-token rate limits use separate budgets for read and write operations to protect service availability and fairness. See the [REST API Rate Limiting](/sdk-api/rest-api#rate-limiting) documentation for current limits and retry guidance. **Trace Explorer Enhancements** Trace Explorer gains several improvements in 26.10. * **Full-page view**: Open any trace in a dedicated full-page view in addition to the side drawer, giving you more space to inspect complex trace trees. * **Search on historical spans**: Full-text search over prompt and response content is now available on spans ingested before 26.9. Existing applications gain retroactive search coverage automatically — no action required. * **Improved filter dropdowns**: The span name, span type, and agent name filter dropdowns now load options from the server with search support. Boolean evaluator fields now support `IN` and `NOT IN` operators. * **Trace drawer layout**: The trace drawer defaults to List view with a 70/30 split (span details 70%, trace tree 30%) and adapts to narrow screens. * *Benefit*: Investigate individual spans across an entire application with broader search coverage, more precise filters, and a more usable trace view. **GenAI Application Dashboard: Inline Add Chart** You can now add charts to a GenAI Application dashboard directly from edit mode, without navigating away. * In edit mode, a **+** tile appears in the dashboard grid. Click it to choose between adding a saved chart or creating a new one. * **Saved Charts**: Opens a searchable drawer listing existing GenAI charts for the current project. Select one or more to add them to the dashboard layout. * **New Chart**: Opens the chart creation flow with the current project pre-selected. On save, you are returned to the dashboard with the new chart added to the layout automatically. * Your draft layout persists across page refreshes and round-trips to the chart creation page, so unsaved edits are not lost. * *Benefit*: Build and iterate on GenAI Application dashboards without losing your in-progress layout. #### Fixes and Security Updates * **Breadcrumbs Fixed for Charts**: When you navigate to a chart from a dashboard, the breadcrumbs now route back to the originating dashboard. *Benefit*: Preserves navigation context so you can return directly to the dashboard you came from. **Release 26.9** #### What's New and Improved **Custom Histogram Bins for Numerical Columns** Numerical columns now support custom bin boundaries for histograms and drift metrics (PSI, JSD), enabling domain-specific or quantile-based binning instead of the default 10 uniform bins. * Set custom bins at model creation or update via `model.schema["column"].bins = [...]` and `model.update()`, or through the UI schema editor * Bins must be strictly increasing, span \[min, max], with at most 16 boundary values (15 bins) * When omitted, 10 uniform bins are auto-generated (default behavior unchanged) * Updating bins triggers re-computation of historical aggregates; models with more than 10M events per environment are not eligible for bin updates * See [Customizing Your Model Schema](/developers/python-client-guides/model-onboarding/customizing-your-model-schema#modifying-the-histogram-bins) **GenAI Traces TTL** You can now bound the storage growth of GenAI trace, span, session, and evaluator data in long-running deployments by applying a retention window to raw GenAI data. * **Anchor**: Retention is measured from Fiddler-side ingestion time, so backfilled or late-arriving spans are retained for the full window after ingestion * **Availability**: Retention applies to GenAI data ingested into newly-onboarded deployments. To enable retention on an existing deployment, contact your Fiddler Customer Success Manager **FQL Enhancements: `min()`/`max()` Aggregate Functions and `null` Keyword** Two additions to Fiddler Query Language (FQL) expand the expressiveness of custom metric definitions for both ML and agentic applications. * **`min(x)` and `max(x)` aggregate functions**: Compute the minimum or maximum value of a numeric column or expression across all rows in a time window. Use them to track feature or attribute ranges (`max(col) - min(col)`), detect extreme values, or build ratio-based metrics (`min(col) / max(col)`) * For ML: accepts column references (e.g., `min(Prediction)`) * For agentic/GenAI: accepts `attribute()` calls (e.g., `max(attribute('response_time_ms', type='user', scope='span'))`) `min(x)` / `max(x)` aggregate a single expression across rows. To compare multiple already-computed aggregates, use `least(...)` / `greatest(...)` instead. * **`null` keyword**: The `null` literal can now be used directly as a return value in FQL expressions — for example, in `if()` to propagate missing data: `if(is_null(col), null, col * 2)`. Use `is_null()` and `is_not_null()` to filter by null values Available for both ML and GenAI/agentic custom metrics. See [Fiddler Query Language](/observability/platform/fiddler-query-language) for the full reference. **Session-Level Attributes in GenAI Charts** GenAI Application charts now support **Session** as a query scope alongside **Span**, enabling Attribute metrics over custom session-level attributes published via the Fiddler SDK in addition to per-span attributes. * Pick **Session** from the **Query Scope** dropdown when configuring an Attribute metric — the attribute picker then lists session-scoped attributes you have published for the application * *Scope*: Available for the Attribute metric only. Other built-in metrics (Traffic, Latency, Token Count, Evaluator) remain Span-only in the chart Query Scope dropdown **Executive Dashboard** Executive Dashboard is currently in private preview, not yet available to all customers. * **Improved Error States**: We now give more helpful information if the user viewing the dashboard has no access to projects or if the projects they can access have no onboarded models, instead of displaying a generic error message as we were previously doing. **LLM Gateway: AWS Bedrock, Azure OpenAI, and Azure AI Provider Support** The LLM Gateway now supports AWS Bedrock, Azure OpenAI, and Azure AI as providers, enabling teams to route evaluator and LLM-as-a-Judge requests through AWS and Azure-hosted LLM deployments. Configure each provider in **Settings > LLM Gateway** by selecting the provider and configuring models and authentication credentials. Bedrock provides access to foundation models from leading AI providers: * **Anthropic** (`bedrock/anthropic.*`) — Claude models for advanced reasoning and long-context tasks * **Amazon** (`bedrock/amazon.nova-*`) — Nova family for multimodal and text generation * **Meta** (`bedrock/meta.llama*`) — Open-weights Llama models across multiple sizes * **Mistral AI** (`bedrock/mistral.*`) — High-performance models optimized for efficiency Both default and custom model IDs (e.g., fine-tuned or newly released models) are supported. **Authentication methods** * **API Key** — Use Fiddler's managed AWS credentials * **AWS Access Key** — Provide your own AWS access key ID, secret access key, and region **Optional VPC endpoint support** Configure a custom API Base URL to route requests through an AWS VPC endpoint (e.g., `https://vpce-xxx.bedrock-runtime.us-east-1.vpce.amazonaws.com`) instead of the public Bedrock endpoint. Access OpenAI models hosted on Azure OpenAI Service: * GPT-4 and GPT-4 Turbo for advanced reasoning and long-context tasks * GPT-3.5 Turbo for fast, cost-effective completions * GPT-4o for multimodal capabilities * Custom fine-tuned models Customers specify their Azure deployment name (which may differ from the base model name). **Authentication methods** * **API Key** — Use your Azure deployment's API key for simple authentication * **Microsoft Entra ID** (formerly Azure AD) — OAuth 2.0 client credentials flow with tenant ID, client ID, and client secret for enterprise SSO integration **Custom endpoint support** Configure a custom API Base URL to target specific Azure regions or resource endpoints, e.g., `https://.openai.azure.com/`. Access models from the Azure AI Model Catalog: * **Anthropic** — Claude models (Opus, Sonnet, Haiku) * **Meta** — Llama models (8B to 70B parameters) * **Mistral AI** — Mistral and Mixtral models * **Cohere** — Command and Embed models * Other third-party foundation models available in the Azure AI catalog Customers specify their Azure AI deployment name. **Authentication methods** * **API Key** — Use your Azure deployment's API key for simple authentication * **Microsoft Entra ID** (formerly Azure AD) — OAuth 2.0 client credentials flow with tenant ID, client ID, and client secret for enterprise SSO integration **Custom endpoint support** Configure a custom API Base URL to target specific Azure regions or resource endpoints, e.g., `https://.services.ai.azure.com/`. **Named Access Keys and Configurable Limits** You can now create multiple access keys with descriptive names, making it easier to manage credentials across different integrations and environments. Keys are managed under **Settings > Credentials**, in the Access Keys section. * **Named access keys**: Assign a descriptive name to each key at creation so you can quickly identify which integration or environment uses it. * **Configurable limit**: Each user can create up to 5 keys by default. Contact Fiddler Support to request a higher limit. A key's full value is shown only once, at creation. Copy and store it securely before closing the dialog — Fiddler cannot retrieve it later. Existing access keys continue to work. We recommend creating any new keys with names going forward; the option to create unnamed keys will be removed in a future release. See [Managing Credentials](/reference/administration/settings#credentials) for setup steps and security guidance. **Trace Explorer** Trace Explorer is a new spans-first exploration surface for GenAI applications, providing a paginated, filterable, searchable view of every span ingested into your application. Access it via the **Trace Explorer** tab on any GenAI Application Details page. Trace Explorer is currently in public preview. * **Server-side filterable DataGrid**: Browse spans across a 7-day default window with columns for type, name, input, output, timestamp, duration, and status (`Ok` / `Error` / `Unset`); open the trace drawer from the Actions column to inspect the full trace tree * **Full-text search with scope**: Search prompt and response content with a scope selector (All / Input / Output), backed by a new dedicated content index for fast substring lookups * **Structured filters**: Filter by span fields, IDs, token counts, user-defined span attributes, and evaluator outputs, with type-aware operators including negation * **Dynamic columns**: Evaluator outputs and user-defined span attributes appear as columns automatically based on your application's schema * **Sorting**: Sort by start time (default) or duration in the UI *** **Release 26.8** #### What's New and Improved **Dashboard and Chart PDF/PNG Export** All dashboard surfaces — Executive Dashboard, Symphony dashboards, GenAI Application dashboards, and chart detail pages (Monitoring, GenAI Monitoring, Feature Analytics, and Embedding Visualization) — now include an **Export** button that captures the current view as a PDF or PNG file. * **PDF export**: Renders the full dashboard at a consistent page width, scales content to fit, and produces a multi-page PDF when the content is taller than a single page * **PNG export**: Captures the visible dashboard as a single high-resolution image * **Smart exclusions**: UI chrome such as control panels, date pickers, and fullscreen toggles are excluded from the export so the output contains only chart content * **Force-load**: Before capturing, the exporter pre-fetches all chart data and waits for charts to finish rendering, so exports are never blank or partially loaded * *Scope*: Available on all dashboard surfaces when the `enable_dashboard_export_ui` feature flag is enabled **Chart Legend Bulk Selection and Isolate** Charts with more than three legend items now include a context-aware bulk selection button and support double-click to isolate a single series. This applies to GenAI charts and ML charts. * **Dynamic bulk action label**: The button reads "Hide All" when all series are visible, "Show All" when all are hidden, and "Invert Selection" when the chart has a mix of visible and hidden series * **Double-click to isolate**: Double-clicking a legend item hides every other series and shows only the clicked one, making it easy to focus on a single metric * *Benefit*: Quickly toggle visibility of many series at once or drill into a single series without clicking each legend item individually * *Scope*: Applies to both Monitoring and GenAI Application charts when more than three legend items are present **Chart Legend Selection Filters RCA View for GenAI Charts** The RCA table for GenAI charts will now be filtered by whatever is selected in the chart legend, making the filtering experience faster and more intuitive. * **Works with Filters Panel**: RCA chart will be filtered by the intersection of filter selections between the legend and the filters panel in the sidebar **Agentic Custom Metrics** You can now define custom aggregate metrics over OpenTelemetry span attributes using Fiddler Query Language (FQL). Agentic Custom Metrics are scoped to your organization and can be optionally narrowed to specific projects, making them ideal for tracking cross-cutting concerns across agentic workflows. * **FQL-based definitions**: Write expressions like `average(attribute('gen_ai.usage.input_tokens', type='system', scope='span'))` to define metrics over any span attribute — system or user-defined * **Flexible scoping**: Create organization-wide global metrics or scope them to specific projects for team-level visibility * **Full lifecycle management**: Create, view, and delete custom metrics directly from the Fiddler UI. * **Use cases**: Track cost per span, compute custom latency percentiles, measure token usage ratios, or aggregate any numeric span attribute over time * *Benefit*: Define the exact measurements that matter to your agentic applications without waiting for built-in metric support * *Scope*: Available for all GenAI Applications **Fiddler Fast Trust Safety Model v2.6.0** [Fiddler Fast Trust Safety](/observability/llm/enrichments#safety) model has been updated with improved detection capabilities. * **Improved Jailbreaking Detection**: Enhanced accuracy for identifying jailbreaking attempts in prompts * **Improved Roleplaying Detection**: Enhanced accuracy for detecting content where the model is instructed to adopt a specific persona or character * *Note*: No changes to the model interface — works as a drop-in replacement for the previous version **LLM Gateway: Fiddler-Hosted Ministral 3 8B Model** The LLM Gateway now offers Mistral's Ministral 3 8B Instruct as a Fiddler-hosted model for evaluators and LLM-as-a-Judge workflows. This feature is currently in public preview. * **Model ID**: `fiddler/ministral3-8b` * **Use case**: Complex or nuanced evaluations that benefit from stronger reasoning capabilities * **Trade-off**: Slower than `fiddler/llama3.1-8b` but better suited for evaluations requiring deeper analysis * *Benefit*: Run sophisticated evaluators without configuring external provider credentials or incurring per-token charges **Evaluator Editing** Evaluators can now be edited via the Evaluator Library. You can now modify and refine evaluators to meet your monitoring needs. **Gini Coefficient Custom Metric (FQL)** The `gini()` function is now available in Fiddler Query Language (FQL) for defining custom metrics on ML models. It computes the Gini coefficient derived from the Lorenz curve, measuring how well a model's predicted scores rank actual values. * **Syntax**: `gini(actual=Target, predicted=Score)` — both `actual` and `predicted` are required keyword arguments of type `Number` * **All ML task types**: Works for binary classification, multiclass classification, regression, and ranking models * **Normalized Gini**: Compute the normalized Gini coefficient (scaled to 1 for a perfect model) with `gini(actual=Target, predicted=Score) / gini(actual=Target, predicted=Target)` * **AUC shortcut**: For binary classification, the normalized Gini can also be derived as `2 * auroc() - 1` * **Categorical targets**: For binary classification models with categorical target columns, use an `if` expression to convert to numeric (e.g. `gini(actual=if(churn == 'yes', 1, 0), predicted=score)`) * *Benefit*: Compute Gini-based model performance metrics — widely used in insurance and credit risk modeling — directly in custom metric definitions, charts, and alerts * *Scope*: Available for ML custom metrics only (not for GenAI or agentic applications). See [Fiddler Query Language](/observability/platform/fiddler-query-language) and [Custom Metrics](/observability/platform/custom-metrics) for full documentation *** **Release 26.7** #### What's New and Improved **LLM Gateway: Vertex AI Provider Support** The LLM Gateway now supports Google Vertex AI as a provider, enabling teams to route evaluator and LLM-as-a-Judge requests through GCP using service account credentials. Vertex AI provides access to a wide range of models from the Model Garden, organized by family: * **Gemini**: `vertex_ai/gemini-*` * **Anthropic (Claude)**: `vertex_ai/claude-*` * **Meta/Llama**: `vertex_ai/meta/{MODEL}` * **Mistral**: `vertex_ai/mistral-*` * **DeepSeek**: `vertex_ai/deepseek-ai/{MODEL}` * **Qwen**: `vertex_ai/qwen/*` * **AI21 (Jamba)**: `vertex_ai/jamba-*` * **OpenAI (GPT-OSS)**: `vertex_ai/openai/gpt-oss-*` * **ZAI (GLM)**: `vertex_ai/zai-org/{MODEL}` * **OpenAI-compatible**: `vertex_ai/openai/` * **Non-OpenAI-compatible**: `vertex_ai/` Configure Vertex AI access in **Settings > LLM Gateway** by providing a GCP service account JSON key, project ID, and location. **Evaluator Library** A new Evaluator Library provides a centralized place to create, view, duplicate, and manage evaluators independently of rules. Create evaluators directly from the library and select from them when setting up new rules. **Multi-Target Event Updates for LLM Models** LLM and NOT\_SET models with multiple target columns now correctly preserve all target columns during event updates. Previously, only the first target column was retained and additional targets were silently dropped. * *Benefit*: You can update multiple target columns (e.g., `comment` and `feedback`) in a single PATCH request without data loss * *Scope*: Affects only `LLM` and `NOT_SET` model task types, which are the only tasks that support multiple targets. Classification, regression, and ranking models (single target) are unaffected **Evaluation Dataset Management** Evaluation datasets can now be created, populated, and deleted directly from the UI. You can upload items via CSV with guided column mapping, including auto-mapping based on the existing dataset schema when adding to datasets that already contain data. * *Benefit*: You can manage evaluation datasets entirely from the UI without writing code; smart auto-mapping reduces friction for repeated uploads * *Note*: CSV uploads are limited to 1,000 rows per upload #### Fixes and Security Updates * **LLM Gateway**: Provider delete and update operations now return `409 Conflict` instead of a generic `400` when credentials are referenced by evaluators * **Security Updates**: Applied routine security patches and version updates to application frameworks to stay current * **Chart zoom and legend state preserved across re-renders**: Zoom position and legend selection no longer reset when hovering over chart elements or when the chart re-renders. Previously, user-interactive chart state was discarded on every option update, causing charts to "jitter" and lose filter settings *** **Release 26.6** #### What's New and Improved **Executive Dashboard (Preview)** A new Executive Dashboard provides organization-wide visibility into model health and alerting across all projects in a single view. This feature is now available as *private preview*; if you would like access to this feature, please contact your Customer Success Manager. * **KPI Summary Cards**: At-a-glance metrics including total models, critical and warning alert counts, and monitoring coverage percentage * *Benefit*: You can quickly assess overall AI system health without navigating into individual projects * **Alert Breakdown by Type and Severity**: Alert summary cards grouped by type (drift, performance, data integrity) showing affected models, top triggered metrics, and time since last trigger * *Benefit*: Identify which alert categories need attention and drill down to specific alerts with one click * **Cross-Project Model Health Table**: A unified table listing all models across projects with severity status indicators, traffic volume, last event timestamp, and model owner * *Benefit*: Compare model health across the entire organization and quickly spot models that need investigation * **Configurable Time Range**: Selectable time windows (7D, 14D, 30D, 90D) to control the reporting period for all dashboard metrics * *Benefit*: Adjust the analysis window to match your reporting cadence or investigate recent vs. long-term trends * **Model Fleet Health Donut Chart**: Visual distribution of healthy, warning, critical, and unmonitored models across the organization * *Benefit*: Instantly understand the proportion of your model fleet in each health state **LiteLLM Proxy OpenTelemetry Integration** Fiddler now automatically ingests OpenTelemetry traces emitted by LiteLLM proxy, with no SDK or code changes required in your application. * **Zero-configuration ingestion**: Point `OTEL_EXPORTER_OTLP_ENDPOINT` at your Fiddler instance and set your application ID — traces flow in automatically * **Purpose-built span mapper**: Handles LiteLLM proxy's span format (`acompletion` operation name, JSON message attributes, infrastructure spans) and maps them to Fiddler's semantic convention * **Full conversation capture**: Extracts system prompt, last user turn, and assistant response from LiteLLM's JSON message attributes (`gen_ai.input.messages`, `gen_ai.output.messages`) * **Cost and proxy metadata**: LiteLLM cost fields (`gen_ai.cost.*`) and proxy metadata (`metadata.*`) are preserved as user-visible span attributes for auditing and cost attribution See the [LiteLLM Integration guide](/integrations/agentic-ai/litellm-integration) for setup instructions. **GenAI Dashboard Inline Editing** The GenAI Application dashboard now supports inline editing, allowing you to rearrange, resize, and delete chart tiles directly within the application view without navigating to a separate configuration page. * **Drag-and-Drop Rearrangement**: Reorder dashboard charts by dragging and dropping tiles into new positions * *Benefit*: Quickly customize your dashboard layout to prioritize the metrics that matter most * **Inline Resize**: Resize chart tiles directly on the dashboard using drag handles * *Benefit*: Adjust chart sizes to give more space to complex visualizations without leaving the page * **Swap Behavior**: When dragging a tile onto another, the tiles swap positions rather than overlapping * *Benefit*: Predictable layout behavior that preserves all your charts during rearrangement **Sortable Numeric Columns in RCA Events Table** Numeric columns (integers and floats) in the RCA Raw Events tab can now be sorted in ascending or descending order. Sorting is performed on the currently displayed data (up to 1,000 events), making it easier to identify outliers and top contributors within the loaded set. * *Benefit*: You can quickly find the highest or lowest values for evaluator scores, custom metrics, and other numeric columns without manual scanning. **Clickable URL Hyperlinks in Data Tables** URL strings in RCA data table cells are now automatically detected and rendered as clickable hyperlinks that open in a new browser tab. * *Benefit*: You can click directly from an RCA row to open source documents, external links, or trace URLs without copying and pasting. **Test Alert Notifications** You can now send test notifications for alert rules directly from the UI, verifying that your notification channels (email, webhook) are correctly configured before alerts fire in production. * **Send Test Alert Action**: A new "Send Test Alert" option is available in the alert rules 3-dot menu * *Benefit*: Validate notification delivery without waiting for a real alert to trigger * **Backend API**: New `POST /v3/alert-rules/{id}/test-notification` endpoint supports test notification delivery with org-scoping and input validation * *Benefit*: Programmatic access to test notifications for automation and CI/CD workflows #### Fixes and Security Updates * **Alert Email Input**: Email addresses typed into the alert notification recipient field are now automatically captured when the field loses focus, preventing silent data loss when the user clicks away without pressing Enter. Email validation logic has been consolidated into a shared `webapp-common` helper for consistent behavior across all alert configuration surfaces * **Security Updates**: Applied routine security patches and version updates to application frameworks to stay up-to-date with the latest improvements. *** **Release 26.5** #### What's New and Improved *No user-facing features in this release.* #### Fixes and Security Updates * **Charting**: Fixed an issue where the Metric Query Name displayed as empty when backend data was missing; a default name is now shown instead * **Security Updates**: Applied routine security patches and version updates to application frameworks to stay up-to-date with the latest improvements. *** **Release 26.4** #### What's New and Improved **Fiddler LangGraph SDK 1.4.0: Decorator and Manual Instrumentation** The Fiddler LangGraph SDK (1.4.0) introduces decorator-based and manual instrumentation modes alongside the existing `LangGraphInstrumentor` auto-instrumentation, giving you fine-grained control over trace structure and metadata for custom application logic and non-LangGraph components. Key additions include the `@trace()` decorator, context managers for explicit span control, typed span wrappers with semantic helpers, and a global `get_client()` singleton. For the full changelog, see the [LangGraph SDK 1.4.0 release notes](/changelog/langgraph-sdk). For implementation guides and code examples, see the [LangGraph SDK integration guide](/integrations/agentic-ai/langgraph-sdk) and the [SDK API reference](/sdk-api/langgraph/fiddler-client). **GenAI Application Page Redesign** The GenAI Applications page now offers a grid-based card view alongside the existing list view, giving you a more visual and scannable overview of your applications at a glance. * **Grid-Based Application View**: A new card-based grid layout is available as an alternative to the existing list view * *Benefit*: Faster visual scanning and easier identification of applications, especially in environments with many GenAI applications * **Project-Level Administration**: Projects are now exposed as a manageable entity within the admin console * *Benefit*: Administrators can manage project-level RBAC permissions and perform project deletion directly from the UI * *Note*: This enables customers to manage access control and lifecycle for projects without requiring backend intervention **GenAI Chart and Alert Controls Rework** Chart controls and alert controls across GenAI experiences have been redesigned for a more unified and intuitive monitoring workflow. * **Unified Chart Controls**: Reworked chart controls provide a consistent experience across all GenAI monitoring views * *Benefit*: Streamlined chart configuration with fewer clicks and a more intuitive layout * **Reworked Alert Controls**: Alert configuration within GenAI experiences has been updated to align with the new chart controls * *Benefit*: Consistent interaction patterns between charting and alerting workflows * **Automatic Chart Migration**: Existing GenAI charts are automatically migrated to the new format during the upgrade **Breaking Change** — This is a breaking change to chart and alert configurations. The automatic migration supports all valid configurations. In the rare event that a migration fails, the affected chart should be recreated manually. **Model TTL Management** You can now configure Time-to-Live (TTL) policies for ClickHouse event data at the organization, project, or model level, enabling fine-grained control over data retention. * **Hierarchical TTL Configuration**: TTL values can be set at organization, project, or model scope by platform administrators using the config manager APIs * *How it works*: More specific levels take precedence — model-level TTL overrides project-level, which overrides organization-level * *Unit*: Days (minimum 7 days) * **Lazy Pruning**: Data pruning occurs on a background schedule, at intervals of at least 4 hours * *Note*: Dashboards and historical charts are unaffected; only raw event queries are limited to data within the TTL window * **Opt-In by Default**: Existing deployments are unaffected unless custom TTL values are explicitly configured * *Note*: The deployment-wide default is controlled by the `EVENTS_TABLE_TTL_DAYS` environment variable, which defaults to no TTL Pruning is irreversible. Once data is pruned, it cannot be recovered. **OTel Collector Performance Improvements** Infrastructure improvements to the OpenTelemetry Collector enhance throughput and reliability for high-volume trace ingestion. * **Size-Based Batching**: Sending queues now use byte-based sizing instead of count-based * *Benefit*: More predictable batching behavior for payloads of varying sizes, especially large spans * **Percentage-Based Memory Limiter**: The collector's memory limiter is now percentage-based, adapting to container memory limits automatically * *Benefit*: Better suited to containerized deployments compared to the previous fixed-value approach * **Configurable Kafka Producer**: Kafka producer max request size is now configurable with optional compression * *Benefit*: Supports larger trace and event payloads without hitting message size limits #### Client Versions Refer to the [LangGraph SDK changelog](/changelog/langgraph-sdk) for version-specific details. #### Fixes and Security Updates * **Security Updates**: Applied routine security patches and version updates to application frameworks to stay up-to-date with the latest improvements. *** **Release 26.3** #### What's New and Improved **RAG Health Metrics: Answer Relevance 2.0, Context Relevance, and RAG Faithfulness** RAG Health Metrics is a purpose-built diagnostic framework for Retrieval-Augmented Generation applications. The three evaluators work together to pinpoint exactly where RAG pipelines fail — whether in retrieval, generation, or query understanding — transforming debugging from manual trial-and-error into targeted root cause analysis. * **Answer Relevance 2.0** (Enhanced): Improved ordinal scoring system replaces binary scoring * *Scoring*: High (1.0), Medium (0.5), Low (0.0) with detailed reasoning * *Benefit*: Granular assessment of how well responses address user queries * *Availability*: Agentic Monitoring, Experiments, LLM Observability * **Context Relevance** (New): Measures whether retrieved documents are relevant to the query * *Scoring*: High (1.0), Medium (0.5), Low (0.0) with detailed reasoning * *Benefit*: Isolate retrieval problems from generation problems in your RAG pipeline * *Availability*: Agentic Monitoring and Experiments (not available in LLM Observability) * **RAG Faithfulness** (Repackaged): LLM-as-a-Judge faithfulness evaluator with standardized inputs and outputs, now part of the RAG Health Metrics triad * *Scoring*: Binary — Yes (1.0) / No (0.0) with detailed reasoning * *Inputs*: `user_query`, `rag_response`, `retrieved_documents` * *Outputs*: `label`, `value`, `reasoning` * *Benefit*: Combined with Answer Relevance and Context Relevance for comprehensive RAG pipeline diagnostics * *Availability*: Agentic Monitoring, Experiments, LLM Observability * *Note*: FTL Faithfulness (`ftl_response_faithfulness`) continues unchanged for guardrails and LLM Observability use cases * *Note*: RAG Faithfulness and FTL Faithfulness are separate evaluators with different architectures **Diagnostic Framework Benefits:** Use the three evaluators together to diagnose RAG pipeline issues: | What the metrics tell you | Why it's happening | Next Step | | --------------------------------- | ------------------------------------- | ------------------------------------------------ | | High relevance + Low faithfulness | Hallucinations despite being on-topic | Check if retrieval provided sufficient grounding | | High faithfulness + Low relevance | Grounded but didn't answer the query | Check if retrieval provided relevant information | | Low Context Relevance | Retrieval pulling wrong documents | Fix retrieval mechanism | RAG Health Metrics works alongside Fiddler's existing 80+ LLM metrics (toxicity, PII, coherence, and more) — providing targeted RAG diagnostics that complement your existing observability stack. **CustomJudge in Evals SDK** The `CustomJudge` evaluator class is now available in the Fiddler Evals SDK (0.3.0), enabling custom LLM-as-a-Judge evaluators in Experiments workflows. * **Prompt Template Style**: Define custom evaluators using `prompt_template` with Jinja `{{ placeholder }}` syntax and `output_fields` for structured evaluation results * *Benefit*: Build domain-specific evaluation criteria for any use case — brand voice compliance, bias detection, topic classification, and more * *Note*: This is the same `CustomJudge` class available in Agentic Monitoring, now also accessible through the Evals SDK for Experiments workflows **Improved Reasoning Quality for LLM-as-a-Judge Evaluators** The quality of the `reasoning` field has been improved for all LLM-as-a-Judge evaluators when using the Fiddler-hosted Llama model. * **Better Reasoning Output**: More intelligent, consistent reasoning that better aligns with predicted labels * *Scope*: All pre-built LLM-as-a-Judge evaluators in Agentic Monitoring, and custom LLM-as-a-Judge evaluators using Prompt Template-style prompt specs in Traditional Monitoring * *Benefit*: More detailed and accurate reasoning explanations for evaluation results * *Note*: Evaluation speed may be slightly slower in some cases due to higher quality reasoning output; tokens per second remains constant **Fiddler LangGraph SDK Enhancements** The Fiddler LangGraph SDK (1.3.1) includes infrastructure upgrades and new observability capabilities. * **OpenTelemetry Upgrade**: Updated to OpenTelemetry 1.39.1 / 0.60b1 (api, sdk, instrumentation, otlp exporter) * *Note*: Removed hardcoded OpenTelemetry span/batch limits; SDK now uses OpenTelemetry defaults * **Full LLM Message History**: New span attributes `gen_ai.input.messages` and `gen_ai.output.messages` capture complete LLM message history * *Benefit*: Better debugging and observability of LLM interactions within agentic workflows **Fiddler Strands Pipeline Support** Message history from Strands span events is now extracted and stored as span attributes for querying. * *Benefit*: Enables observability and analysis of Strands-based agentic pipelines within the Fiddler platform #### Client Versions | Component | Version | | --------------------- | ------- | | Fiddler Python Client | 3.11 | | Fiddler Evals SDK | 0.3.0 | | Fiddler LangGraph SDK | 1.3.1 | | Fiddler Strands SDK | 0.4.0 | Refer to the [Evals SDK changelog](/changelog/evals-sdk) and [LangGraph SDK changelog](/changelog/langgraph-sdk) for version-specific details. #### Deprecations and Removals **DSPy-style Prompt Specifications Removed from Documentation** DSPy-style Prompt Specifications are not supported in Agentic Monitoring or Experiments. Example notebooks have been updated to use the `CustomJudge` class with Prompt Template style exclusively. * **Replacement**: Use `CustomJudge` with `prompt_template` (Jinja syntax) and `output_fields` for structured evaluation results * *Note*: DSPy-style prompt specs remain available in Traditional Monitoring but are no longer the recommended approach * *Action Required*: If using custom LLM-as-a-Judge evaluators, adopt `CustomJudge` with Prompt Template syntax **Fixes and Security Updates** * **Security Updates**: Applied routine security patches and version updates to application frameworks to stay up-to-date with the latest improvements. *** **Release 26.2** #### What's New and Improved **Enhanced Sentiment Evaluator Performance** The Sentiment evaluator has been optimized to leverage GPU acceleration when available, significantly improving evaluation speed for all input sizes. * **GPU Acceleration**: Sentiment evaluator now automatically detects and utilizes GPU resources when available * *Benefit*: Dramatically faster evaluation performance - under 80ms on the scoring endpoint for all input sizes * *Note*: Falls back to CPU processing if GPU is unavailable, maintaining backward compatibility * **Performance Optimization**: Replaced model weights with GPU-compatible version * *Note*: Input is truncated at 512 tokens as before **GenAI Application Deletion** You can now delete GenAI applications directly from the GenAI Applications List page, providing better application lifecycle management. * *Benefit*: Streamlined cleanup of test and deprecated applications #### Deprecations and Removals **Answer Relevance Evaluator** The Answer Relevance evaluator has been removed from the list of available evaluators as we prepare to release an improved version. * **Removed from Available Evaluators**: Answer Relevance is no longer available for new evaluation rules * *Note*: Existing Answer Relevance rules will continue to function normally * **Replacement Timeline**: Answer Relevance v2 will be introduced in Fiddler v26.3 * *Benefit*: The updated evaluator will provide improved accuracy and performance **Fixes and Security Updates** * **Security Updates**: Applied routine security patches and version updates to application frameworks to stay up-to-date with the latest improvements. **Release 26.1** #### What's New and Improved **Performance Optimization for Metrics** Significant improvements to the metric fetching engine and metadata caching to enhance query performance and reduce database load. * **Optimized Metric Fetching**: Metric fetching engine now retrieves sparse data from the database more efficiently * *Benefit*: Significantly reduced data transfer and processing overhead for metric queries * **Smart In-Memory Processing**: Missing values are efficiently filled in-memory only when necessary * *Note*: For example, when preserving zero-traffic bins * *Benefit*: Improved query performance without sacrificing data completeness * **LRU Metadata Caching**: Implemented Least Recently Used (LRU) caching for frequently accessed metadata * *Scope*: Caches Projects, Models, Baselines, Segments, and Applications metadata * *Benefit*: Further reduces database load and improves response times for common queries **Span Latency Monitoring** New charting capabilities for monitoring span latency across your agentic and LLM applications. * **Span Latency Charts**: Added new charts specifically designed for span latency visualization * *Benefit*: Better visibility into performance characteristics of individual operations * **Granular Latency Filtering**: Filter latencies by different time granularities * *Options*: Microseconds, milliseconds, or seconds * *Benefit*: Analyze performance at the appropriate scale for your use case **Charts Preview in Agentic Alerts** Enhanced alert configuration with visual chart previews to help you set accurate thresholds. * **Visual Threshold Tuning**: Charts preview shows data points that fall under Critical and Warning thresholds * *Benefit*: Dynamically fine-tune alert thresholds based on observed trends * *Benefit*: Reduce false positives by visualizing actual data distribution before setting alerts **Fixes and Security Updates** * **Security Updates**: Applied routine security patches and version updates to application frameworks to stay up-to-date with the latest improvements. **Release 25.22** ### What's New and Improved **Enhanced Agentic Observability Dashboards** Improved out-of-the-box monitoring experience for LLM and agentic applications with expanded default dashboards and automated safety evaluation. * **Default Safety Evaluator**: New applications automatically include FTL safety evaluator rule * *Benefit*: Immediate safety monitoring for all LLM spans and outputs without manual configuration * **Expanded Dashboard Charts**: Default dashboards now include 4 charts in addition to traffic monitoring and traffic metrics * *Safety Analysis*: Monitor safety evaluator results for responsible AI deployment * *Token Consumption*: Track LLM token usage for cost optimization * **Accurate Token Counting**: SDK-based token counting replaces previous estimation method * *Benefit*: Precise cost tracking and optimization insights for LLM operations * **Production Monitoring Parity**: Metric cards gaining feature parity with monitoring charts * *New Support*: Token counts and custom attributes now available in metric cards * *Benefit*: Consistent monitoring capabilities across different visualization types **Extended Alert Capabilities for Agentic Applications** Alert system expanded beyond traffic monitoring to support comprehensive LLM application observability. * **Token Count Alerts**: Set thresholds for LLM token consumption * *Benefit*: Proactive cost management and budget protection for API usage * **Attribute-Based Alerts**: Create alerts on numerical and categorical custom attributes * *Benefit*: Monitor business-specific metrics and application-specific dimensions **Programmatic Model Schema Updates** Add columns to production models after initial onboarding without downtime or data re-ingestion. Supports adding inputs, outputs, targets, and metadata columns with all data types. *Action Required*: Requires Python Client SDK 3.11 or higher **Important Notes**: * New columns will have null values for historical events * Future events must include data for newly added columns **Event Deletion and Pipeline Improvements** Critical fixes to data pipeline operations and rate limit handling for improved reliability. * **Event Deletion Bug Fixes**: Resolved issues with event deletion operations in the data pipeline * *Benefit*: Reliable data cleanup and management for production systems * **Rate Limit Handling**: Added HTTP 429 responses for rate limit scenarios * *Benefit*: Clear feedback when API rate limits are exceeded, enabling proper retry logic ### Client Version This release works best with Python Client SDK **3.11** or higher. **Release 25.21** ### What's New and Improved **Harrier Alerts MVP: Enhanced Traffic Monitoring** Introducing the first release of Harrier Alerts, enabling you to set up granular traffic monitoring for your ML and LLM applications with configurable alert thresholds. * **1-Hour Traffic Alerts**: Monitor traffic patterns with hourly granularity to catch issues quickly * *Benefit*: Detect traffic anomalies and potential problems within an hour of occurrence * **1-Day Traffic Alerts**: Track daily traffic patterns for broader trend analysis * *Benefit*: Identify long-term traffic patterns and plan capacity accordingly * **Configurable Thresholds**: Set custom alert thresholds based on your application needs * *Note*: Available for both hourly and daily monitoring periods **User-Defined Attributes for Enhanced Observability** Add custom attributes to your agentic and LLM application traces for deeper insights into your specific use cases and business metrics. * **Span-Level Attributes**: Add granular metadata to individual operations * *Format*: `fiddler.span.user.{key}` for operation-specific attributes * **Flexible Metadata**: Capture any custom data relevant to your monitoring needs * *Benefit*: Filter, group, and analyze traces using your own business dimensions * *Action Required*: SDK update required to use this feature **Rule-Based Evaluators** Create custom evaluation rules for your LLM applications with flexible, condition-based logic. * **Custom Evaluation Logic**: Define specific rules and conditions for evaluating LLM outputs * **Flexible Conditions**: Set up complex evaluation criteria based on your use case * *Benefit*: Tailor evaluation to your specific quality and safety requirements **Custom LLM as a Judge (LLMaaJ)** Build custom LLM-based evaluators using your preferred models and evaluation criteria. * **Flexible Model Selection**: Use any LLM as an evaluator for your applications * **Custom Prompts**: Define evaluation criteria with your own prompting strategies * *Benefit*: Create domain-specific evaluators that understand your unique requirements **Pre-Built LLMaaJ Improvements** Enhanced Fiddler's pre-built LLM evaluators with improved accuracy and updated evaluation criteria. * **Updated Evaluation Logic**: Refined prompts and evaluation criteria for better accuracy * **Improved Response Quality**: More consistent and reliable evaluation results * *Note*: Input and output formats have been updated for improved performance * *Compatibility*: These evaluators were deactivated in 25.20 to prepare for these improvements **Streamlined GenAI Application Onboarding** Redesigned the GenAI application onboarding flow for a simpler, more intuitive setup experience. * **Simplified Steps**: Reduced complexity in creating new GenAI applications * **Improved Guidance**: Better in-app instructions and tooltips * *Benefit*: Get your agentic and LLM applications monitored faster with less configuration **Performance Optimization: Event Deletion** Improved memory efficiency when deleting events by time range. * **Reduced Memory Usage**: Delete operations now process data in chunks to minimize memory consumption * **Better Scalability**: Handle large-scale deletions without resource constraints * *Performance Impact*: Significantly lower memory footprint for bulk delete operations ### Deprecations **Enrichment Features: Toxicity and Custom LLM Classifier** The following enrichment features are being deprecated in favor of the improved LLMaaJ evaluators: * **Deprecated Features**: * Toxicity enrichment * Custom LLM Classifier enrichment * **Replacement**: Use the new Custom LLMaaJ or Pre-Built LLMaaJ evaluators * Enhanced evaluation capabilities with LLM-based judges * More flexible and accurate evaluation * **Migration Path**: Configure equivalent evaluators using the new LLMaaJ framework * *Benefit*: Modern evaluation infrastructure with better accuracy and flexibility #### Fixes and Security Updates * **Security Updates**: Applied routine security patches and version updates to application frameworks to stay up-to-date with the latest improvements. #### Client Version Client version updates are required for User-Defined Attributes functionality. Refer to the [Python SDK changelog](/changelog/python-sdk) for version-specific details. #### Documentation Updates * **OpenTelemetry Integration**: New comprehensive documentation for OpenTelemetry integration * Quick Start guide for custom agent frameworks * Advanced patterns and production configurations * [OpenTelemetry Quick Start →](/developers/quick-starts/opentelemetry-quick-start) * **User-Defined Attributes**: Documentation for adding custom attributes to traces * Session and span-level attribute patterns * Best practices for custom metadata **Release 25.20** ### What's New and Improved **Enhanced Fiddler Fast Trust Safety Model** [Fiddler Fast Trust Safety](/observability/llm/enrichments#safety) model has been updated to improve accuracy and expand classification capabilities based on customer feedback. * **Improved Cryptocurrency Handling**: Reduced false positives when analyzing content that references cryptocurrency and related financial terms * *Benefit*: More accurate safety assessments for fintech and Web3 applications without unnecessary flagging of legitimate cryptocurrency discussions * **New Roleplaying Detection**: Added `roleplaying` label to identify content where the model is instructed to adopt a specific persona or character * *Impact*: Enhanced ability to detect potential prompt injection attempts and inappropriate persona adoption * *Note*: Users with existing FTL Safety enrichments that did not specify label subsets via the `classifiers` configuration will automatically see the new `roleplaying` label on newly ingested data ### Deprecations **Custom LLM Classifier** The Custom LLM Classifier feature is now deprecated and will be removed in a future release. Users should migrate to the more powerful and flexible LLM-as-a-Judge with Prompt Spec feature. * **Replacement**: [LLM-as-a-Judge with Prompt Specs](/observability/llm/llm-evaluation-prompt-specs) provides enhanced capabilities for custom evaluations with greater control and flexibility * **Migration Path**: Refer to the LLM-as-a-Judge documentation for implementation guidance and examples * *Benefit*: LLM-as-a-Judge offers more sophisticated evaluation workflows, better prompt engineering capabilities, and improved consistency for custom classification tasks ### Fixes and Security Updates * **Security Updates**: Applied routine security patches and version updates to application frameworks to stay up-to-date with the latest improvements. #### What's New and Improved **Enhanced Session Management** Fiddler 25.19 introduces improved session management that keeps users authenticated during active usage while maintaining security through standardized timeout policies. * **Extended Active Sessions**: Users remain authenticated while actively using Fiddler, eliminating the previous 2-hour hard timeout that logged out active users * *Benefit*: Uninterrupted workflow for active users while maintaining robust security controls * **Intelligent Idle Detection**: Sessions automatically expire after 2 hours of inactivity * *Default Configuration*: 2-hour idle timeout, 24-hour maximum session lifetime, 1-hour access token lifetime * **Multi-Tab Session Synchronization**: Session state is synchronized across multiple browser tabs, providing a consistent experience * *Benefit*: Seamless transitions between browser tabs without unexpected logouts * **Proactive Token Refresh**: Access tokens are automatically refreshed in the background when actively using the application **Jobs Page Optimization** The Jobs page now provides a more focused view of job history while improving system performance through intelligent data retention policies. * **Streamlined Job Display**: The Succeeded/Failed tab shows only the jobs that require attention or review * Failed streaming jobs remain visible for 30 days * All batch ingestion jobs (successful and failed) remain visible for 30 days * Successful streaming jobs are removed immediately upon completion * *Benefit*: Cleaner job history makes it easier to identify jobs that need attention * **Performance Improvements**: Chunk-level data purging reduces internal metadata table sizes * *Benefit*: Faster page load times, especially for high-volume environments * **Smart Data Retention**: The system maintains a 30-day retention period for jobs that may need to be replayed or investigated while removing unnecessary successful streaming job entries ### Fixes and Security Updates * **Security Updates**: Applied routine security patches and version updates to application frameworks to stay up-to-date with the latest improvements. #### Fixes and Security Updates * **Security Updates**: Applied routine security patches and version updates to application frameworks to stay up-to-date with the latest improvements. #### Fixes and Security Updates * **Security Updates**: Applied routine security patches and version updates to application frameworks to stay up-to-date with the latest improvements. #### What's New and Improved * **Login Redirection** * Users are now automatically redirected to their originally requested URL after signing in. This enhancement improves the user experience by eliminating the need to manually navigate back to the intended page after authentication. * Customizable Identity Provider Group Prefix * Organizations can now configure a custom prefix for identity provider group mapping instead of the default `fiddler_` prefix. This enhancement allows Fiddler to work with existing organizational naming conventions for Active Directory, LDAP, and SSO groups. Previously, Fiddler required groups to follow the exact naming pattern: * `fiddler_ORG_ADMIN` * `fiddler_ORG_MEMBER` * `fiddler_ ` With this update, administrators can specify a custom prefix that matches their organization's group naming policy. Refer to the [Mapping LDAP Groups & Users to Fiddler Teams](/reference/access-control/mapping-ad-groups-to-fiddler-teams) guide for more details. #### What's New and Improved **New Fiddler AuthN Management Console** We're excited to introduce the new Fiddler AuthN management console, built on a robust authentication framework. This upgrade enhances Fiddler's authentication and user management capabilities with improved security and administrative control. **Key Features:** * **Dedicated Management Console**: Access authentication administration at `https://authn-{your-instance}.cloud.fiddler.ai` * **Enhanced SSO Integration**: Improved support for Okta, Microsoft Entra ID, Google, and Ping Identity with standardized configuration * **Identity Provider Group Sync**: Automatic mapping of external groups to Fiddler teams with customizable group prefixes * **Role-Based Administration**: Granular admin roles including "Org Owner" and "Org User Manager" for delegated management * **Mixed Authentication Support**: Simultaneous SSO and email-based authentication methods This enhancement delivers enterprise-grade authentication management while maintaining backward compatibility with existing configurations. *Benefit*: Provides improved security, streamlined administration, and enhanced user experience through modern authentication infrastructure. [Explore Authentication Documentation →](/reference/access-control) #### Fixes and Security Updates * **Security Updates**: Applied routine security patches and version updates to application frameworks to stay up-to-date with the latest improvements. #### What's New and Improved **Fast Personally Identifiable Information (PII) Guardrails** We've added Fast PII detection to Fiddler Guardrails, joining Fast Safety and Fast Faithfulness to provide comprehensive real-time protection for LLM applications. * **Comprehensive PII Detection**: Automatically detects and flags PII leakage across 25+ categories including personal identifiers, financial data, government IDs, and digital identifiers * **Detailed Output**: Returns detected PII spans with labels, confidence scores, and character offsets for precise identification and redaction * **Enterprise Ready**: Optimized for low latency and high-scale deployment with consistent sub-second response times * **Compliance Support**: Helps meet privacy regulations like GDPR, CCPA, and HIPAA by preventing PII exposure The Fast PII Guardrails integrate seamlessly via REST API and can be used independently or combined with existing guardrails for layered protection. For technical implementation details, see the [Guardrails documentation](/getting-started/guardrails). #### Fixes and Security Updates * **Security Updates**: Applied routine security patches and version updates to application frameworks to stay up-to-date with the latest improvements. * **Security Updates**: Applied routine security patches and version updates to application frameworks to stay up-to-date with the latest improvements. * **Alerts UI Consistency**: Fixed various display inconsistencies in the Alerts interface to improve user experience and visual consistency across the platform. #### What's New and Improved * **Concurrent Enrichment Processing** * Introduced parallel processing for independent enrichment operations, significantly improving performance when multiple enrichments are applied to your LLM data * *Performance Impact:* Reduces overall enrichment processing time by up to 70% when using multiple enrichments (e.g., combining PII detection, toxicity analysis, and sentiment scoring) * *Benefit:* Faster data processing enables near real-time monitoring for high-volume LLM applications, reducing the delay between data ingestion and actionable insights * *Note:* This feature is currently in controlled rollout. Contact your customer success manager if you'd like early access #### Fixes and Security Updates * **Security Updates**: Applied routine security patches and version updates to application frameworks to stay up-to-date with the latest improvements. * **Security Updates**: Applied routine security patches and version updates to application frameworks to stay up-to-date with the latest improvements. #### What's New and Improved * **Custom LLM Enrichment & Evaluations Enhancements** * *Improved Determinism:* Temperature parameter now defaults to 0 for classification use cases, ensuring more consistent and repeatable results * *Enhanced Flexibility:* The Evaluations endpoint now accepts a temperature parameter, matching the configuration options available in Enrichment * *Benefit:* Teams can achieve more predictable classification outputs while maintaining the flexibility to adjust temperature when needed for specific use cases * **Fiddler Fast Trust Faithfulness v2.4.1** * *Performance Boost:* Up to 150ms faster processing on longer input texts * *Benefit:* Reduced latency for faithfulness checks on documents and extended conversations, enabling more responsive LLM monitoring at scale * *Impact:* Particularly beneficial for applications processing lengthy contexts or high-volume document analysis workflows #### What's New and Improved * **Custom Webhook Support for Alert Notifications** * Extended webhook integration capabilities beyond Slack and Microsoft Teams to support any webhook provider * *Key Features:* * [Create custom webhook](/reference/administration/settings) configurations for any third-party service or internal system * Configure custom webhooks with alert rules for flexible notification routing * Maintain existing Slack and Microsoft Teams integrations alongside custom webhooks * *Benefit:* Organizations can now integrate Fiddler alerts with their preferred communication platforms and incident management systems * **Enhanced Data Ingestion Performance with ClickHouse Optimization** * *Performance Improvements include:* * End-to-end ingestion latency reduced by up to 10x for faster data processing * Label update operations now complete significantly faster * Event deletion performance dramatically improved * Enhanced ClickHouse storage efficiency and query performance * *Benefit:* Teams can now process and analyze data in near real-time, enabling faster decision-making and more responsive monitoring of production models #### Fixes and Security Updates * **Security Updates**: Applied routine security patches and version updates to application frameworks to stay up-to-date with the latest improvements. #### What's New and Improved * **Updated Fiddler Fast Trust Faithfulness Model** * *Classification Improvements:* * Improved accuracy on Q\&A and simple knowledge-retrieval tasks * Enhanced accuracy on Q\&A with longer contexts * Improved accuracy on "off-label" tasks like JSON-to-Text and Dialogue/Chat exchanges * *Performance Boost:* * 15-20% faster processing on longer contexts * **Enhanced Fiddler Fast Trust Safety Model** * Increased Safety model context window from 4,000 to 800,000 tokens * *Benefit:* Enables comprehensive safety analysis on much larger documents and conversations without truncation * **Multi-threading for Embedding Enrichment** * Implemented parallel processing for embedding generation * *Performance Impact:* At least a 5x improvement in processing speed for embedding enrichments * *Scalability:* Can achieve even greater performance with additional threads and resources * *Benefit:* Significantly reduces processing time for high-volume LLM monitoring pipelines * **Microsoft Teams Webhook Integration** * Added native support for Microsoft Teams webhook notifications alongside existing Slack integration * *Benefit:* Teams can now receive alert notifications directly in their Microsoft Teams channels * *How to use:* Configure Microsoft Teams webhooks in the Webhook Integrations tab of the [Settings](/reference/administration/settings) page * *Impact:* Streamlines communication workflows for organizations using Microsoft Teams as their primary collaboration platform #### Fixes and Security Updates * **Security Updates**: Applied routine security patches and version updates to application frameworks to stay up-to-date with the latest improvements. * **Security Updates**: Applied routine security patches and version updates to application frameworks to stay up-to-date with the latest improvements. **Documentation Updates** * **New Glossary Feature:** We've expanded our Product Concepts guide with a comprehensive [glossary](/glossary). Each term now has its own dedicated page containing: * Detailed explanations * Implementation guidance * Related resources and references This enhancement makes it easier to understand key product terminology and concepts while providing deeper technical context when needed. We'll continue to add new terms to the glossary incrementally over time. #### What's New and Improved * **Custom LLM Enrichment**: Leverage [Llama3.1 8B](https://huggingface.co/meta-llama/Llama-3.1-8B) to categorize input data using your own prompts and custom categories * *Benefit*: Enables flexible classification tasks tailored to your specific business needs, going beyond pre-defined enrichment types #### Fixes and Security Updates * **Security Updates**: Applied routine security patches and version updates to application frameworks to stay up-to-date with the latest improvements. #### Documentation Updates * **Removed Deployment Guide**: The Deployment Guide is no longer relevant to Fiddler SaaS and managed SaaS offerings. #### Improvements * **Baseline Name Length**: Increased the maximum allowed characters from 30 to 256. This change enables more descriptive baseline names for complex projects with multiple models and datasets. * *Action Required*: None. Existing baselines remain unchanged. * **Enhanced Job Error Messages**: Error messages during metrics aggregation now specifically identify which step in the data ingestion process failed, helping you troubleshoot pipeline issues faster. * *Benefit*: Reduces debugging time by pinpointing in which step jobs are failing. #### Fixes and Security Updates * **Security Updates**: Applied routine security patches to container images and application frameworks to address recent vulnerabilities. * **Homepage Cache Timestamp**: Fixed an issue where cached dashboard data would display incorrect "Last Updated" timestamps, leading to confusion about data freshness. #### Documentation Updates * **Streamlined Structure**: Reorganized documentation with improved navigation paths between related topics. * *New Section*: Consolidated technical guides and API references into the "Technical Reference" section. #### What's New and Improved #### Now Available in Public Preview * **UI-based Model Onboarding with Draft Mode**: Iteratively refine your model schema before publishing. Validate sample data, collaborate with your team, and deploy with confidence. This streamlines the model deployment process for faster time-to-value. See our new [Model Guides](/observability/model-ui) for details and best practices. #### Improvements * **Enhanced Charts Framework**: Implemented significant improvements to our charting system, delivering more consistent rendering and reliable performance across all dashboards and visualizations. * **Fast Faithfulness Trust Model Enhancements**: Improved classification accuracy overall by 23% and reduced the Q\&A benchmark error rate by 36%. #### Fixes and Security Updates * **Performance Optimization**: Updated application framework components to improve validation speed during model onboarding and data publishing processes. * **Enhanced Error Handling**: Redesigned validation messages during Baseline creation to provide more actionable and detailed troubleshooting guidance. * **Concurrency Improvements**: Optimized metrics calculation when model edits trigger recalculations, reducing processing time while preventing disruption to production data pipelines. #### Documentation Updates * **Streamlined Structure**: Merged the former UI Guide into the Product Guide for a more intuitive navigation experience. * **Expanded Content**: Added comprehensive data publishing guides with practical examples and best practices for various data types and formats. * **New UI Onboarding Guide**: Published detailed documentation for the new UI-based model onboarding feature, including step-by-step instructions and best practices. #### What's New and Improved **New Priority Queue for Streaming Data** We've added a dedicated queue for processing streaming inference data. This improvement gives streaming events priority handling compared to batch processing jobs. **Improvements** This release enhances the clarity of error messages when configuring different baseline types for a model. **How it helps you** * Faster processing times for streaming data * Reduced latency for real-time monitoring applications * No delays from large batch upload operations **How It Works** Streaming events now flow through a separate, high-priority processing lane—similar to an HOV lane on a highway—bypassing any congestion from batch operations. This feature works automatically with your existing implementation. No configuration changes required. #### What's New and Improved We have added Token Count as a new addition to Fiddler's out-of-the-box enrichments. Token count visibility is a key factor for monitoring and optimizing LLM applications. This enrichment is particularly useful for cost analysis, as it tracks API usage and helps teams understand the financial implications of their LLM usage. It also aids in identifying performance issues related to token limits and supports system health monitoring by detecting unusual patterns or truncated responses. Teams can use token metrics to optimize prompts for efficiency and quality while understanding usage patterns across their application. Combined with existing quality metrics, token counts offer a more complete view of LLM system performance and help teams make data-driven decisions about their prompt engineering and resource allocation. #### Client Version Python client version is updated to [3.8](/changelog/python-sdk) and includes new support for updating additional parameters of Alert rules, including `warning_threshold`, `critical_threshold`, and `evaluation_delay`. #### What's New and Improved **Introducing Fiddler Guardrails!** Fiddler AI has introduced Fiddler Guardrails, a new feature that extends the Fiddler Trust Service and is designed to enhance the safety and security of Large Language Model (LLM) applications. This tool proactively detects and mitigates risks such as hallucinations and prompt injection attacks, ensuring more reliable and trustworthy AI operations. Organizations can confidently deploy LLM applications with improved oversight and protection by integrating Fiddler Guardrails. You can see the full announcement [here](/changelog) for a comprehensive overview of this feature. **Improvements** This release includes updates focused on improving system performance, stability, and scalability. These improvements ensure a smoother user experience and provide a more robust platform for future developments. **Guardrails Endpoint Change** This release updates the following Guardrails REST API endpoints. The [Guardrails guide ](/getting-started/guardrails)provides detailed usage information. | Guardrail Service | Previous Endpoint | Current Endpoint | | ---------------------------- | --------------------------- | ------------------------- | | Fast Safety Guardrails | ftl\_prompt\_safety | ftl-safety | | Fast Faithfulness Guardrails | ftl\_response\_faithfulness | ftl-response-faithfulness | #### What's New and Improved Introducing **UI Model Onboarding**, a powerful new capability that enables teams to onboard models directly through the Fiddler user interface. This streamlined approach to model integration enhances the platform's accessibility while maintaining robust monitoring capabilities. Here's what this means for you: * Easy to use: We designed the Model Onboarding UI to be user-friendly, making it simple and intuitive to onboard your models. * More accessible: This new feature makes it easy to onboard your models even if you're not a Python expert. What can you do with it? * Onboard models for different tasks: Currently, it supports three model task types: Not Set, Regression, and Binary/Multiclass Classification. * Upload your data: Upload your sample data, and Fiddler will automatically try to understand its structure, saving you time from entering details manually. * Review and edit: You can quickly review and edit the data structure (schema) inferred by Fiddler. * Define targets: Specify the target variable that your model is designed to predict. * Provide model details: Give your model a name and other important information. This feature is currently in public preview which you can learn more about [here](/reference/feature-maturity-definitions#public-preview). We appreciate your feedback as we work to enhance the UI Model Onboarding experience. #### What's New and Improved We're excited to introduce three updates in this release that will significantly improve workflow efficiency. These updates include enhancements to alert notifications, schema management, and model onboarding workflows. * **Pause Alert Notifications** * Users can now pause and resume notifications for specific alert rules without interrupting their evaluation. This feature helps reduce alert fatigue and prioritize critical alerts. * Highlights: * New bell icon for toggling notification status directly from the alert rule table. * Notifications can be paused or resumed with clear visual feedback and confirmation messages. * Benefits: * Reduced alert fatigue. * Continued evaluation of paused alerts without disruption. * **Model Schema Editing (Private Preview)** * Say goodbye to re-onboarding models for schema updates! This feature allows users to edit numerical and categorical columns and add metadata columns directly within the platform. * Highlights: * Adjust numerical ranges and add new categories to categorical columns. * Add metadata columns for enhanced schema flexibility. * Automatic recalculation of metrics and aggregates after edits. * Benefits: * Faster schema updates with no re-onboarding required. * Keeps metrics and alerts in sync with the latest schema changes. * **UI-Based Model Onboarding (Private Preview)** * Simplify model onboarding with our new interactive UI. Add models without relying on Python APIs, making onboarding faster and more accessible to all team members. * Highlights: * Supports key task types: Not Set, Regression, and Binary Classification. * Automatic schema inference and validation with error detection. * Benefits: * Streamlines onboarding for non-technical users. * Reduces errors with built-in validation checks. **Private Preview** * The Model Schema Editing and UI-Based Model Onboarding features are available for private preview. For more details on how to participate, please refer to the private preview [guide](/reference/feature-maturity-definitions#private-preview). #### What's New and Improved * **Native Integration with AWS SageMaker AI** * Fiddler is now natively supported within the newly launched Amazon SageMaker partner AI ecosystem. This integration enables enterprises to validate, monitor, analyze, and improve their ML models in production, all within their existing private and secure Amazon SageMaker AI environment. Read the official announcement [here](https://www.fiddler.ai/blog/fiddler-delivers-native-enterprise-grade-ai-observability-to-amazon-sagemaker-ai-customers). Note Fiddler Python client version [3.7+](/changelog/python-sdk) is required for this feature. * **Download Dataset Code in UI** * Now you can download your baseline and non-production datasets faster than ever with just a click! Building on the popular feature we introduced for production data in the Root Cause Analysis Events table, we've added ready-to-use Python code snippets right in the interface. Simply copy and paste these snippets to jumpstart your data analysis in your notebooks. * **Python Client Highlights** * The latest release of Fiddler's Python client brings two powerful new convenience features to streamline your workflow: * Our new Project.get\_or\_create() class function simplifies project creation in notebooks. This feature prevents name conflict errors during project creation when your notebook runs multiple times, saving you time and reducing the need for additional exception handling. * We've also added model.remove\_column(), a simpler way to remove columns during model onboarding. This function replaces the multi-step process previously required, making model configuration faster and more intuitive. * To enhance reliability, we've implemented a configurable HTTP retry mechanism that you can fine-tune to match your network environment. * For more details, please refer to the [Python Client Release notes](/changelog/python-sdk). #### Discontinued * **The SQL Analyze Page Discontinued** * The legacy SQL Analyze page has been removed as of 24.18. The new Analyze experience within monitoring charts Root Cause Analysis now enables data table generation using Fiddler Query Language (FQL) and supports the creation of analytical charts such as confusion matrices, feature distribution charts, and more. #### Client Version Client version [3.7+](/changelog/python-sdk) is required for the updates and features mentioned in this release. #### What's New and Improved * **Feature Analytics in Root Cause Analysis (Public Preview)** * The root cause analysis experience within monitoring charts now allows users to view feature distribution, feature correlation, and correlation matrix. #### Discontinued * **SQL Methods in the Python Client Discontinued** * From Client 3.6 and onwards, `get_slice` and `download_slice` are discontinued. In their stead, use the new `download_data` method to download production and non-production data from your Fiddler models. If you have any questions or need any assistance migrating scripts using the deprecated methods, please contact your Fiddler customer success manager. * Use of or support for **Python 3.8 is discontinued** by Fiddler. Note Python 3.8 has been designated [End of Life](https://devguide.python.org/versions/) as of October 7, 2024. #### What's New and Improved * **New Chart Type: Correlation Matrix (Public Preview)** * The Correlation Matrix chart enables users to visualize relationships between up to eight columns in a heatmap, making it easy to spot significant patterns. By clicking on any cell representing the relationship between two features, users can open a Feature Correlation chart for that pair, offering more detailed insights into the correlation score. * **Events Table in Root Cause Analysis (Public Preview)** * The root cause analysis experience within monitoring charts now allows users to perform deeper investigations by viewing and downloading up to 1,000 raw events, providing valuable insights for understanding and addressing potential issues. #### What's New and Improved * **New Chart Type: Metric Card (Public Preview)** * We’re excited to introduce the Metric Card chart type, which allows users to display up to four key numerical values in a clear and concise card format. This new visualization enhances data presentation by enabling quick insights into critical metrics, making it easier for decision-makers to spot trends or performance indicators at a glance. * **New Chart Type: Feature Correlation (Public Preview)** * The Feature Correlation chart, part of Feature Analytics charts, enables users to analyze and visualize the relationships between different features within their models. By offering a clear view of correlations, this tool supports more informed model diagnostics and refinement. #### What's New and Improved * This release focused on system performance, stability, and security enhancements. These improvements ensure a smoother user experience and provide a more robust platform for future developments. #### What's New and Improved * NEW Standalone Feature Distribution Chart (Public Preview) * Create feature distribution charts for numerical and categorical data types that can be added to dashboards. * Embedding Visualization UX Improvements * User interface and usability improvements to the UMAP embedding visualization chart. * Additional database performance improvements. #### Deprecated and Decommissioned * Fairness was decommissioned in v24.8, and the documentation has now been removed. * Surfacing Error Messages for Failed Jobs * Error messages for failed jobs are now visible directly on the UI job status page, simplifying the process of diagnosing and resolving issues. * User Selected Default Dashboards * Any dashboard within a project can now be assigned as the default dashboard for a model, with all insights leading directly to the assigned default dashboard. * Custom Feature Impact Feature Release Notes * Introducing Custom Feature Impact: Upload custom feature impact scores for your models, leveraging domain-specific knowledge or external data without requiring the corresponding model artifact. * Easy data upload via API endpoint with required parameters: Model UUID, Feature Names, and Impact Scores. * View updated feature impact scores in: * Model details page * Charts page * Explain page * Flexible update options: Update existing feature impact data by uploading new data for the same model and Seamless integration with existing model artifacts. * Flexible Model Deployment * The `python-38` base image is no longer supported. #### Client Version Client version 3.3+ is required for the updates and features mentioned in this release. #### What's New and Improved * Performance Analytics (Preview) Embedded in Monitoring Charts * Visualize performance analytics charts as part of the root cause analysis flow for Binary Classification, Multiclass Classification, and Regression models, spanning from confusion matrices, precision recall charts, prediction scatterplots and more. #### Client Version Client version 3.3+ is required for the updates and features mentioned in this release. #### What's New and Improved * Support for applied segments in monitoring charts * Create and apply segments dynamically in monitoring charts for exploratory analysis without requiring them to be saved to the model. * User-Defined Feature Impact * The User-Defined Feature Impact enables you to upload custom feature impact for models. This feature addresses several issues reported by our customers, including model artifact size, onboarding complexity, and the need for custom feature impact. * Key highlights * New method: UploadFeatureImpact * Improved Fiddler UI to display uploaded feature impact #### What's New and Improved * Enhanced access controls * Control access with precision: Manage user access to resources with Role-Based Access Control (RBAC), ensuring the right users have the right permissions. * Simplify user management: Assign roles to users and teams to streamline access control and enhance collaboration. \*≠ Protect sensitive resources: Restrict access to sensitive resources, such as models and project settings, with granular permissions. * Work efficiently: Focus on your work without worrying about unauthorized access or data breaches. #### Release of Fiddler Platform Version 24.8 * **Performance Analytics Charts (Public Preview)** * Visualize charts to aid in analyzing model performance for Binary Classification, Multiclass Classification, and Regression models. * Leverage applied segments in Performance Analytics charts to explore problematic cohorts of data. #### What's New and Improved TBD #### Release of Fiddler Platform Version 24.6 * Performance improvements * Improved the performance of various modules / APIs. * Improved observability which can help monitor health and performance of the operations. #### Client Version * Client version 3.1.2+ is required for the updates and features mentioned in this release. #### Release of Fiddler Platform Version 24.5 * Support for model versions for streamlined model management #### What's New and Improved * **Model Versions** * Efficiently manage related models by creating structured versions, facilitating tasks like retraining and comparison analyses. * Users can maintain model lineage, efficiently manage updates, flexibly modify schemas, and adjust parameters. * **Airgapped Enrichments (alpha)** * For privacy sensitive use cases, all data getting enriched stays within customer premises. * **New Deployment Base Images** * We have added new deployment base images to support model versioning. **Client Version** Client version 3.1.0+ is required for the updates and features mentioned in this release. #### Release of Fiddler Platform Version 24.4 * UMAP UI changes * SSO integration changes * New concept: **Environments** * Fundamental changes to product concepts #### What's New and Improved * **UMAP UI** * Vertical scrolling instead of horizontal scrolling for data cards * "View More" option to open data cards in maximized modal * Ability to toggle between data cards in the maximized modal * **SSO integration changes** * Fiddler now integrates with Azure AD SSO, allowing you to leverage existing user roles for access control within Fiddler. This eliminates the need for manual user creation and simplifies user management within your organization. * **Environments** * Each Model now has two environments (Pre-Production and Production) used to house data in different ways. * A Model's Pre-Production environment is used to house non-time series data (Datasets). * A Model's Production environment is used to house time series data. * **Product concept changes** * Datasets are no longer stored at the Project level. Instead, they're stored at the Model level under the Pre-Production Environment. * The Model Details page has been updated with a new design. **Client Version** Client version 3.0+ is required for the updates and features mentioned in this release. #### Client 3.x Release We are launching Client 3.x, this is revamped client 2.x as we move to more object-oriented based methods. This means, any pipeline setup in client 2.x would eventually be required to upgrade to the new methods. **Client 2.x will sunset approximately 6 months post this release.** #### Deprecations and Removals * All IDs will be UUIDs instead of strings. * Dataset deletion is not allowed anymore. For API level changes and updates please check [client history](/changelog/python-sdk) # Python Client SDK Source: https://docs.fiddler.ai/changelog/python-sdk Fiddler's Python client history reference. Contains Python client release highlights, client deprecation notices, and more. [![PyPI](https://img.shields.io/pypi/v/fiddler-client)](https://pypi.org/project/fiddler-client/) ## 3.13 * **New Features** * Added `Model.delete_events()` to delete published production events for a model. Wraps the [Delete Events REST API](/sdk-api/rest-api/events/delete-events) (`DELETE /v3/events`); deletion runs asynchronously and returns a `Job`. * **Select events** by a time range or an explicit list of event IDs (the two are mutually exclusive): * `start_time` / `end_time` — must be provided together. They accept a timezone-aware `datetime` or an ISO 8601 string with an explicit offset (e.g., `'2025-11-17T01:00:00Z'`); non-UTC values are normalized to UTC, and naive datetimes are rejected. * `event_ids` — up to 10,000 IDs per call. * `update_metrics` (default `False`) — whether the server recomputes metrics after deletion. Applies to time-range deletions only. * **Safety guards**: a call with no filter is rejected (to avoid deleting all events for a model), both time bounds are required together, and providing more than 10,000 `event_ids` is rejected. ```python theme={null} job = model.delete_events( start_time='2025-11-17T01:00:00.000Z', end_time='2025-11-17T02:00:00.000Z', update_metrics=True, ) job.wait() # Or delete specific events by ID job = model.delete_events(event_ids=['pred_001', 'pred_002']) job.wait() ``` ## 3.12 * **New Features** * `Model.update()` now supports updating column schema properties (bins, min, max, categories) on existing models * Set custom histogram bins: `model.schema["column"].bins = [...]; model.update()` * Update value ranges: `model.schema["column"].min = value; model.update()` * Update categories: `model.schema["column"].categories = [...]; model.update()` * Added explicit `Model.publish_stream()` and `Model.publish_batch()` methods for publishing inference data * `publish_stream(events=...)` publishes streaming/live events (a list of event dicts) * `publish_batch(source=...)` publishes a batch from a Parquet/CSV file path or a pandas DataFrame * Both accept `update=True` to update previously published events * **Deprecations** * `Model.publish()` is deprecated and now emits a `DeprecationWarning`. Its implicit dispatch is replaced by the explicit `publish_stream()` (streaming events) and `publish_batch()` (batch files and DataFrames) methods. See [Publishing production data](/developers/client-library-reference/publishing-production-data). * **Dependencies & Python Support** * **Migrated to Pydantic v2** (`pydantic>=2.0`, previously `pydantic>=1.10`). Environments pinned to Pydantic v1 must upgrade to v2. * Added support for **Python 3.13 and 3.14** (enabled by the Pydantic v2 migration). * Bumped `pandas>=2.1.0` (previously `>=1.2.5`) and `pyarrow>=17.0.0` (previously `>=15.0.0`); `pip` is no longer a runtime dependency. ## 3.11 * **New Features** * Added `Model.add_column()` method to dynamically add columns to existing model schemas after initial onboarding. Supports adding input features, outputs, targets, and metadata columns. * **Parameters**: * `column` (Column): The column definition to add to the model * `column_type` (str): Type of column - one of 'inputs', 'outputs', 'targets', or 'metadata' (default) * **Important**: New columns have null values for historical events; future events must include the new column * **Validation**: Prevents duplicate column names (raises ValueError) * **New Features** * Added a helper function `create_columns_from_df` to create a `ModelSchema` from a pandas `Dataframe`. * **New Features** * Added ability to specify `auto_threshold_params` while creating/updating alert rules. * **Modifications** * Updated minimum required version of pyarrow from 'pyarrow>=7.0.0' to 'pyarrow>=15.0.0' to address potential security issues from CVE-2025-30065. * **New Features** * Added the ability to create and use Microsoft Teams Webhooks. * **Bug Fixes** * Fixed pydantic validation error for `Webhook` object. * **Modifications** * Improved log message for timeout failure on how timeout can be increased. * **Bug Fixes** * Added missing support for specifying `category` while creating Alert Rule. * **New Features** * Added a new `update` method to the `AlertRule` object, allowing updates to the following fields: `warning_threshold`, `critical_threshold`, and `evaluation_delay`. * Added ability to create alert rules with Fiddler-determined automatic thresholds. * **Modifications** * **Project Deletion Uses v3 API**: * `project.delete()` now utilizes the v3 API for deleting projects. * The method signature remains unchanged. * **Modifications** * **Connection Timeout Settings**: You can now configure network timeout settings when [initializing](/developers/python-client-guides/installation-and-setup) the Python client. The new timeout parameter in init() accepts: * A single number (in seconds) to set the connection timeout * A tuple of two numbers (in seconds) to set both connection and read timeouts separately Release highlights: * **Robustness via retrying**: this release introduces a persistent HTTP request retrying strategy to enhance fault tolerance in view of transient network problems and retryable HTTP request errors. You can take control of the maximum duration for which an HTTP request is retried by setting the environment variable `FIDDLER_CLIENT_RETRY_MAX_DURATION_SECONDS`. * **AWS SageMaker authentication support**: to enable that, install version 2.236.0+ of the [AWS Python SageMaker SDK](https://pypi.org/project/sagemaker/). Then, before calling `init()`, set the environment variable `AWS_PARTNER_APP_AUTH` to `true` and set `AWS_PARTNER_APP_ARN`/`AWS_PARTNER_APP_URL` to meaningful values. * **Logging improvements**: messages are now emitted to `stderr` instead of `stdout`. Only if the calling context does not configure a root logger this library will actively declare a handler for its own log messages (this automation can be disabled by setting `auto_attach_log_handler=False` during `init()`). Compatibility changes: * Pydantic 2.x is now supported (and compatibility with Pydantic 1.x has been retained). * Support for Python 3.8 has been dropped. API surface additions: * Introduced `Project.get_or_create()` to reduce code required for instantiating a project. * Introduced `model.remove_column()` to allow for removing a column from a model object. Fixes: * A transient error during a job status update does not prematurely terminate waiting for a job anymore. * GET requests do not contain the `Content-Type` header anymore. * **Removed** * The `get_slice` and `download_slice` methods are removed. Please use `download_data` to retrieve some data. * The `get_mutual_info` method is removed. * The `SqlSliceQueryDataSource` option is removed from explain, feature impact and importance. Please use the `DatasetDataSource` instead or the UI. * **New Features** * New `download_data` method, to download a slice of data given an environment, time range and segment. Resulted file can be downloaded either as a CSV or a Parquet file. * **Removed** * The `get_fairness` method is removed. Please use charts and custom metrics to track / compute fairness metrics on your model. * **Modifications** * Fixed the error while setting notification config for alert rule. * **Modifications** * Added validation while adding notifications to alert rules. * Upgraded dependencies to resolve known vulnerabilities - deepdiff, mypy, pytest, pytest-mock, python-decouple, types-requests and types-simplejson. * **New Features** * Introduced `upload_feature_impact()` method to upload or update feature impact manually. * **New Features** * Introduced evaluation delay in Alerts Rule. * Optional `evaluation_delay` parameter added to `AlertRule.__init__` method. * It is used to introduce a delay in the evaluation of the alert. * **Modifications** * Fix windows file permission error bug with publish method. * **Modifications** * Adds support to get schema of Column object by `fdl.Column` * **Modifications** * Updated `pydantic` and `typing-extensions` dependencies to support Python 3.12. * **New Features** * Introduced the native support for model versions. * Optional `version` parameter added to `Model`, `Model.from_data`, `Model.from_name` methods. * New `duplicate()` method to seamlessly create new version from existing model. * Optional `name` parameter added to `Model.list` to offer the ability to list all the versions of a model. * **New Features** * Allowed usage of `group_by()` to form the grouped data for ranking models. * **Modifications** * Return Job in ModelDeployment update. * **New Features** * Added `Webhook.from_name()` * **Modifications** * Import path fix for packtools. * **Modifications** * Fix pydantic issue with typing-extensions versions > 4.5.0 * **New Features** * General * Moving all functions of client to an Object oriented approach * Methods return resource object or a deserialized object wherever possible. * Support to search model, project, dataset, baselines by their names using `from_name()` method. * List methods will return iterator which handles pagination internally. * Data * Concept of environments was introduced. * Ability to download slice data to a parquet file. * Publish dataframe as stream instead of batch. * New methods for baselines. * Multiple datasets can be added to a single model. Ability to choose which dataset to use for computing feature impact / importance, surrogate generation etc. * Model can be added without dataset. * Ability to generate schema for a model. * Model delete is async and returns job details. * Added cached properties for `model`: `datasets`, `model_deployment`. * Alerts * New methods for alerts: `enable_notification`, `disable_notification`, `set_notification_config` and `get_notification_config`. * Explainability * New methods in explainability: `precompute_feature_impact`, `precompute_feature_importance`, `get_precomputed_feature_importance`, `get_precomputed_feature_impact`, `precompute_predictions`. * Decoupled model artifact / surrogate upload and feature impact / importance pre-computation. * **Modifications** * All IDs will be UUIDs instead of strings * Dataset delete is not allowed anymore # Fiddler Strands Agent SDK Source: https://docs.fiddler.ai/changelog/strands-sdk Fiddler's Strands Agent SDK release history. Contains Strands Agent SDK release highlights, SDK deprecation notices, and more. [![PyPI](https://img.shields.io/pypi/v/fiddler-strands)](https://pypi.org/project/fiddler-strands/) ## 0.6 * **New Features** * **`clear_llm_context()` function**: New convenience function to explicitly remove LLM context from a `Model` instance, preventing faithfulness evaluation on subsequent non-RAG spans. In multi-step agent workflows, context set after a RAG retrieval step previously leaked into later non-RAG LLM calls (tool planning, routing, etc.), causing unintended faithfulness evaluation. `set_llm_context(model, None)` also now clears context. * **Python 3.14 support**: Added Python 3.14 to the CI test matrix and PyPI classifiers. All runtime dependencies have compatible wheels. * **Fiddler attributes bridged to Strands `trace_attributes`**: Custom span and session attributes set via `set_span_attributes()` and `set_session_attributes()` are now bridged to Strands' native `trace_attributes` mechanism, enabling propagation through the Strands telemetry pipeline without custom hook plumbing for every span type. * **Changes** * **`strands-agents` floor bumped from `>=1.10.0` to `>=1.19.0`**: Required to align with the Strands telemetry features the SDK now consumes. Users on Strands `1.10.x`–`1.18.x` must upgrade to at least `strands-agents 1.19.0`. * **Extended `strands-agents` upper bound to `<=1.33.0`**: Tested compatibility extended to support newer Strands releases. * Bumps `fiddler-otel` dependency to `1.1.1` (gains `add_session_attributes()` support for all OTel primitive value types — `str`, `bool`, `int`, `float`, and homogeneous sequences — previously restricted to `str`). * **Bug Fixes** * **Defensive guard for `trace_attributes` access**: Added a defensive check before accessing `trace_attributes` to prevent attribute errors when bridging Fiddler attributes to Strands telemetry on agents that have not yet initialized the field. ## 0.5 * **Initial PyPI Release** * First version-tagged build of `fiddler-strands` published to PyPI from the consolidated `fiddler-sdk` monorepo (`pip install fiddler-strands`). * Includes all functionality from the 0.4.0 development build (auto-instrumentation, conversation tracking, session and span attributes, LLM context management, and tool-definition tracing). Version 0.4.0 was never published to PyPI. ## 0.4 * **Enhancements** * **Tool Definition Tracing**: Added `gen_ai.tool.definitions` span attribute to all child spans, providing visibility into tool schemas within agent traces. * **Enhancements** * **API Export Fix**: Added `get_llm_context` to module exports — previously available but not importable from the top-level package. * **Documentation**: Added comprehensive docstrings to all critical public APIs to support automatic documentation generation. * **Examples**: Fixed missing example dependencies and Fiddler configuration setup. * **Enhancements** * **LLM Context Management**: New `set_llm_context()` and `get_llm_context()` functions for setting additional context for LLM processing within Strands agent workflows. * **System Prompt Telemetry**: System prompts are now included as part of telemetry events for backend processing. * **Initial Release** * Core `StrandsAgentInstrumentor` with `instrument()` and `uninstrument()` for automatic OpenTelemetry instrumentation of Strands agents. * **Conversation Tracking**: `set_conversation_id()` and `get_conversation_id()` for multi-turn conversation tracking. * **Session Attributes**: `set_session_attributes()` and `get_session_attributes()` for adding custom metadata to trace sessions. * **Span Attributes**: `set_span_attributes()` and `get_span_attributes()` for adding custom metadata to individual spans. * Available as `pip install fiddler-strands`. # RAG Health Diagnostics Source: https://docs.fiddler.ai/concepts/rag-health-diagnostics Understand how RAG Health Metrics diagnose Retrieval-Augmented Generation pipeline failures using Answer Relevance, Context Relevance, and RAG Faithfulness evaluators. ## The RAG Debugging Challenge Retrieval-Augmented Generation (RAG) applications fail in specific ways that generic metrics cannot diagnose. When a RAG system produces a poor response, the failure could originate in any of three stages: 1. **Retrieval** — The system retrieved irrelevant or insufficient documents 2. **Generation** — The LLM generated content not grounded in the retrieved documents 3. **Query understanding** — The response doesn't address what the user actually asked Without targeted diagnostics, debugging RAG failures is manual trial-and-error — inspecting retrieved documents, re-running queries, and guessing where the pipeline broke. RAG Health Metrics transforms this into targeted root cause analysis. ## The RAG Health Metrics Triad RAG Health Metrics is a purpose-built diagnostic framework consisting of three evaluators that work together to pinpoint exactly where RAG pipelines fail: | Evaluator | What It Measures | Scoring | Inputs | | ------------------------ | ---------------------------------------------------- | ----------------------------------- | --------------------------------------------------------------- | | **Answer Relevance 2.0** | Does the response address the user's query? | High (1.0), Medium (0.5), Low (0.0) | `user_query`, `rag_response` (+ optional `retrieved_documents`) | | **Context Relevance** | Are the retrieved documents relevant to the query? | High (1.0), Medium (0.5), Low (0.0) | `user_query`, `retrieved_documents` | | **RAG Faithfulness** | Is the response grounded in the retrieved documents? | Yes (1.0) / No (0.0) | `user_query`, `rag_response`, `retrieved_documents` | All three evaluators return detailed `reasoning` explaining the score, enabling you to understand not just *what* failed but *why*. ### Availability | Evaluator | Agentic Monitoring | Experiments | LLM Observability | | -------------------- | ------------------ | ----------- | ----------------- | | Answer Relevance 2.0 | Yes | Yes | Yes | | Context Relevance | Yes | Yes | **No** | | RAG Faithfulness | Yes | Yes | Yes | **Context Relevance** is available in Agentic Monitoring and Experiments only. It is not available in LLM Observability. ## Diagnostic Workflow Use the three evaluators together to diagnose specific failure modes in your RAG pipeline: | What the metrics tell you | Why it's happening | Next Step | | --------------------------------- | ------------------------------------- | ------------------------------------------------ | | High relevance + Low faithfulness | Hallucinations despite being on-topic | Check if retrieval provided sufficient grounding | | High faithfulness + Low relevance | Grounded but didn't answer the query | Check if retrieval provided relevant information | | Low Context Relevance | Retrieval pulling wrong documents | Fix retrieval mechanism | ### Scenario 1: Hallucination (High Relevance, Low Faithfulness) The response addresses the user's question (high Answer Relevance) but includes claims not supported by the retrieved documents (low RAG Faithfulness). This indicates the LLM is generating plausible-sounding content rather than grounding its response in the provided context. **Root cause:** Generation layer — the LLM is not sufficiently constrained by the retrieved documents. **Actions to investigate:** * Review the system prompt — does it instruct the LLM to only use provided context? * Check if the retrieved documents contain enough detail to answer the question * Consider adding explicit grounding instructions to the prompt ### Scenario 2: Off-Topic Response (Low Relevance, High Faithfulness) The response accurately reflects the retrieved documents (high RAG Faithfulness) but doesn't answer what the user asked (low Answer Relevance). The LLM faithfully summarized the wrong information. **Root cause:** Retrieval layer — the retrieved documents are relevant enough to generate a response, but don't contain the information needed to answer the specific query. **Actions to investigate:** * Review the retrieval query — is it capturing the user's intent? * Check if the knowledge base contains the needed information * Consider improving query expansion or embedding quality ### Scenario 3: Bad Retrieval (Low Context Relevance) The retrieved documents are not relevant to the user's query at all (low Context Relevance). Downstream evaluators may score unpredictably because the entire pipeline is working with the wrong source material. **Root cause:** Retrieval mechanism — the vector search, keyword matching, or hybrid retrieval is pulling wrong documents. **Actions to investigate:** * Review the embedding model — does it capture semantic similarity for your domain? * Check chunking strategy — are documents split at appropriate boundaries? * Examine the retrieval query formulation — is the user's intent preserved? * Consider re-indexing with a domain-adapted embedding model ## Using RAG Health Metrics ### In Experiments (Evals SDK) Evaluate RAG pipelines systematically against test datasets: ```python theme={null} from fiddler_evals import evaluate from fiddler_evals.evaluators import AnswerRelevance, ContextRelevance, RAGFaithfulness evaluators = [ AnswerRelevance(model="openai/gpt-4o", credential="your-llm-credential"), # Is the response relevant? (High/Medium/Low) ContextRelevance(model="openai/gpt-4o", credential="your-llm-credential"), # Are retrieved docs relevant? (High/Medium/Low) RAGFaithfulness(model="openai/gpt-4o", credential="your-llm-credential"), # Is the response grounded? (Yes/No) ] results = evaluate( dataset=dataset, task=my_rag_task, evaluators=evaluators, score_fn_kwargs_mapping={ "user_query": lambda x: x["inputs"]["user_query"], "rag_response": "rag_response", "retrieved_documents": lambda x: x["inputs"]["retrieved_documents"], } ) ``` ### In Agentic Monitoring Configure Evaluator Rules to continuously evaluate production RAG spans. Navigate to your application's **Evaluator Rules** tab and add rules for Answer Relevance, Context Relevance, and RAG Faithfulness. Map the evaluator inputs to your span attributes. See [Evaluator Rules](/evaluate-and-test/evaluator-rules) for step-by-step configuration instructions. ## RAG Faithfulness vs Faithfulness (Centor Model) Fiddler provides two separate faithfulness evaluators with different architectures: | Feature | RAG Faithfulness | Faithfulness (Centor Model) | | ---------------------------- | --------------------------------------------------- | ------------------------------------------------------- | | **Type** | LLM-as-a-Judge | Centor Model for Faithfulness | | **Class** | `RAGFaithfulness` | `FTLResponseFaithfulness` | | **Inputs** | `user_query`, `rag_response`, `retrieved_documents` | `context`, `response` | | **Outputs** | `label` (yes/no), `value` (1/0), `reasoning` | `faithful_prob` (0.0–1.0) | | **Best for** | RAG pipeline diagnostics, comprehensive evaluation | Guardrails, real-time monitoring, low-latency use cases | | **Part of RAG Health triad** | Yes | No | Choose RAG Faithfulness when you need detailed reasoning and diagnostic context as part of the RAG Health Metrics triad. Choose Faithfulness (Centor Model) when you need sub-100ms latency for production guardrails. ## Complementary Metrics RAG Health Metrics works alongside Fiddler's existing 80+ LLM metrics. RAG systems fail in specific ways that generic metrics cannot diagnose — RAG Health Metrics provides the targeted diagnostics, while metrics like toxicity, PII detection, coherence, and sentiment provide complementary quality and safety coverage. ## Next Steps * [RAG Health Metrics Tutorial](/developers/tutorials/experiments/rag-health-metrics-tutorial) — End-to-end hands-on guide * [Experiments Getting Started](/getting-started/experiments#rag-system-evaluation) — RAG evaluation use case * [Evaluator Rules](/evaluate-and-test/evaluator-rules) — Configure production monitoring # Semantic Mappings Source: https://docs.fiddler.ai/concepts/semantic-mappings How Fiddler maps raw OTel attribute keys to canonical semantic concepts for cross-framework analytics, alerts, and dashboards ## Overview Fiddler ingests OpenTelemetry traces from a wide range of AI frameworks and SDKs — OTel [GenAI Semantic Conventions](https://github.com/open-telemetry/semantic-conventions-genai), OpenInference (LlamaIndex, LangChain), Vercel AI SDK, Claude Code, LiteLLM, Langfuse, and many more. Each framework uses its own attribute key names for the same underlying concept. For example, the number of input tokens might be sent as `gen_ai.usage.input_tokens` by one framework, `llm.token_count.prompt` by another, and `ai.usage.promptTokens` by a third. Server-side semantic mappings solve this problem by associating each raw attribute key with a canonical **semantic concept** — a framework-agnostic name like `input_tokens`, `model_name`, or `input`. This enables Fiddler's dashboards, alerts, custom metrics, and evaluators to work consistently across all frameworks without requiring per-framework instrumentation (client-side). ## How It Works When your application sends OpenTelemetry traces to Fiddler, the raw attribute keys are stored exactly as sent — Fiddler does not transform or rename them. In the backend, Fiddler enables you to map each attribute key to a semantic concept, producing a canonical name alongside the original key. All downstream features — monitoring charts, alert rules, custom metrics, evaluator input configuration, and the Explorer — use the semantic concept for queries. This means a dashboard showing "average input tokens over time" works identically whether your application uses the OTel GenAI convention (`gen_ai.usage.input_tokens`), the OpenInference convention (`llm.token_count.prompt`), or any other supported framework's naming. Custom attributes that don't map to any semantic concept are still stored and queryable by their original key name. Semantic mapping only applies to attributes that Fiddler recognizes as carrying a known concept. ## Semantic Concepts Fiddler defines over 30 semantic concepts, organized into the following categories. ### Token Usage | Concept | Description | | ----------------------------- | ---------------------------------------------- | | `input_tokens` | Number of tokens in the input/prompt | | `output_tokens` | Number of tokens in the output/completion | | `total_tokens` | Total token count (input + output) | | `cache_read_input_tokens` | Cached input tokens read (Claude, GPT caching) | | `cache_creation_input_tokens` | Cached input tokens created | | `reasoning_tokens` | Reasoning tokens (o1/o3 models) | ### Cost (Estimated) | Concept | Description | | ------------- | ---------------------- | | `total_cost` | Total LLM usage cost | | `input_cost` | Input/prompt cost | | `output_cost` | Output/completion cost | ### Model and Provider | Concept | Description | | --------------- | --------------------------------------------------------- | | `model_name` | LLM model identifier (e.g., `gpt-4.1`, `claude-sonnet-4`) | | `provider_name` | LLM provider identifier (e.g., `openai`, `anthropic`) | ### Agent and Tool | Concept | Description | | ------------------- | -------------------------------- | | `agent_name` | Agent name | | `agent_id` | Agent identifier | | `agent_description` | Agent description | | `tool_name` | Tool/function name | | `tool_id` | Tool call identifier | | `tool_type` | Tool type or category | | `tool_definitions` | Tool/function schema definitions | ### Session and User | Concept | Description | | ------------ | ---------------------------------- | | `session_id` | Conversation or session identifier | | `user_id` | End-user identifier | ### Content | Concept | Description | | --------------------- | ---------------------------------- | | `input` | LLM prompt or user input content | | `output` | LLM completion or response content | | `system_instructions` | System prompt or instructions | | `retrieval_context` | RAG retrieval context | | `tool_input` | Tool call arguments | | `tool_output` | Tool call results | ### Performance | Concept | Description | | --------- | ------------------- | | `latency` | Span duration | | `ttft` | Time to first token | ### Span Identity | Concept | Description | | ----------- | --------------------------------------------------------- | | `span_name` | Span name | | `span_type` | Span type or kind (e.g., `llm`, `tool`, `agent`, `chain`) | ### Metadata | Concept | Description | | --------------- | ----------------------- | | `received_time` | Ingestion timestamp | | `request_id` | LLM request identifier | | `response_id` | LLM response identifier | | `finish_reason` | LLM stop/finish reason | ## Default Mappings Fiddler ships with **over 140+ pre-configured mappings** covering a dozen AI frameworks and SDKs. If your application uses any of the following frameworks, traces are automatically mapped to semantic concepts with no configuration required: * **OTel GenAI Semantic Conventions** — the standard OpenTelemetry conventions for generative AI (`gen_ai.usage.*`, `gen_ai.request.*`, `gen_ai.response.*`) * **OpenInference** — used by LlamaIndex, LangChain, and other frameworks (`llm.token_count.*`, `input.value`, `output.value`) * **Vercel AI SDK** — (`ai.usage.*`, `ai.prompt`, `ai.response.*`) * **Claude Code** — (`input_tokens`, `output_tokens`, `user_prompt`, `model`) * **LiteLLM** — (`gen_ai.cost.*`) * **Langfuse SDK** — (`langfuse.session.id`, `langfuse.user.id`) * **Google Agent Development Kit (ADK, part of Gemini Enterprise Agent Platform)** — (`gcp.vertex.agent.*`) * **LiveKit** — (`lk.input_text`, `lk.response.text`) * **Genkit** — (`genkit:input`, `genkit:output`) * **MLflow** — (`mlflow.spanInputs`, `mlflow.spanOutputs`) * **Traceloop / OpenLLMetry** — (`traceloop.entity.input`, `traceloop.entity.output`) Many semantic concepts are mapped from multiple frameworks. For example, the `input` concept is mapped from over a dozen different attribute keys across all supported frameworks, so Fiddler can display user prompts regardless of which SDK generated the trace. ## When to Add Custom Mappings The default mappings cover most common frameworks. You may need to add custom mappings when: * **Using a framework not in the default list** — if your application uses an AI framework or SDK that Fiddler doesn't ship mappings for, you can add mappings for that framework's attribute keys. * **Custom instrumentation** — if your application uses proprietary or internal attribute key names that differ from standard OTel conventions. * **Internal naming conventions** — if your organization has adopted non-standard attribute key naming that you want Fiddler to recognize. For example, if your application sends `my_framework.prompt_tokens` for input token counts, you can create a mapping from `my_framework.prompt_tokens` to the `input_tokens` semantic concept. After the mapping propagates, all charts, alerts, and metrics that use `input_tokens` will include data from this key. ## Span Types ### Why span type mapping is needed Each AI framework labels span operations differently. OTel GenAI uses `gen_ai.operation.name` with values like `chat` and `completion`. OpenInference uses `openinference.span.kind` with values like `LLM` and `RETRIEVER`. Vercel AI SDK uses `ai.operationId` with values like `ai.generateText`. Langfuse uses `langfuse.observation.type` with values like `generation`. Without normalization, filtering for "all LLM calls" or "all tool executions" in Fiddler would require knowing every framework's convention. Fiddler resolves this by automatically normalizing raw span type values into a set of canonical types. When a span is ingested, Fiddler checks its attributes for known span type keys (determined by the semantic mapping for the `span_type` concept), extracts the raw value, lowercases it, and maps it to a canonical type. ### Canonical span types Fiddler recognizes 10 canonical span types: | Type | Description | | ----------- | ------------------------------------------------------- | | `llm` | LLM inference calls (chat completions, text generation) | | `tool` | Tool or function executions | | `agent` | Agent invocations | | `chain` | Chain or pipeline steps | | `embedding` | Embedding operations | | `retriever` | Retrieval operations (RAG) | | `reranker` | Reranking operations | | `guardrail` | Guardrail checks | | `evaluator` | Evaluator runs | | `span` | Generic span (default for unrecognized values) | ### How span type is inferred Fiddler checks the following attribute keys to find the span type value: | Attribute Key | Framework | | --------------------------- | ------------------------------------- | | `span_type` | Generic / direct | | `span.type` | Claude Code | | `fiddler.span.type` | Fiddler legacy | | `openinference.span.kind` | OpenInference (LlamaIndex, LangChain) | | `langfuse.observation.type` | Langfuse SDK | | `gen_ai.operation.name` | OTel GenAI, LiteLLM, Strands | | `ai.operationId` | Vercel AI SDK | | `genkit:metadata:subtype` | Genkit | Once a raw value is found, it is lowercased and mapped to a canonical type using the table below. If the raw value is not recognized, the span type defaults to `span`. ### Recognized raw values The following table lists all recognized raw values and the canonical span type they map to. Raw values are case-insensitive (lowercased before lookup). #### Identity values These are already canonical and map directly: | Raw Value | Span Type | | ----------- | ----------- | | `llm` | `llm` | | `tool` | `tool` | | `agent` | `agent` | | `chain` | `chain` | | `embedding` | `embedding` | | `retriever` | `retriever` | | `reranker` | `reranker` | | `guardrail` | `guardrail` | | `evaluator` | `evaluator` | | `span` | `span` | #### OpenInference | Raw Value | Span Type | | --------- | --------- | | `UNKNOWN` | `span` | | `PROMPT` | `span` | All other uppercase OpenInference values (`LLM`, `TOOL`, `AGENT`, `CHAIN`, `EMBEDDING`, `RETRIEVER`, `RERANKER`, `GUARDRAIL`) are lowercased and match the identity values above. #### Claude Code | Raw Value | Span Type | | ---------------------- | --------- | | `interaction` | `agent` | | `llm_request` | `llm` | | `tool.blocked_on_user` | `chain` | | `tool.execution` | `chain` | #### Langfuse | Raw Value | Span Type | | ------------ | --------- | | `generation` | `llm` | | `event` | `span` | #### OTel GenAI / LiteLLM / Strands | Raw Value | Span Type | | -------------------------- | ----------- | | `chat` | `llm` | | `completion` | `llm` | | `acompletion` | `llm` | | `text_completion` | `llm` | | `atext_completion` | `llm` | | `responses` | `llm` | | `aresponses` | `llm` | | `_aresponses_websocket` | `llm` | | `anthropic_messages` | `llm` | | `generate_content` | `llm` | | `agenerate_content` | `llm` | | `generate_content_stream` | `llm` | | `agenerate_content_stream` | `llm` | | `generate` | `llm` | | `execute_tool` | `tool` | | `invoke_agent` | `agent` | | `create_agent` | `agent` | | `embeddings` | `embedding` | | `aembedding` | `embedding` | #### Genkit | Raw Value | Span Type | | ------------------ | ----------- | | `model` | `llm` | | `background-model` | `llm` | | `embedder` | `embedding` | | `tool.v2` | `tool` | #### Vercel AI SDK | Raw Value | Span Type | | ------------------------------ | ----------- | | `ai.generateText` | `llm` | | `ai.generateText.doGenerate` | `llm` | | `ai.streamText` | `llm` | | `ai.streamText.doStream` | `llm` | | `ai.generateObject` | `llm` | | `ai.generateObject.doGenerate` | `llm` | | `ai.streamObject` | `llm` | | `ai.streamObject.doStream` | `llm` | | `ai.embed` | `embedding` | | `ai.embed.doEmbed` | `embedding` | | `ai.embedMany` | `embedding` | | `ai.embedMany.doEmbed` | `embedding` | | `ai.toolCall` | `tool` | ### Adding new span type mappings If your framework uses span type values that Fiddler doesn't recognize (appearing as `span` in the Explorer), contact your Fiddler deployment administrator to add the mapping. New mappings take effect within approximately 5 minutes and apply to all subsequently ingested spans. ## Managing Mappings via the UI Semantic mappings are managed from the **Settings > Semantic Mappings** tab in the Fiddler UI. The tab displays all current mappings in a table with two columns: * **Attribute Name** — the raw OTel attribute key (e.g., `gen_ai.usage.input_tokens`) * **Semantic Name** — the canonical concept it maps to (e.g., `input_tokens`) To add a new mapping: 1. Click the **Add Mapping** button 2. Enter the raw attribute key in the **Attribute Name** field 3. Select the semantic concept from the **Semantic Name** dropdown 4. Click **Add** To delete a mapping, use the delete action on the mapping row. Only **Org Admins** can create or delete mappings. All users can view the current mappings. Semantic Mappings tab showing attribute name to semantic name mappings ## Propagation After creating or deleting a mapping, changes take effect within approximately **5 minutes**. Only new spans ingested after the mapping propagates are affected — existing data is not reprocessed. ## Constraints and Limits | Constraint | Value | | ---------------------------------- | ------------------------------------ | | Maximum total mappings | 1,000 | | Maximum mappings per request | 100 | | Maximum attribute key length | 256 characters | | Write rate limit | 10 requests/minute, 100 requests/day | | Propagation delay | \~5 minutes | | Required role for write operations | Org Admin | ## Unmapped Attributes Attributes that don't map to any semantic concept are still fully functional. They are stored with their original key name, appear in the Explorer's span detail view, and are queryable in FQL custom metrics via the `attribute()` function. The only difference is that they won't appear in built-in dashboards or metrics that rely on semantic concepts (such as the token usage chart or the model breakdown view). If you need an unmapped attribute to participate in these features, add a semantic mapping for it. ## Deleting or Changing a Mapping When you delete a mapping or remap an attribute key to a different semantic concept, the change only affects new spans ingested after the mapping propagates (\~5 minutes). Existing data retains the semantic name that was assigned at ingestion time and is not reprocessed. This means: * **Deleting a mapping** — new spans with that attribute key will no longer have a semantic name assigned. The attribute is still stored and queryable by its original key, but it stops appearing in concept-based dashboards and metrics. * **Remapping to a different concept** — new spans will use the new semantic concept. Older spans will continue to use the previous concept. During the transition period, both old and new data are independently queryable. # Model Onboarding Source: https://docs.fiddler.ai/developers/client-library-reference/model-onboarding * [Create a Project and Model](/developers/python-client-guides/model-onboarding/create-a-project-and-model): Explore our guide to creating a project and onboarding a model for observation. Learn how projects organize models and define a ModelSpec and Model Task. * [Customizing Your Model Schema](/developers/python-client-guides/model-onboarding/customizing-your-model-schema): Delve into our guide to customize your Model Schema with Fiddler. Learn how to adjust a column’s value range, possible values, and data type to match your model. * [Updating Model Schema](/developers/python-client-guides/model-onboarding/updating-model-schema): Learn how to modify your model's schema after initial creation by adding new columns using the Python client's add\_column() method. Add features, metadata, and tracking columns to existing models. * [Task Types](/developers/python-client-guides/model-onboarding/task-types): Explore our guide to selecting a model task type when onboarding your ML models and LLM applications. * [Custom Missing Values](/developers/python-client-guides/model-onboarding/specifying-custom-missing-value-representations): Learn how you can customize a model column to assign values to be treated as missing or null data in order to handle a value or token that is inserted in place of null. # Publishing Production Data Source: https://docs.fiddler.ai/developers/client-library-reference/publishing-production-data Navigate our client guide to publishing production data. Learn how to provide event data to Fiddler, update it, and retrieve it efficiently. ### Publish Inference Events to Fiddler After you onboard an ML model or LLM application as a Fiddler Model, you can publish inference events for analysis, performance monitoring, and reporting. There are two types of inference data: * Pre-production data: Static datasets such as training or testing data that serve as Baseline references for comparison * Production data: Time series data from live model inferences that Fiddler monitors against your baselines #### Integration Methods Fiddler offers two ways to publish inference data: **Python Client Library** Use the Python client for Python environments. Publish production and pre-production inference data with `Model.publish_stream()` for streaming events or `Model.publish_batch()` for batch uploads. For more details, see the [Python client SDK](/sdk-api/python-client/connection) documentation. **REST API** Use the [REST API](/sdk-api/rest-api/alert-rules) for language-agnostic integration across any platform. Both production and pre-production inference data use a common interface. ### Publish Pre-Production Data Publish pre-production data to Fiddler as a single dataset. You can add multiple baseline datasets to a model to create customized references for different metrics and alert rules. Fiddler accepts pre-production data in these formats: * Pandas DataFrame * Parquet file * CSV file For detailed instructions, see the [Creating a Baseline](/developers/python-client-guides/publishing-production-data/creating-a-baseline-dataset) guide. > **Note**: > > Pre-production datasets are immutable after publication. You can't update them or delete individual rows. #### Upload a Static Pre-Production Baseline ```python theme={null} dataset_file_path = 'path_to_your_data.parquet' dataset_name = 'a_unique_identifying_name' project = fdl.Project.from_name(name='your_project_name') model = fdl.Model.from_name(name='your_model_name', project_id=project.id) job = model.publish_batch( source=dataset_file_path, environment=fdl.EnvType.PRE_PRODUCTION, dataset_name=dataset_name, ) # publish_batch() is asynchronous. Use the publish job's wait() method # if synchronous behavior is desired. # job.wait() ``` ### Publish Production Data Fiddler provides several methods for publishing and editing production inference data: * Batch publishing (`Model.publish_batch()`): Send data in batches using pandas DataFrames, Parquet files, or CSV files * Stream publishing (`Model.publish_stream()`): Send individual events or small batches in near real-time * Update publishing: Modify previously published data * Delete publishing: Remove published data when needed Fiddler accepts production data in these formats: * Pandas DataFrames * Parquet files * CSV files * List of Python dictionaries (limited to stream and updates) A list of dictionaries is an additional data format on top of the three common to pre-production and production data. Choose the method that best fits your use case by reviewing the publishing guides below: * [Publish batch events](/developers/python-client-guides/publishing-production-data/publishing-batches-of-events) * [Stream live events](/developers/python-client-guides/publishing-production-data/streaming-live-events) * [Update published events](/developers/python-client-guides/publishing-production-data/updating-events) * [Delete events](/developers/python-client-guides/publishing-production-data/deleting-events) * [Publish ranking events](/developers/python-client-guides/publishing-production-data/ranking-events) * [Event deduplication](/developers/python-client-guides/publishing-production-data/event-deduplication) #### Key Considerations Here are some considerations to keep in mind as you onboard models and begin publishing production data to Fiddler. **Inference Event Unique Identifier** Fiddler requires a unique identifier on each event published should you later need to update ground truth labels and/or metadata columns. * Define the unique identifier column name when onboarding a model: `Model.event_id_col` * A unique index on the event id column is not enforced * When [event deduplication](/developers/python-client-guides/publishing-production-data/event-deduplication) is not enabled, duplicate values are accepted and events sharing the same event id value will all be used in calculating metrics **Event Deduplication** When event deduplication is enabled, Fiddler uses the `event_id_col` value to detect and drop duplicate events across multiple layers — within a single batch, against recently stored events, and across concurrent publish calls. This prevents duplicate events from inflating aggregated metrics such as drift scores, event counts, and model performance indicators. * Event deduplication is not enabled by default — contact Fiddler support to enable it * Events without an event ID (null or missing) are never deduplicated * Deduplication applies to insert operations only — update operations are not deduplicated For full details on how each layer works, see [Event Deduplication](/developers/python-client-guides/publishing-production-data/event-deduplication). **Inference Event Timestamp** Fiddler requires a timestamp for each inference event which is used as the event occurrence timestamp in time-series monitoring charts and alert rule evaluation. * Define the timestamp column name when onboarding a model: `Model.event_ts_col` * If not defined, Fiddler will use the time of publication as the event occurrence timestamp * Timestamps are stored and rendered in UTC * Timestamps with timezone are accepted but will be converted to UTC * Fiddler supports basic pandas timestamp formats by inferring from the data ### Data Retention Policy Fiddler retains production inference event data for 90 days. Contact your Fiddler customer success representative if you need a different retention period. #### Raw Event Data * Retained for 90 days from publication date * Automatically deleted after 90 days * Policy applies globally #### Pre-Calculated Metrics * Standard metrics derived from raw data are retained indefinitely * Dashboards and charts continue to display historical trends after raw data expires #### Runtime features * Custom metrics require raw event data and aren't available for data older than 90 days # Monitoring Agentic Content Generation Source: https://docs.fiddler.ai/developers/cookbooks/agentic-content-generation Monitor agentic content generation for quality, safety, and brand compliance using built-in evaluators and custom LLM-as-a-Judge scoring. Ensure quality, safety, and brand compliance in content generation agents using a combination of Fiddler's built-in evaluators for baseline quality and custom `CustomJudge` evaluators for domain-specific governance. **Use this cookbook when:** You have content generation agents (writing reports, customer communications, marketing copy) and need automated quality gates to replace manual review of every draft. **Time to complete**: \~20 minutes ```mermaid theme={null} graph LR A["Generated\nContent"] --> B["Built-In Evaluators"] A --> C["Custom Judges"] subgraph "Baseline Quality" B --> D["Relevance"] B --> E["Coherence"] B --> F["Conciseness"] end subgraph "Domain Governance" C --> G["Brand Voice"] C --> H["Compliance"] end D --> I{"Quality\nGate"} E --> I F --> I G --> I H --> I I -->|Pass| J["APPROVED"] I -->|Fail| K["REJECTED"] I -->|Marginal| L["REVIEW"] style J fill:#6f9,stroke:#333 style K fill:#f96,stroke:#333 style L fill:#ffd,stroke:#333 ``` **Prerequisites** * Fiddler account with API access * LLM credential configured in **Settings > LLM Gateway** * `pip install fiddler-evals pandas` *** ## The Content Generation Challenge Enterprise content generation agents produce volume that exceeds human review capacity. Without automated quality gates, teams face: * **Reviewer fatigue** — manually reviewing hundreds of drafts per day * **Inconsistent quality** — different reviewers apply different standards * **Brand drift** — subtle changes in tone or style go undetected The solution: combine Fiddler's built-in evaluators (quality, safety) with custom LLM-as-a-Judge evaluators (brand voice, compliance) for automated governance. ## Recommended Evaluators ### Built-In Evaluators (Baseline Quality) | Evaluator | What It Measures | Value | | -------------------- | ---------------------------------------------- | --------------------- | | **Answer Relevance** | Does the output address the input instruction? | Instruction adherence | | **Coherence** | Logical flow and clarity | Narrative quality | | **Conciseness** | Brevity without losing meaning | Message clarity | | **Sentiment** | Positive, negative, or neutral tone | Brand alignment | | **Prompt Safety** | 11 safety dimensions (toxicity, bias, etc.) | Risk mitigation | ### Custom Evaluators (Domain-Specific Governance) | Evaluator | What It Measures | Value | | --------------------- | ----------------------------------------- | ------------------------------ | | **Brand Voice Match** | Adherence to company style guide | Automated brand governance | | **Bias Detection** | Potential bias across multiple dimensions | Compliance and risk mitigation | *** Replace `URL`, `TOKEN`, and credential names with your Fiddler account details. Find your credentials in **Settings > Access Tokens** and **Settings > LLM Gateway**. ```python theme={null} import pandas as pd from fiddler_evals import init from fiddler_evals.evaluators import ( AnswerRelevance, Coherence, Conciseness, CustomJudge, ) URL = 'https://your-org.fiddler.ai' TOKEN = 'your-access-token' LLM_CREDENTIAL_NAME = 'your-llm-credential' LLM_MODEL_NAME = 'openai/gpt-4o' init(url=URL, token=TOKEN) # Built-in evaluators for baseline quality relevance = AnswerRelevance(model=LLM_MODEL_NAME, credential=LLM_CREDENTIAL_NAME) coherence = Coherence(model=LLM_MODEL_NAME, credential=LLM_CREDENTIAL_NAME) conciseness = Conciseness(model=LLM_MODEL_NAME, credential=LLM_CREDENTIAL_NAME) ``` Use `CustomJudge` to evaluate content against your company's style guide: ```python theme={null} brand_voice_judge = CustomJudge( prompt_template=""" Determine whether the provided content adheres to the provided brand guidelines. Content: {{ content }} Brand Guidelines: {{ brand_guidelines }} """, output_fields={ 'voice_match_score': { 'type': 'string', 'choices': ['Perfect Match', 'Minor Deviations', 'Off-Brand'], }, 'reasoning': {'type': 'string'}, }, model=LLM_MODEL_NAME, credential=LLM_CREDENTIAL_NAME, ) ``` See [Building Custom Judge Evaluators](/developers/cookbooks/custom-judge-evaluators) for a deep-dive into `prompt_template`, `output_fields`, and iterative prompt improvement. ```python theme={null} # Example: your brand guidelines brand_guidelines = ( "Use professional, approachable tone. " "Address customers as 'you'. " "Avoid jargon, slang, and exclamation marks. " "Keep sentences under 25 words." ) # Sample content from your agent generated_content = [ { 'instruction': 'Write a welcome email for new customers', 'content': 'Welcome to our platform. We are glad you chose us. ' 'Your account is ready and you can start exploring features ' 'right away.', }, { 'instruction': 'Write a welcome email for new customers', 'content': 'OMG WELCOME!!! You are going to LOVE this!! ' 'Our platform is literally the BEST thing ever!!!', }, { 'instruction': 'Explain the refund process', 'content': 'To request a refund, navigate to your order history, ' 'select the item, and click Request Refund. Processing takes ' '3-5 business days.', }, ] # Evaluate each piece of content for item in generated_content: # Built-in evaluators rel_score = relevance.score( user_query=item['instruction'], rag_response=item['content'], ) coh_score = coherence.score(prompt=item['instruction'], response=item['content']) con_score = conciseness.score(response=item['content']) # Custom brand voice judge brand_scores = brand_voice_judge.score(inputs={ 'content': item['content'], 'brand_guidelines': brand_guidelines, }) brand_dict = {s.name: s for s in brand_scores} print(f"\nInstruction: {item['instruction'][:50]}...") print(f" Relevance: {rel_score.label} ({rel_score.value})") print(f" Coherence: {coh_score.label}") print(f" Conciseness: {con_score.label}") print(f" Brand Voice: {brand_dict['voice_match_score'].label}") print(f" Reason: {brand_dict['reasoning'].label}") ``` **Expected output:** ``` Instruction: Write a welcome email for new customers... Relevance: high (1.0) Coherence: high Conciseness: high Brand Voice: Perfect Match Reason: Professional tone, addresses customer directly, no jargon or exclamation marks, sentences are concise. Instruction: Write a welcome email for new customers... Relevance: medium (0.5) Coherence: low Conciseness: low Brand Voice: Off-Brand Reason: Uses all-caps, multiple exclamation marks, slang ("OMG", "literally"), and informal tone — violates all brand guidelines. Instruction: Explain the refund process... Relevance: high (1.0) Coherence: high Conciseness: high Brand Voice: Perfect Match Reason: Clear, professional instructions with appropriate tone and sentence length. ``` Combine evaluator scores into an automated quality gate that flags content for human review: ```python theme={null} def quality_gate(instruction, content, brand_guidelines): """Automated quality gate for content generation agents. Returns 'APPROVED', 'REVIEW', or 'REJECTED' with reasons. """ issues = [] # Check relevance rel = relevance.score(user_query=instruction, rag_response=content) if rel.value < 0.5: issues.append(f'Low relevance ({rel.label})') # Check coherence coh = coherence.score(prompt=instruction, response=content) if coh.value < 0.5: issues.append(f'Low coherence ({coh.label})') # Check brand voice brand = brand_voice_judge.score(inputs={ 'content': content, 'brand_guidelines': brand_guidelines, }) brand_dict = {s.name: s for s in brand} voice = brand_dict['voice_match_score'].label if voice == 'Off-Brand': issues.append(f'Off-brand content') elif voice == 'Minor Deviations': issues.append(f'Minor brand deviations') if not issues: return 'APPROVED', [] elif any('Off-Brand' in i or 'Low' in i for i in issues): return 'REJECTED', issues else: return 'REVIEW', issues # Run the quality gate for item in generated_content: status, issues = quality_gate( item['instruction'], item['content'], brand_guidelines, ) print(f"{status}: {item['content'][:60]}...") if issues: print(f" Issues: {', '.join(issues)}") ``` **Expected output:** ``` APPROVED: Welcome to our platform. We are glad you chose us. Your ... REJECTED: OMG WELCOME!!! You are going to LOVE this!! Our platform... Issues: Low coherence (low), Off-brand content APPROVED: To request a refund, navigate to your order history, sel... ``` *** ## Production Monitoring To deploy these evaluators in production: 1. **Evaluator Rules**: Configure built-in evaluators (Answer Relevance, Coherence, Conciseness) as Evaluator Rules in your Agentic Monitoring application. See [Evaluator Rules](/evaluate-and-test/evaluator-rules). 2. **Custom Judges in Experiments**: Run the Brand Voice Match judge as a recurring experiment against sampled production outputs to track brand compliance over time. 3. **Alerting**: Set up alerts on evaluator score degradation to catch systemic quality drift after model updates or prompt changes. *** ## Next Steps * [Building Custom Judge Evaluators](/developers/cookbooks/custom-judge-evaluators) — Deep-dive into `CustomJudge` capabilities * [Evaluator Rules](/evaluate-and-test/evaluator-rules) — Deploy evaluators in production * [Evals SDK Integration](/integrations/agentic-ai/evals-sdk) — Integration patterns for agentic workflows *** **Related**: [Evaluator Rules](/evaluate-and-test/evaluator-rules) — Configure evaluators for production monitoring # Agentic Document Extraction Source: https://docs.fiddler.ai/developers/cookbooks/agentic-document-extraction Build observable, measurable document extraction pipelines using Fiddler's agentic tracing, custom evaluators, and experiments. # Agentic Document Extraction Build reliable, measurable document extraction pipelines using Fiddler's agentic observability (tracing), custom evaluators, and experiments to catch hallucinated fields, schema drift, and silent accuracy degradation. While this cookbook uses invoice extraction as a running example, the patterns apply to any pipeline that extracts structured data from documents — medical records, legal filings, research papers, support tickets, or any other source. **Use this cookbook when:** You have an LLM-based agent extracting structured data from any document type — invoices, medical records, legal contracts, research papers, support tickets, or other sources — and need observability, automated quality evaluation, and production monitoring. **Time to complete**: \~30 minutes ```mermaid theme={null} graph LR A["Source\nDocument"] --> B["Parse"] B --> C["Extract\n(LLM)"] C --> D["Validate"] subgraph "Fiddler Observability" E["Tracing\n(OpenTelemetry)"] F["Evaluators\n(Custom + Built-In)"] G["Experiments\n(Benchmarking)"] end D --> E D --> F F --> G G --> H{"Quality\nGate"} H -->|Pass| I["Production"] H -->|Fail| J["Review"] style I fill:#6f9,stroke:#333 style J fill:#f96,stroke:#333 ``` **Prerequisites** * Fiddler account with API access * LLM credential configured in **Settings > LLM Gateway** * `pip install fiddler-evals pandas` *** ## Understanding the Problem Document extraction — pulling structured data from unstructured or semi-structured documents — is one of the most common enterprise AI applications. Whether the source is an invoice, a medical record, a legal filing, or a support ticket, the core challenge is the same. When an LLM-based agent handles this work, it introduces new failure modes that traditional rule-based parsers never had: hallucinated field values, inconsistent schemas, and silent accuracy degradation after model updates. A document extraction agent typically follows a multi-step workflow: 1. **Parse** — normalize raw document text into a consistent format 2. **Extract** — use an LLM to pull structured fields (vendor name, invoice number, line items, totals) into JSON 3. **Validate** — check that the output is complete, correctly formatted, and mathematically consistent Each step can fail in different ways, and the failures compound. A parsing step that drops a line item produces an extraction that looks correct but is missing data. An LLM that hallucinates a subtotal produces a validation that passes the schema check but fails the math check. Without observability at every step, these issues are invisible until a downstream system — or a customer — catches them. **Common failure modes in document extraction:** * **Schema drift:** The model starts omitting fields it previously extracted reliably * **Numeric hallucination:** Dollar amounts or quantities that don't match the source document * **Date format inconsistency:** Dates returned in varying formats despite explicit instructions * **Math errors:** Extracted totals that don't equal subtotal + tax * **Silent degradation:** Accuracy drops gradually after a model update, with no hard errors to trigger alerts *** ## How Fiddler Helps: Three Layers of Observability Fiddler provides three complementary capabilities for document extraction pipelines: ### 1. Agentic Observability (Tracing) By instrumenting your extraction pipeline with OpenTelemetry, every step — parse, extract, validate — appears as a span in Fiddler's trace view. This gives you: * **Span hierarchy:** A root `chain` span with child `tool` and `llm` spans, showing exactly how the agent orchestrates each step * **LLM telemetry:** Model name, token usage (input/output/total), and the full prompt and response captured on the extraction span * **Error attribution:** When an extraction fails, you can see which step failed and why, including error type and message * **Custom attributes:** Tag spans with metadata like `document_type`, `invoice_id`, or any business-relevant dimension for filtering in dashboards **Learn more:** [OpenTelemetry Quick Start](/developers/quick-starts/opentelemetry-quick-start) **Other integration options:** While this cookbook uses OpenTelemetry for maximum flexibility, Fiddler also provides dedicated SDKs with auto-instrumentation for popular agentic frameworks — including [LangGraph](/integrations/agentic-ai/langgraph-sdk), [Strands](/integrations/agentic-ai/strands-sdk), [LangChain](/integrations/agentic-ai/langchain-sdk), and [LiteLLM](/integrations/agentic-ai/litellm-integration). These SDKs require minimal code changes (often a single `instrument()` call) and produce the same traces in Fiddler. For custom Python agents without a framework, the [Fiddler OTel SDK](/integrations/agentic-ai/fiddler-otel-sdk) (`fiddler-otel`) provides a `@trace` decorator for lightweight instrumentation. See the [full integration guide](/integrations/agentic-ai-and-llm-frameworks/agentic-ai) to choose the right option for your stack. ### 2. Fiddler Experiments (Offline Evaluation) Experiments let you systematically measure extraction quality against a ground-truth dataset. You define a dataset of test cases (source documents + expected extractions), run your pipeline against them, and score the results with custom evaluators. This gives you: * **Repeatable benchmarks:** Compare extraction accuracy across model versions, prompt changes, or schema updates * **Per-test-case drill-down:** See exactly which fields mismatched and why, for every test case * **Side-by-side comparison:** Run the same dataset against different model versions and compare field accuracy in a single view **Learn more:** [Experiments](/getting-started/experiments) ### 3. Production Monitoring Signals In production, you compute aggregate signals over rolling time windows and set alerts on threshold breaches. These signals act as early warning systems for extraction quality degradation. **Learn more:** [Agentic Monitoring](/getting-started/agentic-monitoring) *** ## Definition: Built-In Evaluators (Fiddler Evals SDK) The Fiddler Evals SDK (`fiddler-evals`) provides pre-built evaluators that deliver immediate, generalized assessments of LLM performance. For document extraction, they establish a baseline for output quality without requiring ground-truth data. Built-in evaluators include `Coherence`, `Conciseness`, `AnswerRelevance`, `Sentiment`, and more — each available as a Python class you instantiate and pass to the `evaluate()` function. **Learn more:** [Evals SDK Reference](/sdk-api/evals/evaluate) ## Definition: Custom Evaluators Custom evaluators allow you to encode domain-specific quality standards directly into the evaluation process. For document extraction, this means comparing extracted fields against known correct values, checking schema completeness, and validating mathematical consistency. The Fiddler Evals SDK provides three approaches for building custom evaluators: * **`CustomJudge`** — An LLM-as-a-Judge evaluator that uses a Jinja prompt template and structured output fields. Ideal for nuanced, qualitative assessments like per-field accuracy or math consistency checks. * **`EvalFn`** — Wraps any Python function as an evaluator. Best for deterministic checks like schema completeness or exact-match comparisons. * **Subclass `Evaluator`** — Extend the base `Evaluator` class for full control over scoring logic, input handling, and multi-score returns. **Learn more:** [CustomJudge Evaluators](/sdk-api/evals/custom-judge) *** ## Recommended Evaluators for Document Extraction | Evaluator | What does it measure? | What value does it provide? | | ---------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | | **Coherence** | Assesses the logical flow and clarity of the LLM's extraction output. | **Output Quality:** Catches garbled or malformed extraction responses before they reach downstream systems. | | **Conciseness** | Evaluates whether the extraction output is focused and free of extraneous commentary. | **Schema Discipline:** Ensures the model returns structured data, not explanations or caveats mixed into the output. | | **"Field Accuracy" Custom Evaluator** (See Deep Dive below) | Compares each extracted scalar field (vendor name, invoice number, date, subtotal, tax, total) against a ground-truth value. | **Granular Quality Control:** Pinpoints exactly which fields the model extracts reliably vs. which require prompt tuning or model changes. | | **"Schema Completeness" Custom Evaluator** (See Deep Dive below) | Measures the fraction of required fields that are present and non-null in the extraction output. | **Completeness Assurance:** Catches schema drift — when a model starts silently omitting fields it previously extracted correctly. | | **"Per-Field Accuracy" `CustomJudge`** (See Deep Dive below) | Uses a `CustomJudge` evaluator to assess extraction accuracy for each specific field against the source text. | **Automated Review:** Provides human-like accuracy assessment at scale without requiring manual comparison of every extraction. | | **"Math Consistency" Custom Evaluator** | Checks whether extracted numeric fields are internally consistent (e.g., total == subtotal + tax). | **Numeric Integrity:** Catches hallucinated dollar amounts that pass schema validation but fail basic arithmetic. | ## Recommended Production Monitoring Signals Beyond per-document evaluators, you should track aggregate signals over rolling time windows to detect systemic issues. | Signal | What does it measure? | Alert threshold (suggested) | | --------------------------- | ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------- | | **Success Rate** | Fraction of extractions completing without exception. | Alert when \< 95%. Catches API errors, timeouts, and crashes. | | **Validation Failure Rate** | Fraction of extractions with at least one validation error (missing fields, bad date format, math mismatch). | Alert when > 20%. Catches silent quality degradation. | | **Field Completeness** | Average fraction of required fields present and non-null across all extractions. | Alert when \< 90%. Catches schema drift after model updates. | | **Math Accuracy** | Fraction of extractions where `total == subtotal + tax` within a small tolerance. | Alert when \< 90%. Catches numeric hallucination trends. | In production, these signals would be computed over rolling windows (e.g., hourly or daily) and configured as Fiddler alerts. A sudden drop in math accuracy after a model update, for example, would trigger an alert before the bad data propagates to downstream accounting systems. *** ## Deep Dive: Tracing an Extraction Pipeline with OpenTelemetry Fiddler's agentic observability uses OpenTelemetry (OTEL) to capture the full execution of your extraction pipeline as a structured trace. Each trace consists of spans with a parent-child hierarchy that mirrors your agent's logic. A typical extraction trace has the following structure: ``` extraction_pipeline (chain) ├── parse_document (tool) ├── extract_fields (llm) └── validate_output (tool) ``` * **`extraction_pipeline`** — the root span, typed as `chain`. Carries agent-level metadata: `gen_ai.agent.name`, `gen_ai.agent.id`, and custom attributes like `fiddler.span.user.document_type` and `fiddler.span.user.invoice_id`. * **`parse_document`** — a `tool` span. Records the raw input and cleaned output of the normalization step. * **`extract_fields`** — an `llm` span. This is where the richest telemetry lives: `gen_ai.request.model`, `gen_ai.usage.input_tokens`, `gen_ai.usage.output_tokens`, `gen_ai.input.messages`, and `gen_ai.output.messages`. * **`validate_output`** — a `tool` span. Records the validation result: which checks passed, which failed, and the specific error messages. When an extraction produces incorrect data, the span hierarchy lets you pinpoint the root cause: * **Parse failed?** The `parse_document` span shows the raw input was garbled or the normalization dropped content. * **LLM hallucinated?** The `extract_fields` span shows the exact prompt and response, plus token usage that may indicate the model was truncating output. * **Validation caught it?** The `validate_output` span shows which checks failed, so you know whether the issue is a missing field, a bad date, or a math error. Without this trace structure, you only see "extraction failed" — with it, you see *why*. When any step throws an exception, the root span captures `fiddler.error.message` and `fiddler.error.type`, making it filterable in Fiddler dashboards. You can quickly find all traces where the LLM returned unparseable JSON, or where the OpenAI API timed out, without searching through logs. **Learn more:** [OpenTelemetry Integration](/integrations/agentic-ai/opentelemetry-integration) *** ## Deep Dive: Custom Evaluators for Extraction Quality While built-in evaluators like `Coherence` catch general output quality issues, document extraction requires domain-specific evaluators that understand your schema and can compare against ground truth. The Fiddler Evals SDK provides multiple ways to build these: subclassing `Evaluator` for complex scoring logic, wrapping functions with `EvalFn` for simple checks, and using `CustomJudge` for LLM-based assessment. This evaluator compares each extracted scalar field against a known correct value. It handles numeric fields with a tolerance (to account for rounding differences) and string fields with case-insensitive comparison. **What it checks:** `vendor_name`, `invoice_number`, `date`, `subtotal`, `tax`, `total` **Scoring:** Returns the fraction of fields that match (0.0–1.0). A score of `0.83` means 5 out of 6 fields matched. ```python theme={null} from fiddler_evals import Evaluator, Score class FieldAccuracyEvaluator(Evaluator): NUMERIC_FIELDS = ['subtotal', 'tax', 'total'] def score(self, extracted: dict, expected: dict) -> Score: matches = 0 total_fields = len(expected) for field in expected.keys(): ext_val = extracted.get(field) exp_val = expected.get(field) if ext_val is None or exp_val is None: continue if field in self.NUMERIC_FIELDS: if abs(float(ext_val) - float(exp_val)) < 0.01: matches += 1 else: if str(ext_val).strip().lower() == str(exp_val).strip().lower(): matches += 1 accuracy = matches / total_fields return Score( name="field_accuracy", evaluator_name=self.name, value=accuracy, reasoning=f"{matches}/{total_fields} fields matched", ) ``` **Why it matters:** Aggregate field accuracy tells you how reliable your pipeline is. But the per-field breakdown tells you *where* to focus improvement. If `date` is the field that most often mismatches, you know to adjust the date formatting instructions in your prompt — not rebuild the entire pipeline. This evaluator checks what fraction of required fields are present and non-null in the extraction output, independent of whether the values are correct. Wrapping a simple Python function with `EvalFn` is the most concise way to build deterministic evaluators. **What it checks:** All required schema fields (`vendor_name`, `invoice_number`, `date`, `line_items`, `subtotal`, `tax`, `total`) **Scoring:** Returns the fraction present (0.0–1.0). A score of `0.86` means 6 out of 7 required fields were populated. ```python theme={null} from fiddler_evals.evaluators import EvalFn REQUIRED_FIELDS = ['vendor_name', 'invoice_number', 'date', 'line_items', 'subtotal', 'tax', 'total'] def schema_completeness(extracted: dict) -> float: present = sum(1 for f in REQUIRED_FIELDS if extracted.get(f) is not None) return present / len(REQUIRED_FIELDS) schema_completeness_evaluator = EvalFn( schema_completeness, score_name="schema_completeness" ) ``` **Why it matters:** Schema completeness is the earliest signal of extraction degradation. A model may still extract *some* fields correctly while silently dropping others. Tracking completeness separately from accuracy lets you distinguish between "the model is wrong" and "the model isn't even trying." For cases where you want a more nuanced assessment — or where ground-truth data is unavailable — you can use a `CustomJudge` to evaluate extraction quality directly from the source text. `CustomJudge` uses a Jinja prompt template with `{{ placeholder }}` syntax and structured `output_fields` to define what the LLM judge should return. ```python theme={null} from fiddler_evals.evaluators import CustomJudge field_accuracy_judge = CustomJudge( prompt_template=""" Evaluate the accuracy of extracted fields from the source document. Compare each extracted field against the original text and determine whether it was extracted correctly. Source Document: {{ source_text }} Extracted Data: {{ extracted_fields }} Required Fields: {{ required_fields }} """, output_fields={ "vendor_name_correct": { "type": "boolean", "description": "Was the vendor name extracted correctly?", }, "invoice_number_correct": { "type": "boolean", "description": "Was the invoice number extracted correctly?", }, "date_correct": { "type": "boolean", "description": "Was the date extracted correctly?", }, "amounts_correct": { "type": "boolean", "description": "Were the dollar amounts extracted correctly?", }, "overall_accuracy": { "type": "string", "choices": ["All Correct", "Partially Correct", "Mostly Incorrect"], }, "reasoning": { "type": "string", "description": "Explain which fields matched or mismatched and why.", }, }, model="openai/gpt-4o", credential="your-openai-credential", ) # Score a single extraction scores = field_accuracy_judge.score(inputs={ "source_text": raw_document_text, "extracted_fields": json.dumps(extracted_data), "required_fields": "vendor_name, invoice_number, date, subtotal, tax, total", }) # Access individual scores scores_dict = {s.name: s for s in scores} print(scores_dict["overall_accuracy"].label) # e.g. "All Correct" print(scores_dict["reasoning"].label) # detailed explanation ``` * The judge takes the original source document and the extracted fields as inputs — no ground truth required. * It assesses each field independently, producing both per-field booleans and an overall accuracy classification. * By flagging "Mostly Incorrect" extractions, you can route them for human review or reprocessing. * This approach scales to production volumes where maintaining ground-truth datasets is impractical. This `CustomJudge` evaluates whether the extracted numeric fields are internally consistent with the source document. ```python theme={null} from fiddler_evals.evaluators import CustomJudge math_consistency_judge = CustomJudge( prompt_template=""" Verify the mathematical consistency of extracted invoice fields. Check that: (1) the total equals subtotal plus tax, (2) line item prices multiplied by quantities sum to the subtotal, (3) all numeric values match the source document. Source Document: {{ source_text }} Extracted Data: {{ extracted_fields }} """, output_fields={ "total_matches_sum": { "type": "boolean", "description": "Does total equal subtotal + tax?", }, "line_items_sum_correct": { "type": "boolean", "description": "Do line item totals sum to the subtotal?", }, "values_match_source": { "type": "boolean", "description": "Do all numeric values match the source document?", }, "math_consistency": { "type": "string", "choices": ["Fully Consistent", "Minor Discrepancy", "Major Error"], }, "reasoning": { "type": "string", "description": "Explain any discrepancies found.", }, }, model="openai/gpt-4o", credential="your-openai-credential", ) ``` * This judge catches a category of errors that schema validation alone cannot: values that are present and correctly formatted but numerically wrong. * A "Major Error" flag on `math_consistency` indicates the model hallucinated dollar amounts — a critical failure for any financial document extraction system. * Tracking the `line_items_sum_correct` field over time reveals whether the model struggles more with line-item aggregation than with reading individual totals. *** ## Deep Dive: Using Fiddler Experiments for Extraction Benchmarking Fiddler Experiments provide a structured way to benchmark your extraction pipeline against a ground-truth dataset. This is especially valuable when you need to: * **Compare model versions:** Does your current model extract dates more accurately than a smaller or newer variant? * **Test prompt changes:** Does adding "Return 0 for tax if not applicable" reduce errors on tax-exempt invoices? * **Validate schema changes:** After adding a new required field, does the existing accuracy hold? The Fiddler Evals SDK (`fiddler-evals`) provides the `evaluate()` function as the main entry point for running experiments. The workflow is: 1. **Create a Dataset** with source documents as inputs and ground-truth extractions as expected outputs 2. **Define a Task** — a Python function that runs your extraction pipeline on each input 3. **Attach Evaluators** — built-in evaluators, `CustomJudge` instances, `EvalFn`-wrapped functions, or `Evaluator` subclasses 4. **Run with `evaluate()`** and review per-test-case scores in the Fiddler UI Replace `url`, `token`, and credential names with your Fiddler account details. Find your credentials in **Settings > Access Tokens** and **Settings > LLM Gateway**. ```python theme={null} import json from fiddler_evals import init, Project, Application, Dataset, evaluate from fiddler_evals.pydantic_models.dataset import NewDatasetItem from fiddler_evals.evaluators import Coherence, Conciseness # 1. Initialize connection init(url="https://your-org.fiddler.ai", token="your-token") # 2. Set up project hierarchy: Project > Application > Dataset project = Project.get_or_create(name="document_extraction") app = Application.get_or_create( name="invoice_extractor", project_id=project.id ) dataset = Dataset.create( name="invoice_test_set", application_id=app.id ) # 3. Add test cases with ground-truth expected outputs dataset.insert([ NewDatasetItem( inputs={ "source_text": "Invoice #12345\nFrom: Acme Corp\nDate: 2025-01-15\n" "Widget A 2 x $50.00 = $100.00\nSubtotal: $100.00\n" "Tax: $8.00\nTotal: $108.00", }, expected_outputs={ "vendor_name": "Acme Corp", "invoice_number": "12345", "date": "2025-01-15", "subtotal": 100.00, "tax": 8.00, "total": 108.00, }, metadata={"document_type": "invoice"}, ), # ... additional test cases ]) # 4. Define the extraction task def extraction_task(inputs: dict, extras: dict, metadata: dict) -> dict: # Replace with your actual extraction logic result = run_extraction_pipeline(inputs["source_text"]) return { "extracted_fields": result, # raw dict for custom evaluators "source_text": inputs["source_text"], "response": str(result), # string for built-in evaluators } # 5. Run the experiment with multiple evaluators results = evaluate( dataset=dataset, task=extraction_task, evaluators=[ FieldAccuracyEvaluator(), # Evaluator subclass schema_completeness_evaluator, # EvalFn field_accuracy_judge, # CustomJudge math_consistency_judge, # CustomJudge Coherence(model="openai/gpt-4o", credential="your-cred"), Conciseness(model="openai/gpt-4o", credential="your-cred"), ], name_prefix="invoice_extraction_v1", # Maps dataset columns and task outputs to evaluator score() arguments score_fn_kwargs_mapping={ "extracted": "extracted_fields", # for FieldAccuracyEvaluator (from task output) "expected": lambda x: x["expected_outputs"], # for FieldAccuracyEvaluator (from dataset item) "source_text": "source_text", # for CustomJudge evaluators "extracted_fields": "extracted_fields", # for CustomJudge evaluators "response": "response", # for Coherence & Conciseness }, max_workers=4, ) # 6. Analyze results for result in results.results: print(f"\nDataset item {result.experiment_item.dataset_item_id}:") for score in result.scores: print(f" {score.name}: {score.value} — {score.reasoning}") ``` The experiment results show you not just aggregate scores, but individual test cases where your pipeline struggled. If 7 out of 8 invoices score 100% field accuracy but one scores 67%, you can drill into that specific case to see what went wrong — perhaps it was an invoice with an unusual date format or a tax-exempt order. The real power of Experiments is iterative improvement. Because `evaluate()` returns structured results and each experiment is tracked in the Fiddler UI, you can run A/B comparisons: 1. Run a baseline experiment with your current prompt and model 2. Identify the weakest test cases (lowest field accuracy or schema completeness) 3. Adjust your prompt, model, or preprocessing to address those failures 4. Run a new experiment against the same dataset and compare side-by-side with the baseline 5. Repeat until accuracy meets your threshold ```python theme={null} # Compare two model versions against the same dataset results_gpt4o = evaluate( dataset=dataset, task=extraction_task_gpt4o, evaluators=evaluators, name_prefix="gpt4o_baseline", ) results_gpt4o_mini = evaluate( dataset=dataset, task=extraction_task_gpt4o_mini, evaluators=evaluators, name_prefix="gpt4o_mini_comparison", ) # View side-by-side in the Fiddler UI print(f"GPT-4o: {results_gpt4o.experiment.get_app_url()}") print(f"GPT-4o-mini: {results_gpt4o_mini.experiment.get_app_url()}") ``` This workflow turns prompt engineering from guesswork into a measurable process. **Learn more:** [Experiments](/getting-started/experiments) *** ## How These Evaluators Can Help ### 1. Catching Silent Quality Degradation Document extraction pipelines rarely fail loudly. More often, they degrade gradually — a model update causes date formatting to shift, or a prompt change inadvertently reduces field completeness. By tracking Field Accuracy and Schema Completeness over time, you catch these regressions before they reach downstream systems. A 5% drop in math accuracy after a model update is invisible in error logs but immediately visible in Fiddler dashboards. ### 2. Reducing Manual Review Burden Without automated evaluation, every extracted document needs human review to verify accuracy. With Fiddler evaluators acting as an automated quality gate, your team reviews only the extractions flagged for low accuracy or missing fields. If 95% of extractions pass validation, your reviewers focus on the 5% that need attention — not the full volume. ### 3. Enabling Confident Model and Prompt Changes Changing a model or prompt in a document extraction pipeline is risky without a way to measure the impact. Fiddler Experiments give you a controlled environment to test changes against a known dataset before deploying to production. You can prove that a prompt change improved date accuracy from 87% to 98% before it touches a single real document. ### 4. Building Trust with Downstream Consumers Finance teams, compliance officers, and ERP systems that consume extracted data need to trust its accuracy. Fiddler's monitoring signals — success rate, field completeness, math accuracy — provide auditable evidence that your extraction pipeline is performing within acceptable bounds. When a downstream consumer questions a data point, you can trace it back to the specific span that produced it. ### 5. Detecting Document-Type-Specific Weaknesses By tagging traces with custom attributes like `document_type` (invoice, receipt, contract) or `vendor_name`, you can segment your monitoring signals and discover that your pipeline handles standard invoices at 98% accuracy but struggles with receipts (85%) or international invoices with VAT (78%). This guides where to invest in prompt engineering or training data. *** ## Next Steps * [Building Custom Judge Evaluators](/developers/cookbooks/custom-judge-evaluators) — Deep-dive into `CustomJudge` capabilities * [Running RAG Experiments at Scale](/developers/cookbooks/rag-experiments-at-scale) — Structured experiments with Datasets and golden label validation * [Monitoring Agentic Content Generation](/developers/cookbooks/agentic-content-generation) — Quality and brand compliance for content agents * [Evaluator Rules](/evaluate-and-test/evaluator-rules) — Deploy evaluators in production * [Evals SDK Integration](/integrations/agentic-ai/evals-sdk) — Integration patterns for agentic workflows *** **Related**: [OpenTelemetry Quick Start](/developers/quick-starts/opentelemetry-quick-start) | [Experiments Quick Start](/developers/quick-starts/experiments-quick-start) | [CustomJudge Evaluators](/developers/cookbooks/custom-judge-evaluators) # AI Security Source: https://docs.fiddler.ai/developers/cookbooks/ai-security Monitor for AI security concerns using built-in evaluators and custom LLM-as-a-Judge scoring. ## Overview As GenAI applications handle increasingly sensitive data and interact directly with users, security becomes a pressing concern. A single security breach, whether it's a successful jailbreak attempt, leaked PII, or harmful content reaching users, can undermine trust and expose organizations to significant risk. This cookbook provides a framework for using Fiddler's evaluators and guardrails to protect your AI applications from threats, including jailbreak attempts, harmful content generation, PII leakage, and policy violations. *** ## Understanding AI Security Risks AI security encompasses multiple threat vectors: **Prompt-based attacks:** * **Jailbreaking:** Attempts to bypass safety restrictions and make the model behave in unintended ways * **Prompt injection:** Malicious instructions embedded in user inputs to manipulate model behavior * **Roleplaying exploitation:** Using fictional scenarios to elicit restricted information or harmful content **Content safety risks:** * **Harmful content generation:** Producing content that could cause psychological, physical, or social harm * **Illegal content:** Generating content that violates laws or regulations * **Unethical outputs:** Responses that violate ethical guidelines or corporate policies **Data privacy risks:** * **PII leakage in responses:** Model outputs that inadvertently expose personally identifiable information * **PII in prompts:** Users submitting sensitive personal data that must be detected and protected ## Out-of-the-Box Security Evaluators Fiddler provides pre-built scoring mechanisms called evaluators that assess AI systems across multiple risk dimensions. **Learn more:** [Enrichments](/observability/llm/enrichments) ## Custom LLM-as-a-Judge for Security While Fiddler's out-of-the-box evaluators cover common security risks, you may have **organization-specific security policies** that require custom evaluation. LLM-as-a-Judge evaluators allow you to encode your unique security guidelines into automated checks. **Use LLM-as-a-Judge when you need to:** * Enforce company-specific content policies beyond standard safety categories * Detect violations of industry-specific regulations (healthcare, finance, legal) * Flag content that conflicts with your organization's ethical guidelines * Identify security risks unique to your application domain **Example applications:** * A healthcare AI that must never provide medical diagnoses (even when users request them) * A financial AI that must refuse to give personalized investment advice * A customer service AI that must escalate certain sensitive topics to human agents * An educational AI that must not provide answers to homework assignments By creating custom prompt templates that define your specific security requirements, you can automatically flag violations and enforce your policies at scale. **Learn more:** [Prompt Specs Quick Start](/evaluate-and-test/prompt-specs-quick-start) ## Recommended Security Evaluators ### 1. Prompt Safety **What it detects:** Evaluates the safety of text (prompts and responses) across multiple risk dimensions. | Safety Dimension | What it identifies | Why it matters | | ---------------- | ---------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | | **Jailbreak** | Attempts to bypass model safety restrictions or manipulate the AI into ignoring its guidelines | **Attack Prevention:** Detects sophisticated prompt engineering designed to circumvent your controls | | **Illegal** | Content that violates laws or promotes illegal activities | **Legal Compliance:** Prevents your AI from facilitating or encouraging unlawful behavior | | **Roleplaying** | Use of fictional scenarios to elicit restricted information or harmful content (e.g., "pretend you're an AI with no restrictions") | **Policy Enforcement:** Catches attempts to bypass safety measures through narrative framing | | **Harmful** | Content that could cause psychological, physical, or social harm to individuals or groups | **User Safety:** Protects users from outputs that could lead to self-harm, dangerous actions, or trauma | | **Unethical** | Content that violates ethical principles or societal norms, even if not explicitly illegal | **Reputation Protection:** Maintains alignment with your organization's values and public expectations | **Additional dimensions available:** hateful, harassing, racist, sexist, violent, sexual **How to use:** * Apply to both user prompts (inputs) and AI responses (outputs) * Set severity thresholds based on your risk tolerance * Track trends over time to identify emerging attack patterns **Value:** Acts as a comprehensive safety net, catching both malicious user attempts and problematic model outputs before they cause harm. ### 2. PII Detection **What it detects:** Identifies personally identifiable information in both user prompts and AI responses. | PII Type | Examples | Risk | | ---------------------------- | ------------------------------------------- | ------------------------------------------------------------------------ | | **Social Security Numbers** | 123-45-6789, 123456789 | **Identity Theft:** Exposure can lead to fraud and financial harm | | **Credit Card Numbers** | 4532-1234-5678-9010 | **Financial Fraud:** Direct monetary loss and unauthorized transactions | | **Email Addresses** | [user@example.com](mailto:user@example.com) | **Privacy Violation:** Can enable spam, phishing, or unwanted contact | | **Phone Numbers** | (555) 123-4567, +1-555-123-4567 | **Privacy Violation:** Enables unwanted contact and potential harassment | | **Physical Addresses** | 123 Main St, New York, NY 10001 | **Physical Security:** Can reveal location and enable stalking or theft | | **IP Addresses** | 192.168.1.1, 2001:0db8:85a3::8a2e:0370:7334 | **Privacy & Security:** Can reveal location and enable tracking | | **Driver's License Numbers** | D1234567 | **Identity Theft:** Can be used for fraud and impersonation | | **Passport Numbers** | 123456789 | **Identity Theft:** International fraud and identity compromise | | **Medical Record Numbers** | MRN-789456 | **HIPAA Violation:** Protected health information exposure | | **Bank Account Numbers** | 123456789012 | **Financial Fraud:** Unauthorized access to funds | | **National ID Numbers** | Varies by country | **Identity Theft:** Government ID compromise | | **Tax IDs / EINs** | 12-3456789 | **Business Fraud:** Corporate identity theft | | **Dates of Birth** | 01/15/1990 | **Identity Verification:** Combined with other data, enables fraud | | **Names** | John Smith, Jane Doe | **Privacy Context:** When combined with other PII, increases risk | **Where to apply:** **Input Detection (User Prompts):** * **Purpose:** Identify when users are submitting sensitive personal information * **Actions:** * Warn users not to share PII * Redact PII before processing * Log incidents for security review * **Example:** User asks "Can you analyze my credit report? My SSN is 123-45-6789..." **Output Detection (AI Responses):** * **Purpose:** Catch when the model inadvertently includes PII in responses * **Actions:** * Block response from reaching the user * Regenerate without PII * Flag for investigation (How did the model access this PII?) * **Example:** Model trained on customer service logs accidentally includes someone's phone number in a response **Value:** Prevents privacy violations, ensures compliance with GDPR/CCPA/HIPAA, and protects users from identity theft. *** ## Guardrails vs. Post-Production Observability Fiddler supports two complementary approaches to AI security: **real-time guardrails** and **post-production observability**. Understanding when to use each is critical for building secure AI systems. ### Real-Time Guardrails **What they are:** Security checks that evaluate and potentially block AI inputs or outputs **before they are processed or delivered to users**. **How they work:** 1. User submits a prompt → Guardrail evaluates for safety/PII 2. If violation detected → Request is blocked or modified 3. If safe → Request proceeds to model 4. Model generates response → Guardrail evaluates output 5. If violation detected → Response is blocked or regenerated 6. If safe → Response delivered to user **When to use real-time guardrails:** | Scenario | Why Guardrails are Essential | Example | | ---------------------------- | -------------------------------------------------- | ------------------------------------------------------------ | | **User-facing applications** | Cannot allow harmful content to reach users | Customer support chatbot must block offensive responses | | **High-stakes domains** | Single failure has severe consequences | Healthcare AI must never provide medical diagnoses | | **Compliance requirements** | Regulations mandate prevention, not just detection | Financial AI must block PII from being logged or transmitted | | **Jailbreak prevention** | Must stop malicious prompts before processing | Detect and reject prompt injection attacks | | **PII protection** | Cannot allow sensitive data to be exposed | Prevent credit card numbers from appearing in responses | **Tradeoffs:** * **Latency:** Adds processing time to each request (typically 100-500ms) * **False positives:** May occasionally block legitimate requests * **Cost:** Requires additional compute for real-time evaluation **Learn more:** [Guardrails Quick Start](/developers/quick-starts/guardrails-quick-start) ### Post-Production Observability **What it is:** Continuous monitoring and analysis of AI behavior **after** requests have been processed, using historical data to identify patterns, trends, and emerging threats. **How it works:** 1. AI processes requests normally (no blocking) 2. All prompts and responses are logged to Fiddler 3. Security evaluators run asynchronously on logged data 4. Dashboards show trends, patterns, and anomalies 5. Alerts trigger when thresholds are exceeded 6. Teams investigate and respond to issues **When to use post-production observability:** | Scenario | Why Observability is Valuable | Example | | --------------------------------- | -------------------------------------------------- | ------------------------------------------------------------------- | | **Threat intelligence** | Identify attack patterns and emerging risks | Notice spike in jailbreak attempts targeting a specific weakness | | **Model behavior analysis** | Understand how the model responds to edge cases | Discover the model occasionally generates PII in rare scenarios | | **Compliance auditing** | Maintain historical records for regulatory review | Demonstrate you monitor and address security issues over time | | **Performance optimization** | Improve guardrails based on real-world data | Reduce false positive rate by analyzing blocked legitimate requests | | **Trend monitoring** | Track security metrics over time | See if harmful content attempts increase after a news event | | **A/B testing security measures** | Compare security performance across model versions | Evaluate if new prompt reduces jailbreak success rate | **Tradeoffs:** * **No prevention:** Issues are detected after they occur * **Requires follow-up:** Teams must act on insights * **Best for learning:** Ideal for understanding threats and improving defenses **Learn more:** [Enrichments](/observability/llm/enrichments) ### Using Both Approaches Together **The most secure AI systems combine real-time guardrails with post-production observability:** **Real-time guardrails provide:** * Immediate protection for users * Prevention of high-severity incidents * Compliance with "must prevent" requirements **Post-production observability provides:** * Insights to improve guardrails * Detection of sophisticated attacks that evade guardrails * Trend analysis for proactive security **Example workflow:** to block high-confidence threats (Jailbreak score > 0.9, PII detected) to log all requests and responses and alert on issues for medium-severity flags (Jailbreak score 0.5-0.9) in flagged content based on findings (tighten thresholds, add custom rules) as new threats emerge *** ## How These Evaluators Can Help ### 1. Prevent Security Incidents Before They Occur Real-time guardrails act as a security perimeter, blocking malicious inputs and harmful outputs before they reach users. This prevents: * Reputational damage from AI generating offensive content * Legal liability from privacy violations * User harm from dangerous or misleading information ### 2. Detect and Respond to Emerging Threats Post-production observability helps you identify: * **New attack vectors:** Novel jailbreak techniques not caught by existing rules * **Systematic weaknesses:** Topics or phrasings where the model consistently fails safety checks * **Coordinated attacks:** Patterns suggesting organized attempts to compromise your AI ### 3. Maintain Compliance and Auditability For regulated industries, security monitoring provides: * **Audit trails** demonstrating proactive security measures * **Compliance evidence** for GDPR, CCPA, HIPAA, and other regulations * **Incident documentation** showing how you detected and responded to threats * **Risk assessment data** to support security reviews and certifications ### 4. Build Trust with Users Transparent security practices signal to users that you take their safety and privacy seriously: * Publish security metrics and response times * Communicate how you protect user data * Demonstrate continuous improvement in safety measures ### 5. Optimize Security vs. User Experience By analyzing false positives in observability dashboards, you can: * Tune guardrails to reduce unnecessary blocking * Identify legitimate use cases that trigger safety flags * Balance security rigor with user experience *** ## Get Started Ready to secure your AI applications? Here's how to begin: * Enable **Prompt Safety** for comprehensive threat detection * Enable **PII Detection** for privacy protection * Review evaluation results in Fiddler dashboards * Identify your highest-priority security requirements * Configure guardrails with appropriate thresholds * Test thoroughly before production deployment * Set up dashboards for key security metrics * Configure alerts for anomalies * Schedule regular security reviews * Analyze patterns in flagged content * Refine guardrail thresholds based on false positive/negative rates * Add custom LLM-as-a-Judge evaluators for organization-specific policies **For step-by-step tutorials:** * **Guardrails setup:** [Guardrails Quick Start](/developers/quick-starts/guardrails-quick-start) * **Enrichments & observability:** [Enrichments](/observability/llm/enrichments) * **Custom LLM-as-a-Judge:** [Prompt Specs Quick Start](/evaluate-and-test/prompt-specs-quick-start) **Security is not a one-time configuration, it's an ongoing practice.** By combining real-time guardrails with continuous observability, you can protect users, maintain compliance, and build AI systems worthy of trust. # Tracking Bias and Accuracy Across Cohorts Source: https://docs.fiddler.ai/developers/cookbooks/bias-and-accuracy Track GenAI accuracy and bias across protected cohorts using Fiddler out-of-the-box evaluators, custom LLM-as-a-Judge scoring, and segment-based fairness analysis. ## Overview GenAI applications span a wide variety of tasks, from summarization and information extraction to Q\&A systems and autonomous agents. Each task type presents unique challenges for accuracy measurement and bias detection. This cookbook provides a framework for selecting the right Fiddler evaluators (both out-of-the-box and custom LLM-as-a-Judge) to ensure your models deliver reliable, fair, and high-quality outputs across different use cases. ## Understanding Bias in GenAI **Bias** in GenAI primarily refers to unfair treatment of people by an LLM based on protected characteristics such as: * Nationality * Gender * Age * Socioeconomic status * Sexual orientation * Race/ethnicity This is the most critical concern when monitoring for bias in production systems. A model exhibits bias when it performs differently for users or content associated with different demographic groups. Beyond these social considerations, models can also exhibit **inconsistent behavior across different input types**—such as performing differently on technical documents vs. narrative content. While less critical than bias related to protected characteristics, tracking these patterns can still improve overall model quality. ### Measuring Bias with Fiddler **A great way to detect bias is to compare accuracy metrics across protected cohorts.** For example: * Does your Q\&A system achieve lower Answer Relevance scores for questions about certain cultural topics? * Does your summarization model produce less faithful summaries for content written by authors from specific demographic backgrounds? * Does your chatbot provide less helpful responses when discussing topics related to certain protected characteristics? Fiddler provides two complementary approaches for bias detection: 1. **LLM-as-a-Judge for individual assessment:** Custom evaluators that assess each request for potential bias indicators 2. **Segment analysis for comparative measurement:** Compare accuracy metrics across protected cohorts to identify disparities Both approaches are detailed in the Deep Dive sections below. ## Out-of-the-Box Evaluators These pre-built metrics provide immediate, generalized assessments of LLM performance. They offer a quick, low-effort way to establish a baseline for quality and compliance. **Learn more:** [Enrichments](/observability/llm/enrichments) ## Custom LLM-as-a-Judge Evaluators These evaluators allow you to inject specific business rules and task-specific quality standards directly into the evaluation process. By using a structured prompt template to define the criteria, the LLM acts as an automated, scalable subject matter expert, turning nuanced judgments into objective, trackable data. **Learn more:** [Prompt Specs Quick Start](/evaluate-and-test/prompt-specs-quick-start) ## Recommended Evaluators by GenAI Task ### Summarization **Use Case Description:** Summarization models condense long-form content (documents, articles, meeting transcripts, research papers) into concise summaries while preserving key information and maintaining factual accuracy. **Accuracy Evaluators:** | Evaluator | What does it measure? | What value does it provide? | | ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | | **Faithfulness** (optimized for summarization) | Assesses whether the summary accurately represents the source material without introducing hallucinations or distortions. | **Accuracy Baseline:** Ensures the summary doesn't fabricate or misrepresent information from the original text. | | **Conciseness** | Evaluates whether the summary is appropriately brief while retaining essential information. | **Efficiency:** Confirms the model is truly summarizing, not just excerpting or paraphrasing at length. | **Bias Detection Strategy:** * Tag summaries with metadata about source content (author demographics, topic categories, document type) * Compare Faithfulness and Conciseness scores across segments * You can also monitor token count differences between summaries of similar-length documents from different segments * Example: Do summaries of technical papers by women researchers average 20% fewer tokens than those by men, suggesting less thorough coverage? ### Information Extraction **Use Case Description:** Information extraction models parse unstructured or semi-structured text (invoices, receipts, contracts, emails, forms) to identify and extract specific data fields like names, dates, amounts, addresses, or custom entities relevant to your business. **Accuracy Evaluators:** | Evaluator | What does it measure? | What value does it provide? | | ------------------------------------- | --------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- | | **Per-Field Accuracy LLM-as-a-Judge** | Evaluates extraction accuracy for each specific field (e.g., "name," "date," "amount"). | **Granular Quality Control:** Pinpoints which fields the model extracts reliably vs. which require improvement. | | **Overall Accuracy LLM-as-a-Judge** | Assesses whether all required information was extracted correctly in aggregate. | **Completeness Check:** Ensures no critical data is missed during extraction. | **Bias Detection Strategy:** * Tag extractions with metadata about the source (document format, language, content domain, demographic context) * Compare per-field accuracy rates across segments * Example: Does the model correctly extract names from resumes with non-Western names at the same rate as Western names? ### Question & Answer (RAG Systems) **Use Case Description:** RAG (Retrieval-Augmented Generation) systems answer user questions by first retrieving relevant information from a knowledge base, then generating responses grounded in that context. These systems power customer support chatbots, internal knowledge assistants, and documentation search tools. **Note:** Evaluation strategies differ for **closed-ended questions** (verifiable facts) vs. **open-ended questions** (requiring interpretation). **Accuracy Evaluators:** | Evaluator | What does it measure? | What value does it provide? | | --------------------- | ---------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Answer Relevance** | Assesses whether the response accurately addresses the user's question. | **Intent Matching:** Especially critical for open-ended questions—confirms the response addresses the *spirit* of the question, not just surface-level keywords. | | **RAG Faithfulness** | Evaluates whether the answer is grounded in the retrieved context without hallucination. | **Factual Accuracy:** For closed-ended questions, ensures the model said the "right thing" based on retrieved documents. For open-ended questions, confirms claims are supported by context. | | **Context Relevance** | Measures whether the retrieved documents are actually relevant to the question. | **Retrieval Quality:** Identifies when the retrieval subsystem is returning poor-quality or off-topic context. | | **Conciseness** | Evaluates whether answers are appropriately brief. | **User Experience:** Prevents over-explaining simple questions or burying key information in verbose responses. | **Closed-Ended vs. Open-Ended Questions:** * **Closed-Ended:** "What is the capital of France?" → Focus on **RAG Faithfulness** (Did it say "Paris"?) * **Open-Ended:** "How can I improve team productivity?" → Focus on **Answer Relevance** (Does it address the intent?) and **RAG Faithfulness** (Are suggestions grounded in retrieved best practices?) **Bias Detection Strategy:** * Tag questions with metadata about topic category, user demographics (if available), or question complexity * Compare Answer Relevance and RAG Faithfulness scores across segments * Monitor **response token count** and **sentiment** across different question types * Example: Do questions about minority health issues receive lower Answer Relevance scores or shorter responses than general health questions? ### Chatbots **Use Case Description:** Conversational AI agents engage in multi-turn dialogues with users for customer support, HR assistance, IT helpdesk, sales qualification, or general-purpose assistance. Unlike simple Q\&A, chatbots maintain conversation context and handle follow-up questions. **Accuracy Evaluators:** | Evaluator | What does it measure? | What value does it provide? | | ---------------------- | --------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | | **Answer Relevance** | Assesses whether responses stay on-topic throughout the conversation. | **Conversational Coherence:** Prevents the chatbot from drifting off-topic or ignoring user intent. | | **RAG Faithfulness** | Ensures responses are grounded in retrieved knowledge (if using RAG). | **Trust Building:** Users trust chatbots that cite or reference real information rather than making things up. | | **Sentiment Analysis** | Tracks the emotional tone of chatbot responses. | **Tone Management:** Ensures the bot maintains an appropriate, helpful tone even when users are frustrated. | **Note:** Apply the same **Context Relevance** and **Conciseness** evaluators recommended for Q\&A systems if your chatbot uses retrieval. **Bias Detection Strategy:** * Tag conversations with user demographics, conversation topic, or user satisfaction ratings * Compare Answer Relevance, RAG Faithfulness, and Sentiment scores across segments * Monitor **average response length** and **response time** across different user groups * Example: Do users from certain demographic groups receive responses with consistently more negative sentiment or fewer tokens? ### Classification **Use Case Description:** Classification models categorize text inputs into predefined classes. Common applications include sentiment analysis (positive/negative/neutral), topic categorization (finance/sports/politics), intent detection (purchase/support/information), content moderation, and spam filtering. **Accuracy Measurement Strategy:** For GenAI classification tasks, traditional ML performance metrics such as precision, recall, and F1-score are highly effective. Since the task can be treated the same way as a predictive ML task, these metrics provide quantitative benchmarks for application performance. **Bias Detection Strategy:** * Tag classifications with metadata about input characteristics (writing style, topic, demographic context) * Compare precision, recall, and F1 scores across segments in Fiddler * Example: Does sentiment classification achieve 85% accuracy for product reviews written by younger users but only 70% for older users? ### Autonomous Agents **Use Case Description:** Autonomous agents are AI systems that independently plan, execute multi-step workflows, call external tools or APIs, and make decisions to accomplish complex goals. Examples include AI assistants that can book travel, research assistants that gather and synthesize information, or automation agents that handle business processes. **Accuracy Evaluators:** | Evaluator | What does it measure? | What value does it provide? | | ------------------------------------- | ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------- | | **Tool Call Accuracy LLM-as-a-Judge** | Evaluates whether the agent selected and invoked the correct tool with proper parameters. | **Execution Reliability:** Prevents the agent from calling the wrong APIs or passing invalid arguments. | | **Context Relevance** | Assesses whether the agent retrieved or used appropriate information before taking action. | **Decision Quality:** Ensures the agent's actions are informed by relevant context. | **Bias Detection Strategy:** * Tag agent interactions with task type, user demographics, or workflow complexity * Compare Context Relevance and Tool Call Accuracy across segments * Monitor **number of tool calls** and **task completion time** across different user groups * Example: Does the agent require more steps to complete identical tasks for certain user populations? ### Code Generation **Use Case Description:** Code generation models translate natural language descriptions into working code. Applications range from developer productivity tools (generating boilerplate, writing tests, explaining code) to low-code/no-code platforms where non-developers can create automation scripts or data processing pipelines. **Accuracy Evaluators:** | Evaluator | What does it measure? | What value does it provide? | | ------------------------- | --------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | | **Custom LLM-as-a-Judge** | Evaluates code quality, correctness, security, and adherence to coding standards. | **Code Review Automation:** Acts as a first-pass reviewer to catch obvious errors, security vulnerabilities, or style violations. | **Bias Detection Strategy:** * Tag code generation requests with programming language, user experience level, or problem domain * Compare correctness and security scores across segments * Monitor **generated code token count** for similar requests across different segments * Example: Does the model generate less secure code for web development tasks compared to data science tasks? ### Content Generation **Use Case Description:** Content generation models create original written content tailored to specific audiences and purposes. Applications include marketing copy, blog posts, social media content, email campaigns, product descriptions, internal communications, and creative writing assistance. **Accuracy Evaluators:** | Evaluator | What does it measure? | What value does it provide? | | --------------------------------------------- | ----------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | | **Answer Relevance** | Assesses whether the content addresses the original prompt or brief. | **Instruction Adherence:** Ensures the model delivers what was requested, not something tangentially related. | | **Custom LLM-as-a-Judge: Audience Alignment** | Evaluates whether the content is appropriate for the target audience (tone, complexity, terminology). | **Targeted Communication:** Confirms the content speaks to the intended reader (e.g., executives vs. technical users vs. general public). | | **Coherence** | Assesses logical flow and narrative quality. | **Readability:** Ensures content is easy to follow and professionally written. | | **Sentiment Analysis** | Tracks the emotional tone of generated content. | **Brand Safety:** Prevents overly negative or inappropriate messaging from reaching audiences. | **Bias Detection Strategy:** * Tag content with target audience demographics, topic category, or content type * Compare Answer Relevance, Coherence, and audience alignment scores across segments * Monitor **content token count** and **sentiment scores** for similar prompts targeting different audiences * Example: Does content generated for female audiences consistently receive lower Coherence scores or different sentiment patterns than content for male audiences? ## Deep Dive: Detecting Bias with LLM-as-a-Judge LLM-as-a-Judge evaluators can be designed to assess individual requests for potential bias indicators. This approach is most effective when you have **specific bias criteria** you want to detect in each prompt or response. ### When to Use LLM-as-a-Judge for Bias Detection Use this approach when you need to: * **Flag potentially biased content** in individual responses (e.g., stereotypical language, exclusionary phrasing) * **Assess prompt safety** for bias-related concerns (e.g., requests that might elicit biased responses) * **Evaluate fairness** of individual outputs (e.g., does a job description use inclusive language?) * **Score bias indicators** that can later be aggregated across segments ### Limitations of LLM-as-a-Judge for Bias Detection **Important:** LLM-as-a-Judge evaluators process one request at a time and **cannot compare performance across demographic groups**. They can identify potentially problematic content, but they cannot tell you if your model performs differently for different user populations. For that, you need **segment analysis** (see next section). ## Deep Dive: Detecting Bias Through Segment Analysis Segment analysis is the most powerful method for detecting **performance disparities** across protected cohorts. By comparing accuracy metrics between demographic groups, you can identify systemic bias in your GenAI systems. ### How Segment Analysis Works Since LLM-as-a-Judge evaluators process requests individually and cannot compare across prompts, Fiddler enables bias detection through a four-step process: #### Step 1: Apply Accuracy Evaluators to All Requests Use the appropriate out-of-the-box and custom LLM-as-a-Judge evaluators for your use case (as outlined above) to score every request for accuracy and quality. **Examples:** * **Summarization:** Faithfulness, Conciseness * **Q\&A:** Answer Relevance, RAG Faithfulness * **Content Generation:** Answer Relevance, Coherence, Audience Alignment * **Information Extraction:** Per-Field Accuracy, Overall Accuracy #### Step 2: Tag Requests with Relevant Metadata Enrich your data with tags that enable meaningful comparisons. The specific tags depend on your use case: **User-level tags:** * Demographics (age group, gender, location, language) * User segment (enterprise vs. SMB, premium vs. free tier) * Experience level (new user vs. power user) **Content-level tags:** * Topic category (e.g., "women's health" vs. "men's health" vs. "general health") * Content source (author demographics, publication type) * Language or dialect * Domain (technical vs. general, formal vs. informal) **Interaction-level tags:** * Channel (web, mobile, API) * Time of day * Session length #### Step 3: Compare Metrics Across Segments in Fiddler Use Fiddler's dashboards to calculate and compare: **Accuracy metrics:** * Average Answer Relevance, Faithfulness, Coherence scores by segment * Per-field extraction accuracy rates by segment * Classification precision/recall/F1 by segment **Behavioral metrics:** * Token count distributions (are responses equally detailed?) * Response time (do certain queries take longer?) * Retrieval quality (Context Relevance by segment) * Sentiment patterns (are responses equally positive/neutral?) #### Step 4: Investigate Disparities When you identify statistically significant differences: **Quantify the gap:** * What's the magnitude of the disparity? (e.g., 15% difference in Faithfulness scores) * How many users are affected? * Is the gap consistent over time or growing? **Root cause analysis:** * Is the bias in the training data? * Is it in the prompt or system instructions? * Is it in the retrieval system (for RAG applications)? * Is it in the evaluation criteria themselves? **Remediation:** * Adjust prompts to be more explicit about fairness requirements * Augment training data to balance representation * Retrain or fine-tune models * Filter or reweight retrieval results * Update evaluation criteria to catch edge cases ### Example: Detecting Gender Bias in a Healthcare Q\&A System **Scenario:** You want to ensure your healthcare Q\&A system provides equally helpful answers regardless of the topic's demographic context. **Implementation:** **Step 1: Apply Accuracy Evaluators** * Enable **Answer Relevance** evaluator for all questions * Enable **RAG Faithfulness** evaluator for all questions **Step 2: Tag Questions by Topic** Create a tagging system for health topics: * `topic: "women's health"` (menstruation, pregnancy, menopause, etc.) * `topic: "men's health"` (prostate health, testosterone, etc.) * `topic: "general health"` (nutrition, exercise, sleep, etc.) * `topic: "pediatric care"` (child development, vaccinations, etc.) **Step 3: Compare Metrics in Fiddler** Create segments for each topic category and compare. Example: | Segment | Avg Answer Relevance | Avg RAG Faithfulness | Avg Response Length (tokens) | Sample Size | | -------------- | -------------------- | -------------------- | ---------------------------- | ----------- | | Women's health | 0.78 | 0.82 | 145 | 1,247 | | Men's health | 0.91 | 0.89 | 203 | 1,156 | | General health | 0.88 | 0.87 | 195 | 3,892 | | Pediatric care | 0.85 | 0.86 | 188 | 891 | **Step 4: Investigate & Remediate** **Finding:** Women's health questions receive: * 14% lower Answer Relevance scores (0.78 vs. 0.91) * 8% lower RAG Faithfulness scores (0.82 vs. 0.89) * 29% shorter responses (145 vs. 203 tokens) **Root Cause Investigation:** 1. Examine retrieved documents for women's health queries → Discovery: Knowledge base has 40% fewer articles on women's health topics 2. Review sample low-scoring responses → Discovery: Model often retrieves general health content instead of women's-health-specific sources 3. Check Context Relevance scores → Discovery: Retrieved documents are less relevant for women's health (0.72 vs. 0.85 for men's health) **Remediation Actions:** 1. **Immediate:** Adjust retrieval parameters to prioritize topic-specific matches 2. **Short-term:** Expand knowledge base with high-quality women's health content 3. **Medium-term:** Fine-tune retrieval model on balanced health topic dataset 4. **Ongoing:** Monitor disparity metrics weekly to ensure improvement **Example Result After Remediation:** *Numbers below are illustrative.* | Segment | Avg Answer Relevance | Avg RAG Faithfulness | Avg Response Length (tokens) | | -------------- | -------------------- | -------------------- | ---------------------------- | | Women's health | 0.86 ↑ | 0.87 ↑ | 192 ↑ | | Men's health | 0.91 | 0.89 | 203 | Gap reduced from 14% to 5% for Answer Relevance. ### Advanced Segment Analysis Techniques **1. Intersectional Analysis** You can also examine intersections in protected groups rather than just single demographic attributes: * How does the system perform for questions about "women's health" in Spanish vs. English? * Do younger users get different quality responses than older users for the same topics? **2. Temporal Monitoring** Track metrics over time to catch drift: * Did a model update introduce new disparities? * Are gaps widening or narrowing? * Do disparities appear at certain times of day or during high-traffic periods? **3. Cohort Comparison** Compare multiple segments simultaneously: ```text theme={null} Segment Analysis: Answer Relevance by Topic - Women's health: 0.78 - Men's health: 0.91 - LGBTQ+ health: 0.74 ← Additional disparity discovered - General health: 0.88 ``` **4. Statistical Significance Testing** Ensure observed differences aren't due to random variation: * Use adequate sample sizes for each segment * Calculate confidence intervals * Apply appropriate statistical tests (t-tests, ANOVA, etc.) ## How These Evaluators Can Help ### 1. Establishing Accuracy Baselines By combining out-of-the-box metrics (like Faithfulness, Answer Relevance) with custom LLM-as-a-Judge evaluators, you create a comprehensive accuracy profile for your GenAI application. This lets you: * Set quality thresholds (e.g., "95% of summaries must achieve Faithfulness > 0.85") * Compare model versions objectively * Track accuracy degradation over time ### 2. Detecting Bias at Scale Manual review of thousands of responses for bias is impractical. By combining LLM-as-a-Judge flagging with segment analysis, you can: * **Flag problematic individual outputs** for immediate remediation * **Quantify fairness gaps** across demographic groups with statistical rigor * **Identify systemic disparities** that would be invisible in aggregate metrics * **Build audit trails** demonstrating proactive bias monitoring for compliance ### 3. Continuous Monitoring & Improvement By tracking these metrics in Fiddler over time, you can: * Identify systemic drift in accuracy or bias after model updates * Catch when prompt changes inadvertently introduce new biases * Build feedback loops that route low-quality outputs for retraining data * Measure the effectiveness of bias mitigation efforts ### 4. Compliance & Governance For regulated industries, bias detection isn't just about fairness—it's about compliance. Automated bias tracking provides an audit trail showing you actively monitor and mitigate unfair treatment, which can be critical for regulatory reviews and demonstrating responsible AI practices. ## Related Resources * [Evaluator Rules](/evaluate-and-test/evaluator-rules) * [Prompt Specs Quick Start](/evaluate-and-test/prompt-specs-quick-start) # Overview Source: https://docs.fiddler.ai/developers/cookbooks/cookbooks Use-case oriented guides for solving real-world AI evaluation and monitoring problems with Fiddler. Cookbooks are use-case oriented guides that demonstrate end-to-end workflows for solving real problems with Fiddler. Unlike quick starts (which introduce product features) or tutorials (which deep-dive into specific capabilities), cookbooks are organized by scenario — they show you how to combine multiple Fiddler features to achieve a practical goal. **Prerequisites for all cookbooks** * Fiddler account with API access * Python 3.10+ * Fiddler Evals SDK: `pip install fiddler-evals` * LLM credential configured in **Settings > LLM Gateway** ## RAG Evaluation & Monitoring | Cookbook | Use Case | Key Features | | ----------------------------------------------------------------------------------------- | --------------------------------------------------- | ---------------------------------------------------------------- | | [RAG Evaluation Fundamentals](/developers/cookbooks/rag-evaluation-fundamentals) | "I have a RAG app and want to evaluate its quality" | RAG Faithfulness, Answer Relevance, direct `.score()` API | | [Running RAG Experiments at Scale](/developers/cookbooks/rag-experiments-at-scale) | "I want to compare RAG pipeline configurations" | Datasets, Experiments, `evaluate()`, golden label validation | | [Detecting Hallucinations in RAG](/developers/cookbooks/hallucination-detection-pipeline) | "I want to monitor my RAG app for hallucinations" | RAG Health triad, Evaluator Rules, LLM Observability enrichments | ## Custom Evaluators | Cookbook | Use Case | Key Features | | --------------------------------------------------------------------------------- | -------------------------------------------- | ----------------------------------------------------------------------- | | [Building Custom Judge Evaluators](/developers/cookbooks/custom-judge-evaluators) | "I need domain-specific evaluation criteria" | `CustomJudge`, prompt templates, `output_fields`, iterative improvement | ## Agentic AI | Cookbook | Use Case | Key Features | | ----------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | ---------------------------------------------------- | | [Monitoring Agentic Content Generation](/developers/cookbooks/agentic-content-generation) | "I want to ensure quality and brand compliance in content generation agents" | Built-in evaluators + custom Brand Voice Match judge | *** ## Related Resources * [Experiments Getting Started](/getting-started/experiments) — Product overview * [Experiments Quick Start](/developers/quick-starts/experiments-quick-start) — SDK setup and first experiment * [RAG Health Diagnostics](/concepts/rag-health-diagnostics) — Conceptual guide to the diagnostic triad * [Evals SDK Advanced Guide](/developers/tutorials/experiments/evals-sdk-advanced) — Advanced patterns # Building Custom Judge Evaluators Source: https://docs.fiddler.ai/developers/cookbooks/custom-judge-evaluators Build domain-specific LLM-as-a-Judge evaluators using CustomJudge with prompt templates, structured output fields, and iterative prompt improvement. Create domain-specific evaluators using `CustomJudge` to encode business rules, quality criteria, or classification tasks that built-in evaluators don't cover. **Use this cookbook when:** You need evaluation criteria specific to your domain, such as topic classification, brand voice matching, compliance checking, or custom quality rubrics. **Time to complete**: \~20 minutes ```mermaid theme={null} graph LR A["Define Prompt\nTemplate"] --> B["Set Output\nFields"] B --> C["Run\nEvaluation"] C --> D["Check\nAccuracy"] D -->|Misclassifications| E["Refine Prompt\n& Add Constraints"] E --> C D -->|Accurate| F["Deploy"] style E fill:#ffd,stroke:#333 style F fill:#6f9,stroke:#333 ``` **Prerequisites** * Fiddler account with API access * LLM credential configured in **Settings > LLM Gateway** * `pip install fiddler-evals pandas` *** Replace `URL`, `TOKEN`, and credential names with your Fiddler account details. Find your credentials in **Settings > Access Tokens** and **Settings > LLM Gateway**. ```python theme={null} import pandas as pd from fiddler_evals import init from fiddler_evals.evaluators import CustomJudge URL = 'https://your-org.fiddler.ai' TOKEN = 'your-access-token' LLM_CREDENTIAL_NAME = 'your-llm-credential' LLM_MODEL_NAME = 'openai/gpt-4o' init(url=URL, token=TOKEN) ``` This example classifies news summaries into topics — **Sci/Tech**, **Sports**, **Business**, or **World**: ```python theme={null} df = pd.DataFrame( [ { 'text': 'Google announces new AI chip designed to accelerate ' 'machine learning workloads.', 'ground_truth': 'Sci/Tech', }, { 'text': 'The Lakers defeated the Celtics 112-108 in overtime, ' 'with LeBron James scoring 35 points.', 'ground_truth': 'Sports', }, { 'text': 'Federal Reserve raises interest rates by 0.25% citing ' 'persistent inflation concerns.', 'ground_truth': 'Business', }, { 'text': 'United Nations Security Council votes to impose new ' 'sanctions on North Korea.', 'ground_truth': 'World', }, { 'text': 'Microsoft acquires gaming company Activision Blizzard ' 'for $69 billion.', 'ground_truth': 'Sci/Tech', }, ] ) ``` Define your evaluation criteria using a `prompt_template` with `{{ placeholder }}` markers and `output_fields` that define the structured response: ```python theme={null} simple_judge = CustomJudge( prompt_template=""" Determine the topic of the given news summary. Pick one of: Sports, World, Sci/Tech, Business. News Summary: {{ news_summary }} """, output_fields={ 'topic': {'type': 'string'}, 'reasoning': {'type': 'string'}, }, model=LLM_MODEL_NAME, credential=LLM_CREDENTIAL_NAME, ) ``` **How It Works** * **`prompt_template`**: Your evaluation prompt with `{{ placeholder }}` markers (Jinja syntax). Placeholders are filled from the `inputs` dict passed to `.score()`. * **`output_fields`**: Schema defining the expected outputs. Each field specifies a `type` (`string`, `boolean`, `integer`, `number`) and optional `choices` or `description`. ```python theme={null} results = [] for _, row in df.iterrows(): scores = simple_judge.score(inputs={'news_summary': row['text']}) scores_dict = {s.name: s for s in scores} results.append( { 'ground_truth': row['ground_truth'], 'predicted': scores_dict['topic'].label, 'reasoning': scores_dict['reasoning'].label, } ) results_df = pd.DataFrame(results) accuracy = (results_df['ground_truth'] == results_df['predicted']).mean() print(f'Accuracy: {accuracy:.0%}') # Show misclassified misclassified = results_df[results_df['ground_truth'] != results_df['predicted']] if len(misclassified) > 0: print(f'\nMisclassified ({len(misclassified)}):') for _, row in misclassified.iterrows(): print(f' Expected: {row["ground_truth"]}, Predicted: {row["predicted"]}') ``` **Expected output:** ``` Accuracy: 80% Misclassified (1): Expected: Sci/Tech, Predicted: Business ``` The simple prompt often confuses tech company acquisitions (like the Microsoft-Activision deal) with Business news. The next step shows how to fix this with clearer topic guidelines. Add clearer topic guidelines and constrain outputs with `choices`: ```python theme={null} improved_judge = CustomJudge( prompt_template=""" Determine the topic of the given news summary. Use topic 'Sci/Tech' if the news summary is about a company or business in the tech industry, or if the news summary is about a scientific discovery or research, including health and medicine. Use topic 'Sports' if the news summary is about a sports event or athlete. Use topic 'Business' if the news summary is about a company or industry outside of science, technology, or sports. Use topic 'World' if the news summary is about a global event or issue. News Summary: {{ news_summary }} """, output_fields={ 'topic': { 'type': 'string', 'choices': ['Sci/Tech', 'Sports', 'Business', 'World'], }, 'reasoning': {'type': 'string'}, }, model=LLM_MODEL_NAME, credential=LLM_CREDENTIAL_NAME, ) ``` Key improvements: * **Explicit guidelines** for each topic eliminate ambiguity * **`choices`** constrains the LLM output to valid categories only **Compare Results** ```python theme={null} improved_results = [] for _, row in df.iterrows(): scores = improved_judge.score(inputs={'news_summary': row['text']}) scores_dict = {s.name: s for s in scores} improved_results.append( { 'ground_truth': row['ground_truth'], 'predicted': scores_dict['topic'].label, } ) improved_df = pd.DataFrame(improved_results) original_accuracy = (results_df['ground_truth'] == results_df['predicted']).mean() improved_accuracy = (improved_df['ground_truth'] == improved_df['predicted']).mean() print(f'Simple prompt: {original_accuracy:.0%}') print(f'Improved prompt: {improved_accuracy:.0%}') ``` **Expected output:** ``` Simple prompt: 80% Improved prompt: 100% ``` *** ## Output Field Types `CustomJudge` supports four output field types: | Type | Description | Example Use | | --------- | ---------------------------------------------- | --------------------------------------- | | `string` | Free-form text or categorical (with `choices`) | Topic classification, reasoning | | `boolean` | True/False | Compliance checks, binary quality gates | | `integer` | Whole numbers | 1-5 rating scales | | `number` | Floating-point | 0.0-1.0 confidence scores | ### Using `choices` for Categorical Output ```python theme={null} output_fields={ 'sentiment': { 'type': 'string', 'choices': ['positive', 'negative', 'neutral'], }, } ``` ### Using `description` to Guide the LLM ```python theme={null} output_fields={ 'quality_score': { 'type': 'integer', 'description': 'Overall quality rating from 1 (poor) to 5 (excellent)', }, } ``` *** ## Real-World Examples ### Brand Voice Match Evaluate whether generated content adheres to brand guidelines: ```python theme={null} brand_judge = CustomJudge( prompt_template=""" Determine whether the provided content adheres to the provided brand guidelines. Content: {{ content }} Brand Guidelines: {{ brand_guidelines }} """, output_fields={ 'voice_match_score': { 'type': 'string', 'choices': ['Perfect Match', 'Minor Deviations', 'Off-Brand'], }, 'reasoning': {'type': 'string'}, }, model=LLM_MODEL_NAME, credential=LLM_CREDENTIAL_NAME, ) scores = brand_judge.score(inputs={ 'content': 'Hey! Check out our AMAZING new product!!!', 'brand_guidelines': 'Use professional tone. Avoid exclamation marks ' 'and all-caps. Address customers formally.', }) ``` **Expected output:** ``` voice_match_score: Off-Brand reasoning: The content uses informal language ("Hey!"), multiple exclamation marks, and all-caps ("AMAZING"), all of which violate the brand guidelines. ``` ### Compliance Checking Verify responses meet regulatory requirements: ```python theme={null} compliance_judge = CustomJudge( prompt_template=""" Review the following financial advice response for regulatory compliance. Customer Question: {{ question }} Advisor Response: {{ response }} Check for: unauthorized guarantees, missing disclaimers, inappropriate risk characterization. """, output_fields={ 'compliant': { 'type': 'boolean', 'description': 'Does the response meet regulatory standards?', }, 'issues_found': { 'type': 'string', 'description': 'List any compliance issues identified', }, }, model=LLM_MODEL_NAME, credential=LLM_CREDENTIAL_NAME, ) ``` *** ## Next Steps * [Running RAG Experiments at Scale](/developers/cookbooks/rag-experiments-at-scale) — Use CustomJudge evaluators in structured experiments * [Monitoring Agentic Content Generation](/developers/cookbooks/agentic-content-generation) — Combine built-in evaluators with custom Brand Voice judges * [Evaluator Rules](/evaluate-and-test/evaluator-rules) — Deploy custom evaluators in production monitoring *** **Source notebook**: [Fiddler Cookbook: Custom Judge Evaluators](https://github.com/fiddler-labs/fiddler-examples/blob/main/cookbooks/Fiddler_Cookbook_Custom_Judge_Evaluators.ipynb) # Detecting Hallucinations in RAG Source: https://docs.fiddler.ai/developers/cookbooks/hallucination-detection-pipeline Build a complete hallucination detection pipeline combining Evals SDK evaluation with LLM Observability enrichments for continuous RAG monitoring. Build a hallucination detection pipeline that combines pre-deployment evaluation with the Evals SDK and continuous production monitoring through LLM Observability enrichments and Evaluator Rules. **Use this cookbook when:** You want to monitor your RAG application for hallucinations across both testing and production environments. **Time to complete**: \~25 minutes ```mermaid theme={null} graph LR subgraph "Layer 1: Pre-Deployment" A["Design Test Cases"] --> B["Run Diagnostic\nEvaluation"] B --> C["Classify\nFailure Modes"] end subgraph "Layer 2: Production" D["Evaluator Rules\n(Agentic)"] E["LLM Obs\nEnrichments"] end C --> D C --> E D --> F["Alerts &\nInvestigation"] E --> F style C fill:#ffd,stroke:#333 style F fill:#f96,stroke:#333 ``` **Prerequisites** * Fiddler account with API access * LLM credential configured in **Settings > LLM Gateway** * `pip install fiddler-evals fiddler-client pandas` *** ## The Two-Layer Approach Hallucination detection works best as a two-layer pipeline: | Layer | Tool | Purpose | | ------------------ | ----------------------------------- | --------------------------------------------------------- | | **Pre-deployment** | Evals SDK | Test against known scenarios, validate with golden labels | | **Production** | LLM Observability + Evaluator Rules | Continuous monitoring of live traffic | *** ## Layer 1: Pre-Deployment Evaluation Use the RAG Health Metrics triad to distinguish hallucinations from other failure modes: Replace `URL`, `TOKEN`, and credential names with your Fiddler account details. Find your credentials in **Settings > Access Tokens** and **Settings > LLM Gateway**. ```python theme={null} import pandas as pd from fiddler_evals import init, evaluate, Project, Application, Dataset from fiddler_evals.evaluators import ( AnswerRelevance, ContextRelevance, RAGFaithfulness, ) URL = 'https://your-org.fiddler.ai' TOKEN = 'your-access-token' LLM_CREDENTIAL_NAME = 'your-llm-credential' LLM_MODEL_NAME = 'openai/gpt-4o' init(url=URL, token=TOKEN) project = Project.get_or_create(name='hallucination_detection') app = Application.get_or_create( name='rag-hallucination-test', project_id=project.id, ) dataset = Dataset.get_or_create( name='hallucination-scenarios', application_id=app.id, ) ``` Design test cases that specifically probe for hallucination patterns: ```python theme={null} hallucination_scenarios = pd.DataFrame( [ { 'scenario': 'Grounded response', 'user_query': 'What is the return policy?', 'retrieved_documents': [ 'Returns accepted within 30 days with receipt.', ], 'rag_response': 'You can return items within 30 days ' 'if you have a receipt.', }, { 'scenario': 'Fabricated details', 'user_query': 'What is the return policy?', 'retrieved_documents': [ 'Returns accepted within 30 days with receipt.', ], 'rag_response': 'You can return items within 60 days. ' 'No receipt needed. We also offer free shipping on returns.', }, { 'scenario': 'Insufficient context', 'user_query': 'What are the shipping costs?', 'retrieved_documents': [ 'We ship to all 50 US states.', ], 'rag_response': 'Standard shipping is $5.99 and express ' 'shipping is $12.99.', }, ] ) dataset.insert_from_pandas( df=hallucination_scenarios, input_columns=['user_query', 'retrieved_documents', 'rag_response'], metadata_columns=['scenario'], ) ``` ```python theme={null} def passthrough_task(inputs, extras, metadata): return { 'rag_response': inputs['rag_response'], 'retrieved_documents': inputs['retrieved_documents'], } result = evaluate( dataset=dataset, task=passthrough_task, evaluators=[ RAGFaithfulness(model=LLM_MODEL_NAME, credential=LLM_CREDENTIAL_NAME), AnswerRelevance(model=LLM_MODEL_NAME, credential=LLM_CREDENTIAL_NAME), ContextRelevance(model=LLM_MODEL_NAME, credential=LLM_CREDENTIAL_NAME), ], score_fn_kwargs_mapping={ 'user_query': lambda x: x['inputs']['user_query'], 'retrieved_documents': 'retrieved_documents', 'rag_response': 'rag_response', }, ) ``` Use the diagnostic workflow to classify failures: ```python theme={null} for r in result.results: scores = {s.evaluator_name: s for s in r.scores} scenario = r.dataset_item.metadata.get('scenario', 'unknown') faithfulness = scores.get('rag_faithfulness') relevance = scores.get('answer_relevance') context = scores.get('context_relevance') # Classify the failure mode if faithfulness and faithfulness.value == 0: diagnosis = 'HALLUCINATION' elif context and context.value < 0.5: diagnosis = 'BAD RETRIEVAL' elif relevance and relevance.value < 0.5: diagnosis = 'OFF-TOPIC' else: diagnosis = 'HEALTHY' print(f'{scenario}: {diagnosis}') if faithfulness: print(f' Faithfulness: {faithfulness.label} — {faithfulness.reasoning}') ``` **Expected output:** ``` Grounded response: HEALTHY Faithfulness: yes — The response accurately reflects the return policy stated in the retrieved document. Fabricated details: HALLUCINATION Faithfulness: no — The response claims a 60-day return window and no receipt requirement, but the source document states 30 days with receipt. Insufficient context: HALLUCINATION Faithfulness: no — The response provides specific prices ($5.99, $12.99) that are not supported by the retrieved document. ``` **Reading the diagnosis:** The triad distinguishes *why* a response failed: * **HALLUCINATION** = Faithfulness fails (response fabricates information) * **BAD RETRIEVAL** = Context Relevance fails (wrong documents retrieved) * **OFF-TOPIC** = Answer Relevance fails (response doesn't address the question) *** ## Layer 2: Production Monitoring For applications using Agentic Monitoring, configure Evaluator Rules to continuously evaluate production spans: 1. Navigate to your application's **Evaluator Rules** tab 2. Add a rule for **RAG Faithfulness** 3. Map evaluator inputs to your span attributes: * `user_query` → your query span attribute * `rag_response` → your response span attribute * `retrieved_documents` → your context span attribute 4. Set alert thresholds (e.g., alert when faithfulness drops below 80%) See [Evaluator Rules](/evaluate-and-test/evaluator-rules) for step-by-step instructions. For applications using LLM Observability, configure enrichments during model onboarding to monitor for hallucinations: ```python theme={null} import fiddler as fdl fiddler_enrichments = [ # Faithfulness (Centor Model) for low-latency hallucination detection fdl.Enrichment( name='Faithfulness', enrichment='ftl_response_faithfulness', columns=['source_docs', 'response'], config={ 'context_field': 'source_docs', 'response_field': 'response', 'threshold': 0.5, }, ), # Safety enrichments fdl.Enrichment( name='Safety', enrichment='ftl_prompt_safety', columns=['question', 'response'], ), # Embeddings for drift detection fdl.TextEmbedding( name='Prompt TextEmbedding', source_column='question', column='Enrichment Prompt Embedding', ), ] ``` LLM Observability uses **Faithfulness (Centor Model)** (`ftl_response_faithfulness`), powered by a proprietary Fiddler Centor Model for low-latency scoring. This is a **different evaluator** from the RAG Faithfulness used in Layer 1 — it has different inputs (`context`, `response`) and outputs probability scores (`faithful_prob` 0.0–1.0) rather than binary labels. For detailed diagnostic reasoning, use **RAG Faithfulness** via Evaluator Rules or the Evals SDK. *** ## Combining Both Layers The most effective hallucination detection pipeline uses both layers: | Stage | What to Do | Tool | | ----------------- | ------------------------------------------ | -------------------------------------- | | **Development** | Test against known hallucination scenarios | Evals SDK + RAG Faithfulness | | **Pre-release** | Run experiments comparing pipeline changes | Evals SDK + full diagnostic triad | | **Production** | Continuous monitoring with alerting | Evaluator Rules or LLM Obs enrichments | | **Investigation** | Deep-dive into flagged events | Evals SDK `.score()` on specific cases | *** ## Next Steps * [RAG Health Diagnostics](/concepts/rag-health-diagnostics) — Conceptual guide to failure mode diagnosis * [RAG Evaluation Fundamentals](/developers/cookbooks/rag-evaluation-fundamentals) — Direct evaluation with `.score()` API * [Evaluator Rules](/evaluate-and-test/evaluator-rules) — Configure production monitoring rules *** **Source notebooks**: * [Fiddler Cookbook: RAG Evaluation Fundamentals](https://github.com/fiddler-labs/fiddler-examples/blob/main/cookbooks/Fiddler_Cookbook_RAG_Evaluation_Fundamentals.ipynb) * [Fiddler Quickstart: LLM Chatbot](https://github.com/fiddler-labs/fiddler-examples/blob/main/quickstart/latest/Fiddler_Quickstart_LLM_Chatbot.ipynb) # RAG Evaluation Fundamentals Source: https://docs.fiddler.ai/developers/cookbooks/rag-evaluation-fundamentals Evaluate RAG application quality using Fiddler's built-in evaluators with direct scoring for rapid iteration on retrieval and generation quality. Evaluate your RAG application's retrieval and generation quality using Fiddler's built-in evaluators. This cookbook demonstrates the direct `.score()` API for rapid iteration on test cases before scaling to full experiments. **Use this cookbook when:** You have a RAG application and want to quickly assess whether responses are faithful to retrieved documents and relevant to user queries. **Time to complete**: \~15 minutes ```mermaid theme={null} graph LR A["Define Test Cases"] --> B["Score with Evaluators"] B --> C{"Faithfulness?"} B --> D{"Relevance?"} C -->|Yes| E["Grounded"] C -->|No| F["Hallucination"] D -->|High| G["On-topic"] D -->|Low| H["Off-topic"] style F fill:#f96,stroke:#333 style H fill:#f96,stroke:#333 style E fill:#6f9,stroke:#333 style G fill:#6f9,stroke:#333 ``` **Prerequisites** * Fiddler account with API access * LLM credential configured in **Settings > LLM Gateway** * `pip install fiddler-evals pandas` *** Replace `URL`, `TOKEN`, and credential names with your Fiddler account details. Find your credentials in **Settings > Access Tokens** and **Settings > LLM Gateway**. ```python theme={null} import pandas as pd from fiddler_evals import init from fiddler_evals.evaluators import RAGFaithfulness, AnswerRelevance URL = 'https://your-org.fiddler.ai' TOKEN = 'your-access-token' LLM_CREDENTIAL_NAME = 'your-llm-credential' # From Settings > LLM Gateway LLM_MODEL_NAME = 'openai/gpt-4o' # Or your preferred model init(url=URL, token=TOKEN) # Initialize evaluators faithfulness = RAGFaithfulness(model=LLM_MODEL_NAME, credential=LLM_CREDENTIAL_NAME) relevance = AnswerRelevance(model=LLM_MODEL_NAME, credential=LLM_CREDENTIAL_NAME) ``` Define representative test cases that cover both successful and failing RAG scenarios: ```python theme={null} test_cases = pd.DataFrame( [ { 'scenario': 'Perfect Match', 'user_query': 'What is the capital of France?', 'retrieved_documents': ['Paris is the capital of France.'], 'rag_response': 'The capital of France is Paris.', }, { 'scenario': 'Hallucination', 'user_query': 'What are the office hours?', 'retrieved_documents': ['We are closed on weekends.'], 'rag_response': 'We are open 9 AM to 5 PM every day.', }, { 'scenario': 'Irrelevant Answer', 'user_query': 'How do I reset my password?', 'retrieved_documents': ['To reset, click "Forgot Password".'], 'rag_response': 'Our system is very secure and uses 256-bit encryption.', }, ] ) ``` Use the `.score()` method to evaluate each test case directly. Each evaluator returns a `Score` object with `value`, `label`, and `reasoning`: ```python theme={null} def evaluate_row(row): f_score = faithfulness.score( user_query=row['user_query'], rag_response=row['rag_response'], retrieved_documents=row['retrieved_documents'], ) r_score = relevance.score( user_query=row['user_query'], rag_response=row['rag_response'], ) return pd.Series( { 'Faithfulness': f_score.label, 'Relevance': r_score.label, 'Status': 'HEALTHY' if f_score.label == 'yes' and r_score.value >= 0.5 else 'ISSUE DETECTED', } ) results = test_cases.join(test_cases.apply(evaluate_row, axis=1)) ``` ```python theme={null} results[['scenario', 'Faithfulness', 'Relevance', 'Status']] ``` **Expected output:** | scenario | Faithfulness | Relevance | Status | | ----------------- | ------------ | --------- | -------------- | | Perfect Match | yes | high | HEALTHY | | Hallucination | no | high | ISSUE DETECTED | | Irrelevant Answer | yes | low | ISSUE DETECTED | The hallucination case scores high on relevance (it addresses the question) but fails faithfulness (the response fabricates hours not in the context). The irrelevant answer is faithful to the context but doesn't actually answer the user's question. *** ## Understanding the Evaluators ### [RAG Faithfulness](/sdk-api/evals/rag-faithfulness) RAG Faithfulness checks whether the response is grounded in the retrieved documents. * **Inputs**: `user_query`, `rag_response`, `retrieved_documents` * **Scoring**: Binary — Yes (1.0) / No (0.0) * **Use for**: Detecting hallucinations where the LLM generates plausible but unsupported claims ### [Answer Relevance](/sdk-api/evals/answer-relevance) Answer Relevance measures how well the response addresses the user's query. * **Inputs**: `user_query`, `rag_response` (+ optional `retrieved_documents`) * **Scoring**: Ordinal — High (1.0), Medium (0.5), Low (0.0) * **Use for**: Detecting off-topic responses where the LLM answers a different question **RAG Faithfulness vs. Faithfulness (Centor Model):** This cookbook uses `RAGFaithfulness`, an LLM-as-a-Judge evaluator. Fiddler also offers `FTLResponseFaithfulness`, powered by a proprietary Fiddler Centor Model with different inputs (`context`, `response`) and probability-based scoring (`faithful_prob` 0.0–1.0). These are separate evaluators — see the [Evaluators Glossary](/glossary/enrichment) for details. *** ## Next Steps * [Running RAG Experiments at Scale](/developers/cookbooks/rag-experiments-at-scale) — Use Datasets and Experiments to evaluate systematically across larger test sets * [Detecting Hallucinations in RAG](/developers/cookbooks/hallucination-detection-pipeline) — Set up continuous hallucination monitoring in production * [RAG Health Diagnostics](/concepts/rag-health-diagnostics) — Conceptual guide to the diagnostic triad *** **Source notebook**: [Fiddler Cookbook: RAG Evaluation Fundamentals](https://github.com/fiddler-labs/fiddler-examples/blob/main/cookbooks/Fiddler_Cookbook_RAG_Evaluation_Fundamentals.ipynb) # Running RAG Experiments at Scale Source: https://docs.fiddler.ai/developers/cookbooks/rag-experiments-at-scale Run structured RAG experiments with Datasets, golden label validation, and side-by-side comparison of pipeline configurations. Move beyond ad-hoc evaluation to structured experiments that track results, validate against golden labels, and enable side-by-side comparison of RAG pipeline configurations. **Use this cookbook when:** You want to compare different retrieval strategies, LLM models, or prompt configurations across a standardized test set. **Time to complete**: \~25 minutes ```mermaid theme={null} graph TD A["Project"] --> B["Application"] B --> C["Dataset"] C --> D["Experiment v1"] C --> E["Experiment v2"] D --> F["Compare Results"] E --> F subgraph Evaluators G["Context Relevance"] H["RAG Faithfulness"] I["Answer Relevance"] end D -.-> Evaluators E -.-> Evaluators ``` **Prerequisites** * Fiddler account with API access * LLM credential configured in **Settings > LLM Gateway** * `pip install fiddler-evals pandas` * Familiarity with [RAG Evaluation Fundamentals](/developers/cookbooks/rag-evaluation-fundamentals) recommended *** Experiments are organized as: **Project > Application > Dataset > Experiment** Replace `URL`, `TOKEN`, and credential names with your Fiddler account details. Find your credentials in **Settings > Access Tokens** and **Settings > LLM Gateway**. ```python theme={null} import pandas as pd from fiddler_evals import Application, Dataset, Project, evaluate, init from fiddler_evals.evaluators import AnswerRelevance, ContextRelevance, RAGFaithfulness URL = 'https://your-org.fiddler.ai' TOKEN = 'your-access-token' LLM_CREDENTIAL_NAME = 'your-llm-credential' LLM_MODEL_NAME = 'openai/gpt-4o' init(url=URL, token=TOKEN) project = Project.get_or_create(name='rag_experiments') application = Application.get_or_create( name='rag-pipeline-comparison', project_id=project.id, ) dataset = Dataset.get_or_create( name='rag-test-cases', application_id=application.id, ) ``` Include `expected_quality` labels so you can validate whether evaluators correctly identify good and bad responses: ```python theme={null} rag_data = pd.DataFrame( [ { 'scenario': 'Perfect Match', 'expected_quality': 'good', 'user_query': 'What is the capital of France?', 'retrieved_documents': [ 'Paris is the capital and largest city of France.', 'France is located in Western Europe.', ], 'rag_response': 'The capital of France is Paris.', }, { 'scenario': 'Irrelevant Context', 'expected_quality': 'bad', 'user_query': 'How do I reset my password?', 'retrieved_documents': [ 'To make pasta, boil water and add salt.', 'Italian cuisine features many pasta dishes.', ], 'rag_response': 'To reset your password, go to the login page ' 'and click Forgot Password.', }, { 'scenario': 'Hallucination', 'expected_quality': 'bad', 'user_query': 'What are the business hours?', 'retrieved_documents': [ 'Our office is located at 123 Main Street.', 'We are closed on federal holidays.', ], 'rag_response': 'Our business hours are Monday through Friday, ' '9 AM to 5 PM.', }, { 'scenario': 'Irrelevant Answer', 'expected_quality': 'bad', 'user_query': 'What is your return policy?', 'retrieved_documents': [ 'Returns are accepted within 30 days of purchase.', 'Items must be unused and in original packaging.', ], 'rag_response': 'We offer free shipping on orders over $50. ' 'Delivery takes 3-5 business days.', }, ] ) ``` ```python theme={null} if not list(dataset.get_items()): dataset.insert_from_pandas( df=rag_data, input_columns=['user_query', 'retrieved_documents', 'rag_response'], expected_output_columns=['expected_quality'], metadata_columns=['scenario'], ) print(f'Inserted {len(rag_data)} test cases') else: print('Dataset already has items, skipping insert') ``` **Expected output:** ``` Inserted 4 test cases ``` The idempotency check (`if not list(dataset.get_items())`) prevents duplicate inserts if you re-run the notebook. Remove this check if you want to refresh the dataset. Define a task function that returns the RAG response, then run the experiment with all three RAG Health evaluators: ```python theme={null} def rag_task(inputs: dict, extras: dict, metadata: dict) -> dict: """Return pre-recorded RAG response. Replace with your actual RAG pipeline in production. """ return {'rag_response': inputs['rag_response']} evaluators = [ ContextRelevance(model=LLM_MODEL_NAME, credential=LLM_CREDENTIAL_NAME), RAGFaithfulness(model=LLM_MODEL_NAME, credential=LLM_CREDENTIAL_NAME), AnswerRelevance(model=LLM_MODEL_NAME, credential=LLM_CREDENTIAL_NAME), ] result = evaluate( dataset=dataset, task=rag_task, evaluators=evaluators, score_fn_kwargs_mapping={ 'user_query': lambda x: x['inputs']['user_query'], 'retrieved_documents': lambda x: x['inputs']['retrieved_documents'], 'rag_response': 'rag_response', }, ) print(f'Experiment: {result.experiment.name}') print(f'Evaluated {len(result.results)} test cases') ``` **Understanding `score_fn_kwargs_mapping`:** This dict maps evaluator parameter names to data sources. Use a **lambda** to extract values from dataset inputs (`x['inputs']['...']`), or a **string** to reference a key from the task function's return dict. **Expected output:** ``` Experiment: rag-test-cases-2026-02-07-001 Evaluated 4 test cases ``` Check whether the evaluators correctly identified quality issues by comparing their scores against your expected labels: ```python theme={null} from fiddler_evals.pydantic_models.experiment import ExperimentItemResult from fiddler_evals.pydantic_models.score import Score validation_results = [] correct = 0 for r in result.results: expected = r.dataset_item.expected_outputs.get('expected_quality') has_problem = any(s.value < 0.5 for s in r.scores) predicted = 'bad' if has_problem else 'good' if expected == predicted: correct += 1 validation_results.append( ExperimentItemResult( experiment_item=r.experiment_item, dataset_item=r.dataset_item, scores=[ Score( name='predicted_quality', evaluator_name='OverallQuality', value=1.0 if predicted == 'good' else 0.0, label=predicted, reasoning=f'Expected: {expected}', ) ], ) ) result.experiment.add_results(validation_results) print( f'Evaluator Accuracy: {correct}/{len(result.results)} ' f'({100 * correct / len(result.results):.0f}%)' ) ``` **Expected output:** ``` Evaluator Accuracy: 4/4 (100%) ``` ```python theme={null} print(f'View in Fiddler: {URL}/evals/experiments/{result.experiment.id}') # Build results DataFrame rows = [] for r, v in zip(result.results, validation_results): row = { 'scenario': r.dataset_item.metadata.get('scenario'), 'expected': r.dataset_item.expected_outputs.get('expected_quality'), 'predicted': v.scores[0].label, } row.update({s.evaluator_name: s.value for s in r.scores}) rows.append(row) pd.DataFrame(rows) ``` **Expected output:** | scenario | expected | predicted | ContextRelevance | RAGFaithfulness | AnswerRelevance | | ------------------ | -------- | --------- | ---------------- | --------------- | --------------- | | Perfect Match | good | good | 1.0 | 1.0 | 1.0 | | Irrelevant Context | bad | bad | 0.0 | 0.0 | 0.5 | | Hallucination | bad | bad | 0.5 | 0.0 | 1.0 | | Irrelevant Answer | bad | bad | 1.0 | 0.0 | 0.0 | *** ## Comparing Pipeline Configurations To compare different RAG configurations, run multiple experiments against the same dataset: Replace `rag_pipeline_v1` and `rag_pipeline_v2` with your actual RAG pipeline functions. Each function must accept `(inputs, extras, metadata)` and return a dict containing `rag_response`. ```python theme={null} # Experiment 1: Default retrieval result_v1 = evaluate( dataset=dataset, task=rag_pipeline_v1, evaluators=evaluators, score_fn_kwargs_mapping={ 'user_query': lambda x: x['inputs']['user_query'], 'retrieved_documents': lambda x: x['inputs']['retrieved_documents'], 'rag_response': 'rag_response', }, ) # Experiment 2: Improved retrieval with re-ranking result_v2 = evaluate( dataset=dataset, task=rag_pipeline_v2, evaluators=evaluators, score_fn_kwargs_mapping={ 'user_query': lambda x: x['inputs']['user_query'], 'retrieved_documents': lambda x: x['inputs']['retrieved_documents'], 'rag_response': 'rag_response', }, ) # Compare results side-by-side in the Fiddler UI print(f'V1: {URL}/evals/experiments/{result_v1.experiment.id}') print(f'V2: {URL}/evals/experiments/{result_v2.experiment.id}') ``` Both experiments appear in the Fiddler UI under the same Application, enabling side-by-side comparison of scores across all test cases. *** ## Next Steps * [RAG Evaluation Fundamentals](/developers/cookbooks/rag-evaluation-fundamentals) — Direct `.score()` API for quick iteration * [Building Custom Judge Evaluators](/developers/cookbooks/custom-judge-evaluators) — Add domain-specific evaluation criteria * [RAG Health Metrics Tutorial](/developers/tutorials/experiments/rag-health-metrics-tutorial) — Step-by-step tutorial *** **Source notebook**: [Fiddler Cookbook: RAG Experiments at Scale](https://github.com/fiddler-labs/fiddler-examples/blob/main/cookbooks/Fiddler_Cookbook_RAG_Experiments_at_Scale.ipynb) # Overview Source: https://docs.fiddler.ai/developers/index Practical guides, tutorials, and reference documentation for building with Fiddler. ## ⚡ Quick Starts Get up and running in minutes with step-by-step quick start guides: * [**Get Started in \<10 Minutes**](/developers/quick-starts/get-started-in-less-than-10-minutes) - Fastest way to integrate Fiddler * **Agentic Monitoring Quick Starts** - Monitor AI agents and multi-step workflows * [OpenTelemetry Quick Start](/developers/quick-starts/opentelemetry-quick-start) (`fiddler-otel`) or * [LangChain SDK Quick Start](/developers/quick-starts/langchain-sdk-quick-start) (`fiddler-langchain`) or * [LangGraph SDK Quick Start](/developers/quick-starts/langgraph-sdk-quick-start) (`fiddler-langgraph`) or * [Strands Agent SDK Quick Start](/developers/quick-starts/strands-agent-quick-start) (`fiddler-strands`) * [**Experiments Quick Start**](/developers/quick-starts/experiments-quick-start) - Evaluate LLM outputs with custom metrics * [**Guardrails Quick Start**](/developers/quick-starts/guardrails-quick-start) - Add safety guardrails to your AI applications ## 📚 Tutorials In-depth, hands-on tutorials organized by product area: ### Experiments Learn how to evaluate and test your LLM applications: * [RAG Health Metrics Tutorial](/developers/tutorials/experiments/rag-health-metrics-tutorial) * [Evals SDK Advanced Guide](/developers/tutorials/experiments/evals-sdk-advanced) * [Advanced Prompt Specs](/developers/tutorials/llm-monitoring/prompt-specs-advanced) ### Agentic & LLM Monitoring Monitor production LLM applications and AI agents: * [LangGraph SDK Quick Start](/developers/quick-starts/langgraph-sdk-quick-start) * [LangGraph SDK Advanced](/developers/tutorials/llm-monitoring/langgraph-sdk-advanced) * [Simple LLM Monitoring](/developers/quick-starts/simple-llm-monitoring) ### Guardrails Implement safety controls for your AI applications: * [Faithfulness Guardrails](/developers/tutorials/guardrails/guardrails-faithfulness) * [Safety Guardrails](/developers/tutorials/guardrails/guardrails-safety) * [PII Detection Guardrails](/developers/tutorials/guardrails/guardrails-pii) ### ML Monitoring Monitor traditional ML models in production: * [ML Monitoring Quick Start](/developers/quick-starts/simple-ml-monitoring) * [NLP Model Monitoring](/developers/tutorials/ml-monitoring/simple-nlp-monitoring-quick-start) * [Class Imbalance Handling](/developers/tutorials/ml-monitoring/class-imbalance-monitoring-example) * [Model Versions](/developers/tutorials/ml-monitoring/ml-monitoring-model-versions) * [Ranking Models](/developers/tutorials/ml-monitoring/ranking-model) * [Regression Models](/developers/tutorials/ml-monitoring/ml-monitoring-regression) * [Feature Impact Analysis](/developers/tutorials/ml-monitoring/user-defined-feature-impact) * [Computer Vision Monitoring](/developers/tutorials/ml-monitoring/cv-monitoring) ## 🍳 Cookbooks Use-case oriented guides that demonstrate end-to-end workflows for solving real problems: * [**RAG Evaluation Fundamentals**](/developers/cookbooks/rag-evaluation-fundamentals) — Evaluate RAG quality with built-in evaluators * [**Running RAG Experiments at Scale**](/developers/cookbooks/rag-experiments-at-scale) — Compare pipeline configurations systematically * [**Building Custom Judge Evaluators**](/developers/cookbooks/custom-judge-evaluators) — Create domain-specific evaluation criteria * [**Detecting Hallucinations in RAG**](/developers/cookbooks/hallucination-detection-pipeline) — Monitor for hallucinations in production * [**Monitoring Agentic Content Generation**](/developers/cookbooks/agentic-content-generation) — Quality and brand compliance for content agents ## 📖 Client Library Reference Comprehensive reference documentation for Fiddler's Python client: ### Getting Started * [Installation and Setup](/developers/python-client-guides/installation-and-setup) * [Naming Convention Guidelines](/developers/python-client-guides/naming-convention-guidelines) * [Alerts with Fiddler Client](/developers/python-client-guides/alerts-with-fiddler-client) ### Model Onboarding * [Create a Project and Model](/developers/python-client-guides/model-onboarding/create-a-project-and-model) * [Customizing Your Model Schema](/developers/python-client-guides/model-onboarding/customizing-your-model-schema) * [Task Types](/developers/python-client-guides/model-onboarding/task-types) * [Custom Missing Values](/developers/python-client-guides/model-onboarding/specifying-custom-missing-value-representations) ### Publishing Production Data * [Creating a Baseline Dataset](/developers/python-client-guides/publishing-production-data/creating-a-baseline-dataset) * [Publishing Batches of Events](/developers/python-client-guides/publishing-production-data/publishing-batches-of-events) * [Streaming Live Events](/developers/python-client-guides/publishing-production-data/streaming-live-events) * [Updating Events](/developers/python-client-guides/publishing-production-data/updating-events) * [Deleting Events](/developers/python-client-guides/publishing-production-data/deleting-events) * [Ranking Events](/developers/python-client-guides/publishing-production-data/ranking-events) For supported task setup and schema guidance, continue with the [*Model Onboarding guide*](/developers/client-library-reference/model-onboarding) and [*Updating Model Schema*](/developers/python-client-guides/model-onboarding/updating-model-schema). *** ## Related Documentation * [**SDK & API Reference**](/sdk-api/index) - Complete API documentation * [**Integrations**](/integrations) - Connect Fiddler with your ML stack * [**Documentation**](/) - Product guides and platform documentation # Alerts with Fiddler Client Source: https://docs.fiddler.ai/developers/python-client-guides/alerts-with-fiddler-client Discover our guide to alerts with Fiddler Client. Learn to set up alert rules to add, delete, and list all alerts, including triggered alerts. The Fiddler API client provides programmatic control for alert management alongside the Fiddler UI, enabling these key workflows: * Create alert rules * Remove alert rules * Retrieve all configured alert rules * Access triggered alert history > 📘 Note: For UI-based alert configuration, refer to the [alert setup guide](/observability/platform/alerts-platform). ## Creating Alert Rules The Fiddler client can be used to create a variety of alert rule types, including **Data Drift**, **Performance**, **Data Integrity**, **Service Metrics**, and **Custom Metrics**. The Fiddler client supports multiple alert rule types, including: * Data Drift * Performance * Data Integrity * Service Metrics * Custom Metrics ### Understanding Alert Thresholds When configuring thresholds: * **Absolute thresholds** (`CompareTo.RAW_VALUE`): For percentage-based metrics like `null_violation_percentage`, express values as percentages (e.g., 10 for 10%). * **Relative thresholds** (`CompareTo.TIME_PERIOD`): Express values as decimal fractions regardless of metric type (e.g., 0.1 for 10%) ## Example Implementations ### Example 1: Data Integrity Alert with Static Threshold This example creates an alert that monitors for missing values in the `age` column. It triggers notifications when null values exceed 5% (warning) or 10% (critical) of daily values. ```python theme={null} MODEL_ID = '299c7b40-b87c-4dad-bb94-251dbcd3cbdf' alert_rule = AlertRule( name='Bank Churn Missing Values Static Percent', model_id=MODEL_ID, metric_id='null_violation_percentage', priority=Priority.HIGH, compare_to=CompareTo.RAW_VALUE, condition=AlertCondition.GREATER, bin_size=BinSize.DAY, critical_threshold=10, warning_threshold=5, columns=['age'], ).create() notifications = alert_rule.set_notification_config( emails=['your.email@example.com', 'alerts.group@example.com'], ) ``` ### Example 2: Data Integrity Alert with Historical Comparison This example creates an alert that compares today's missing values against yesterday's values. It triggers when null values increase by 5% (warning) or 10% (critical) compared to the previous day. ```python theme={null} MODEL_ID = '299c7b40-b87c-4dad-bb94-251dbcd3cbdf' alert_rule = AlertRule( name='Bank Churn Missing Values Rolling Historical Percent', model_id=MODEL_ID, metric_id='null_violation_percentage', priority=Priority.HIGH, compare_to=CompareTo.TIME_PERIOD, compare_bin_delta=1, condition=AlertCondition.GREATER, bin_size=BinSize.DAY, critical_threshold=0.1, warning_threshold=0.05, columns=['age'], ).create() notifications = alert_rule.set_notification_config( emails=['your.email@example.com', 'alerts.group@example.com'], ) ``` ### Example 3: Performance Alert with Time-Based Comparison This example creates a performance alert that monitors for precision changes. It compares today's precision with yesterday's values and triggers when precision decreases by 5% (warning) or 10% (critical). ```python theme={null} MODEL_ID = '4531bfd9-2ca2-4a7b-bb5a-136c8da09ca2' alert_rule = AlertRule( name='Bank Churn Precision Relative', model_id=MODEL_ID, metric_id='precision', priority=Priority.HIGH, compare_to=CompareTo.TIME_PERIOD, compare_bin_delta=1, condition=AlertCondition.LESSER, bin_size=BinSize.DAY, critical_threshold=0.1, warning_threshold=0.05, ).create() notifications = alert_rule.set_notification_config( emails=['your.email@example.com', 'alerts.group@example.com'], ) ``` > 🚧 Please note, the possible values for compare\_bin\_delta vs bin\_size are: | Bin Size | Allowed Compare bin delta | | ------------- | ------------------------------------- | | BinSize.Hour | \[1, 24, 24 \* 7, 24 \* 30, 24 \* 90] | | BinSize.Day | \[1, 7, 30, 90] | | BinSize.Week | \[1] | | BinSize.Month | \[1] | ### Retrieving Alert Rules The AlertRule.list() method retrieves alert rules that match your specified criteria. This method returns a Python iterator of matching rules. ```python theme={null} MODEL_ID = '4531bfd9-2ca2-4a7b-bb5a-136c8da09ca2' alert_rules = AlertRule.list( model_id=MODEL_ID, # Optional parameter metric_id='jsd', # Optional parameter columns=['age'], # Optional parameter ordering=[ 'critical_threshold' ], # Add **-** prefix for descending sort ['-critical_threshold'] ) ``` > **Tip**: All filter parameters are optional. Omit them to retrieve all alert rules. ### Removing Alert Rules To delete an alert rule, call the delete() method on an AlertRule object. You can retrieve the rule object using either: * The list() method with filters * The get() method with the rule's unique identifier Alert Rule list with Copy alert rule ID highlighted in an alert rule's context menu ```python theme={null} # Delete from a list of alerts MODEL_ID = '4531bfd9-2ca2-4a7b-bb5a-136c8da09ca2' alert_rules = AlertRule.list(model_id=MODEL_ID) for alert_rule in alert_rules: if alert_rule.name == 'Bank Churn Precision Relative': alert_rule.delete() break # Delete using the alert rule's unique identifier ALERT_RULE_ID = '6da9c3c0-a9fa-4ab6-8b64-8d07b0736e77' rule = AlertRule.get(id_=ALERT_RULE_ID) rule.delete() ``` > **Tip**: Find the alert rule ID in the Alert Rule tab of your Fiddler Alerts page. ### Accessing Triggered Alerts Use the AlertRecord.list() method to retrieve alerts triggered by a specific rule: ```python theme={null} from datetime import datetime triggered_alerts = AlertRecord.list( alert_rule_id=ALERT_RULE_ID, # Required: ID of the alert rule start_time=datetime(2024, 9, 1), # Optional: Start of time range end_time=datetime(2024, 9, 24), # Optional: End of time range ordering=['alert_time_bucket'], # Optional: Sort order # Use '-alert_time_bucket' for descending ) ``` ### Configuring Notifications After creating an alert rule, configure how notifications are sent when the rule triggers. Fiddler supports these notification channels: * Email * PagerDuty * Slack webhooks * Custom webhooks You can specify multiple notification types, and each type can have multiple recipients. ```python theme={null} ALERT_RULE_ID = '72e8835b-cde2-4dd2-a435-a35d4b51196b' rule = AlertRule.get(id_=ALERT_RULE_ID) rule.set_notification_config( emails=['your.email@example.com', 'alerts.group@example.com'], webhooks=['8b403d99-530a-4c5a-a519-89688d65ddc1'], # Webhook UUID pagerduty_services=[ 'pagerduty_service_1', 'pagerduty_service_2', ], # PagerDuty service names pagerduty_severity='critical', # Only applies to PagerDuty ) ``` > **Important**: PagerDuty, Slack webhooks, and custom webhooks must be pre-configured by your Fiddler administrator. # Installation and Setup Source: https://docs.fiddler.ai/developers/python-client-guides/installation-and-setup Explore our installation guide to set up Fiddler’s Python SDK client. Learn how to connect, install, import, authorize, and set log levels in your environment. Fiddler offers a **Python SDK client** that lets you connect directly to your Fiddler environment from a Jupyter Notebook or automated pipeline. *** ### Install the Fiddler Client The client is available for download from PyPI via pip: ```bash theme={null} pip install -q fiddler-client ``` Fiddler follows the Python Software Foundation's support schedule for Python versions. See the [Python version support policy](/reference/python-support-policy) for details. ### Import the Fiddler Client Once you've installed the client, you can import the `fiddler` package into any Python script: ```python theme={null} import fiddler as fdl ``` *** ### Authorize the Client To use the Fiddler client, you will need **authorization details** that contain * The [URL](#find-your-url) you are connecting to * A [personal access token](#find-your-authorization-token) for your user #### Find Your URL The URL should point to **where Fiddler has been deployed** for your organization. On-premise customers will use the URL specified by their IT operations team. If you are using Fiddler's managed cloud service, you will have been provided with a unique URL, which will be in one of the forms shown below: ```html theme={null} # Managed SaaS https://.fiddler.ai # Managed SaaS Peering https://.cloud.fiddler.ai ``` #### Find Your Authorization Token To find your authorization token, navigate to the **Settings** page, click the **Credentials** tab, and then use the **Create Key** button (if there is not already an authorization token for your user). Settings page Credentials tab displaying Create Key button #### Connect the Client to Fiddler Once you've located the URL of your Fiddler environment and your authorization token, you can connect the Fiddler client to your environment. ```python theme={null} import fiddler as fdl URL = 'https://app.fiddler.ai' AUTH_TOKEN = '' # Connect to the Fiddler client # This call will also validate the client vs server version compatibility. fdl.init(url=URL, token=AUTH_TOKEN) print(f'Client version: {fdl.__version__}') print(f'Server version: {fdl.conn.server_version}') ``` ### Set Log Level Set the log level for the desired verbosity. ```python theme={null} import fiddler as fdl import logging # Create and configure the root logger prior to calling init() logging.basicConfig( level=logging.WARN, format="%(asctime)s.%(msecs)03d [%(name)s] %(levelname)s: %(message)s", datefmt="%y%m%d-%H:%M:%S", ) fdl.init(url=URL, token=AUTH_TOKEN) ``` > 📘 Info > > For detailed documentation on the Fiddler Python Client SDK’s many features, check out the [Python Client SDK reference](/sdk-api/python-client/connection) section. # Create a Project and Model Source: https://docs.fiddler.ai/developers/python-client-guides/model-onboarding/create-a-project-and-model Explore our guide to creating a project and onboarding a model for observation. Learn how projects organize models and define a ModelSpec and Model Task. ### What is a Project? A project helps organize models under observation and serves as the authorization unit to manage access to your models. To onboard a model to Fiddler, you need to have a project to associate it with. Once Fiddler's Python client is connected to your environment, you can either create a new project or use an existing one to onboard your model. #### Create a Project Using the Python client, you can create a project by calling the Project object's create function after setting the desired project name. ```python theme={null} # Please be mindful that the Project name must be unique and should not have spaces or special characters. PROJECT_NAME = 'quickstart_example' ## Create the Project project = fdl.Project(name=PROJECT_NAME) project.create() print(f'New project created with id = {project.id}') ``` You should now see the newly created project on the Projects page in the Fiddler UI. #### List All Projects Using an existing project, you may list all the projects that you are authorized to view. ```python theme={null} for project in fdl.Project.list(): print(f'Project: {project.id} - {project.name}') ## This will print ALL project IDs and Names that you have access to. ``` ### Onboarding a Model To onboard a model you need to define a **ModelSpec** and optionally a **Model Task**. If you do not specify a model task during Model creation it can be set later or left unset. #### Define the ModelSpec A **ModelSpec object** defines what role each column of your inference data serves in your model. Fiddler supports five column roles: 1. Inputs (features), 2. Outputs (predictions), 3. Targets (ground truth labels), 4. Metadata (additional information passed along with the inference) 5. Custom features (additional information that Fiddler should generate like embeddings or enrichments) ```python theme={null} model_spec = fdl.ModelSpec( inputs=['CreditScore', 'Geography', 'Gender', 'Age', 'Tenure', 'Balance', 'NumOfProducts', 'HasCrCard', 'IsActiveMember', 'EstimatedSalary'], outputs=['probability_churned'], targets=['Churned'], decisions=[], metadata=[], custom_features=[], ) ``` #### Define the Model Task Fiddler supports a variety of model tasks. Create a `ModelTask` object and an additional `ModelTaskParams` object to specify the ordering of labels. ```python theme={null} model_task = fdl.ModelTask.BINARY_CLASSIFICATION task_params = fdl.ModelTaskParams(target_class_order=['no', 'yes']) ``` #### Infer the Model Schema Onboard the model schema to Fiddler by passing in: 1. the data sample dataframe, called `sample_df` below 2. the `ModelSpec` object 3. the `ModelTask` and `ModelTaskParams` objects 4. the event/inference ID column and event/inference timestamp columns ```python theme={null} MODEL_NAME = 'my_model' model = fdl.Model.from_data( name=MODEL_NAME, project_id=fdl.Project.from_name(PROJECT_NAME).id, source=sample_df, spec=model_spec, task=model_task, task_params=task_params, event_id_col=id_column, event_ts_col=timestamp_column ) ``` Depending on the input size this step might take a moment to complete. It is not a local operation, but requires uploading the sample dataframe to the Fiddler HTTP API. #### Review and Edit the Schema Schema inference is just a helping hand. The resulting schema needs human review and potentially some edits, as documented in the section titled [Customizing your Model Schema](/developers/python-client-guides/model-onboarding/customizing-your-model-schema). #### Define Model Columns Using Pandas DataFrame Column Types When defining the columns of a model, use the data types from a Pandas DataFrame. Note that no type inference is performed; it is the responsibility of the user to ensure that the DataFrame's column types are correct. The mapping of column types is as follows: | Pandas | Fiddler (fdl.DataType) | | -------------------- | ---------------------- | | int8 | INTEGER | | int16 | INTEGER | | int32 | INTEGER | | int64 | INTEGER | | uint8 | INTEGER | | uint16 | INTEGER | | uint32 | INTEGER | | uint64 | INTEGER | | float16 | FLOAT | | float32 | FLOAT | | float64 | FLOAT | | complex64 | STRING | | complex128 | STRING | | string | STRING | | object | STRING | | bool | BOOLEAN | | boolean | BOOLEAN | | datetime64\[ns] | TIMESTAMP | | datetime64\[ns, UTC] | TIMESTAMP | | timedelta64\[ns] | STRING | | period\[freq] | STRING | | category | CATEGORY | | interval | STRING | ```python theme={null} MODEL_NAME = 'my_model' model_schema = fdl.utils.column_generator.create_columns_from_df(sample_df) model = fdl.Model( name=MODEL_NAME, project_id=project.id, schema=model_schema, spec=model_spec, task=model_task, task_params=task_params) ``` The resulting model's schema should be reviewed by the user. Any necessary edits should be made according to the guidelines outlined in the preceding section. #### Onboard the Model After making sure the schema looks good, the model can be onboarded with the following API call: ```python theme={null} model.create() ``` # Customizing Your Model Schema Source: https://docs.fiddler.ai/developers/python-client-guides/model-onboarding/customizing-your-model-schema Delve into our guide to customize your Model Schema with Fiddler. Learn how to adjust a column’s value range, possible values, and data type to match your model. There can be occasions when the `fdl.ModelSchema` object generated by `fdl.Model.from_data` infers a column's data type **differently than the type intended** by the model developer. In these cases you can modify the ModelSchema columns as needed prior to creating the model in Fiddler. Let's walk through an example of how to do this. *** Suppose you've loaded in a dataset as a pandas DataFrame. ```python theme={null} import pandas as pd df = pd.read_csv('example_dataset.csv') ``` Below is an example of what is displayed upon inspection. Tabular view of CSV data. *** You then create a `fdl.Model` object by inferring the column schema details from this DataFrame. ```python theme={null} model = fdl.Model.from_data( name='my_model', project_id=PROJECT_ID, source=df, ) ``` Below is an example of what is displayed upon inspection of `model.schema`. Raw output of the ModelSchema object properties. ```json theme={null} ``` Upon inspection you may notice that **a few things are off**: 1. The [value range](#modifying-the-value-range) of `output_column` is set to `[0.01, 0.99]`, when it should really be `[0.0, 1.0]`. 2. There are no [possible values](#modifying-the-possible-values) set for `feature_3`. 3. The [data type](#modifying-the-data-type) of `feature_3` is set to `DataType.STRING`, when it should really be `DataType.CATEGORY`. 4. The [histogram bins](#modifying-the-histogram-bins) for a numerical column may need to be adjusted for better distribution analysis (e.g., quantile-based instead of uniform). What's the downside of not making sure that ranges and categories are reviewed and properly set? A production traffic event that encodes a number outside of the specified value range or a category value that is not in the set of valid category values will further down the line be flagged as a so-called Data Integrity violation. Depending on the alerting config, this may result in an alert. It's also worth noting however that an event which has a violation in its columns is still processed, and metrics that can be generated are still generated. The below examples demonstrate how to address each of the issues noted: #### Modifying the Value Range Let's say we want to modify the range of `output_column` in the above `fdl.Model` object to be `[0.0, 1.0]`. You can do this by setting the `min` and `max` of the `output_column` column. ```python theme={null} model.schema['output_column'].min = 0.0 model.schema['output_column'].max = 1.0 ``` #### Modifying the Histogram Bins By default, Fiddler auto-generates 10 uniform bins for numerical columns based on the column’s min and max values. You can customize these bins to better represent your data distribution — for example, using quantile-based bins or domain-specific ranges. ```python theme={null} model.schema['output_column'].bins = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0] ``` Custom bins must: * Be strictly monotonically increasing * Start at the column’s `min` value * End at the column’s `max` value * Have at least 2 and at most 16 boundary values (1 to 15 bins) Custom bins affect how feature distributions and drift metrics (PSI, JSD) are computed. Bins are used for histogram bucketing in data drift calculations. #### Modifying the Possible Values Let’s say we want to modify the possible values of `feature_3` to be `[‘Yes’, ‘No’]`. You can do this by setting the `categories` of the `feature_3` column. ```python theme={null} model.schema['feature_3'].categories = ['Yes', 'No'] ``` #### Modifying the Data Type Let's say we want to modify the data type of `feature_3` to be `DataType.CATEGORY`. You can do this by setting the `data_type` of the `feature_3` column. ```python theme={null} model.schema['feature_3'].data_type = fdl.DataType.CATEGORY ``` **Note**: when converting a column to a CATEGORY, you must also set the list of unique possible values: ```python theme={null} model.schema['feature_3'].categories = ['Yes', 'No'] ``` **Note**: if converting a column from numeric (integer or float) to a category, you must also remove the min/max numeric range values and bins that were automatically calculated from the sample data. ```python theme={null} model.schema['output_column'].min = None model.schema['output_column'].max = None model.schema['output_column'].bins = None ``` A complete example might look like this: ```python theme={null} sample_data_df = pd.read_csv('some.csv') # configure your ModelSpec here # model_spec = ... # configure your ModelTask here, or use NOT_SET # model_task = ... # Infer your model's schema from a sample of data ml_model = fdl.Model.from_data( source=sample_data_df, name=MODEL_NAME, version=VERSION_NAME, project_id=project.id, spec=model_spec, task=model_task ) # Make any adjustments to the inferred ModelSchema BEFORE creating the model ml_model.schema['feature_3'].data_type = fdl.DataType.CATEGORY ml_model.schema['feature_3'].categories = ['0', '1'] # The original datatype was inferred as an integer, but we preferred a category. # Clear out the min, max, and bins values derived from the sample data as they do not apply to categories ml_model.schema['feature_3'].min = None ml_model.schema['feature_3'].max = None ml_model.schema['feature_3'].bins = None # Now create the model with the inferred schema and your overrides ml_model.create() ``` # Custom Missing Values Source: https://docs.fiddler.ai/developers/python-client-guides/model-onboarding/specifying-custom-missing-value-representations Learn how you can customize a model column to assign values to be treated as missing or null data in order to handle a value or token that is inserted in place of null. Your data may contain missing values represented in nonstandard ways instead of `null` or `NaN`. For example, an upstream system might use "-1.0" or "-999" in a Float column to indicate missing data. Fiddler lets you specify custom missing value representations for each column when defining your model schema. ## Customize Missing Data Values in Your Schema To specify which values should be treated as nulls when publishing data to Fiddler: You can modify your ModelSchema object just before onboarding your model to include details about which values should be replaced with nulls when publishing data to Fiddler. ```python theme={null} # Assume an instantiated Fiddler Model: # model = Model.from_data(...) # Modify your ModelSchema object before calling model.create() model.schema['my_column'].replace_with_nulls = [ '-1.0', '-999' ] ``` This configuration tells Fiddler to automatically consider these values as `null` when processing your data and generating data integrity metrics. For more information, see our in-depth [guide](/developers/python-client-guides/model-onboarding/customizing-your-model-schema) on customizing your model schema before creating your Fiddler model. # Task Types Source: https://docs.fiddler.ai/developers/python-client-guides/model-onboarding/task-types Explore our guide to selecting a model task type when onboarding your ML models and LLM applications. Fiddler supports **six** model tasks. These include: * Binary Classification * Multi-class Classification * Regression * Ranking * LLM * Not set **Binary classification** is the task of classifying the elements of an outcome set into two groups (each called class) on the basis of a classification rule. Onboarding a Binary classification task in Fiddler requires the following: * A single output column of type float (range 0-1) which represents the soft output of the model. This column has to be defined. * A single target column that represents the true outcome. This column has to be defined. * A list of input features has to be defined. Typical binary classification problems include: * Determining whether a customer will churn or not. Here the outcome set has two outcomes: The customer will churn or the customer will not. Further, the outcome can only belong to either of the two classes. * Determining whether a patient has a disease or not. Here the outcome set has two outcomes: the patient has the disease or does not. **Multiclass classification** is the task of classifying the elements of an outcome set into three or more groups (each called class) on the basis of a classification rule. Onboarding a Multiclass classification task in Fiddler requires the following: * Multiple output columns (one per class) of type float (range 0-1) which represent the soft outputs of the model. Those columns have to be defined. * A single target column that represents the true outcome. This column has to be defined. * A list of input features has to be defined. Typical multiclass classification problems include: * Determining whether an image is a cat, a dog, or a bird. Here the outcome set has more than two outcomes. Further, the image can only be determined to be one of the three outcomes and it's thus a multiclass classification problem. **Regression** is the task of predicting a continuous numeric quantity. Onboarding a Regression task in Fiddler requires the following: * A single numeric output column that represents the output of the model. This column has to be defined. * A single numeric target column that represents the true outcome. This column has to be defined. * A list of input features has to be defined. Typical regression problems include: * Determining the average home price based on a given set of housing-related features such as its square footage, number of beds and baths, its location, etc. * Determining the income of an individual based on features such as age, work location, job sector, etc. **Ranking** is the task of constructing a rank-ordered list of items given a particular query that seeks some information. Onboarding a Ranking task in Fiddler requires the following: * A single numeric output column that represents the output of the model. This column has to be defined. * A single target column that represents the true outcome. This column has to be defined. * A list of input features has to be defined. Typical ranking problems include: * Ranking documents in information retrieval systems. * Ranking relevancy of advertisements based on user search queries. **LLM** is the task dedicated for Large Language Models, a type of transformer model. It represents a deep learning model that can process human languages. Onboarding an LLM task in Fiddler doesn't require any specific format with regards to the targets/outputs/inputs definition. Those can be defined or not, with any type and no minimum or maximum column has to be defined. However, in that setting, Fiddler doesn't offer XAI functionalities or performance metrics. Typical LLM problems include: * Chatbots and Virtual assistants that can answer questions. * Content creation like articles, blog posts, etc. **Not set** is the task to choose if a use-case is not covered by the previous tasks or the use-case doesn't need performance metrics. In this setting, the user doesn't have to specify the required data as discussed above to onboard their model. Onboarding a `NOT_SET` task in Fiddler doesn't require any specific format with regards to the targets/outputs/inputs definition Those can be defined or not, with any type and no minimum or maximum column has to be defined. However, in that setting, Fiddler doesn't offer XAI functionalities or performance metrics. # Updating Model Schema Source: https://docs.fiddler.ai/developers/python-client-guides/model-onboarding/updating-model-schema Learn how to modify your model's schema after initial creation by adding new columns using the Python client's add\_column() method. Add features, metadata, and tracking columns to existing models. Learn how to modify your model's schema after initial creation by adding new columns. ## Overview Sometimes you need to add new columns to an existing model in production. Common scenarios include: * Adding new features that weren't in the original training data * Including additional metadata for monitoring purposes * Extending the model with derived features * Adding tracking columns for business metrics Fiddler allows you to update your model schema programmatically using the Python client's `add_column()` method. **Availability:** This feature requires Fiddler Python Client SDK version 3.11 or later. For detailed API reference, see [Model.add\_column()](/sdk-api/python-client/model#add_column). ## Prerequisites * An existing model in Fiddler * Python client installed and initialized (version 3.11+) * Appropriate permissions to modify the model ## Adding a Column Use the `add_column()` method on your model instance to add a new column: ### Basic Example ```python theme={null} import fiddler as fdl from fiddler import Column, DataType # Fetch existing model model = fdl.Model.from_name( name="fraud_detector", project_id="YOUR_PROJECT_ID" ) # Define new column (bins are optional — auto-generated from min/max if omitted) new_column = Column( name="transaction_amount", data_type=DataType.FLOAT, min=0.0, max=100000.0, bins=[0, 100, 500, 1000, 5000, 10000, 50000, 100000] ) # Add to model schema model.add_column(column=new_column, column_type='metadata') ``` ## Column Types The `column_type` parameter specifies where the column will be used in your model. Available types: * **`'inputs'`**: Model input features used for predictions * **`'outputs'`**: Model prediction outputs (probabilities, scores, etc.) * **`'targets'`**: Ground truth labels for evaluation * **`'metadata'`**: Tracking/monitoring data (default) ## Data Type Examples Fiddler supports the following data types for model columns: * **Integer** (`DataType.INTEGER`): Whole numbers (e.g., age, count) * **Float** (`DataType.FLOAT`): Decimal numbers (e.g., price, score, probability) * **Category** (`DataType.CATEGORY`): Categorical values from a predefined set * **String** (`DataType.STRING`): Text data * **Boolean** (`DataType.BOOLEAN`): True/false values * **Vector** (`DataType.VECTOR`): Multi-dimensional numerical arrays (embeddings) * **Timestamp** (`DataType.TIMESTAMP`): Date and time values ### Numeric Column (Integer) ```python theme={null} from fiddler import Column, DataType age_col = Column( name="customer_age", data_type=DataType.INTEGER, min=18, max=100 ) model.add_column(column=age_col, column_type='metadata') ``` ### Numeric Column (Float) ```python theme={null} score_col = Column( name="risk_score", data_type=DataType.FLOAT, min=0.0, max=1.0 ) model.add_column(column=score_col, column_type='outputs') ``` ### Categorical Column ```python theme={null} category_col = Column( name="product_category", data_type=DataType.CATEGORY, categories=["Electronics", "Clothing", "Food", "Books"] ) model.add_column(column=category_col, column_type='inputs') ``` ### String Column ```python theme={null} text_col = Column( name="customer_feedback", data_type=DataType.STRING ) model.add_column(column=text_col, column_type='metadata') ``` ### Boolean Column ```python theme={null} bool_col = Column( name="is_premium_customer", data_type=DataType.BOOLEAN ) model.add_column(column=bool_col, column_type='metadata') ``` ### Vector Column (Embeddings) ```python theme={null} embedding_col = Column( name="text_embedding", data_type=DataType.VECTOR, n_dimensions=768 ) model.add_column(column=embedding_col, column_type='inputs') ``` ### Timestamp Column ```python theme={null} timestamp_col = Column( name="transaction_time", data_type=DataType.TIMESTAMP ) model.add_column(column=timestamp_col, column_type='metadata') ``` ## Important Considerations ### Historical Data Adding a column doesn't automatically populate historical data. The new column will have `null` values for all past events. Only newly published events will contain values for the added column. Additionally, the baseline dataset won't have data for this new column. If you need to compute drift metrics for the new column, upload a new baseline dataset that includes the column data: ```python theme={null} import pandas as pd # Prepare baseline data with the new column included baseline_df = pd.DataFrame({ "feature1": [...], "feature2": [...], "region": ["US", "EU", "APAC", ...] # New column added to schema }) # Upload new baseline dataset baseline_publish_job = model.publish_batch( source=baseline_df, environment=fdl.EnvType.PRE_PRODUCTION, dataset_name='baseline_with_new_column', ) print(f'Baseline upload initiated with Job ID = {baseline_publish_job.id}') ``` ### Schema Validation The column definition must pass Fiddler's validation rules: * Column names must be unique within the model * Data types must be valid * Numeric columns should specify min/max ranges * Numeric columns may optionally specify custom bins (must span \[min, max], be strictly increasing, at most 16 boundary values) * Categorical columns should specify categories * Vector columns must specify dimensions ### Publishing Data After adding a column, remember to include it when publishing new events: ```python theme={null} import fiddler as fdl import pandas as pd # Add new column to model model.add_column( column=Column(name="region", data_type=DataType.STRING), column_type='metadata' ) # Publish events including the new column events_df = pd.DataFrame({ "timestamp": [...], "feature1": [...], "feature2": [...], "region": ["US", "EU", "APAC", ...] # New column }) model.publish_batch(source=events_df, environment=fdl.EnvType.PRODUCTION) ``` ## Common Use Cases ### Adding Multiple Columns ```python theme={null} # Define multiple columns columns_to_add = [ Column(name="customer_segment", data_type=DataType.INTEGER, min=1, max=5), Column(name="region", data_type=DataType.STRING), Column(name="is_returning", data_type=DataType.BOOLEAN) ] # Add each column for col in columns_to_add: model.add_column(column=col, column_type='metadata') print(f"Added column: {col.name}") ``` ### Adding a Feature Column ```python theme={null} # Add a new feature that wasn't in original training data new_feature = Column( name="days_since_last_purchase", data_type=DataType.INTEGER, min=0, max=365 ) model.add_column(column=new_feature, column_type='inputs') ``` ## Error Handling ### Duplicate Column Names ```python theme={null} try: model.add_column( column=Column(name="existing_column", data_type=DataType.STRING), column_type='metadata' ) except ValueError as e: print(f"Error: {e}") # Output: Column 'existing_column' already exists in model schema ``` ## Complete Example Here's a complete workflow for adding columns to an existing model: ```python theme={null} import fiddler as fdl from fiddler import Column, DataType import pandas as pd # Initialize Fiddler client fdl.init( url="https://your-instance.fiddler.ai", token="your-api-token" ) # Get existing model model = fdl.Model.from_name( name="credit_risk_model", project_id="my-project-id" ) print(f"Current columns: {[col.name for col in model.schema.columns]}") # Add new metadata columns new_columns = [ Column( name="customer_tier", data_type=DataType.CATEGORY, categories=["Bronze", "Silver", "Gold", "Platinum"] ), Column( name="account_age_days", data_type=DataType.INTEGER, min=0, max=10000 ), Column( name="transaction_history_summary", data_type=DataType.STRING ) ] # Add each column for col in new_columns: try: model.add_column(column=col, column_type='metadata') print(f"✓ Added: {col.name}") except ValueError as e: print(f"✗ Failed to add {col.name}: {e}") # Verify columns were added print(f"Updated columns: {[col.name for col in model.schema.columns]}") # Publish new events with the added columns new_events = pd.DataFrame({ # Existing columns "timestamp": ["2024-01-01T12:00:00Z"], "credit_score": [720], "annual_income": [75000], # Newly added columns "customer_tier": ["Gold"], "account_age_days": [365], "transaction_history_summary": ["Regular activity, no delinquencies"] }) job = model.publish_batch(source=new_events, environment=fdl.EnvType.PRODUCTION) print(f"Published events with new columns. Job ID: {job.id}") ``` ## Related Documentation * [Create a Project and Model](/developers/python-client-guides/model-onboarding/create-a-project-and-model) * [Customizing Your Model Schema](/developers/python-client-guides/model-onboarding/customizing-your-model-schema) * [Publishing Production Data](/developers/client-library-reference/publishing-production-data) * [Model Task Types](/developers/python-client-guides/model-onboarding/task-types) ## Frequently Asked Questions (FAQ) **Q: Can I modify an existing column?** A: `add_column()` is only for adding new columns. To modify an existing column's properties (like min, max, bins, or categories), update the property on the schema and call `model.update()`: ```python theme={null} model = fdl.Model.get(id_="abc-123") model.schema["credit_score"].bins = [350, 500, 650, 850] model.update() ``` > **Note:** Bin boundaries must span the column's existing \[min, max] range. If you are also changing the range, update min and max in the same call. See [Customizing Your Model Schema](/developers/python-client-guides/model-onboarding/customizing-your-model-schema) for details. **Q: What happens to existing alerts and monitors?** A: Existing alerts and monitors continue to work. However, you may want to create new monitors for the added columns. **Q: Can I add multiple columns at once?** A: You need to call `add_column()` separately for each column. The method updates the model after each addition. # Naming Convention Guidelines Source: https://docs.fiddler.ai/developers/python-client-guides/naming-convention-guidelines Learn Fiddler's naming requirements: start with lowercase letters, use only a-z, 0-9, and underscores afterwards. See examples and best practices. ## Core Fiddler Asset Naming Requirements The following naming convention applies specifically to these core Fiddler platform assets: Projects, Models, Baselines, and Webhooks. Other elements in the platform may have different naming rules. ### Required Format * Names must start with a lowercase letter (a-z) * After the first character, names may contain: * Lowercase letters (a-z) * Numbers (0-9) * Underscores (\_) * Names cannot contain uppercase letters, spaces, hyphens, or special characters * Each asset type has specific length requirements: | Fiddler Asset | Minimum Name Length | Maximum Name Length | | ------------- | ------------------- | ------------------- | | Baseline | 3 | 256 | | Model | 2 | 30 | | Project | 2 | 32 | | Webhook | 2 | 127 | ### Examples #### Valid Names * `model_1` * `test_project_2023` * `prod_env` * `my_baseline_123` #### Invalid Names * `Model1` (starts with uppercase) * `1_model` (starts with a number) * `test-project` (contains hyphen) * `my feature` (contains space) * `project#1` (contains special character) * `m` (too short for any asset type) * `_test` (starts with underscore) * `extremely_long_name_that_exceeds_the_character_limit_for_models_and_projects` (exceeds length limits for Models, Projects, and Webhooks) ### Best Practices While following the required format, we recommend these additional best practices: * Use descriptive names that indicate the purpose or content * Use underscores to separate words for better readability * Keep names reasonably short while maintaining clarity * Be consistent with naming patterns across similar items * Consider using prefixes to group related assets (e.g., `prod_`, `dev_`, `test_`) ### Note on Other Platform Elements This naming convention applies specifically to core Fiddler assets (Projects, Models, Baselines, and Webhooks). Other elements in the Fiddler platform may have different naming requirements or restrictions. Consult the specific documentation for those elements if needed. # Creating a Baseline Dataset Source: https://docs.fiddler.ai/developers/python-client-guides/publishing-production-data/creating-a-baseline-dataset Learn to create a baseline dataset and detect data drift in production. Explore baseline types in Fiddler and start building one that fits your model best. Fiddler requires a baseline to detect data drift in production data. Baselines serve as a point of reference for Fiddler to understand what data distributions the model expects to see for all of its inputs and outputs. In other words, a baseline is a **representative sample** of the data you expect to see in production. It represents the ideal data that your model works best on. For this reason, in most cases, **a baseline dataset should be sampled from your model’s training set.** A few things to remember when designing baselines: > * It’s important to include **enough data** to ensure you have a representative sample of the expected data distributions. If using the training data for your baseline, you don't necessarily need all the training data, but rather enough to properly denote the minimums, maximums, and each distinct categorical value to be encountered. > * You may want to consider **including extreme values (min/max)** of each column in your training set so you can adequately monitor range violations in production data. However, if you choose not to, you can manually specify these ranges before onboarding your model (see [customizing your dataset schema](/developers/python-client-guides/model-onboarding/customizing-your-model-schema)). ## Types of Baselines There are four (4) types of baselines in Fiddler: 1. **Static Pre-production** - A static pre-production baseline is created by publishing a dataset to Fiddler. Typically, these datasets are training datasets or subsets thereof. Training data is an excellent baseline as it represents the data the model should expect to receive in production. You may also choose to use testing datasets or samples of production inference data as well. 2. **Static Production** - Using time ranges, previously ingested inference logs can be defined to define a static production baseline. For example, you can define a baseline as a point of reference from every event or inference ingested from March 2024. It is worth noting that static production baselines are not immutable. For example, if new events are published into the time range of the baseline, the distributions defined by the baseline will be recalculated. 3. **Rolling Production** - A rolling production baseline provides a dynamic reference point that shifts with time, like a sliding window that always reflects a fixed period prior to the present moment. For example, with a one-month rolling baseline, today's data is compared with data from exactly one month ago, and this comparison window automatically shifts forward each day. Unlike static baselines, which remain fixed, rolling baselines maintain a consistent time distance from your current data, making them ideal for analyzing recurring patterns in your production environment. 4. **Default Static** - Fiddler always creates this type of baseline for you for every model. This ensures Fiddler can deliver drift calculations even if no other baseline type was defined. This default baseline is named *default\_static\_baseline* and gets created at the time of initial model schema creation. It is defined as a static production baseline using the time range starting 12 months before the Fiddler model object creation date and ending 3 months after that date. It is worth noting that default static production baselines are not immutable like static production baselines. For example, if new events are published into the time range of the baseline, the distributions defined by the baseline will be recalculated, and this may have some impact on previously calculated drift values used in Alerts and Charts. An example of how to create each type of baseline can be found below. ### Static Pre-production Baseline A baseline gets created when you upload your pre-production dataset as shown in the example below. Note that `dataset_name` is used to specify the baseline name and the environment is set to PRE\_PRODUCTION to indicate this is not monitored, time-series data. ```python theme={null} baseline_publish_job = model.publish_batch( source=sample_data_df, environment=fdl.EnvType.PRE_PRODUCTION, dataset_name=STATIC_BASELINE_NAME, ) print( f'Initiated pre-production dataset upload with Job ID = {baseline_publish_job.id}' ) ``` ### Static Production Baseline ```python theme={null} static_prod_baseline = fdl.Baseline( name='static_prod_1', model_id=model.id, environment=fdl.EnvType.PRODUCTION, type_=fdl.BaselineType.STATIC, start_time=(datetime.now() - timedelta(days=0.5)).timestamp(), end_time=(datetime.now() - timedelta(days=0.25)).timestamp(), ) static_prod_baseline.create() print(f'Static production baseline created with id - {static_prod_baseline.id}') ``` ### Rolling Production Baseline ```python theme={null} rolling_prod_baseline = fdl.Baseline( name='rolling_prod_1', model_id=model.id, environment=fdl.EnvType.PRODUCTION, type_=fdl.BaselineType.ROLLING, window_bin_size=fdl.WindowBinSize.WEEK, offset_delta=4, ) rolling_prod_baseline.create() print(f'Rolling production baseline created with id - {rolling_prod_baseline.id}') ``` #### Default Static Baseline (*Note: while this example doesn't illustrate explicitly creating a default baseline, it illustrates when the default static baseline gets created.*) ```python theme={null} model = fdl.Model.from_data( name=MODEL_NAME, project_id=project.id, source=sample_data_df, spec=model_spec, task=model_task, task_params=task_params, event_id_col=id_column, event_ts_col=timestamp_column, ) model.create() # Default static production baseline created automatically at this point # with a time range between 12 months prior to and 3 months after today's date ``` ### List A Model's Baselines ```python theme={null} for baseline in fdl.Baseline.list(model_id=model.id): print(f'Baseline: {baseline.id} - {baseline.name}') ``` # Deleting Events Source: https://docs.fiddler.ai/developers/python-client-guides/publishing-production-data/deleting-events Dive into our guide on deleting existing events from your data whether due to regulatory compliance, custom data retention policies, or publishing mistakes. Fiddler enables you to delete previously published production inference data by unique identifier or by event timestamp, using either the Python client's `Model.delete_events()` method or the [Delete Events REST API](/sdk-api/rest-api/events/delete-events). Deleting events with the Python client requires `fiddler-client` 3.13.0 or later. On earlier client versions, use the REST API directly. See the [Python SDK changelog](/changelog/python-sdk) for release details. Common reasons for deletion include: * Complying with data privacy regulations ([GDPR](https://commission.europa.eu/law/law-topic/data-protection/legal-framework-eu-data-protection_en), [CCPA](https://www.oag.ca.gov/privacy/ccpa), etc.) * Removing erroneously published data * Correcting data inaccuracies ## Deletion Methods Fiddler supports two filtering methods for deletion (only one method can be used per request): ### Delete by Event ID Delete specific inference events by providing their unique identifiers. The event ID corresponds to the `event_id_col` specified during [Model](/sdk-api/python-client/model) onboarding. Event IDs are designed to be unique. If duplicate `event_id` values have been published, deleting by event ID will remove all events matching those IDs from the raw events table. Aggregated metrics are not recalculated for event ID-based deletions — requests that combine `event_ids` with `update_metrics=True` are rejected. See [event deduplication](/developers/python-client-guides/publishing-production-data/event-deduplication) for avoiding duplicate events. You can delete up to 10,000 events per request. If you need to delete more events in one request, please contact Fiddler support. ### Delete by Timestamp Range Delete events that fall within a designated time range by specifying start and end timestamps. The filtering is based on the timestamp column (`event_ts_col`) defined during [Model](/sdk-api/python-client/model) onboarding. Deletions are processed in batches (default batch size: 100K events) to ensure efficiency and resilience. Both timestamps must be aligned to hour boundaries (for example, `2025-11-17T01:00:00Z`), and the range applies as `start_time` ≤ t \< `end_time`. Ensure that the `max_memory_usage` setting in ClickHouse is configured to handle the number of events specified by the batch size (controlled by the `EVENT_DELETION_BATCH_SIZE` environment variable). You can delete up to 100 million events per day using this endpoint. If you require a higher daily deletion limit, please contact Fiddler support. ## Impact on Monitoring Metrics When deleting inference data with the time range filter, you can control how the deletion affects your monitoring metrics using the `update_metrics` parameter: * Preserve existing aggregated metrics (default): `update_metrics=False` * Recalculate metrics to reflect the data removal: `update_metrics=True` `update_metrics` applies only to time range deletions. Event ID-based deletions do not recalculate aggregated metrics, and requests that set `update_metrics=True` together with `event_ids` are rejected. ## Important Considerations * Deletions are permanent and cannot be undone * Pre-production (baseline) datasets do not support row-level deletion * Large-scale deletions may temporarily impact data ingestion performance. * By default, the event deletion API allows up to 30 requests per day. * If the rate limit is exceeded, the API will return a `429 Too Many Requests` response, along with rate limiting headers: * `X-RateLimit-Limit` – The maximum number of allowed requests in the current window. * `X-RateLimit-Remaining` – The number of remaining requests in the current window. * `Retry-After` – The number of seconds to wait before retrying, or the HTTP date when the rate limit resets. * `X-RateLimit-Reset` – The UTC epoch time (seconds) when the current rate limiting window resets. ## Deleting Events with the Python Client Use `Model.delete_events()` to delete events directly from the Python client (`fiddler-client` 3.13.0+). Deletion runs asynchronously on the server: the method returns a [Job](/sdk-api/python-client/job) you can wait on or poll for completion. ### Example: Deleting Events by Timestamp Range ```python theme={null} import fiddler as fdl project = fdl.Project.from_name(name='your_project_name') model = fdl.Model.from_name(name='your_model_name', project_id=project.id) # Delete one hour of events. Timestamps must be timezone-aware (an ISO 8601 # string with an explicit offset, or a timezone-aware datetime) and aligned # to hour boundaries. The range applies as start_time <= t < end_time. job = model.delete_events( start_time='2025-11-17T01:00:00Z', end_time='2025-11-17T02:00:00Z', update_metrics=True, # Recalculate monitoring metrics after deletion ) job.wait() ``` ### Example: Deleting Events by Event ID ```python theme={null} import fiddler as fdl project = fdl.Project.from_name(name='your_project_name') model = fdl.Model.from_name(name='your_model_name', project_id=project.id) # Delete specific events by ID (up to 10,000 IDs per request). job = model.delete_events(event_ids=['pred_001', 'pred_002']) job.wait() ``` Validation to be aware of: * Provide either a time range or a list of event IDs in a single request — not both. * `start_time` and `end_time` must be provided together. Naive datetimes (without timezone information) are rejected; non-UTC values are normalized to UTC. * A call with no filter is rejected, to avoid accidentally deleting all events for a model. ## Deleting Events with the REST API The [Delete Events REST API](/sdk-api/rest-api/events/delete-events) (`DELETE /v3/events`) accepts the following parameters: | Parameter | Type | Default | Description | | --------------- | --------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | model\_id | UUID | - | Unique identifier for the model from which production events are deleted. | | time\_range | Optional\[dict] | - | Dictionary with `start_time` (inclusive) and `end_time` (exclusive) in UTC, both aligned to the hour (format: `'YYYY-MM-DD HH:00:00'`). Specify timestamps so that the entire range covers complete hours—do not use minutes or seconds. The range filter applies as `start_time` ≤ t \< `end_time`. | | event\_ids | Optional\[list] | - | List of event\_ids to be deleted. | | update\_metrics | Optional\[bool] | False | Determines if the monitoring metrics are recalculated to reflect the changes. Supported for time range deletions only. | ### Example: Deleting Inference Events by Timestamp Range ```python theme={null} import requests headers = {'Content-Type': 'application/json', 'Authorization': f'Bearer {token}'} data = {'model_id': model.id, 'time_range':{ 'start_time':'2024-09-27 17:00:00', 'end_time':'2024-09-27 18:00:00', }, 'update_metrics':True, } response = requests.delete( url=f'{url}/v3/events', headers=headers, json=data, ) ``` ### Example: Deleting Inference Events by Event IDs ```python theme={null} import requests headers = {'Content-Type': 'application/json', 'Authorization': f'Bearer {token}'} data = { 'model_id': model.id, 'event_ids': ['event_id1', 'event_id2'], } response = requests.delete( url=f'{url}/v3/events', headers=headers, json=data, ) ``` > 📘 Please delete events with caution when `update_metrics=True`. We recommend not deleting events while there is an ongoing publish or update operation within the same data range. ## Related Resources * [Delete Events REST API reference](/sdk-api/rest-api/events/delete-events) * [Model SDK reference](/sdk-api/python-client/model) * [Event deduplication](/developers/python-client-guides/publishing-production-data/event-deduplication) * [Python SDK changelog](/changelog/python-sdk) # Event Deduplication Source: https://docs.fiddler.ai/developers/python-client-guides/publishing-production-data/event-deduplication Learn how Fiddler prevents duplicate inference events from inflating your monitoring metrics. When enabled, Fiddler's event deduplication feature ensures that the same inference event is stored and counted only once within the deduplication windows, even when events are published multiple times due to retries, overlapping batch uploads, or client-side errors. Event deduplication is not enabled by default. To enable it for your deployment, contact Fiddler support. ## Prerequisites Event deduplication requires that a unique identifier column is defined on your model: * Set `event_id_col` to the name of the column containing unique event identifiers when onboarding your model using `Model.from_data()` or `Model()`. * Events that do not have a value in this column (null or missing) are always accepted and stored without deduplication. ```python theme={null} model = fdl.Model.from_data( name='your_model_name', project_id=fdl.Project.from_name('your_project_name').id, source=sample_df, spec=model_spec, task=model_task, event_id_col='your_event_id_column', # required for deduplication event_ts_col='your_timestamp_column', ) ``` ## How Deduplication Works Fiddler applies multiple independent layers of deduplication as events move through the ingestion pipeline. Each layer targets a different source of duplication. | Layer | What it prevents | Window | | ------------------------------- | ----------------------------------------------------------- | ------------------- | | Request retry protection | Same HTTP request processed twice due to client retry | 30 minutes | | Within-batch deduplication | Duplicate event IDs in the same publish call | Entire batch | | Against recently stored events | Event IDs that already exist in recent ingestion history | 1 hour (default) | | Across concurrent publish calls | Same event ID arriving in parallel chunks | 5 minutes (default) | | Storage-level idempotency | Same internal batch resubmitted due to infrastructure retry | 7 days | Request retry protection and storage-level idempotency are always active. The remaining layers are part of event deduplication. ### Request Retry Protection When the Fiddler client SDK retries a publish request due to a network timeout or transient error, Fiddler detects the retry and returns the original result without reprocessing the events. This prevents duplicate job submissions and duplicate event ingestion caused by client-side retry logic. * **Window:** 30 minutes. A retried request received within 30 minutes of the original is recognized and deduplicated. * **Always active:** This layer requires no configuration and is always enabled. ### Within-Batch Deduplication If the same event ID appears more than once within a single publish call (for example, duplicate rows in a DataFrame or CSV), Fiddler keeps the first occurrence and drops subsequent duplicates before the events are stored. * **Window:** The entire publish batch. ### Against Recently Stored Events Before storing incoming events, Fiddler checks whether their event IDs already exist in recently ingested data. If a match is found, the incoming event is dropped. * **Window:** 1 hour (default). Event IDs are checked against events ingested within the past hour. ### Across Concurrent Publish Calls Large batch uploads are internally split into chunks and processed in parallel. If the same event ID appears across multiple chunks — for example, when overlapping files are uploaded concurrently — Fiddler uses a short-lived shared cache to detect and drop the duplicates. * **Window:** 5 minutes (default). Event IDs seen within the past 5 minutes are held in cache and used to deduplicate overlapping chunks. ### Storage-Level Idempotency If an internal processing failure causes the same batch of events to be retried and resubmitted to storage, Fiddler's storage layer silently ignores the duplicate insert using a per-chunk idempotency token. * **Always active:** This layer requires no configuration. * It protects against infrastructure-level retries and does not deduplicate individual events by event ID. > **Note:** > > If all events in a publish call are identified as duplicates, the call succeeds with no new events stored — it is not treated as an error. ## Without Deduplication When event deduplication is not enabled, duplicate events published via retries or overlapping batches are accepted and stored. This may affect the accuracy of aggregated metrics such as event counts, drift scores, and model performance indicators shown in monitoring dashboards, charts, and alerts. To enable deduplication for your deployment, contact Fiddler support. ## Limitations * Deduplication applies to **insert operations only**. Update operations (used to add ground truth labels or metadata) are never deduplicated. * Events with a null or missing event ID are never deduplicated. They are always accepted and stored, and receive a system-generated identifier. * Enabling deduplication does not retroactively correct metrics affected by previously published duplicates. ## Related Resources * [Publishing Batches of Events](/developers/python-client-guides/publishing-production-data/publishing-batches-of-events) * [Streaming Live Events](/developers/python-client-guides/publishing-production-data/streaming-live-events) * [Deleting Events](/developers/python-client-guides/publishing-production-data/deleting-events) * [Publishing Production Data Reference](/developers/client-library-reference/publishing-production-data) # Publishing Batches of Events Source: https://docs.fiddler.ai/developers/python-client-guides/publishing-production-data/publishing-batches-of-events Dive into our guide on publishing batches of events. Learn how Fiddler supports multiple source formats when publishing batches of events. Fiddler provides multiple options for publishing batches of production data, allowing you to choose the format and method that best suits your needs. ### Supported Data Formats * pandas DataFrame * CSV file (`.csv`), * Parquet file (`.parquet`) ### Supported Data Locations * In memory - pandas DataFrame * Local disk - CSV, parquet > **Note:** > > Fiddler's Python client offers the ability to integrate with Cloud data stores such as AWS S3. Refer to our [Integrations Guides](/integrations) for examples. ### Batch Publishing Examples Publish a batch of inference events using a parquet file, CSV file, or DataFrame using `Model.publish_batch()`. This method executes asynchronously and returns a Job object. The job can be used to: * Track by ID in the UI on the Jobs page * Poll for status until completion * Use the `wait()` method for synchronous behavior * Log the job ID for reference #### Parquet File ```python theme={null} import fiddler as fdl # Instantiate the Model object for your model project = fdl.Project.from_name(name='your_project_name') model = fdl.Model.from_name(name='your_model_name', project_id=project.id) publish_job = model.publish_batch(source='my_events_batch.parquet') # publish_batch() is asynchronous. Use the publish job's wait() method # if synchronous behavior is desired. publish_job.wait() ``` #### CSV File ```python theme={null} import fiddler as fdl # Instantiate the Model object for your model project = fdl.Project.from_name(name='your_project_name') model = fdl.Model.from_name(name='your_model_name', project_id=project.id) publish_job = model.publish_batch(source='my_events_batch.csv') ``` #### Pandas DataFrame ```python theme={null} import pandas as pd import fiddler as fdl # Instantiate the Model object for your model project = fdl.Project.from_name(name='your_project_name') model = fdl.Model.from_name(name='your_model_name', project_id=project.id) my_events_df = pd.read_csv('my_events_batch.csv') publish_job = model.publish_batch(source=my_events_df) ``` *Please allow a few minutes for events to populate the related charts.* *Total processing time is a function of both width and count of the inference events.* # Ranking Events Source: https://docs.fiddler.ai/developers/python-client-guides/publishing-production-data/ranking-events Explore our guide to publishing production data. Learn how to publish and update ranking events in a grouped format with a detailed example. ### Publish Inference Events for Ranking Models A ranking machine learning model orders items based on their relevance to a specific query or context. Unlike classification or regression models that predict absolute values, ranking models focus on relative ordering between items. #### Grouping Format for Ranking Model Inference Events Before publishing ranking model events to Fiddler, format them in a **grouped format**. This means items returned for the same query ID (specified by the group\_by parameter in TaskParams) appear in a single row with values stored as lists. Example of correctly grouped format: | srch\_id | price\_usd | review\_score | ... | prediction | target | | -------- | -------------------------- | ------------------ | ------ | ------------------------ | ---------- | | 101 | \[134.77,180.74,159.80] | \[5.0,2.5,4.5] | \[...] | \[1.97, 0.84,-0.69] | \[1,0,0] | | ... | ... | | ... | ... | ... | | 112 | \[26.00,51.00,205.11,73.2] | \[3.0,4.5,2.0,1.0] | \[...] | \[10.75,8.41,-0.23,-3.2] | \[0,1,0,0] | In this example, `srch_id` is the `group_by` column, and all other columns contain lists corresponding to each group. #### How to Convert a Flat CSV File Into Grouped Format If your data is in a flat CSV file (one item per row), use Fiddler's utility function to convert it to the required grouped format: ```python theme={null} from fiddler.utils.helpers import group_by import pandas as pd # Read the flat CSV file df = pd.read_csv('path/to/ranking_events.csv') # Convert to grouped format df_grouped = group_by(df=df, group_by_col='srch_id') ``` The `group_by_col` argument should match the column specified in the `group_by` parameter of your [Model](/sdk-api/python-client/connection) object. ### Publish Grouped Ranking Events After preparing your grouped data, publish it to Fiddler: ```python theme={null} project = fdl.Project.from_name(name='your_project_name') model = fdl.Model.from_name(name='your_model_name', project_id=project.id) # df_grouped DataFrame from above example publish_job = model.publish_batch(source=df_grouped) # publish_batch() is asynchronous. Use the publish job's wait() method # if synchronous behavior is desired. publish_job.wait() ``` ### Update Ranking Events You can update existing ranking events while maintaining the same grouped format. #### Prepare the Updating DataFrame To update the ground truth labels (called 'target values' in Fiddler), create a dataframe with the required updates while keeping the grouped format. Call `Model.publish_batch()` with update set to true: ```python theme={null} project = fdl.Project.from_name(name='your_project_name') model = fdl.Model.from_name(name='your_model_name', project_id=project.id) # Publish updates to existing events update_job = model.publish_batch(source=modified_df_grouped, update=True) print(f'Update job: {update_job.id}') ``` Fiddler will update only the columns included in your modified dataframe while preserving all other data. Event update behavior is described in more detail in the [Event Update](/developers/python-client-guides/publishing-production-data/updating-events) guide. # Streaming Live Events Source: https://docs.fiddler.ai/developers/python-client-guides/publishing-production-data/streaming-live-events Learn how to stream your ML model's inference event data using the Fiddler Python client. You can stream production data to Fiddler as an alternative to batch publishing. Streaming offers lower latency, which is beneficial for high-velocity or near real-time models. ### When to Use Streaming vs. Batch Publishing * Use `Model.publish_stream()` when low latency is a priority and you're working with individual events or small batches * Use `Model.publish_batch()` for large datasets or when you need to track longer-running processes with Job objects #### Stream Individual Inference Events To stream a single inference event: ```python theme={null} project = fdl.Project.from_name(name='your_project_name') model = fdl.Model.from_name(name='your_model_name', project_id=project.id) # A single event must still be passed as a list. model.publish_stream(events=[ { 'customer_id': 1234, 'timestamp': 1710428785, 'CreditScore': 650, 'Geography': 'France', 'Gender': 'Female', 'Age': 45, 'Tenure': 2, 'Balance': 10000.0, 'NumOfProducts': 1, 'HasCrCard': 'Yes', 'isActiveMember': 'Yes', 'EstimatedSalary': 120000, 'probability_churned': 0.105, 'churn': 1 } ]) ``` #### Stream Small Batches of Events For better efficiency, you can stream multiple events at once: ```python theme={null} # For multiple events, where `my_events` is a list of Python dictionaries model.publish_stream(events=my_events) ``` > 🚧 Note > > Convert a pandas DataFrame to a list of event dictionaries using the to\_dict function. ```python theme={null} my_events = my_df.to_dict(orient='records') ``` For batches larger than 5,000 events, prefer [`Model.publish_batch()`](/developers/python-client-guides/publishing-production-data/publishing-batches-of-events) over streaming. # Updating Events Source: https://docs.fiddler.ai/developers/python-client-guides/publishing-production-data/updating-events Dive into our guide on updating inference events. Learn how to update your ground truth labels and metadata using the Fiddler Python client. Fiddler allows you to update specific fields in previously published events. While your model feature values can't be updated, you can update: * Target column values (ground truth labels) * Metadata columns Input, Output, and Custom Feature column types cannot be updated once published. If values for these columns are included with your update (`update_event=True`), they will be ignored. ### Updating Ground Truth Labels Updating ground truth labels is the most common use case for post-publish updates. You can update events when: * Actual values become available for events initially published without labels * You discover that initially uploaded labels are incorrect Things to keep in mind about ground truth labels (target values): * Use null values when initially publishing inferences that don't yet have labels * Fiddler automatically keeps aggregated performance metrics current as labels are updated * Labels can be updated multiple times if necessary ### Updating Metadata Columns Fiddler supports updating **metadata** columns with new values. This is particularly useful for supporting alternate labels that can be used with Custom Metrics to calculate alternative performance metrics. Things to keep in mind regarding metadata updates: * Updated values are visible in Feature Analytics and [Root Cause Analysis ](/observability/analytics#root-cause-analysis)views * Pre-calculated aggregated metrics will not reflect the updated values * Custom Metrics, used in charts and alerts, will always use the current values since they're calculated at runtime * Updating metadata columns requires additional processing time, so only send updates when necessary ### Label Update Examples #### Stream Label Updates As with inference publishing, label updates can be sent as streams or batches. **Stream Update Data Formats** * List of Python dictionaries **Stream Update One or More Events** Integrate Fiddler directly into your production system to publish label updates as they occur. The event ID, the column chosen for Model.event\_id\_col, is required. ```python theme={null} import fiddler as fdl # Instantiate the Model object for your model project = fdl.Project.from_name(name='your_project_name') model = fdl.Model.from_name(name='your_model_name', project_id=project.id) event_update = [ { 'label_value': 1, 'event_id': 'A1', }, ... ] # Streaming update returns the list of event ID(s) updated. event_id = model.publish_stream( events=event_update, environment=fdl.EnvType.PRODUCTION, update=True, ) ``` **Stream Update Label and Metadata** Metadata column(s) can also be updated. ```python theme={null} import fiddler as fdl # Instantiate the Model object for your model project = fdl.Project.from_name(name='your_project_name') model = fdl.Model.from_name(name='your_model_name', project_id=project.id) event_update = [ { 'metadata_col': 'yes', 'label_value': 1, 'event_id': 'A1', }, ] event_id = model.publish_stream( events=event_update, environment=fdl.EnvType.PRODUCTION, update=True, ) ``` #### Batch Update Data Formats * pandas DataFrame * CSV file (`.csv`), * Parquet file (`.parquet`) **Batch Update Events** Publish larger sets of label updates using batch publishing. The event ID, the column chosen for Model.event\_id\_col, is required. ```python theme={null} import pandas as pd import fiddler as fdl project = fdl.Project.from_name(name='your_project_name') model = fdl.Model.from_name(name='your_model_name', project_id=project.id) label_batch = pd.read_parquet('path_to_your_updated_labels/data.parquet') update_job = model.publish_batch( source=label_batch, environment=fdl.EnvType.PRODUCTION, update=True, ) ``` Refer to `Model.publish_stream()` and `Model.publish_batch()` documentation for more details on different sources and parameters. > 📘 **There are a few points to be aware of:** > > * Performance metrics (available in monitoring charts and alert rules) will be computed as ground truth labels are inserted and recomputed when later updated. > * For example, if the ground truth values are originally missing from events in a given time range, there will be **no performance metrics available** for that time range. Once the events are updated, performance metrics will be computed and will populate the monitoring charts. > * Events that do not originally have ground truth labels should be **uploaded with empty values**—not dummy values. If dummy values are used, you will have improper performance metrics, and once the new values come in, the old, incorrect values will still be present. > * Metrics based on **Metadata** columns won't reflect updates. > * In order to update existing events, you will need access to the event IDs used at the time of upload. > * Updating the event timestamp, `Model.event_ts_col`, is not supported. # Experiments Quick Start Source: https://docs.fiddler.ai/developers/quick-starts/experiments-quick-start Quick start guide for running experiments on LLM applications using the Fiddler Evals SDK Systematically evaluate your LLM applications, RAG systems, and AI agents using the Fiddler Evals SDK with built-in evaluators and custom metrics. **Time to complete**: \~20 minutes ## What You'll Learn * Initialize the Fiddler Evals SDK and organize your experiments * Create experiment datasets with test cases * Use built-in evaluators (faithfulness, relevance, coherence, etc.) * Create custom evaluators for domain-specific requirements * Run experiments and analyze results *** ## Prerequisites * **Fiddler Account**: Active account with API access * **Python 3.10+** * **Fiddler Evals SDK**: `pip install fiddler-evals` * **Access Token**: From [Settings > Credentials](/reference/administration/settings#credentials) *** ## Quick Start ### Step 1: Connect to Fiddler ```python theme={null} from fiddler_evals import init # Initialize connection init( url='https://your-org.fiddler.ai', token='your-access-token' ) ``` ### Step 2: Create Project and Application ```python theme={null} from fiddler_evals import Project, Application, Dataset from fiddler_evals.pydantic_models.dataset import NewDatasetItem # Create organizational structure project = Project.get_or_create(name='my_eval_project') application = Application.get_or_create( name='my_llm_app', project_id=project.id ) # Create experiment dataset dataset = Dataset.create( name='experiment_dataset', application_id=application.id, description='Test cases for LLM experiments' ) ``` ### Step 3: Add Test Cases ```python theme={null} # Define test cases test_cases = [ NewDatasetItem( inputs={"question": "What is the capital of France?"}, expected_outputs={"answer": "Paris is the capital of France"}, metadata={"type": "Factual", "category": "Geography"} ), NewDatasetItem( inputs={"question": "Explain photosynthesis"}, expected_outputs={"answer": "Photosynthesis is the process by which plants convert sunlight into energy"}, metadata={"type": "Explanation", "category": "Science"} ), ] # Insert test cases into dataset dataset.insert(test_cases) print(f"✅ Added {len(test_cases)} test cases") ``` ### Step 4: Define Your LLM Task ```python theme={null} def my_llm_task(inputs, extras, metadata): """Your LLM application logic.""" question = inputs.get("question", "") # Call your LLM here (example uses placeholder) # In production, call OpenAI, Anthropic, or your LLM answer = f"Mock response to: {question}" return {"answer": answer} ``` ### Step 5: Run Experiment with Built-In Evaluators ```python theme={null} from fiddler_evals import evaluate from fiddler_evals.evaluators import ( AnswerRelevance, Conciseness, FTLPromptSafety ) MODEL = "openai/gpt-4o" CREDENTIAL = "your-llm-credential" # From Settings > LLM Gateway # Run evaluation results = evaluate( dataset=dataset, task=my_llm_task, evaluators=[ AnswerRelevance(model=MODEL, credential=CREDENTIAL), Conciseness(model=MODEL, credential=CREDENTIAL), FTLPromptSafety() # Centor Models run locally, no model= needed ], name_prefix="my_experiment", score_fn_kwargs_mapping={ "user_query": lambda x: x["inputs"]["question"], "rag_response": "answer", "response": "answer", "text": "answer", } ) print(f"✅ Evaluated {len(results.results)} test cases") ``` ### Step 6: Analyze Results ```python theme={null} # Access results programmatically for item_result in results.results: print(f"\nTest Case: {item_result.dataset_item_id}") print(f"Task Output: {item_result.task_output}") # View scores from each evaluator for score in item_result.scores: print(f" {score.name}: {score.value} - {score.reasoning}") # View results in Fiddler UI print(f"\n🔗 View results: https://your-org.fiddler.ai") ``` *** ## Built-In Evaluators The Fiddler Evals SDK includes 13 pre-built evaluators: ### Quality & Accuracy * **AnswerRelevance** - Measures response relevance to the question (High / Medium / Low) * **Coherence** - Evaluates logical flow and consistency * **Conciseness** - Checks for unnecessary verbosity ### Safety & Trust * **FTLPromptSafety** - Detects prompt injection, jailbreaks, and unsafe prompts * **FTLResponseFaithfulness** - Evaluate faithfulness of LLM responses (powered by the Centor Model for Faithfulness) ### RAG Health Metrics * **AnswerRelevance** - Measures how well responses address user queries (High / Medium / Low) * **ContextRelevance** - Evaluates whether retrieved documents are relevant to the query (High / Medium / Low) * **RAGFaithfulness** - Checks if response is grounded in retrieved documents (Yes / No) Use these three evaluators together as a diagnostic triad to pinpoint whether RAG pipeline issues originate in retrieval, generation, or query understanding. ### Example: RAG Experiment ```python theme={null} from fiddler_evals.evaluators import AnswerRelevance, ContextRelevance, RAGFaithfulness # Add context to test cases rag_test_cases = [ NewDatasetItem( inputs={ "user_query": "What is the capital of France?", "retrieved_documents": "Paris is the capital and largest city of France." }, expected_outputs={"rag_response": "Paris"} ), ] dataset.insert(rag_test_cases) # Evaluate with RAG Health Metrics evaluators rag_results = evaluate( dataset=dataset, task=my_rag_task, # Your RAG system evaluators=[ AnswerRelevance(model="openai/gpt-4o", credential="your-llm-credential"), ContextRelevance(model="openai/gpt-4o", credential="your-llm-credential"), RAGFaithfulness(model="openai/gpt-4o", credential="your-llm-credential") ], score_fn_kwargs_mapping={ "rag_response": "rag_response", "retrieved_documents": lambda x: x["inputs"]["retrieved_documents"], "user_query": lambda x: x["inputs"]["user_query"] } ) ``` *** ## Custom Evaluators Create domain-specific evaluators for your use case: ```python theme={null} from fiddler_evals.evaluators.base import Evaluator from fiddler_evals.pydantic_models.score import Score class CustomToneEvaluator(Evaluator): """Evaluates if response matches desired tone.""" def score(self, response: str, desired_tone: str = "professional") -> Score: # Your custom evaluation logic is_professional = self._check_tone(response, desired_tone) return Score( name="tone_match", value=1.0 if is_professional else 0.0, reasoning=f"Response {'matches' if is_professional else 'does not match'} {desired_tone} tone" ) def _check_tone(self, text: str, tone: str) -> bool: # Implement your tone detection logic # Could use keyword matching, LLM-as-judge, or ML model return True # Placeholder # Use custom evaluator results = evaluate( dataset=dataset, task=my_llm_task, evaluators=[CustomToneEvaluator()], score_fn_kwargs_mapping={ "response": "answer", "desired_tone": "professional" } ) ``` *** ## Advanced Features ### Batch Experiments with Parallel Processing ```python theme={null} # Evaluate with parallel workers for faster execution results = evaluate( dataset=dataset, task=my_llm_task, evaluators=[AnswerRelevance(model="openai/gpt-4o", credential="your-llm-credential"), Conciseness(model="openai/gpt-4o", credential="your-llm-credential")], max_workers=5 # Process 5 test cases in parallel ) ``` ### Import Datasets from Files ```python theme={null} # From CSV dataset.insert_from_csv_file( csv_file_path='test_cases.csv', inputs_columns=['question'], expected_outputs_columns=['answer'] ) # From JSONL dataset.insert_from_jsonl_file( jsonl_file_path='test_cases.jsonl' ) # From Pandas DataFrame import pandas as pd df = pd.DataFrame({ 'question': ['Q1', 'Q2'], 'expected_answer': ['A1', 'A2'] }) dataset.insert_from_pandas( dataframe=df, inputs_columns=['question'], expected_outputs_columns=['expected_answer'] ) ``` ### Track Experiment Metadata ```python theme={null} # Add experiment metadata for tracking results = evaluate( dataset=dataset, task=my_llm_task, evaluators=[AnswerRelevance(model="openai/gpt-4o", credential="your-llm-credential")], name_prefix="experiment_v2", # Version your experiments score_fn_kwargs_mapping={"response": "answer"} ) # Results are automatically tracked in Fiddler # View experiment history in the Fiddler UI ``` *** ## Complete Example: RAG Experiment Pipeline ```python theme={null} from fiddler_evals import init, Project, Application, Dataset, evaluate from fiddler_evals.pydantic_models.dataset import NewDatasetItem from fiddler_evals.evaluators import ( RAGFaithfulness, AnswerRelevance, ContextRelevance, Conciseness ) # Step 1: Initialize init(url='https://your-org.fiddler.ai', token='your-token') # Step 2: Set up organization project = Project.get_or_create(name='rag_experiments') app = Application.get_or_create(name='doc_qa_system', project_id=project.id) dataset = Dataset.create(name='qa_test_set', application_id=app.id) # Step 3: Create test cases test_cases = [ NewDatasetItem( inputs={ "user_query": "What is machine learning?", "retrieved_documents": "Machine learning is a subset of AI that enables " "systems to learn from data." }, expected_outputs={ "rag_response": "Machine learning is a subset of AI." }, metadata={"difficulty": "easy"} ), ] dataset.insert(test_cases) # Step 4: Define RAG task def rag_task(inputs, extras, metadata): """Your RAG system implementation.""" user_query = inputs["user_query"] retrieved_documents = inputs["retrieved_documents"] # Call your RAG system (simplified example) rag_response = generate_answer(user_query, retrieved_documents) return { "rag_response": rag_response, "retrieved_documents": retrieved_documents, } # Step 5: Run comprehensive evaluation results = evaluate( dataset=dataset, task=rag_task, evaluators=[ RAGFaithfulness(model="openai/gpt-4o", credential="your-llm-credential"), # Check factual grounding (Yes/No) AnswerRelevance(model="openai/gpt-4o", credential="your-llm-credential"), # Check relevance to query (High/Medium/Low) ContextRelevance(model="openai/gpt-4o", credential="your-llm-credential"), # Check retrieval quality (High/Medium/Low) Conciseness(model="openai/gpt-4o", credential="your-llm-credential"), # Check for verbosity ], name_prefix="rag_eval_v1", score_fn_kwargs_mapping={ "rag_response": "rag_response", "retrieved_documents": "retrieved_documents", "user_query": lambda x: x["inputs"]["user_query"], } ) # Step 6: Analyze print(f"Evaluated {len(results.results)} test cases") for result in results.results: print(f"\n{result.dataset_item_id}:") for score in result.scores: print(f" {score.name}: {score.value:.3f}") ``` *** ## Best Practices 1. **Start Small**: Begin with 10-20 test cases to validate your setup 2. **Use Multiple Evaluators**: Combine quality, safety, and domain-specific evaluators 3. **Version Your Experiments**: Use `name_prefix` to track different experiment runs 4. **Monitor Over Time**: Run experiments regularly to catch regressions 5. **Custom Evaluators**: Create domain-specific evaluators for specialized needs 6. **Leverage Parallelization**: Use `max_workers` for faster evaluation of large datasets 7. **Organize Hierarchically**: Use Projects > Applications > Datasets structure *** ## Next Steps ### Complete Guides * [**Evals SDK Quick Start**](/evaluate-and-test/evals-sdk-quick-start) - Full tutorial with detailed examples * [**Evals SDK Reference**](/sdk-api/evals/evaluate) - Complete API documentation ### Concepts & Background * [**Experiments Overview**](/getting-started/experiments) - Why and when to run experiments * [**Centor Models**](/glossary/centor-models) - Fiddler's purpose-built LLM evaluation models ### Integration Guides * [**Evals SDK Integration**](/integrations/agentic-ai/evals-sdk) - Integration patterns and examples * [**LangGraph SDK**](/integrations/agentic-ai/langgraph-sdk) - Monitor LangGraph agents * [**Strands Agents SDK**](/integrations/agentic-ai/strands-sdk) - Monitor Strands agents *** ## Summary You've learned how to: * ✅ Initialize the Fiddler Evals SDK with `init()` * ✅ Create Projects, Applications, and Datasets for organization * ✅ Build experiment datasets with test cases * ✅ Use 13 built-in evaluators for quality, safety, and RAG metrics * ✅ Create custom evaluators for domain-specific requirements * ✅ Run experiments with the `evaluate()` function * ✅ Analyze results programmatically and in the Fiddler UI The Fiddler Evals SDK provides a comprehensive framework for systematic LLM experiments, enabling you to ensure quality, safety, and accuracy before deploying your AI applications. # Get Started in <10 Minutes Source: https://docs.fiddler.ai/developers/quick-starts/get-started-in-less-than-10-minutes Choose your integration path and get started with Fiddler in under 10 minutes Welcome to Fiddler! Choose your integration path based on what you want to accomplish. Each quick start gets you up and running in 10-20 minutes. *** ## 🎯 What Do You Want to Do? ### 🤖 Monitor AI Agents & Multi-Step Workflows **Best for:** Applications using LangGraph, Strands, or custom agentic frameworks Your AI agents make complex decisions across multiple steps. Monitor the complete workflow from initial reasoning to final response. **Choose your framework:** | Framework | Integration | Time | Quick Start | | ------------------------- | -------------------- | ------ | -------------------------------------------------------------------------- | | **LangGraph / LangChain** | Auto-instrumentation | 10 min | [LangGraph SDK →](/developers/quick-starts/langgraph-sdk-quick-start) | | **Strands Agents** | Native integration | 10 min | [Strands Agents SDK →](/developers/quick-starts/strands-agent-quick-start) | | **Custom / Other** | OpenTelemetry | 15 min | [OpenTelemetry →](/developers/quick-starts/opentelemetry-quick-start) | **What you'll monitor:** * Agent decision-making and tool selection * Multi-step reasoning chains * LLM calls with inputs/outputs * Tool usage and external API calls * Error propagation and recovery *** ### 💬 Monitor Simple LLM Applications **Best for:** Single-shot LLM inference, chatbots, simple RAG systems You're using LLMs for straightforward tasks like Q\&A, content generation, or basic chat interfaces. **Quick Start:** [Simple LLM Monitoring →](/developers/quick-starts/simple-llm-monitoring) ⏱️ 10 min **What you'll monitor:** * LLM prompts and completions * Token usage and costs * Response latency * Quality metrics (toxicity, PII, sentiment) * Embedding visualizations *** ### 📊 Monitor Traditional ML Models **Best for:** Scikit-learn, XGBoost, TensorFlow, PyTorch models in production You have traditional ML models (classification, regression, ranking) deployed and need to track their performance. **Quick Start:** [Simple ML Monitoring →](/developers/quick-starts/simple-ml-monitoring) ⏱️ 10 min **What you'll monitor:** * Model performance (accuracy, precision, recall) * Data drift and distribution shifts * Feature importance * Prediction analytics * Custom business metrics *** ### 🧪 Evaluate & Test LLM Applications **Best for:** Pre-deployment testing, A/B testing, regression testing You want to systematically evaluate LLM quality before deployment or compare different prompts/models. **Quick Start:** [Experiments →](/developers/quick-starts/experiments-quick-start) ⏱️ 15 min **What you'll evaluate:** * Response accuracy and relevance * Semantic similarity * Custom domain-specific metrics * Safety and bias * RAG-specific metrics (faithfulness, context relevance) *** ### 🛡️ Add Safety Guardrails **Best for:** Protecting LLM applications from harmful content, PII leaks, and hallucinations You need real-time protection to prevent your LLM from generating harmful, sensitive, or incorrect content. **Quick Start:** [Guardrails →](/developers/quick-starts/guardrails-quick-start) ⏱️ 10 min **What you'll protect against:** * Harmful and toxic content * PII leaks (emails, SSNs, credit cards) * Hallucinations and unsupported claims * Jailbreak attempts * Content policy violations *** ## 🤔 Not Sure Where to Start? ### If you're building with AI agents: Start with [**Agentic Observability**](/developers/quick-starts/langgraph-sdk-quick-start) - it covers everything you need for multi-step workflows. ### If you're using LLMs for simple tasks: Start with [**Simple LLM Monitoring**](/developers/quick-starts/simple-llm-monitoring) - perfect for chat, Q\&A, and content generation. ### If you have traditional ML models: Start with [**Simple ML Monitoring**](/developers/quick-starts/simple-ml-monitoring) - track performance and drift for any ML model. ### If you want to test before deploying: Start with [**Experiments**](/developers/quick-starts/experiments-quick-start) - build confidence with systematic testing. ### If you need to protect your users: Start with [**Guardrails**](/developers/quick-starts/guardrails-quick-start) - add safety checks in minutes. *** ## 🚀 Quick Comparison | Use Case | Monitoring Type | Best Quick Start | Time | | ------------------------------------------------ | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------ | | Multi-agent systems, complex workflows | Agentic | [LangGraph](/developers/quick-starts/langgraph-sdk-quick-start) / [Strands](/developers/quick-starts/strands-agent-quick-start) / [OTeL](/developers/quick-starts/opentelemetry-quick-start) | 10 min | | Simple chatbots, Q\&A, content generation | LLM | [Simple LLM Monitoring](/developers/quick-starts/simple-llm-monitoring) | 15 min | | Classification, regression, ranking models | ML | [Simple ML Monitoring](/developers/quick-starts/simple-ml-monitoring) | 10 min | | Pre-deployment testing, A/B testing | Experiments | [Experiments](/developers/quick-starts/experiments-quick-start) | 15 min | | Safety, PII protection, hallucination prevention | Guardrails | [Guardrails](/developers/quick-starts/guardrails-quick-start) | 10 min | *** ## 📚 After Your Quick Start Once you've completed a quick start: 1. **Explore the UI** - View your dashboards, metrics, and insights 2. **Set Up Alerts** - Get notified when issues occur 3. **Customize Metrics** - Add domain-specific monitoring 4. **Read Advanced Guides** - Deep dive into specific features 5. **Join the Community** - Get help and share best practices *** ## 💡 Pro Tips * **Start Simple**: Pick one quick start, complete it fully, then expand * **Use Notebooks**: Most quick starts have Colab notebooks for hands-on learning * **Test Data First**: Use sample data before connecting production systems * **Monitor + Evaluate**: Combine monitoring with evaluation for comprehensive coverage * **Layer Guardrails**: Add safety checks on both inputs and outputs *** ## Need Help? * **Documentation**: Browse our [complete documentation](/) * **Getting Started Guides**: Read conceptual overviews for [Agentic](/getting-started/agentic-monitoring), [LLM](/getting-started/llm-monitoring), [ML](/getting-started/ml-observability), [Experiments](/getting-started/experiments), or [Guardrails](/getting-started/guardrails) * **Support**: Contact your Fiddler team or \<[support@fiddler.ai](mailto:support@fiddler.ai)> *** # Google ADK SDK Quick Start Source: https://docs.fiddler.ai/developers/quick-starts/google-adk-quick-start Learn how to integrate Google ADK agents with Fiddler using the Fiddler ADK SDK for automatic instrumentation and comprehensive observability. ## What You'll Learn In this guide, you'll learn how to: * Set up a Fiddler application for monitoring Google ADK agents * Install and configure the Fiddler ADK SDK * Instrument ADK agents with automatic telemetry * Run a multi-turn agent with tool calls * Verify monitoring is working correctly **Time to complete**: \~10 minutes ## Prerequisites Before you begin, ensure you have: * **Fiddler Account**: An active account with [access](/reference/access-control/role-based-access) to create applications * **Python 3.10+**: Verify your version: ```bash theme={null} python --version ``` * **Fiddler ADK SDK**: Install the SDK: ```bash theme={null} # Using uv (recommended) uv add fiddler-adk # Or using pip pip install fiddler-adk ``` * **Google Gemini Access**: Either a Gemini API key or Vertex AI credentials: ```bash theme={null} # Option A: Gemini API key export GOOGLE_API_KEY= # Option B: Vertex AI export GOOGLE_GENAI_USE_VERTEXAI=1 export GOOGLE_CLOUD_PROJECT= export GOOGLE_CLOUD_LOCATION=us-central1 ``` If you prefer using a notebook, download it directly from [GitHub](https://github.com/fiddler-labs/fiddler-examples/blob/main/quickstart/latest/Fiddler_Quickstart_Google_ADK_Integration.ipynb) or open it in [Google Colab](https://colab.research.google.com/github/fiddler-labs/fiddler-examples/blob/main/quickstart/latest/Fiddler_Quickstart_Google_ADK_Integration.ipynb) to get started. First, create a dedicated application in Fiddler to receive your agent traces. 1. Sign in to your Fiddler instance 2. Navigate to **GenAI Applications** in the left sidebar 3. Click **Add Application** 4. Enter the application details: * **Name**: `google-adk-monitoring` * **Project**: Select a project from the dropdown or press *Enter* to create a new one 5. Click **Create** and copy the **Application UUID** (you'll need this for configuration) Set up the required credentials. You need your Fiddler API key (from Settings) and the Application UUID from Step 1. Instructions for generating your API key can be found in the [Access guide](/reference/administration/settings#credentials). ```bash theme={null} # Fiddler credentials export FIDDLER_URL="https://your-fiddler-instance.com" export FIDDLER_API_KEY="" export FIDDLER_APPLICATION_ID="" # Google Gemini credentials (choose one) export GOOGLE_API_KEY="" # or for Vertex AI: # export GOOGLE_GENAI_USE_VERTEXAI=1 # export GOOGLE_CLOUD_PROJECT="" ``` **Tip**: Save these in a `.env` file and load with `python-dotenv` for easy reuse. Add two lines to your application to enable Fiddler monitoring: ```python theme={null} import os from fiddler_otel import FiddlerClient from fiddler_adk import GoogleADKInstrumentor # Initialize Fiddler client client = FiddlerClient( api_key=os.environ["FIDDLER_API_KEY"], application_id=os.environ["FIDDLER_APPLICATION_ID"], url=os.environ["FIDDLER_URL"], ) # Enable automatic instrumentation GoogleADKInstrumentor(client).instrument() ``` That's it. All ADK agents created after this point are automatically traced. Create an ADK agent with tools and run it: ```python theme={null} import asyncio from google.adk.agents.llm_agent import Agent from google.adk.runners import Runner from google.adk.sessions import InMemorySessionService from google.genai import types # Define a tool def get_weather(city: str) -> dict: """Get current weather for a city.""" return {"city": city, "temp_f": 72, "condition": "sunny"} # Create agent agent = Agent( model="gemini-2.5-flash", name="weather_agent", description="A helpful weather assistant", instruction="You help users check the weather. Be brief.", tools=[get_weather], ) async def main(): session_service = InMemorySessionService() runner = Runner( agent=agent, app_name="demo", session_service=session_service ) session = await session_service.create_session( app_name="demo", user_id="user1" ) # Send a message message = types.Content( role="user", parts=[types.Part(text="What's the weather in San Francisco?")], ) async for event in runner.run_async( user_id="user1", session_id=session.id, new_message=message ): if hasattr(event, "content") and event.content: parts = getattr(event.content, "parts", []) or [] text = "".join( p.text for p in parts if getattr(p, "text", None) ) if text: print(f"Agent: {text}") # Flush traces before exit client.force_flush(timeout_millis=5000) asyncio.run(main()) ``` After running your agent: 1. Navigate to your Fiddler instance 2. Open the **GenAI Applications** page 3. Click on your application (`google-adk-monitoring`) 4. Open the **Explorer** You should see a trace tree with: * **Agent** span (`invoke_agent`) - the agent execution * **LLM** span (`call_llm`) - the Gemini API call with input/output * **Tool** span (`execute_tool get_weather`) - the tool call with arguments and response Each LLM span shows the user's question, the model's response, system instructions, and token usage. ## Troubleshooting ### No Traces Appearing * Verify `client.force_flush()` is called before the process exits * Check for 401 errors in logs (wrong API key) * Ensure the Application UUID matches an existing GenAI Application ### Gemini API Errors * Verify `GOOGLE_API_KEY` or Vertex AI credentials are set * For Vertex AI, ensure `gcloud auth application-default login` has been run ## Configuration Options ### Supported Models Any Gemini model supported by Google ADK: * `gemini-2.5-flash`, `gemini-2.5-pro` * `gemini-2.0-flash` * `gemini-1.5-flash`, `gemini-1.5-pro` ### Supported ADK Versions * `google-adk >= 1.34.2` (both 1.x and 2.x lines) * `opentelemetry-api >= 1.37.0` ## Next Steps * [**Google ADK Integration Guide**](/integrations/agentic-ai/google-adk-sdk) - Full integration documentation * [**Fiddler Evals SDK**](/integrations/agentic-ai/evals-sdk) - Evaluate agent quality * [**Google ADK SDK Reference**](/sdk-api/adk/google-adk-instrumentor) - API documentation # Guardrails Quick Start Source: https://docs.fiddler.ai/developers/quick-starts/guardrails-quick-start Get started with Fiddler Guardrails to protect your LLM applications from harmful content, PII leaks, and hallucinations Fiddler Guardrails provide real-time protection for your LLM applications by detecting and preventing harmful content, PII leaks, and hallucinations before they reach your users. **Time to complete**: \~15 minutes ## What You'll Learn * How to set up Fiddler Guardrails * How to use the four main guardrail types (Safety, PII, Secret Detection, Faithfulness) * How to interpret risk scores * How to integrate guardrails into your LLM application ## Prerequisites * **Fiddler Environment**: Access to a Fiddler environment with Guardrails enabled * **API Key**: Generated from your Fiddler environment (**Settings → [Credentials](/reference/administration/settings#credentials)**) * **Python 3.8+** (or any HTTP client) *** ## Quick Start: Setting Up Guardrails ### Step 1: Get Your API Key 1. Sign in to your organization's Fiddler environment 2. Go to **Settings → [Credentials](/reference/administration/settings#credentials)** 3. Generate a Fiddler API key and copy it for use in the requests below If you are not sure whether Guardrails is enabled for your environment, contact your Fiddler representative. For access setup, see the [Guardrails Quick Start](/protection/guardrails-quick-start). ### Step 2: Install Required Libraries (Optional) ```bash theme={null} # For Python pip install requests # Or use any HTTP client in your preferred language ``` ### Step 3: Configure Your Connection ```python theme={null} import requests import json # Your API credentials FIDDLER_URL = "https://your-instance.fiddler.ai" # Replace with your Fiddler instance URL API_KEY = "your-api-key-here" # Standard headers for all guardrail requests HEADERS = { "Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json" } ``` *** ## Guardrail Types and Usage Each guardrail type has its own endpoint and request/response format. Choose the appropriate guardrail based on your protection needs. ### 🛡️ Safety Guardrails Detect harmful, toxic, or jailbreaking content across 11 safety dimensions. **Endpoint**: `/v3/guardrails/ftl-safety` **Use cases:** * Content moderation * Jailbreak prevention * Toxic content detection #### Example: Check for Harmful Content ```python theme={null} def check_safety(text): """Check text for safety violations across 11 dimensions.""" response = requests.post( f"{FIDDLER_URL}/v3/guardrails/ftl-safety", headers=HEADERS, json={"data": {"input": text}} ) return response.json() # Test with potentially harmful content test_input = "I want to cause harm to others" safety_scores = check_safety(test_input) print(json.dumps(safety_scores, indent=2)) ``` **Response Format:** ```json theme={null} { "fdl_harmful": 0.92, "fdl_violent": 0.78, "fdl_unethical": 0.65, "fdl_illegal": 0.45, "fdl_sexual": 0.12, "fdl_racist": 0.08, "fdl_jailbreaking": 0.23, "fdl_harassing": 0.54, "fdl_hateful": 0.71, "fdl_sexist": 0.15 } ``` **Safety Dimensions:** * `fdl_harmful` - General harmful content * `fdl_violent` - Violence and threats * `fdl_unethical` - Unethical behavior * `fdl_illegal` - Illegal activities * `fdl_sexual` - Sexual content * `fdl_racist` - Racist content * `fdl_jailbreaking` - Prompt manipulation attempts * `fdl_harassing` - Harassment * `fdl_hateful` - Hateful content * `fdl_sexist` - Sexist content * `fdl_roleplaying` - Prompting persona change #### Interpreting Safety Scores Starting in release 26.13, `0.5` is the calibrated default decision threshold for the Centor Model for Safety. The threshold values in these examples are illustrative — tune them for your data and risk tolerance. See [safety threshold guidance](/protection/guardrails#safety). Each dimension returns a score between 0 and 1: * **0.0 - 0.3**: Low risk (safe to proceed) * **0.3 - 0.5**: Elevated risk, below the calibrated `0.5` decision threshold (review recommended) * **0.5 - 1.0**: At or above the calibrated `0.5` decision threshold (block or flag for review) ```python theme={null} def is_safe(safety_scores, threshold=0.5): """ Check if content passes safety check. Returns True if ALL dimensions are below threshold. """ dangerous_dimensions = [ dim for dim, score in safety_scores.items() if score >= threshold ] if dangerous_dimensions: print(f"⚠️ Safety violations: {dangerous_dimensions}") return False print("✅ Content passed safety check") return True # Use in your application if is_safe(safety_scores): # Proceed with LLM processing pass else: # Block or flag content print("Content blocked due to safety concerns") ``` **→** [**Safety Guardrails Tutorial**](/developers/tutorials/guardrails/guardrails-safety) *** ### 🔒 PII Detection Detect personally identifiable information (PII), protected health information (PHI), and custom sensitive data. **Endpoint**: `/v3/guardrails/sensitive-information` **Use cases:** * Data privacy compliance * GDPR/CCPA protection * Sensitive data redaction #### Example 1: Detect PII ```python theme={null} def detect_pii(text, entity_categories="PII"): """ Detect sensitive information in text. Args: text: Input text to analyze entity_categories: "PII", "PHI", "Custom Entities", or list like ["PII", "PHI"] """ payload = { "data": { "input": text, "entity_categories": entity_categories } } response = requests.post( f"{FIDDLER_URL}/v3/guardrails/sensitive-information", headers=HEADERS, json=payload ) return response.json() # Test with PII data test_text = """ Contact John Doe at john.doe@email.com or call (555) 123-4567. SSN: 123-45-6789. Credit card: 4111-1111-1111-1111. """ pii_results = detect_pii(test_text) print(json.dumps(pii_results, indent=2)) ``` **Response Format:** ```json theme={null} { "fdl_sensitive_information_scores": [ { "score": 0.987, "label": "person", "text": "John Doe", "start": 8, "end": 16 }, { "score": 0.998, "label": "email", "text": "john.doe@email.com", "start": 20, "end": 38 }, { "score": 0.991, "label": "social security number", "text": "123-45-6789", "start": 72, "end": 83 } ] } ``` **Response Fields:** * `score` - Confidence score (0.0 to 1.0) * `label` - Entity type (e.g., "email", "social security number") * `text` - The detected sensitive information * `start` / `end` - Character positions in the input text #### Example 2: Detect PHI (Healthcare Data) ```python theme={null} # Detect protected health information healthcare_text = """ Patient John Smith prescribed metformin for diabetes. Insurance number: HI-987654321. """ phi_results = detect_pii(healthcare_text, entity_categories="PHI") # Display detected PHI entities for entity in phi_results.get("fdl_sensitive_information_scores", []): print(f"Found {entity['label']}: '{entity['text']}' (confidence: {entity['score']:.3f})") ``` #### Example 3: Custom Entity Detection ```python theme={null} # Detect organization-specific sensitive data custom_text = "Employee ID: EMP-2024-001, API key: sk-abc123xyz789" custom_results = detect_pii( custom_text, entity_categories="Custom Entities" ) # Note: For custom entities, you can also specify the entity types: payload = { "data": { "input": custom_text, "entity_categories": "Custom Entities", "custom_entities": ["employee id", "api key", "project code"] } } ``` **Supported Entity Categories:** * **PII**: comprehensive coverage including names, addresses, SSN, credit cards, emails, and phone numbers * **PHI**: healthcare-specific types including medication, medical conditions, and health insurance numbers * **Custom Entities**: Define your own sensitive data patterns #### Processing PII Results ```python theme={null} def redact_pii(text, pii_results): """Redact detected PII from text.""" entities = pii_results.get("fdl_sensitive_information_scores", []) # Sort by position in reverse to maintain correct offsets entities_sorted = sorted(entities, key=lambda x: x['start'], reverse=True) redacted_text = text for entity in entities_sorted: redacted_text = ( redacted_text[:entity['start']] + f"[REDACTED {entity['label'].upper()}]" + redacted_text[entity['end']:] ) return redacted_text # Use in your application if pii_results.get("fdl_sensitive_information_scores"): clean_text = redact_pii(test_text, pii_results) print(f"Redacted: {clean_text}") ``` **→** [**PII Detection Tutorial**](/developers/tutorials/guardrails/guardrails-pii) *** ### 🔑 Secret Detection Detect credentials, API keys, and tokens across \~42 known formats plus high-entropy unknown secrets. **Endpoint**: `/v3/guardrails/secret-detection` **Use cases:** * Prevent credentials from leaking through LLM prompts or responses * Detect and redact secrets before they are logged or forwarded #### Example: Detect Secrets ```python theme={null} def detect_secrets(text): """Detect credentials and API keys in text.""" response = requests.post( f"{FIDDLER_URL}/v3/guardrails/secret-detection", headers=HEADERS, json={"data": {"input": text}} ) return response.json() # Test with an API key in the prompt test_input = "Use this key to call the API: sk-ant-api03-abcdefghijklmnopqrstu" secret_results = detect_secrets(test_input) print(json.dumps(secret_results, indent=2)) ``` **Response Format:** ```json theme={null} { "fdl_secret_detection_scores": [ { "label": "Anthropic API Key", "start": 30, "end": 64 } ] } ``` **Response Fields:** * `label` - Secret type (e.g., `"Anthropic API Key"`, `"AWS Access Key ID"`, or `"Possible Secret"` for entropy-based detections) * `start` / `end` - Character positions for precise redaction #### Processing Secret Results ```python theme={null} def redact_secrets(text, secret_results): """Redact detected secrets from text.""" secrets = secret_results.get("fdl_secret_detection_scores", []) # Apply right-to-left to preserve offsets for secret in sorted(secrets, key=lambda s: s["start"], reverse=True): label = secret["label"].upper().replace(" ", "_") text = ( text[: secret["start"]] + f"[REDACTED {label}]" + text[secret["end"] :] ) return text # Use in your application if secret_results.get("fdl_secret_detection_scores"): clean_text = redact_secrets(test_input, secret_results) print(f"Redacted: {clean_text}") # Redacted: Use this key to call the API: [REDACTED ANTHROPIC_API_KEY] ``` **→** [**Secret Detection Tutorial**](/developers/tutorials/guardrails/guardrails-secrets) *** ### ✅ Faithfulness Detection Detect hallucinations and unsupported claims by comparing LLM outputs to source context (for RAG applications) using Fiddler Centor Models. **Endpoint**: `/v3/guardrails/ftl-response-faithfulness` This guardrail uses the **Centor Model for Faithfulness** for real-time content blocking. For RAG pipeline diagnostics using the LLM-as-a-Judge approach, see [RAG Health Metrics](/concepts/rag-health-diagnostics). **Use cases:** * RAG application accuracy * Fact-checking * Hallucination prevention #### Example: Check Response Faithfulness ```python theme={null} def check_faithfulness(llm_response, source_context): """ Check if LLM response is faithful to the provided context. Args: llm_response: The text generated by your LLM source_context: The reference text from your knowledge base/retrieval """ payload = { "data": { "response": llm_response, "context": source_context } } response = requests.post( f"{FIDDLER_URL}/v3/guardrails/ftl-response-faithfulness", headers=HEADERS, json=payload ) return response.json() # Test with RAG example retrieved_context = """ The Eiffel Tower is located in Paris, France. It was completed in 1889 and stands 330 meters tall. It was designed by Gustave Eiffel. """ llm_response_correct = "The Eiffel Tower in Paris is 330 meters tall and was completed in 1889." llm_response_hallucinated = "The Eiffel Tower in Paris is 450 meters tall and was completed in 1895." # Check faithful response faithful_score = check_faithfulness(llm_response_correct, retrieved_context) print(f"Faithful response score: {faithful_score}") # Check hallucinated response hallucinated_score = check_faithfulness(llm_response_hallucinated, retrieved_context) print(f"Hallucinated response score: {hallucinated_score}") ``` **Response Format:** ```json theme={null} { "fdl_faithful_score": 0.92 } ``` **Score Interpretation:** * **0.0 - 0.3**: Low faithfulness (likely hallucination) * **0.3 - 0.7**: Medium faithfulness (review recommended) * **0.7 - 1.0**: High faithfulness (response is well-supported by context) ```python theme={null} def is_faithful(faithfulness_result, threshold=0.7): """Check if response is faithful to context.""" score = faithfulness_result.get("fdl_faithful_score", 0.0) if score >= threshold: print(f"✅ Response is faithful (score: {score:.3f})") return True else: print(f"⚠️ Possible hallucination detected (score: {score:.3f})") return False # Use in your RAG application if not is_faithful(faithful_score): print("Warning: LLM response may contain unsupported claims") ``` **→** [**Faithfulness Tutorial**](/developers/tutorials/guardrails/guardrails-faithfulness) *** ## Common Integration Patterns ### Pattern 1: Pre-Processing (Input Guardrails) Check user input before sending to your LLM: ```python theme={null} def process_user_input(user_message): """Process and validate user input before LLM processing.""" # Step 1: Check safety safety_scores = check_safety(user_message) # Block if any safety dimension exceeds threshold max_safety_score = max(safety_scores.values()) if max_safety_score >= 0.5: return { "error": "Your message contains inappropriate content.", "blocked": True } # Step 2: Check for secrets and redact if found secret_results = detect_secrets(user_message) if secret_results.get("fdl_secret_detection_scores"): user_message = redact_secrets(user_message, secret_results) print(f"⚠️ Secret detected and redacted") # Step 3: Check for PII and redact if needed pii_results = detect_pii(user_message) if pii_results.get("fdl_sensitive_information_scores"): # Redact PII before sending to LLM user_message = redact_pii(user_message, pii_results) print(f"⚠️ PII detected and redacted") # Step 4: Proceed with LLM call return { "message": user_message, "blocked": False } # Example usage user_input = "My SSN is 123-45-6789. Can you help me?" result = process_user_input(user_input) if not result.get("blocked"): # Safe to send to LLM llm_response = call_your_llm(result["message"]) ``` ### Pattern 2: Post-Processing (Output Guardrails) Check LLM output before returning to user: ```python theme={null} def validate_llm_output(llm_response, retrieval_context=None): """Validate LLM output before returning to user.""" # Step 1: Check for PII in output pii_results = detect_pii(llm_response) if pii_results.get("fdl_sensitive_information_scores"): # Redact any PII in the response llm_response = redact_pii(llm_response, pii_results) print("⚠️ PII detected in LLM output and redacted") # Step 2: Check faithfulness (for RAG applications) if retrieval_context: faithfulness_result = check_faithfulness(llm_response, retrieval_context) if not is_faithful(faithfulness_result, threshold=0.7): return { "response": llm_response, "warning": "This response may contain information not supported by source documents." } return { "response": llm_response, "warning": None } # Example usage in RAG application context = retrieve_from_knowledge_base(user_query) llm_output = generate_llm_response(user_query, context) validated = validate_llm_output(llm_output, context) if validated.get("warning"): print(f"⚠️ {validated['warning']}") return validated["response"] ``` ### Pattern 3: Complete LLM Pipeline with Multiple Guardrails ```python theme={null} def safe_llm_pipeline(user_input, use_rag=True): """Complete LLM pipeline with comprehensive guardrails.""" # === INPUT GUARDRAILS === # 1. Safety check safety_scores = check_safety(user_input) if max(safety_scores.values()) >= 0.5: return {"error": "Inappropriate content detected", "blocked": True} # 2. Secret detection and redaction secret_input = detect_secrets(user_input) if secret_input.get("fdl_secret_detection_scores"): user_input = redact_secrets(user_input, secret_input) # 3. PII detection and redaction pii_input = detect_pii(user_input) if pii_input.get("fdl_sensitive_information_scores"): user_input = redact_pii(user_input, pii_input) # === LLM PROCESSING === context = None if use_rag: context = retrieve_from_knowledge_base(user_input) llm_response = generate_llm_response(user_input, context) # === OUTPUT GUARDRAILS === # 4. PII detection in output pii_output = detect_pii(llm_response) if pii_output.get("fdl_sensitive_information_scores"): llm_response = redact_pii(llm_response, pii_output) # 5. Faithfulness check (for RAG) warning = None if use_rag and context: faithfulness = check_faithfulness(llm_response, context) if faithfulness.get("fdl_faithful_score", 0) < 0.7: warning = "Response may contain unsupported claims" return { "response": llm_response, "warning": warning, "blocked": False } ``` *** ## Best Practices 1. **Layer Multiple Guardrails**: Use safety + PII for inputs, faithfulness + PII for outputs 2. **Set Appropriate Thresholds**: Adjust risk score thresholds based on your use case sensitivity 3. **Log All Checks**: Track guardrail results for monitoring and continuous improvement 4. **Handle Gracefully**: Provide helpful user-facing messages when content is blocked 5. **Monitor Performance**: Track false positives/negatives and adjust thresholds accordingly 6. **Consider Latency**: Guardrail checks add \~100-300ms - use async calls when possible 7. **Mind deployment capacity**: Guardrail throughput is governed by the resources provisioned for your Fiddler deployment; batch and parallelize within that capacity *** ## Error Handling ```python theme={null} def safe_guardrail_check(guardrail_func, *args, **kwargs): """Wrapper for safe guardrail execution with error handling.""" try: response = guardrail_func(*args, **kwargs) return response, None except requests.exceptions.HTTPError as e: if e.response.status_code == 401: error = "Authentication failed. Check your API key." elif e.response.status_code == 413: error = "Input exceeds token length limit." elif e.response.status_code == 429: error = "Rate limit exceeded. Please retry later." else: error = f"HTTP error: {e.response.status_code}" return None, error except requests.exceptions.Timeout: return None, "Request timed out." except Exception as e: return None, f"Unexpected error: {str(e)}" # Usage safety_result, error = safe_guardrail_check(check_safety, user_input) if error: print(f"Guardrail check failed: {error}") # Fallback behavior else: # Process safety_result pass ``` *** ## Next Steps * **API Reference**: [Complete Guardrails API Documentation](/sdk-api/guardrails-api-reference) * **Setup Guide**: [Complete Guardrails Setup](/protection/guardrails-quick-start) * **Concepts**: [Guardrails Overview](/getting-started/guardrails) * **Tutorials**: * [Safety Guardrails Notebook](/developers/tutorials/guardrails/guardrails-safety) * [PII Detection Notebook](/developers/tutorials/guardrails/guardrails-pii) * [Secret Detection Notebook](/developers/tutorials/guardrails/guardrails-secrets) * [Faithfulness Detection Notebook](/developers/tutorials/guardrails/guardrails-faithfulness) * **FAQ**: [Guardrails Frequently Asked Questions](/protection/guardrails-faq) * **Monitoring**: [Integrate Guardrails with LLM Monitoring](/protection/guardrails) *** ## Summary You've learned how to: * ✅ Use Safety Guardrails to detect harmful content across 11 dimensions * ✅ Detect and redact PII, PHI, and custom sensitive information * ✅ Detect and redact credentials, API keys, and tokens * ✅ Check response faithfulness to prevent hallucinations in RAG applications * ✅ Integrate multiple guardrails into your LLM pipeline * ✅ Handle errors and respect rate limits Each guardrail type uses a different endpoint and response format optimized for its specific protection purpose. Combine multiple guardrails for comprehensive LLM application safety. # LangChain SDK Quick Start Source: https://docs.fiddler.ai/developers/quick-starts/langchain-sdk-quick-start Monitor AI agent behavior in LangChain V1 applications. The Fiddler LangChain SDK provides real-time observability for `create_agent`-based workflows and middleware pipelines. Instrument your LangChain V1 application with the Fiddler LangChain SDK in under 10 minutes. ## What You'll Learn By completing this quick start, you'll: * Set up monitoring for a LangChain V1 (`langchain.agents.create_agent`) application * Send your first traces to Fiddler * Verify data collection in the Fiddler dashboard * Understand basic conversation tracking **Before you begin, ensure you have**: * **Python 3.10** or higher (up to Python 3.14) * **Valid Fiddler account** with access to your instance * **A LangChain V1 application** built with `langchain.agents.create_agent` * **Network connectivity** to your Fiddler instance **Supported Python Versions:** * Python 3.10-3.14 **Framework Compatibility:** * **LangChain V1:** `langchain >= 1.0` (the `create_agent` / middleware API) **Core Dependencies:** The SDK automatically installs these OpenTelemetry components: * `opentelemetry-api` * `opentelemetry-sdk` * `opentelemetry-instrumentation` * `opentelemetry-exporter-otlp-proto-http` * `fiddler-otel` (transitive — provides `FiddlerClient`) **Set Up Your Fiddler Application** 1. **Create your application in Fiddler** Log in to your Fiddler instance and navigate to **GenAI Applications**, then click **Add Application** and follow the onboarding wizard to create your application. GenAI Applications page with Add Application button 2. **Copy your Application ID** After creating your application, copy the **Application ID** from the GenAI Applications page using the copy icon next to the ID. This must be a valid UUID4 format (for example, `550e8400-e29b-41d4-a716-446655440000`). You'll need this for Step 3. GenAI Applications page showing Application ID column with copy icons 3. **Get Your Access Token** Go to **Settings** > **Credentials** and copy your access token. You'll need this for Step 3. Refer to the [documentation](/reference/administration/settings#credentials) for more details. Fiddler Settings- Credentials tab showing admin's access token **Install the Fiddler LangChain SDK** For the stable release, install the Fiddler LangChain SDK using pip: ```bash theme={null} pip install fiddler-langchain ``` **Instrument Your Application** Add the Fiddler LangChain SDK to your application with just a few lines of code. The instrumentor patches `langchain.agents.create_agent` so every agent created afterwards is traced automatically — no per-agent middleware configuration is required. ```python theme={null} import langchain.agents from fiddler_otel import FiddlerClient from fiddler_langchain import FiddlerLangChainInstrumentor # Initialize the FiddlerClient. Replace the placeholder values below. fdl_client = FiddlerClient( application_id='', # Application ID copied from UI in Step 1 api_key='', # Your access token url='', # https://your-instance.fiddler.ai ) # Instrument LangChain V1 — must run BEFORE you call create_agent() instrumentor = FiddlerLangChainInstrumentor(client=fdl_client) instrumentor.instrument() # Use the module attribute so the patched create_agent is called. # (If you prefer `from langchain.agents import create_agent`, call # `instrument()` BEFORE that import.) agent = langchain.agents.create_agent( model="openai:gpt-4o-mini", tools=[...], name="my_agent", # used as the root span label in traces ) # Your existing LangChain code runs normally # Traces will automatically be sent to Fiddler ``` **Add Context and Conversation Tracking** The main goal of context setting is to enrich the telemetry data sent to Fiddler: ```python theme={null} from fiddler_langchain import set_llm_context, set_conversation_id import uuid # Attach descriptive context to a specific model — appears on its LLM spans. set_llm_context(model, 'Customer support conversation') # Set a conversation ID for tracking multi-turn conversations set_conversation_id(str(uuid.uuid4())) ``` **Manual middleware alternative.** If you prefer not to use the auto-instrumentor, pass `middleware=[FiddlerAgentMiddleware(client=client, agent_name="my_agent")]` directly to each `create_agent()` call. See the [FiddlerAgentMiddleware](/sdk-api/langchain/fiddler-agent-middleware) reference for details. **Need more control?** This Quick Start uses auto-instrumentation, which traces every `create_agent`-based agent automatically. The SDK also supports per-component span attributes (`add_span_attributes`) and session attributes (`add_session_attributes`) for fine-grained metadata tagging. **Run a Complete Example** This example requires an OpenAI API key. You can create or find your key on the [API keys page](https://platform.openai.com/api-keys) of your OpenAI account. Here's a complete working example to verify your setup: ```python theme={null} import os import uuid import langchain.agents from langchain_openai import ChatOpenAI from langchain_core.tools import tool from fiddler_otel import FiddlerClient from fiddler_langchain import ( FiddlerLangChainInstrumentor, set_conversation_id, set_llm_context, ) # Initialize the FiddlerClient. Replace the placeholder values below. fdl_client = FiddlerClient( application_id='', # Application ID copied from UI in Step 1 api_key='', # Your access token url='', # https://your-instance.fiddler.ai ) # Instrument LangChain V1 — must run BEFORE create_agent() instrumentor = FiddlerLangChainInstrumentor(client=fdl_client) instrumentor.instrument() # Build a simple agent model = ChatOpenAI(model="gpt-4o-mini") @tool def echo(text: str) -> str: """Echo back the input text.""" return text agent = langchain.agents.create_agent( model=model, tools=[echo], name="quickstart_agent", ) # Set descriptive context for this interaction set_llm_context(model, "Quick start example conversation") # Generate and set a conversation ID conversation_id = str(uuid.uuid4()) set_conversation_id(conversation_id) # Run your agent — automatically instrumented result = agent.invoke({ "messages": [{"role": "user", "content": "Hello! How are you?"}] }) print("Response received:", result) print("Conversation ID:", conversation_id) ``` **Short-lived scripts:** The SDK batches spans in memory and exports them on a schedule. If your script exits before the batch is sent, call `fdl_client.shutdown()` (or use `with FiddlerClient(...) as client:`) to flush pending spans. Long-running servers handle this automatically via `atexit`. **Verify Monitoring is Working** 1. **Run your application** using the example above or your own instrumented code 2. **Check the Fiddler dashboard:** Navigate to **GenAI Applications** in your Fiddler instance 3. **Confirm active status:** If Fiddler successfully receives telemetry, your application will show as **Active** GenAI application showing active status **Success Criteria** You should see: * Application status changed to **Active** in the Fiddler dashboard * Trace data appearing within 1-2 minutes of running your example * Context labels match what you set in your code * Conversation ID visible in the trace details **Expected trace hierarchy** for `create_agent`: ``` [Span] quickstart_agent (Agent root - TYPE=agent) ├── [Span] gpt-4o-mini (LLM call - TYPE=llm) ├── [Span] echo (Tool call - TYPE=tool) └── [Span] gpt-4o-mini (LLM call - TYPE=llm) ``` Event chart and spans list view page Agent application span trace view ## Grant Team Access (optional) Provide access to other users by assigning teams and users to the project that contains your applications. Managing permissions through Teams is recommended as a best practice. For more access control details, refer to the [Teams and Users Guide](/reference/administration/settings#access) and the [Role-based Access Guide](/reference/access-control/role-based-access). 1. Open the Settings page and select the Access tab 2. For both Users and Teams, select the "Edit" option to the right of the name 3. Add appropriate team members with the required permission levels ## Configuration Options ### Basic Configuration ```python theme={null} from fiddler_otel import FiddlerClient fdl_client = FiddlerClient( application_id="your-app-id", # Must be valid UUID4 api_key="your-api-key", url="https://your-instance.fiddler.ai", ) ``` ### Advanced Configuration #### Customize Limits for High-Volume Applications Set limits for your events, spans, and associated attributes. This is helpful for tuning reporting data to manageable numbers for highly attributed and/or high-volume applications. ```python theme={null} from opentelemetry.sdk.trace import SpanLimits from fiddler_otel import FiddlerClient custom_limits = SpanLimits( max_events=64, # Default: 32 max_links=64, # Default: 32 max_span_attributes=64, # Default: 32 max_event_attributes=64, # Default: 32 max_link_attributes=64, # Default: 32 max_span_attribute_length=4096, # Default: 2048 ) client = FiddlerClient( application_id="your-app-id", api_key="your-api-key", url="https://your-instance.fiddler.ai", span_limits=custom_limits, ) ``` #### Sampling Traffic Set a specific sampling percentage for incoming data. ```python theme={null} from opentelemetry.sdk.trace import sampling from fiddler_otel import FiddlerClient sampler = sampling.TraceIdRatioBased(0.1) # Sample 10% of traces client = FiddlerClient( application_id="your-app-id", api_key="your-api-key", url="https://your-instance.fiddler.ai", sampler=sampler, ) ``` #### Environment Variables for Batch Processing Adjust the following environment variables that the FiddlerClient will use when processing the OpenTelemetry traffic. ```python theme={null} import os os.environ['OTEL_BSP_MAX_QUEUE_SIZE'] = '500' # Default: 100 os.environ['OTEL_BSP_SCHEDULE_DELAY_MILLIS'] = '500' # Default: 1000 os.environ['OTEL_BSP_MAX_EXPORT_BATCH_SIZE'] = '50' # Default: 10 os.environ['OTEL_BSP_EXPORT_TIMEOUT'] = '10000' # Default: 5000 ``` #### Compression Options The SDK supports data compression to help reduce the overall data volume transmitted over the network. This can help improve network latency. ```python theme={null} from opentelemetry.exporter.otlp.proto.http.trace_exporter import Compression from fiddler_otel import FiddlerClient # Enable gzip compression (default, recommended for production) client = FiddlerClient( application_id="your-app-id", api_key="your-api-key", url="https://your-instance.fiddler.ai", compression=Compression.Gzip, ) ``` ### Environment Variables Reference Configure OpenTelemetry batch processor behavior through environment variables: | Variable | Default | Description | | -------------------------------- | ------- | ------------------------------------------------------ | | `OTEL_BSP_MAX_QUEUE_SIZE` | `100` | Maximum spans in queue before export | | `OTEL_BSP_SCHEDULE_DELAY_MILLIS` | `1000` | Delay between batch exports (milliseconds) | | `OTEL_BSP_MAX_EXPORT_BATCH_SIZE` | `10` | Maximum spans exported per batch | | `OTEL_BSP_EXPORT_TIMEOUT` | `5000` | Export timeout (milliseconds) | | `FIDDLER_API_KEY` | - | Your Fiddler API key (recommended for production) | | `FIDDLER_APPLICATION_ID` | - | Your application UUID4 (recommended for production) | | `FIDDLER_URL` | - | Your Fiddler instance URL (recommended for production) | ### Adding Custom Attributes `fiddler-langchain` exposes two helpers for tagging traces with business metadata: ```python theme={null} from langchain_core.tools import tool from langchain_openai import ChatOpenAI from fiddler_langchain import add_session_attributes, add_span_attributes # Session attributes — appear on every span in the current invocation add_session_attributes("user_id", "alice@example.com") add_session_attributes("environment", "production") # Span attributes — only appear on spans for this specific component model = ChatOpenAI(model="gpt-4o-mini") add_span_attributes(model, department="AI_Engineering", agent_role="flight_assistant") @tool def book_flight(from_airport: str, to_airport: str) -> str: """Book a flight between two airports.""" return f"Booked {from_airport} -> {to_airport}" add_span_attributes(book_flight, third_party="acme_air", reward_points=10.2) ``` | Helper | Scope | Span attribute format | | ------------------------------------- | --------------------------------------- | ---------------------------- | | `add_session_attributes(key, value)` | All spans in the invocation | `fiddler.session.user.{key}` | | `add_span_attributes(node, **kwargs)` | Spans for that model / tool / retriever | `fiddler.span.user.{key}` | ## Async Agents The instrumentation fully supports async agents. Use `agent.ainvoke()` instead of `agent.invoke()` — no additional configuration is needed: ```python theme={null} import asyncio import langchain.agents from langchain_openai import ChatOpenAI from fiddler_langchain import FiddlerLangChainInstrumentor from fiddler_otel import FiddlerClient client = FiddlerClient(api_key="...", application_id="...", url="...") FiddlerLangChainInstrumentor(client=client).instrument() agent = langchain.agents.create_agent( model=ChatOpenAI(model="gpt-4o-mini"), tools=[...], name="my_agent", ) async def main(): result = await agent.ainvoke({"messages": [{"role": "user", "content": "Hello!"}]}) print(result) asyncio.run(main()) ``` ## Troubleshooting ### Common Installation Issues **Problem**: `ModuleNotFoundError: No module named 'fiddler_langchain'` * **Solution**: Install the package: `pip install fiddler-langchain` **Problem**: Version conflicts with existing packages * **Solution**: Use a virtual environment or update conflicting packages ### Common Configuration Issues **Problem**: `ValueError: application_id must be a valid UUID4` * **Solution**: Ensure your Application ID is a valid UUID4 format (e.g., `550e8400-e29b-41d4-a716-446655440000`) **Problem**: `ValueError: URL must have a valid scheme and netloc` * **Solution**: Ensure your URL includes the protocol (e.g., `https://your-instance.fiddler.ai`) **Problem**: Agents are created but no spans appear in Fiddler * **Solution**: Confirm `instrumentor.instrument()` is called **before** `langchain.agents.create_agent()`. The instrumentor patches the module attribute, so agents created prior to instrumentation are not traced. If you use `from langchain.agents import create_agent`, the local name binds to the *unpatched* function — either call `instrument()` before that import, or invoke the function as `langchain.agents.create_agent(...)`. **Problem**: Debugging trace generation * **Solution**: Enable console tracer for local debugging: ```python theme={null} fdl_client = FiddlerClient( application_id="your-app-id", api_key="your-api-key", url="https://your-instance.fiddler.ai", console_tracer=True # Also prints spans to console; OTLP export to Fiddler still active ) ``` `console_tracer=True` is **additive** — span data is printed to stdout **and** continues to be exported to Fiddler via OTLP. Setting this to `True` does **not** disable or suppress the OTLP export to Fiddler. ### Verification Issues **Problem**: Application not showing as "Active" in Fiddler * **Solution**: Check the following: 1. Ensure your application executes instrumented code (the agent must be invoked) 2. Verify that your Fiddler access token and application ID are correct 3. Check network connectivity to your Fiddler instance 4. Enable `console_tracer=True` to see if spans are being generated locally ## Next Steps Now that your application is instrumented: 1. **Explore the data:** Check your Fiddler dashboard for traces, metrics, and performance insights 2. **Review the SDK reference:** Check the [Fiddler LangChain SDK Reference](/integrations/agentic-ai/langchain-sdk) for complete documentation 3. **Optimize for production:** Review [configuration options](/developers/quick-starts/langchain-sdk-quick-start#configuration-options) for high-volume applications # LangGraph SDK Quick Start Source: https://docs.fiddler.ai/developers/quick-starts/langgraph-sdk-quick-start Monitor AI agent behavior in LangGraph and LangChain applications. Fiddler LangGraph SDK provides real-time observability for GenAI workflows and debugging. Instrument your LangGraph or LangChain application with the Fiddler LangGraph SDK in under 10 minutes. ## What You'll Learn By completing this quick start, you'll: * Set up monitoring for a LangGraph or LangChain application * Send your first traces to Fiddler * Verify data collection in the Fiddler dashboard * Understand basic conversation tracking **Before you begin, ensure you have**: * **Python 3.10** or higher (up to Python 3.13) * **Valid Fiddler account** with access to your instance * **A LangGraph or LangChain application** ready for instrumentation * **Network connectivity** to your Fiddler instance **Supported Python Versions:** * Python 3.10-3.14 **Framework Compatibility:** * **LangGraph/LangChain:** >= 0.3.28 and \<= 1.1.0 **Core Dependencies:** The SDK automatically installs these OpenTelemetry components: * `opentelemetry-api` (>= 1.19.0, \<= 1.39.1) * `opentelemetry-sdk` (>= 1.19.0, \<= 1.39.1) * `opentelemetry-instrumentation` (>= 0.40b0, \<= 0.60b1) * `opentelemetry-exporter-otlp-proto-http` (>= 1.19.0, \<= 1.39.1) * `langgraph` (>= 0.3.28, \<= 1.1.0) * `langchain` (>= 0.3.26) 1. **Create your application in Fiddler** Log in to your Fiddler instance and navigate to **GenAI Applications**, then click **Add Application** and follow the onboarding wizard to create your application. GenAI Applications page with Add Application button 2. **Copy your Application ID** After creating your application, copy the **Application ID** from the GenAI Applications page using the copy icon next to the ID. This must be a valid UUID4 format (for example, `550e8400-e29b-41d4-a716-446655440000`). You'll need this for Step 3. GenAI Applications page showing Application ID column with copy icons 3. **Get Your Access Token** Go to **Settings** > **Credentials** and copy your access token. You'll need this for Step 3. Refer to the [documentation](/reference/administration/settings#credentials) for more details. Fiddler Settings- Credentials tab showing admin's access token **Standard Installation** For the stable release, install the Fiddler LangGraph SDK using pip: ```bash theme={null} pip install fiddler-langgraph ``` Add the Fiddler LangGraph SDK to your LangGraph or LangChain application with just a few lines of code: ```python theme={null} from fiddler_langgraph import FiddlerClient, LangGraphInstrumentor # Initialize the FiddlerClient. Replace the placeholder values below. fdl_client = FiddlerClient( application_id='', # Application ID copied from UI in Step 1 api_key='', # Your API key url='', # https://your-instance.fiddler.ai ) # Instrument your application instrumentor = LangGraphInstrumentor(fdl_client) instrumentor.instrument() # Invoke your agent here # You MUST instrument your application BEFORE invoking # Your existing LangGraph code runs normally # Traces will automatically be sent to Fiddler ``` **Add Context and Conversation Tracking** The main goal of context setting is to enrich the telemetry data sent to Fiddler: ```python theme={null} from fiddler_langgraph import set_llm_context, set_conversation_id import uuid # Set descriptive context for LLM processing set_llm_context(model, 'Customer support conversation') # Set conversation ID for tracking multi-turn conversations conversation_id = str(uuid.uuid4()) set_conversation_id(conversation_id) ``` **For AI engineers:** The conversation tracking feature supports multi-turn agent interactions and helps trace decision flows across agent sessions. **Need more control?** This Quick Start uses auto-instrumentation, which captures traces from LangGraph and LangChain automatically. The SDK also supports **decorator-based** and **manual** instrumentation for custom functions, non-LangGraph code, and fine-grained span control. See [Instrumentation Methods](/integrations/agentic-ai/langgraph-sdk#instrumentation-methods) in the integration guide. This example requires an OpenAI API key. You can create or find your key on the [API keys page](https://platform.openai.com/api-keys) of your OpenAI account. Here's a complete working example to verify your setup: ```python theme={null} import os import uuid from fiddler_langgraph import FiddlerClient, LangGraphInstrumentor, set_llm_context, set_conversation_id from langchain_openai import ChatOpenAI from langgraph.prebuilt import create_react_agent # Initialize the FiddlerClient. Replace the placeholder values below. fdl_client = FiddlerClient( application_id='', # Application ID copied from UI in Step 1 api_key='', # Your API key url='', # https://your-instance.fiddler.ai ) # Instrument the application instrumentor = LangGraphInstrumentor(fdl_client) instrumentor.instrument() # Create your agent model = ChatOpenAI(model="gpt-4o-mini") agent = create_react_agent(model, tools=[]) # Set descriptive context for this interaction set_llm_context(model, "Quick start example conversation") # Generate and set a conversation ID conversation_id = str(uuid.uuid4()) set_conversation_id(conversation_id) # Run your agent - automatically instrumented result = agent.invoke({ "messages": [{"role": "user", "content": "Hello! How are you?"}] }) print("Response received:", result) print("Conversation ID:", conversation_id) ``` **Short-lived scripts:** The SDK batches spans in memory and exports them on a schedule. If your script exits before the batch is sent, call `fdl_client.shutdown()` (or use `with FiddlerClient(...) as client:`) to flush pending spans. Long-running servers handle this automatically via `atexit`. See [Flush and shutdown handling](/integrations/agentic-ai/langgraph-sdk#flush-and-shutdown-handling) for details. 1. **Run your application** using the example above or your own instrumented code 2. **Check the Fiddler dashboard:** Navigate to **GenAI Applications** in your Fiddler instance 3. **Confirm active status:** If Fiddler successfully receives telemetry, your application will show as **Active** GenAI application showing active status **Success Criteria** You should see: * Application status changed to **Active** in the Fiddler dashboard * Trace data appearing within 1-2 minutes of running your example * Context labels match what you set in your code * Conversation ID visible in the trace details Event chart and spans list view page Agent application span trace view Agent application span trace timeline ## Grant Team Access (optional) Provide access to other users by assigning teams and users to the project that contains your applications. Managing permissions through Teams is recommended as a best practice. For more access control details, refer to the [Teams and Users Guide](/reference/administration/settings#access) and the [Role-based Access Guide](/reference/access-control/role-based-access). 1. Open the Settings page and select the Access tab 2. For both Users and Teams, select the "Edit" option to the right of the name 3. Add appropriate team members with the required permission levels ## Configuration Options ### Basic Configuration ```python theme={null} from fiddler_langgraph import FiddlerClient fdl_client = FiddlerClient( application_id="your-app-id", # Must be valid UUID4 api_key="your-api-key", url="https://your-instance.fiddler.ai" ) ``` ### Advanced Configuration #### Customize Limits for High-Volume Applications Set limits for your events, spans, and associated attributes. This is helpful for tuning reporting data to manageable numbers for highly attributed and/or high-volume applications. ```python theme={null} from opentelemetry.sdk.trace import SpanLimits from fiddler_langgraph import FiddlerClient # Custom span limits for high-volume applications custom_limits = SpanLimits( max_events=64, # Default: 32 max_links=64, # Default: 32 max_span_attributes=64, # Default: 32 max_event_attributes=64, # Default: 32 max_link_attributes=64, # Default: 32 max_span_attribute_length=4096, # Default: 2048 ) client = FiddlerClient( application_id="your-app-id", # Must be valid UUID4 api_key="your-api-key", url="https://your-instance.fiddler.ai", span_limits=custom_limits, ) ``` #### Sampling Traffic Set a specific sampling percentage for incoming data. ```python theme={null} from opentelemetry.sdk.trace import sampling from fiddler_langgraph import FiddlerClient # Sampling strategy for production sampler = sampling.TraceIdRatioBased(0.1) # Sample 10% of traces client = FiddlerClient( application_id="your-app-id", # Must be valid UUID4 api_key="your-api-key", url="https://your-instance.fiddler.ai", sampler=sampler, ) ``` #### Environment Variables for Batch Processing Adjust the following environment variables that the FiddlerClient will use when processing the OpenTelemetry traffic. ```python theme={null} import os from fiddler_langgraph import FiddlerClient # Configure batch processing os.environ['OTEL_BSP_MAX_QUEUE_SIZE'] = '500' # Default: 100 os.environ['OTEL_BSP_SCHEDULE_DELAY_MILLIS'] = '500' # Default: 1000 os.environ['OTEL_BSP_MAX_EXPORT_BATCH_SIZE'] = '50' # Default: 10 os.environ['OTEL_BSP_EXPORT_TIMEOUT'] = '10000' # Default: 5000 client = FiddlerClient( application_id="your-app-id", # Must be valid UUID4 api_key="your-api-key", url="https://your-instance.fiddler.ai", ) ``` #### Compression Options The SDK supports data compression to help reduce the overall data volume transmitted over the network. This can help improve network latency. ```python theme={null} from opentelemetry.exporter.otlp.proto.http.trace_exporter import Compression from fiddler_langgraph import FiddlerClient # Enable gzip compression (default, recommended for production) client = FiddlerClient( application_id="your-app-id", # Must be valid UUID4 api_key="your-api-key", url="https://your-instance.fiddler.ai", compression=Compression.Gzip, ) # Disable compression (useful for debugging or local development) client = FiddlerClient( application_id="your-app-id", # Must be valid UUID4 api_key="your-api-key", url="https://your-instance.fiddler.ai", compression=Compression.NoCompression, ) # Use deflate compression (alternative to gzip) client = FiddlerClient( application_id="your-app-id", # Must be valid UUID4 api_key="your-api-key", url="https://your-instance.fiddler.ai", compression=Compression.Deflate, ) ``` ### Environment Variables Reference Configure OpenTelemetry batch processor behavior through environment variables: | Variable | Default | Description | | -------------------------------- | ------- | ------------------------------------------------------ | | `OTEL_BSP_MAX_QUEUE_SIZE` | `100` | Maximum spans in queue before export | | `OTEL_BSP_SCHEDULE_DELAY_MILLIS` | `1000` | Delay between batch exports (milliseconds) | | `OTEL_BSP_MAX_EXPORT_BATCH_SIZE` | `10` | Maximum spans exported per batch | | `OTEL_BSP_EXPORT_TIMEOUT` | `5000` | Export timeout (milliseconds) | | `FIDDLER_API_KEY` | - | Your Fiddler API key (recommended for production) | | `FIDDLER_APPLICATION_ID` | - | Your application UUID4 (recommended for production) | | `FIDDLER_URL` | - | Your Fiddler instance URL (recommended for production) | **Example: Tuning for high-volume applications** ```python theme={null} import os os.environ['OTEL_BSP_MAX_QUEUE_SIZE'] = '500' os.environ['OTEL_BSP_SCHEDULE_DELAY_MILLIS'] = '500' os.environ['OTEL_BSP_MAX_EXPORT_BATCH_SIZE'] = '50' os.environ['OTEL_BSP_EXPORT_TIMEOUT'] = '10000' ``` ### LangChain Application Support The SDK supports both LangGraph and LangChain applications. While agent names are automatically extracted from LangGraph applications by the SDK, LangChain applications need the agent name to be explicitly set using the configuration parameter: ```python theme={null} from langchain_core.output_parsers import StrOutputParser # Define your LangChain runnable using LangChain Expression Language (LCEL) chat_app_chain = prompt | llm | StrOutputParser() # Run with agent name configuration response = chat_app_chain.invoke({ "input": user_input, "history": messages, }, config={"configurable": {"agent_name": "service_chatbot"}}) ``` **Important:** If you don't provide an agent name for LangChain applications, it will appear as "UNKNOWN\_AGENT" in the Fiddler UI. All other features, including conversation ID, LLM context, and attribute structure, work the same as with LangGraph. ## Troubleshooting ### Common Installation Issues **Problem**: `ModuleNotFoundError: No module named 'fiddler_langgraph'` * **Solution**: Ensure you've installed the correct package: `pip install fiddler-langgraph` **Problem**: Version conflicts with existing packages * **Solution**: Use a virtual environment or update conflicting packages ### Common Configuration Issues **Problem**: `ValueError: application_id must be a valid UUID4` * **Solution**: Ensure your Application ID is a valid UUID4 format (e.g., `550e8400-e29b-41d4-a716-446655440000`) **Example:** ```python theme={null} # ❌ This will fail client = FiddlerClient( application_id="invalid-id", # Not a valid UUID4 api_key="your-access-token", url="https://instance.fiddler.ai" ) # Raises: ValueError: application_id must be a valid UUID4 string # ✅ Correct format client = FiddlerClient( application_id="550e8400-e29b-41d4-a716-446655440000", # Valid UUID4 api_key="your-access-token", url="https://instance.fiddler.ai" ) ``` **Problem**: `ValueError: URL must have a valid scheme and netloc` * **Solution**: Ensure your URL includes the protocol (e.g., `https://your-instance.fiddler.ai`) **Problem**: Connection errors or timeouts * **Solution**: Check your network connectivity and Fiddler instance URL **Example: Handling connection failures gracefully** ```python theme={null} try: client = FiddlerClient( application_id=os.getenv("FIDDLER_APPLICATION_ID"), api_key=os.getenv("FIDDLER_API_KEY"), url="https://your-instance.fiddler.ai" ) instrumentor = LangGraphInstrumentor(client) instrumentor.instrument() except Exception as e: print(f"Fiddler instrumentation failed: {e}") # Your application continues running without tracing ``` **Problem**: Debugging trace generation * **Solution**: Enable console tracer for local debugging: ```python theme={null} fdl_client = FiddlerClient( application_id="your-app-id", api_key="your-api-key", url="https://your-instance.fiddler.ai", console_tracer=True # Also prints spans to console; OTLP export to Fiddler still active ) ``` `console_tracer=True` is **additive** — span data is printed to stdout **and** continues to be exported to Fiddler via OTLP. Setting this to `True` does **not** disable or suppress the OTLP export to Fiddler. Use it to visually confirm spans are being created during local development. **Problem**: `ImportError: cannot import name 'LangGraphInstrumentor'` * **Solution**: Ensure you have the correct import path: ```python theme={null} from fiddler_langgraph import LangGraphInstrumentor ``` ### Verification Issues **Problem**: Application not showing as "Active" in Fiddler * **Solution**: Check the following: 1. Ensure your application executes instrumented code 2. Verify that your Fiddler access token and application ID are correct 3. Check network connectivity to your Fiddler instance 4. Enable console tracer to see if traces are being generated locally ## Next Steps Now that your application is instrumented: 1. **Explore the data:** Check your Fiddler dashboard for traces, metrics, and performance insights 2. **Custom instrumentation:** Use [decorator-based and manual instrumentation](/integrations/agentic-ai/langgraph-sdk#instrumentation-methods) for fine-grained control 3. **Learn advanced features:** See our [Advanced Guide](/developers/tutorials/llm-monitoring/langgraph-sdk-advanced) for multi-agent scenarios and production patterns 4. **Review the SDK reference:** Check the [Fiddler LangGraph SDK Reference](/sdk-api/langgraph/fiddler-client) for complete documentation 5. **Optimize for production:** Review [configuration options](#configuration-options) for high-volume applications # OpenTelemetry Quick Start Source: https://docs.fiddler.ai/developers/quick-starts/opentelemetry-quick-start Integrate custom AI agents and agentic frameworks with Fiddler using OpenTelemetry for comprehensive observability and monitoring in multi-framework environments. Monitor custom AI agents and multi-framework agentic applications with Fiddler using OpenTelemetry's native instrumentation. ## What You'll Learn In this guide, you'll learn how to: * Set up OpenTelemetry tracing for custom agent frameworks * Configure Fiddler as your OTLP endpoint with proper authentication * Map agent attributes to Fiddler's semantic conventions * Create instrumented LLM and tool spans with required attributes * Verify traces in the Fiddler dashboard **Time to complete**: \~10-15 minutes **When to Use Raw OpenTelemetry** This guide is for advanced scenarios requiring full manual OTLP control: * **Multi-framework environments** requiring unified observability across different agent frameworks * **Existing OpenTelemetry infrastructure** where you want to route Fiddler traces through your own OTel pipeline * **Advanced control** over trace sampling, batch processing, and attribute mapping **When to Use Fiddler SDKs Instead (recommended for most users):** * **Custom Python agents** → Use [Fiddler OTel SDK](/integrations/agentic-ai/fiddler-otel-sdk) (`@trace` decorator, typed span wrappers, zero OTLP setup) * **LangChain V1 agents** → Use [Fiddler LangChain SDK](/integrations/agentic-ai/langchain-sdk) (one `instrument()` call) * **LangGraph agents/workflows** → Use [Fiddler LangGraph SDK](/developers/quick-starts/langgraph-sdk-quick-start) (auto-instrumentation) * **Strands Agents** → Use [Strands Agents SDK](/developers/quick-starts/strands-agent-quick-start) (native integration) SDKs provide automatic instrumentation and require significantly less code. Use raw OpenTelemetry only when SDKs don't fit your use case. ## Prerequisites Before you begin, ensure you have: * **Fiddler Account**: An active account with a GenAI application created * **Python 3.10+** * **OpenTelemetry Packages**: * `pip install opentelemetry-api opentelemetry-sdk opentelemetry-exporter-otlp-proto-http` * **LLM Provider** (for examples): OpenAI API key or similar * **Fiddler Access Token**: Get your token from [Settings > Credentials](/reference/administration/settings#creating-api-keys) For a complete working example with advanced patterns, download the [Advanced OpenTelemetry Notebook](https://github.com/fiddler-labs/fiddler-examples/blob/main/quickstart/latest/Fiddler_Quickstart_OpenTelemetry_Advanced.ipynb) from GitHub or open it in [Google Colab](https://colab.research.google.com/github/fiddler-labs/fiddler-examples/blob/main/quickstart/latest/Fiddler_Quickstart_OpenTelemetry_Advanced.ipynb). 1. **Log in to your Fiddler instance** and navigate to **GenAI Applications** 2. **Select "Add Application"** to create a new application 3. **Copy your Application ID** - This must be a valid UUID4 format (e.g., `550e8400-e29b-41d4-a716-446655440000`) 4. **Get your Access Token** from **Settings** > **Credentials** **Important:** Keep your Application ID and Access Token secure. You'll need both for the next steps. Set up your environment to connect to Fiddler's OTLP endpoint: ```bash theme={null} export OTEL_EXPORTER_OTLP_ENDPOINT="https://your-instance.fiddler.ai" export OTEL_EXPORTER_OTLP_HEADERS="authorization=Bearer ,fiddler-application-id=" export OTEL_RESOURCE_ATTRIBUTES="application.id=" ``` **Environment Variable Breakdown:** | Variable | Description | Example | | ----------------------------- | ------------------------------------- | ---------------------------------------------------------------- | | `OTEL_EXPORTER_OTLP_ENDPOINT` | Your Fiddler instance URL | `https://org.fiddler.ai` | | `OTEL_EXPORTER_OTLP_HEADERS` | Authentication and app ID headers | `authorization=Bearer sk-...,fiddler-application-id=550e8400...` | | `OTEL_RESOURCE_ATTRIBUTES` | Resource-level application identifier | `application.id=550e8400-e29b-41d4-a716-446655440000` | **Python Configuration** (alternative to environment variables): ```python theme={null} import os os.environ['OTEL_EXPORTER_OTLP_ENDPOINT'] = 'https://your-instance.fiddler.ai' os.environ['OTEL_EXPORTER_OTLP_HEADERS'] = 'authorization=Bearer ,fiddler-application-id=' os.environ['OTEL_RESOURCE_ATTRIBUTES'] = 'application.id=' ``` **Tip:** Store credentials in a `.env` file and use `python-dotenv` for local development: ```python theme={null} from dotenv import load_dotenv load_dotenv() # Loads variables from .env file ``` Set up OpenTelemetry with Fiddler's OTLP exporter: ```python theme={null} import os from opentelemetry import trace from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import BatchSpanProcessor from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter # Initialize tracer provider trace.set_tracer_provider(TracerProvider()) tracer = trace.get_tracer(__name__) # Configure OTLP exporter for Fiddler otlp_endpoint = os.getenv('OTEL_EXPORTER_OTLP_ENDPOINT') + '/v1/traces' otlp_exporter = OTLPSpanExporter(endpoint=otlp_endpoint) # Add batch span processor otlp_processor = BatchSpanProcessor(otlp_exporter) trace.get_tracer_provider().add_span_processor(otlp_processor) print(f"✅ OpenTelemetry configured with endpoint: {otlp_endpoint}") ``` **What This Does:** * **TracerProvider**: Manages trace generation * **OTLPSpanExporter**: Exports spans to Fiddler via OTLP protocol * **BatchSpanProcessor**: Batches spans for efficient network transmission **Local Debugging:** Add a console exporter to see traces locally while developing: ```python theme={null} from opentelemetry.sdk.trace.export import ConsoleSpanExporter console_exporter = ConsoleSpanExporter() console_processor = BatchSpanProcessor(console_exporter) trace.get_tracer_provider().add_span_processor(console_processor) ``` Create instrumented spans for your agent's operations. Fiddler requires specific attributes to properly categorize and visualize your agent traces. **Required Fiddler Attributes** **Resource Level** (set via environment variable): * `application.id` - UUID4 of your Fiddler application **Span Level** (required for each span): * `fiddler.span.type` - Type of operation: `"chain"`, `"tool"`, `"llm"`, or `"agent"` **Recommended: Decorate functions with `start_as_current_span`** OpenTelemetry's `tracer.start_as_current_span()` works both as a context manager (`with ... as span:`) and as a **function decorator**. When a span should wrap an entire function — which is the common case for tools, LLM calls, and agent entry points — the decorator form is far less verbose: it starts the span on entry and ends it on return automatically. Inside the function, call `trace.get_current_span()` to set Fiddler attributes on the active span. Reach for the `with` block only when you need a span narrower than a whole function (for example, instrumenting a single section of a larger function). Both forms are pure OpenTelemetry and require no Fiddler SDK. **Example: Simplified Travel Agent** ```python theme={null} import json from openai import OpenAI from opentelemetry import trace client = OpenAI() # Reuse the tracer configured in the "Initialize OpenTelemetry" step above tracer = trace.get_tracer(__name__) AGENT_NAME = "travel_agent" AGENT_ID = "travel_agent_v1" # Define tools @tracer.start_as_current_span("book_hotel") def book_hotel_tool(city: str, date: str): """Book a hotel in the specified city.""" span = trace.get_current_span() span.set_attribute("fiddler.span.type", "tool") span.set_attribute("gen_ai.agent.name", AGENT_NAME) # optional span.set_attribute("gen_ai.agent.id", AGENT_ID) # optional # Tool-specific attributes span.set_attribute("gen_ai.tool.name", "book_hotel") tool_input = {"city": city, "date": date} span.set_attribute("gen_ai.tool.input", json.dumps(tool_input)) # Execute tool result = {"status": "confirmed", "hotel": f"Grand Hotel {city}", "confirmation": "HTL123"} span.set_attribute("gen_ai.tool.output", json.dumps(result)) return result @tracer.start_as_current_span("book_flight") def book_flight_tool(source: str, destination: str, date: str): """Book a flight between two cities.""" span = trace.get_current_span() span.set_attribute("fiddler.span.type", "tool") span.set_attribute("gen_ai.agent.name", AGENT_NAME) # optional span.set_attribute("gen_ai.agent.id", AGENT_ID) # optional # Tool-specific attributes span.set_attribute("gen_ai.tool.name", "book_flight") tool_input = {"source": source, "destination": destination, "date": date} span.set_attribute("gen_ai.tool.input", json.dumps(tool_input)) # Execute tool result = {"status": "confirmed", "flight": "FL456", "departure": "10:00 AM"} span.set_attribute("gen_ai.tool.output", json.dumps(result)) return result @tracer.start_as_current_span("llm_call") def call_llm(user_request: str): """Call the LLM to interpret the request and choose tools.""" span = trace.get_current_span() span.set_attribute("fiddler.span.type", "llm") span.set_attribute("gen_ai.agent.name", AGENT_NAME) # optional span.set_attribute("gen_ai.agent.id", AGENT_ID) # optional # LLM-specific attributes span.set_attribute("gen_ai.request.model", "gpt-4o-mini") span.set_attribute("gen_ai.system", "openai") span.set_attribute("gen_ai.llm.input.user", user_request) span.set_attribute( "gen_ai.llm.input.system", "You are a travel agent. Parse user requests and call appropriate tools." ) # Call OpenAI response = client.chat.completions.create( model="gpt-4o-mini", messages=[ {"role": "system", "content": "You are a travel agent. Parse user requests and call appropriate tools."}, {"role": "user", "content": user_request} ], tools=[ { "type": "function", "function": { "name": "book_hotel", "description": "Book a hotel in a city for a specific date", "parameters": { "type": "object", "properties": { "city": {"type": "string"}, "date": {"type": "string"} }, "required": ["city", "date"] } } }, { "type": "function", "function": { "name": "book_flight", "description": "Book a flight between two cities", "parameters": { "type": "object", "properties": { "source": {"type": "string"}, "destination": {"type": "string"}, "date": {"type": "string"} }, "required": ["source", "destination", "date"] } } } ] ) # Set token usage span.set_attribute("gen_ai.usage.input_tokens", response.usage.prompt_tokens) span.set_attribute("gen_ai.usage.output_tokens", response.usage.completion_tokens) span.set_attribute("gen_ai.usage.total_tokens", response.usage.total_tokens) # Process tool calls tool_results = [] if response.choices[0].message.tool_calls: for tool_call in response.choices[0].message.tool_calls: tool_name = tool_call.function.name tool_args = json.loads(tool_call.function.arguments) if tool_name == "book_hotel": tool_results.append(book_hotel_tool(**tool_args)) elif tool_name == "book_flight": tool_results.append(book_flight_tool(**tool_args)) span.set_attribute("gen_ai.llm.output", f"Called tools and received: {tool_results}") return tool_results # Agent implementation @tracer.start_as_current_span("travel_agent_chain") def travel_agent(user_request: str): """Main travel agent function.""" span = trace.get_current_span() span.set_attribute("fiddler.span.type", "chain") span.set_attribute("gen_ai.agent.name", AGENT_NAME) # optional span.set_attribute("gen_ai.agent.id", AGENT_ID) # optional # call_llm runs as a child span because it is invoked within this span tool_results = call_llm(user_request) return {"status": "success", "bookings": tool_results} # Run the agent result = travel_agent("Book a hotel in Paris for tomorrow and a flight from London to Paris") print(f"Agent result: {result}") ``` **Key Implementation Details:** * **Decorator form**: `@tracer.start_as_current_span("name")` wraps the whole function; retrieve the span inside with `trace.get_current_span()` * **Chain Spans**: Use `fiddler.span.type = "chain"` for high-level workflows * **LLM Spans**: Include model, system prompt, user input, output, and token usage * **Tool Spans**: Include tool name, input JSON, and output JSON * **Nested Spans**: A decorated function called from within another decorated function automatically becomes a child span, building the trace hierarchy **Simpler alternative:** Install `fiddler-otel` to skip all the manual OTLP configuration and attribute boilerplate. The SDK's `start_as_current_span()` method handles span type enforcement and attribute propagation automatically — no need to set `fiddler.span.type`, `gen_ai.agent.name`, or `gen_ai.agent.id` on every span manually. Typed span wrappers like `FiddlerGeneration` and `FiddlerTool` provide helper methods such as `set_model()` and `set_tool_name()` instead of raw `set_attribute()` calls. See [Manual Instrumentation](/integrations/agentic-ai/fiddler-otel-sdk#manual-instrumentation) in the integration guide. 1. **Run your instrumented code** using the example above 2. **Wait 1-2 minutes** for traces to appear in Fiddler 3. **Navigate to GenAI Applications** in your Fiddler instance 4. **Verify application status** changes to **Active** 5. **View traces** to see your agent spans, hierarchy, and attributes **Success Criteria:** ✅ Application shows as **Active** in GenAI Applications ✅ Traces appear in the Explorer ✅ Span hierarchy shows chain → LLM → tools relationship ✅ `fiddler.span.type` is set on every span ✅ LLM token usage is tracked ✅ Tool inputs and outputs are captured **Verification Tip:** Check the trace timeline view to see the execution flow of your agent, including which tools were called and how long each operation took. ## Attribute Reference ### Required Attributes **Resource Level:** | Attribute | Type | Description | Example | | ---------------- | ------ | --------------------------------- | ---------------------------------------- | | `application.id` | string | UUID4 of your Fiddler application | `"550e8400-e29b-41d4-a716-446655440000"` | **Span Level:** | Attribute | Type | Description | Valid Values | | ------------------- | ------ | ----------------- | --------------------------------------- | | `fiddler.span.type` | string | Type of operation | `"chain"`, `"tool"`, `"llm"`, `"agent"` | ### Optional Attributes **Agent Identification:** | Attribute | Type | Description | Example | | ------------------- | ------ | ------------------------------- | ------------------- | | `gen_ai.agent.name` | string | Name of the AI agent | `"travel_agent"` | | `gen_ai.agent.id` | string | Unique identifier for the agent | `"travel_agent_v1"` | **Set agent attributes on every span.** `gen_ai.agent.name` and `gen_ai.agent.id` are optional, but if you include them, set both on **every span within the trace**. Fiddler uses these attributes to attribute spans to the correct agent — spans missing these fields will be unattributed even if other spans in the same trace carry them. **Conversation Tracking:** | Attribute | Type | Description | Example | | ------------------------ | ------ | ------------------------------- | ------------ | | `gen_ai.conversation.id` | string | Session/conversation identifier | `"conv_123"` | **LLM Span Attributes:** | Attribute | Type | Description | Example | | ---------------------------- | ------------------- | ------------------------------ | ------------------------------------------ | | `gen_ai.request.model` | string | Model name | `"gpt-4o-mini"`, `"claude-3-opus"` | | `gen_ai.system` | string | LLM provider | `"openai"`, `"anthropic"` | | `gen_ai.llm.input.system` | string | System prompt | `"You are a helpful assistant"` | | `gen_ai.llm.input.user` | string | User input | `"What's the weather?"` | | `gen_ai.llm.output` | string | LLM response | `"The weather is sunny"` | | `gen_ai.usage.input_tokens` | int | Input tokens used | `42` | | `gen_ai.usage.output_tokens` | int | Output tokens used | `28` | | `gen_ai.usage.total_tokens` | int | Total tokens used | `70` | | `gen_ai.input.messages` | string (JSON array) | Chat history provided to model | `[{"role": "user", "content": "Hello"}]` | | `gen_ai.output.messages` | string (JSON array) | Messages returned by model | `[{"role": "assistant", "content": "Hi"}]` | **Tool Span Attributes:** | Attribute | Type | Description | Example | | -------------------- | ------ | ------------------ | ----------------------- | | `gen_ai.tool.name` | string | Tool/function name | `"search_database"` | | `gen_ai.tool.input` | string | Tool input (JSON) | `"{"query": "hotels"}"` | | `gen_ai.tool.output` | string | Tool output (JSON) | `"{"results": [...]}"` | **Custom User-Defined Attributes:** | Pattern | Level | Example | | ---------------------------- | ----------------- | ------------------------------------------ | | `fiddler.session.user.{key}` | Trace (all spans) | `fiddler.session.user.user_id = "usr_123"` | | `fiddler.span.user.{key}` | Span (individual) | `fiddler.span.user.department = "sales"` | ## Troubleshooting ### Common Issues **Problem:** Application not showing as "Active" **Solutions:** 1. Verify environment variables are set correctly 2. Check that `OTEL_EXPORTER_OTLP_ENDPOINT` includes your Fiddler instance URL 3. Ensure `OTEL_EXPORTER_OTLP_HEADERS` contains valid authorization token and application ID 4. Add console exporter to verify spans are being generated locally 5. Check network connectivity: `curl -I https://your-instance.fiddler.ai` **Problem:** `ModuleNotFoundError` for OpenTelemetry packages **Solutions:** ```bash theme={null} # Install all required packages pip install opentelemetry-api opentelemetry-sdk opentelemetry-exporter-otlp-proto-http # Verify installation pip list | grep opentelemetry ``` **Problem:** Spans not appearing in Fiddler **Solutions:** 1. **Verify required attributes are set:** ```python theme={null} # Every span MUST have this span.set_attribute("fiddler.span.type", "llm") # or "tool", "chain", "agent" # Optional but recommended span.set_attribute("gen_ai.agent.name", "your_agent") span.set_attribute("gen_ai.agent.id", "agent_id") ``` 2. **Check resource attributes:** ```python theme={null} # Verify application.id is set print(os.getenv('OTEL_RESOURCE_ATTRIBUTES')) ``` 3. **Enable console exporter for debugging:** ```python theme={null} from opentelemetry.sdk.trace.export import ConsoleSpanExporter console_exporter = ConsoleSpanExporter() console_processor = BatchSpanProcessor(console_exporter) trace.get_tracer_provider().add_span_processor(console_processor) ``` **Problem:** Authentication errors (401 Unauthorized) **Solutions:** 1. Regenerate your access token from Fiddler Settings > Credentials 2. Verify header format: `authorization=Bearer <token>,fiddler-application-id=<uuid>` 3. Ensure no extra spaces in header values 4. Check token hasn't expired **Problem:** Invalid Application ID error **Solutions:** 1. Copy Application ID directly from Fiddler UI 2. Verify UUID4 format: `550e8400-e29b-41d4-a716-446655440000` 3. Ensure no extra quotes or whitespace ## Configuration Options ### Basic Configuration ```python theme={null} import os from opentelemetry import trace from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import BatchSpanProcessor from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter # Set environment variables os.environ['OTEL_EXPORTER_OTLP_ENDPOINT'] = 'https://your-instance.fiddler.ai' os.environ['OTEL_EXPORTER_OTLP_HEADERS'] = 'authorization=Bearer ,fiddler-application-id=' os.environ['OTEL_RESOURCE_ATTRIBUTES'] = 'application.id=' # Initialize tracing trace.set_tracer_provider(TracerProvider()) tracer = trace.get_tracer(__name__) # Configure OTLP exporter otlp_endpoint = os.getenv('OTEL_EXPORTER_OTLP_ENDPOINT') + '/v1/traces' otlp_exporter = OTLPSpanExporter(endpoint=otlp_endpoint) otlp_processor = BatchSpanProcessor(otlp_exporter) trace.get_tracer_provider().add_span_processor(otlp_processor) ``` ### Advanced Configuration **High-Volume Applications (Batch Processing Tuning):** ```python theme={null} from opentelemetry.sdk.trace.export import BatchSpanProcessor # Customize batch processor settings custom_processor = BatchSpanProcessor( otlp_exporter, max_queue_size=500, # Default: 2048 schedule_delay_millis=500, # Default: 5000 max_export_batch_size=50, # Default: 512 export_timeout_millis=10000 # Default: 30000 ) trace.get_tracer_provider().add_span_processor(custom_processor) ``` **Environment Variable Configuration:** ```bash theme={null} # Batch processor environment variables export OTEL_BSP_MAX_QUEUE_SIZE=500 export OTEL_BSP_SCHEDULE_DELAY_MILLIS=500 export OTEL_BSP_MAX_EXPORT_BATCH_SIZE=50 export OTEL_BSP_EXPORT_TIMEOUT=10000 ``` **Sampling for Production (Reduce Volume):** ```python theme={null} from opentelemetry.sdk.trace import sampling # Sample 10% of traces sampler = sampling.TraceIdRatioBased(0.1) # Create provider with sampler provider = TracerProvider(sampler=sampler) trace.set_tracer_provider(provider) ``` **Compression (Reduce Network Usage):** ```python theme={null} from opentelemetry.exporter.otlp.proto.http.trace_exporter import Compression # Enable gzip compression otlp_exporter = OTLPSpanExporter( endpoint=otlp_endpoint, compression=Compression.Gzip ) ``` **Using FiddlerClient Alternative (Simplified Setup):** **Deprecation notice:** Importing `FiddlerClient` and other core symbols (`trace`, `get_current_span`, `FiddlerSpan`, `FiddlerGeneration`, `FiddlerChain`, `FiddlerTool`, `get_client`, `set_conversation_id`) directly from `fiddler_langgraph` is deprecated and will be removed in a future release. Import from `fiddler_otel` instead: `from fiddler_otel import FiddlerClient`. If you have `fiddler-otel` installed, you can use `FiddlerClient` for simplified setup — it handles OTLP configuration automatically. There are two levels of abstraction: **Option 1: Get a pre-configured tracer** (use raw OTel spans, but skip OTLP configuration): ```python theme={null} from fiddler_otel import FiddlerClient client = FiddlerClient( application_id='', api_key='', url='' ) tracer = client.get_tracer() with tracer.start_as_current_span("my_operation") as span: span.set_attribute("fiddler.span.type", "chain") # ... rest of your code ``` **Option 2: Use SDK span wrappers** (typed helper methods, automatic attribute propagation): ```python theme={null} from fiddler_otel import FiddlerClient client = FiddlerClient( application_id='', api_key='', url='' ) # Span type and agent attributes are set automatically with client.start_as_current_span("llm_call", as_type="generation") as gen: gen.set_model("gpt-4o") gen.set_user_prompt(user_input) response = call_llm(user_input) gen.set_completion(response.content) gen.set_usage(response.usage.prompt_tokens, response.usage.completion_tokens) ``` Both approaches handle OTLP configuration automatically. For graceful exit (e.g. servers or short scripts), call `client.shutdown()` (or `await client.ashutdown()` in async) so buffered spans are sent before the process exits. See [Manual Instrumentation](/integrations/agentic-ai/fiddler-otel-sdk#manual-instrumentation) for complete span wrapper documentation. ## Next Steps Now that you have OpenTelemetry integration working: * **Advanced Patterns:** Download the [Advanced OpenTelemetry Notebook](https://github.com/fiddler-labs/fiddler-examples/blob/main/quickstart/latest/Fiddler_Quickstart_OpenTelemetry_Advanced.ipynb) for: * Multi-agent configurations * Conversation tracking across sessions * Custom user-defined attributes * Production-ready error handling * Comprehensive debugging techniques * **Consider SDKs for Common Frameworks:** * [Fiddler OTel SDK](/integrations/agentic-ai/fiddler-otel-sdk) - `@trace` decorator for custom Python agents (no raw OTel boilerplate) * [Fiddler LangChain SDK](/integrations/agentic-ai/langchain-sdk) - Auto-instrumentation for LangChain V1 agents * [Fiddler LangGraph SDK](/developers/quick-starts/langgraph-sdk-quick-start) - Auto-instrumentation for LangGraph/LangChain * [Strands Agents SDK](/developers/quick-starts/strands-agent-quick-start) - Native Strands agent integration * **Explore Fiddler Capabilities:** * [Getting Started: Agentic Observability](/getting-started/agentic-monitoring) * [OpenTelemetry Integration Overview](/integrations/agentic-ai/opentelemetry-integration) * [Fiddler Python Client SDK](/sdk-api/python-client/connection) * **Production Deployment:** * Review sampling strategies for cost optimization * Implement error handling and retry logic * Set up monitoring alerts * Configure custom attributes for your business context # Simple LLM Monitoring Source: https://docs.fiddler.ai/developers/quick-starts/simple-llm-monitoring Learn the basic onboarding steps to use Fiddler for monitoring LLM applications. Access Google Colab or download the notebook directly from GitHub. This guide will walk you through the basic onboarding steps required to use Fiddler for monitoring of LLM applications, **using sample data provided by Fiddler**. Click [this link to get started using Google Colab →](https://colab.research.google.com/github/fiddler-labs/fiddler-examples/blob/main/quickstart/latest/Fiddler_Quickstart_LLM_Chatbot.ipynb) \
![Google Colab](https://colab.research.google.com/img/colab_favicon_256px.png)\
Or download the notebook directly from [GitHub](https://github.com/fiddler-labs/fiddler-examples/blob/main/quickstart/latest/Fiddler_Quickstart_LLM_Chatbot.ipynb). # Simple ML Monitoring Source: https://docs.fiddler.ai/developers/quick-starts/simple-ml-monitoring This document provides a guide for using Fiddler for model monitoring using sample data provided by Fiddler. This guide will walk you through the basic onboarding steps required to use Fiddler for model monitoring, **using sample data provided by Fiddler**. Click [this link to get started using Google Colab →](https://colab.research.google.com/github/fiddler-labs/fiddler-examples/blob/main/quickstart/latest/Fiddler_Quickstart_Simple_Monitoring.ipynb) \
![Google Colab](https://colab.research.google.com/img/colab_favicon_256px.png)\
Or download the notebook directly from [GitHub](https://github.com/fiddler-labs/fiddler-examples/blob/main/quickstart/latest/Fiddler_Quickstart_Simple_Monitoring.ipynb). # Strands Agent SDK Quick Start Source: https://docs.fiddler.ai/developers/quick-starts/strands-agent-quick-start Learn how to integrate Strands agents with Fiddler using the Fiddler Strands SDK for automatic instrumentation and comprehensive observability of your AI agent workflows. ## What You'll Learn In this guide, you'll learn how to: * Set up a Fiddler application for monitoring Strands agents * Install and configure the Strands Agents SDK * Instrument Strands agents with automatic telemetry * Use helper functions to add custom metadata * Verify monitoring is working correctly * Troubleshoot common integration issues **Time to complete**: \~15 minutes ## Prerequisites Before you begin, ensure you have: * **Fiddler Account**: An active account with [access](/reference/access-control/role-based-access) to create applications * **Python 3.10+**: Verify your version: ```bash theme={null} python --version ``` * **Strands Agents SDK**: Install the SDK (includes Strands agents and OpenTelemetry): ```bash theme={null} # Using uv (recommended) uv add fiddler-strands # Or using pip pip install fiddler-strands ``` * **OpenAI API Key**: For running the example agent: ```bash theme={null} export OPENAI_API_KEY= ``` If you prefer using a notebook, download it directly from [GitHub](https://github.com/fiddler-labs/fiddler-examples/blob/main/quickstart/latest/Fiddler_Quickstart_Strands_Agent_Integration.ipynb) or open it in [Google Colab](https://colab.research.google.com/github/fiddler-labs/fiddler-examples/blob/main/quickstart/latest/Fiddler_Quickstart_Strands_Agent_Integration.ipynb) to get started. Fiddler GenAI Applications page First, create a dedicated application in Fiddler to receive your agent traces. 1. Sign in to your Fiddler instance 2. Navigate to **GenAI Applications** in the left sidebar 3. Click **Add Application** 4. Enter the application details: * **Name**: `strands-agent-monitoring` * **Project**: Select a project from the dropdown or press *Enter* to create a new one 5. Click **Create** and copy the **Application UUID** (you'll need this for configuration) Set up the required environment variables for Fiddler integration. Replace the placeholder values with your actual credentials. Instructions for generating or retrieving your personal access token can be found in the [Access guide](/reference/administration/settings#credentials). ```bash theme={null} # Fiddler URL (adjust domain for your instance) export OTEL_EXPORTER_OTLP_ENDPOINT="http://demo.fiddler.ai" # Your application UUID from Step 1 export OTEL_RESOURCE_ATTRIBUTES=application.id= # Authentication headers (get access token from Fiddler settings) export OTEL_EXPORTER_OTLP_HEADERS="authorization=Bearer ,fiddler-application-id=" # Your OpenAI API key export OPENAI_API_KEY= ``` **Tip**: Save these environment variables in a `.env` file for easy reuse: ```bash theme={null} # Save to .env file cat > .env << 'EOF' OTEL_EXPORTER_OTLP_ENDPOINT=http://demo.fiddler.ai OTEL_RESOURCE_ATTRIBUTES=application.id= OTEL_EXPORTER_OTLP_HEADERS=authorization=Bearer ,fiddler-application-id= OPENAI_API_KEY= EOF # Load in your shell source .env ``` Now configure the Strands telemetry system with automatic Fiddler instrumentation using the SDK. Create `agent_monitoring.py`: ```python theme={null} import os from strands.telemetry import StrandsTelemetry from fiddler_strandsagents import StrandsAgentInstrumentor # Initialize Strands telemetry strands_telemetry = StrandsTelemetry() # Setup exporters strands_telemetry.setup_console_exporter() # For local debugging strands_telemetry.setup_otlp_exporter() # For Fiddler export # Enable automatic instrumentation with Fiddler integration StrandsAgentInstrumentor(strands_telemetry).instrument() ``` **Configuration Breakdown**: * **Console Exporter**: Prints traces to terminal for debugging * **OTLP Exporter**: Sends traces to Fiddler via OpenTelemetry Protocol * **StrandsAgentInstrumentor**: Automatically instruments agents with proper attribute propagation and Fiddler integration **What the SDK Does Automatically**: * Injects logging hooks into Strands agents * Propagates agent attributes (name, ID, system prompt) to all child spans * Processes spans with Fiddler-specific enhancements * Handles all OpenTelemetry complexity behind the scenes With telemetry configured, create a Strands agent that's fully instrumented for Fiddler monitoring. Add to `agent_monitoring.py`: ```python theme={null} from strands import Agent, tool from strands.models.openai import OpenAIModel # Initialize OpenAI model model = OpenAIModel( client_args={"api_key": os.getenv("OPENAI_API_KEY")}, model_id="gpt-4o-mini" ) # Define example tools @tool def get_weather(city: str) -> str: """Get the current weather for a city. Args: city: The name of the city Returns: Weather information as a string """ # In production, call a real weather API return f"The weather in {city} is sunny with a temperature of 72°F" @tool def search_knowledge_base(query: str) -> str: """Search the knowledge base for information. Args: query: The search query Returns: Relevant information from the knowledge base """ # In production, implement actual search logic return f"Search results for '{query}': [relevant documentation snippets]" # Create the agent with telemetry enabled agent = Agent( model=model, system_prompt="""You are a helpful assistant that can check weather and search a knowledge base. Always be concise and accurate in your responses.""", tools=[get_weather, search_knowledge_base] ) # Use the agent if __name__ == "__main__": # Example 1: Simple query response = agent("What's the weather like in San Francisco?") print(f"Response: {response}") # Example 2: Knowledge base query response = agent("Search for information about model monitoring") print(f"Response: {response}") ``` Run your instrumented agent: ```bash theme={null} python agent_monitoring.py ``` After running your agent, verify that traces are appearing in Fiddler. 1. Navigate to your application in Fiddler 2. Click on the **Traces** tab 3. You should see traces from your agent executions 4. Click on a trace to view detailed span information 5. Verify that agent attributes are present on spans (these are set automatically by the SDK): * `gen_ai.agent.name` — optional, but if present should appear on all spans in the trace * `gen_ai.agent.id` — optional, but if present should appear on all spans in the trace **Success Indicators**: * ✅ Traces appear within 30 seconds of agent execution * ✅ Parent and child spans are properly linked * ✅ Agent attributes (`gen_ai.agent.name`, `gen_ai.agent.id`) appear consistently across all spans * ✅ Tool calls are captured as separate spans * ✅ System prompts are visible in trace metadata ## Troubleshooting ### Traces Not Appearing in Fiddler **Issue**: No traces show up after running your agent. **Solutions**: 1. **Verify environment variables**: ```bash theme={null} echo $OTEL_EXPORTER_OTLP_ENDPOINT echo $OTEL_RESOURCE_ATTRIBUTES echo $OTEL_EXPORTER_OTLP_HEADERS ``` 2. **Check network connectivity**: ```bash theme={null} curl -I $OTEL_EXPORTER_OTLP_ENDPOINT ``` 3. **Validate authentication**: * Ensure your access token is valid and not expired * Verify Application UUID matches your Fiddler application 4. **Review console exporter output**: * Check the terminal for trace output * Look for error messages in console logs ### Missing Agent Attributes on Child Spans **Issue**: Tool calls and sub-spans don't have agent context. **Solutions**: 1. **Verify SDK instrumentation is enabled**: ```python theme={null} # Should be in your code from fiddler_strandsagents import StrandsAgentInstrumentor StrandsAgentInstrumentor(strands_telemetry).instrument() ``` 2. **Check instrumentation status**: ```python theme={null} from fiddler_strandsagents import StrandsAgentInstrumentor instrumentor = StrandsAgentInstrumentor(strands_telemetry) print(f"Instrumented: {instrumentor.is_instrumented_by_opentelemetry}") ``` 3. **Add custom attributes using helper functions**: ```python theme={null} from fiddler_strandsagents import set_span_attributes # Add custom attributes to ensure they appear on spans set_span_attributes(agent, custom_attr="value") set_span_attributes(model, environment="production") ``` ### OTLP Export Errors **Issue**: Error messages about OTLP export failures. **Solutions**: 1. **Check endpoint format**: ```bash theme={null} # Should be https://, not include /v1/traces export OTEL_EXPORTER_OTLP_ENDPOINT="http://demo.fiddler.ai" ``` 2. **Verify headers format**: ```bash theme={null} # Headers should be comma-separated key=value pairs export OTEL_EXPORTER_OTLP_HEADERS="authorization=Bearer TOKEN,fiddler-application-id=UUID" ``` 3. **Test with a minimal example**: ```python theme={null} from opentelemetry import trace from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import BatchSpanProcessor from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter provider = TracerProvider() processor = BatchSpanProcessor(OTLPSpanExporter()) provider.add_span_processor(processor) trace.set_tracer_provider(provider) tracer = trace.get_tracer(__name__) with tracer.start_as_current_span("test-span"): print("Test trace sent") ``` ### Performance Issues **Issue**: Agent response times are slower after adding monitoring. **Solutions**: 1. **Use batch span processor** (already default in StrandsTelemetry): ```python theme={null} # Batching reduces overhead from opentelemetry.sdk.trace.export import BatchSpanProcessor ``` 2. **Disable console exporter in production**: ```python theme={null} # Only use OTLP exporter # strands_telemetry.setup_console_exporter() # Comment out strands_telemetry.setup_otlp_exporter() ``` 3. **Adjust sampling rate** if needed: ```python theme={null} from opentelemetry.sdk.trace.sampling import TraceIdRatioBased # Sample 10% of traces sampler = TraceIdRatioBased(0.1) ``` ## Configuration Options ### Basic Configuration For most use cases, the basic configuration is sufficient: ```python theme={null} from strands.telemetry import StrandsTelemetry from fiddler_strandsagents import StrandsAgentInstrumentor strands_telemetry = StrandsTelemetry() strands_telemetry.setup_otlp_exporter() StrandsAgentInstrumentor(strands_telemetry).instrument() ``` ### Adding Custom Metadata with Helper Functions The SDK provides helper functions to enrich your traces with custom business context: ```python theme={null} from fiddler_strandsagents import ( set_conversation_id, set_session_attributes, set_span_attributes, set_llm_context ) # Set conversation ID for tracking related interactions set_conversation_id(agent, 'session_1234567890') # Add session-level attributes for business context set_session_attributes(agent, role='customer_support', cost_center='travel_desk', region='us-west' ) # Add attributes to specific components (models or tools) set_span_attributes(model, model_id='gpt-4o-mini', temperature=0.7) set_span_attributes(search_tool, department='search', version='2.0') # Set LLM context for additional background information set_llm_context(model, 'Available hotels: Hilton, Marriott, Hyatt...') ``` **Helper Functions Available**: * `set_conversation_id(agent, conversation_id)` - Track multi-turn conversations * `set_session_attributes(agent, **kwargs)` - Add session-level business context * `set_span_attributes(obj, **kwargs)` - Add attributes to models, tools, or agents * `set_llm_context(model, context)` - Add background information for LLM interactions * `get_conversation_id(agent)` - Retrieve conversation ID * `get_session_attributes(agent)` - Retrieve session attributes * `get_span_attributes(obj)` - Retrieve span attributes * `get_llm_context(model)` - Retrieve LLM context ### Advanced Configuration For production deployments with custom resource metadata and batch settings: ```python theme={null} import os from strands.telemetry import StrandsTelemetry from fiddler_strandsagents import StrandsAgentInstrumentor from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import BatchSpanProcessor from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter from opentelemetry.sdk.resources import Resource # Create custom resource with additional metadata resource = Resource.create({ "service.name": "strands-agent-service", "service.version": "1.0.0", "deployment.environment": os.getenv("ENVIRONMENT", "production"), "application.id": os.getenv("FIDDLER_APP_ID"), }) # Initialize tracer provider with custom resource provider = TracerProvider(resource=resource) # Configure OTLP exporter with custom settings otlp_exporter = OTLPSpanExporter( endpoint=os.getenv("OTEL_EXPORTER_OTLP_ENDPOINT"), headers={ "authorization": f"Bearer {os.getenv('FIDDLER_BEARER_TOKEN')}", "fiddler-application-id": os.getenv("FIDDLER_APP_ID"), }, timeout=10, # Custom timeout in seconds ) # Add batch processor with custom settings batch_processor = BatchSpanProcessor( otlp_exporter, max_queue_size=2048, # Max spans in queue max_export_batch_size=512, # Spans per export batch schedule_delay_millis=5000, # Export every 5 seconds ) provider.add_span_processor(batch_processor) # Initialize Strands telemetry with custom provider strands_telemetry = StrandsTelemetry(tracer_provider=provider) # Enable Fiddler instrumentation StrandsAgentInstrumentor(strands_telemetry).instrument() ``` **Advanced Options Explained**: * **Custom Resource**: Add service metadata for better organization * **Batch Settings**: Tune for your throughput requirements * **Timeout Configuration**: Adjust for network conditions * **Environment Tagging**: Separate dev/staging/prod traces * **SDK Integration**: Works seamlessly with custom OpenTelemetry configurations ### Multi-Agent Configuration For systems with multiple agents: ```python theme={null} from strands import Agent from strands.models.openai import OpenAIModel # Create multiple agents with distinct identities research_agent = Agent( model=OpenAIModel(model_id="gpt-4o"), system_prompt="You are a research specialist...", tools=[search_tool, analyze_tool], agent_id="research-agent", # Unique identifier agent_name="Research Specialist" ) writing_agent = Agent( model=OpenAIModel(model_id="gpt-4o"), system_prompt="You are a writing specialist...", tools=[write_tool, edit_tool], agent_id="writing-agent", agent_name="Writing Specialist" ) # Agents will appear separately in Fiddler traces ``` **Multi-Agent Benefits**: * ✅ Distinct agent identification in traces * ✅ Separate performance metrics per agent * ✅ Clear visualization of agent interactions * ✅ Easier debugging of complex workflows ## Next Steps Now that you have Strands agents integrated with Fiddler, explore these advanced capabilities: ### Advanced Observability and Evaluation * [Experiments](/getting-started/experiments): Score and enrich your agent telemetry # Experiments Source: https://docs.fiddler.ai/developers/tutorials/experiments Master LLM and AI application experiments with comprehensive tutorials covering the Fiddler Evals SDK, custom evaluators, model comparison, and custom experiment creation. Building reliable AI applications requires systematic evaluation to ensure quality, safety, and consistent performance. This section provides comprehensive tutorials and quick starts to help you evaluate your LLM applications, RAG systems, and AI agents using Fiddler Experiments. **New to Fiddler Experiments?** Start with [Getting Started with Fiddler Experiments](/getting-started/experiments) to understand the core concepts and interface before diving into these tutorials. ## What You'll Learn These tutorials cover the full spectrum of experiment capabilities in Fiddler: ## Recommended Learning Path **New to Fiddler Experiments?** Follow this progression: 1. [**Getting Started with Fiddler Experiments**](/getting-started/experiments) - Understand the why and what (15 min read) 2. [**Evals SDK Quick Start**](/evaluate-and-test/evals-sdk-quick-start) - Build your first experiment (20 min hands-on) 3. [**Advanced Patterns**](/developers/tutorials/experiments/evals-sdk-advanced) - Master production patterns (45 min hands-on) 4. [**Evals SDK Reference**](/sdk-api/evals/evaluate) - Complete SDK documentation (reference) **Evaluating RAG applications?** Follow this path: 1. [**RAG Health Diagnostics**](/concepts/rag-health-diagnostics) - Understand the RAG diagnostic triad (15 min read) 2. [**RAG Health Metrics Tutorial**](/developers/tutorials/experiments/rag-health-metrics-tutorial) - Evaluate RAG systems with Answer Relevance 2.0, Context Relevance, and RAG Faithfulness (30 min hands-on) 3. [**RAG Evaluation Fundamentals Cookbook**](/developers/cookbooks/rag-evaluation-fundamentals) - End-to-end RAG evaluation use case **Already familiar with Fiddler Experiments?** Jump to the Fiddler Evals SDK Reference for API details. *** ### Fiddler Evals SDK Quick Start Get hands-on with the Fiddler Evals SDK in 20 minutes. Learn to create experiment datasets, use built-in evaluators (Answer Relevance, Coherence, Toxicity), build custom evaluators, and run comprehensive experiments with detailed analysis. **Perfect for:** Developers new to the Fiddler Evals SDK who want to understand experiment workflows quickly. [Start the Quick Start](/evaluate-and-test/evals-sdk-quick-start) ### RAG Health Metrics Tutorial Evaluate RAG applications using the diagnostic triad: Answer Relevance 2.0, Context Relevance, and RAG Faithfulness. Learn to identify whether issues stem from retrieval, generation, or query understanding, and run experiments to compare pipeline configurations. **Perfect for:** Teams building or maintaining RAG applications who need systematic evaluation and root cause analysis. [Start the RAG Health Tutorial](/developers/tutorials/experiments/rag-health-metrics-tutorial) ### Fiddler Evals SDK Advanced Guide Master advanced evaluation patterns for production LLM applications. Explore complex data import strategies, context-aware evaluators for RAG systems, multi-score evaluators, lambda-based parameter mapping, and production-ready experiment patterns with 11+ evaluators. **Perfect for:** Teams building production experiment pipelines with sophisticated requirements. [Explore Advanced Patterns](/developers/tutorials/experiments/evals-sdk-advanced) ### Compare LLM Outputs Learn how to systematically compare outputs from different LLM models (like GPT-3.5 and Claude) to determine the most suitable choice for your application. This guide demonstrates side-by-side model comparison workflows using Fiddler's evaluation framework. **Perfect for:** Teams evaluating multiple models or prompt variations to make data-driven decisions. [Compare Models](#compare-llm-outputs) ### Prompt Specs Quick Start Create custom LLM-as-a-Judge evaluations in minutes using Prompt Specs. Learn to define evaluation schemas using JSON, validate and test your evaluations, and deploy custom evaluators to production monitoring—all without manual prompt engineering. **Perfect for:** Teams needing domain-specific evaluation logic without extensive prompt-tuning effort. [Create Custom Evaluations](#prompt-specs-quick-start) ## Key Experiment Capabilities ### Comprehensive Test Suites Create datasets with test cases covering real-world scenarios, edge cases, and expected behaviors. Import data from CSV, JSONL, or pandas DataFrames with flexible column mapping. ### Built-in Evaluators Access production-ready evaluators for common evaluation tasks: * **Quality**: Answer Relevance 2.0 (ordinal scoring), Coherence, Conciseness, Completeness * **RAG Health**: Answer Relevance 2.0, Context Relevance, RAG Faithfulness — the diagnostic triad for RAG pipeline evaluation * **Safety**: Toxicity Detection, Prompt Injection, PII Detection * **Context-Aware**: Faithfulness (Centor Model) for RAG systems * **Sentiment**: Multi-score sentiment and topic classification * **Pattern Matching**: Regex-based format validation ### Custom Evaluation Logic Build evaluators tailored to your domain using: * **Python-based evaluators** with the Evaluator base class * **Prompt Specs** for schema-based LLM-as-a-Judge evaluation * **Multi-score evaluators** returning multiple metrics per test case * **Function wrappers** for existing evaluation functions ### Experiment Management Run comprehensive experiments with: * **Parallel processing** for faster evaluation across large datasets * **Detailed results tracking** with scores, timing, and error handling * **Metadata tagging** for experiment organization and filtering * **Side-by-side comparison** to validate improvements ### Production Integration Deploy evaluations to production monitoring: * **Enrichment pipeline integration** for real-time evaluation * **Automated alerting** based on evaluation metrics * **Dashboard visualization** for tracking quality trends * **Historical tracking** to monitor improvements over time ## Enterprise Experiment Features ### Team Collaboration * **Shared experiment libraries**: Reuse datasets and evaluators across teams * **Access control**: Project-level and application-level permissions * **Experiment tracking**: Compare evaluations across team members and versions ### Production Integration * **CI/CD pipelines**: Automated evaluation before deployment * **Quality gates**: Set score thresholds that must be met for deployment * **Regression detection**: Alert when experiment scores drop ### Compliance & Auditing * **Evaluation history**: Complete audit trail of all experiments * **Reproducibility**: Frozen datasets and evaluators for regulatory compliance * **Export capabilities**: Download results for external analysis and reporting ## Experiment Use Cases ### Single-Turn Q\&A Systems Evaluate direct question-answering applications with relevance, correctness, and conciseness metrics. ### RAG Applications Assess context-grounded responses by checking for faithfulness, relevance, and completeness. ### Multi-Turn Conversations Evaluate dialogue systems with coherence, context retention, and conversation quality metrics. ### Agentic Workflows Test tool-using agents with trajectory evaluation, tool selection accuracy, and task completion metrics. ## Getting Started Paths **For SDK Users:** 1. Start with [Evals SDK Quick Start](/evaluate-and-test/evals-sdk-quick-start) 2. Progress to [Evals SDK Advanced Guide](/developers/tutorials/experiments/evals-sdk-advanced) 3. Review the [Fiddler Evals SDK Reference](/sdk-api/evals/evaluate) **For Custom Evaluation Needs:** 1. Understand LLM Evaluation Prompt Specs concepts 2. Follow the [Prompt Specs Quick Start](/evaluate-and-test/prompt-specs-quick-start) 3. Explore [Advanced Prompt Specs](/developers/tutorials/llm-monitoring/prompt-specs-advanced) patterns **For Model Selection:** 1. Review [Compare LLM Outputs](/evaluate-and-test/llm-evaluation-example) 2. Set up comparison experiments with your candidate models 3. Use evaluation metrics to make data-driven decisions ## Best Practices ### Start Small, Scale Systematically Begin with a focused test suite covering critical functionality. Gradually expand coverage as you understand your application's failure modes. ### Use Multiple Evaluators Combine different evaluator types (quality, safety, domain-specific) for a comprehensive assessment. No single metric captures all aspects of AI application quality. ### Track Over Time Establish baselines and monitor evaluation metrics as your application evolves. Systematic tracking reveals degradation before it impacts users. ### Leverage Metadata Tag test cases with categories, difficulty levels, and business context. Rich metadata enables targeted analysis and root cause investigation. ### Automate Evaluation Integrate evaluations into CI/CD pipelines and deploy to production monitoring. Continuous evaluation prevents quality regressions and maintains user trust. # Evals SDK Advanced Guide Source: https://docs.fiddler.ai/developers/tutorials/experiments/evals-sdk-advanced Advanced experiment patterns for production LLM applications including multi-score evaluators, complex parameter mapping, and comprehensive experiment analysis. ## What You'll Learn This interactive notebook demonstrates advanced evaluation patterns for production LLM applications through comprehensive testing with the TruthfulQA benchmark dataset. **Key Topics Covered:** * Advanced data import with CSV/JSONL and complex column mapping * Real LLM integration with production-ready task functions * Context-aware evaluators for RAG and knowledge-grounded applications * Multi-score evaluators and advanced evaluation patterns * Complex parameter mapping with lambda functions * Production experiments with 11+ evaluators and complete analysis ## Interactive Tutorial The notebook guides you through building a comprehensive experiment pipeline for any LLM application, from single-turn Q\&A to multi-turn conversations, RAG systems, and agentic workflows. [**Open the Advanced Evaluations Notebook in Google Colab →**](https://colab.research.google.com/github/fiddler-labs/fiddler-examples/blob/main/quickstart/latest/Fiddler_Quickstart_Advanced_Evaluations_SDK.ipynb) [**Or download the notebook directly from GitHub →**](https://github.com/fiddler-labs/fiddler-examples/blob/main/quickstart/latest/Fiddler_Quickstart_Advanced_Evaluations_SDK.ipynb) ### Prerequisites * Fiddler account with API credentials * Basic familiarity with the [Evals SDK Quick Start](/evaluate-and-test/evals-sdk-quick-start) * Optional: OpenAI API key for real LLM examples (mock responses available) ### Time Required * **Complete tutorial**: 45-60 minutes * **Quick overview**: 15-20 minutes ## Tutorial Highlights ## Key Takeaways from the Advanced Tutorial Even if you prefer to run the notebook, here are the critical patterns you'll learn: ### 1. Complex Data Import Strategies **CSV Import with Column Mapping**: ```python theme={null} dataset.insert_from_csv_file( file_path='truthfulqa.csv', input_columns=['question', 'category'], expected_output_columns=['best_answer'], extras_columns=['context'], # Separate context for RAG evaluation metadata_columns=['type', 'difficulty'] ) ``` **Why This Matters**: Production datasets rarely have perfect column names. Column mapping lets you use any data source without reformatting files. ### 2. Context-Aware Evaluation for RAG Systems **Faithfulness Checking**: Fiddler provides two faithfulness evaluators: `RAGFaithfulness` (LLM-as-a-Judge, part of the RAG Health Metrics triad) for comprehensive diagnostics, and `FTLResponseFaithfulness` (powered by the Centor Model for Faithfulness) for low-latency guardrails. ```python theme={null} from fiddler_evals.evaluators import RAGFaithfulness, FTLResponseFaithfulness # RAG Faithfulness — LLM-as-a-Judge for RAG pipeline diagnostics rag_faithfulness = RAGFaithfulness(model="openai/gpt-4o", credential="your-llm-credential") # Requires user_query, rag_response, and retrieved_documents # Faithfulness (Centor Model) — powered by the Centor Model for Faithfulness for low-latency guardrails ftl_faithfulness = FTLResponseFaithfulness() # Requires context and response only ``` **Why This Matters**: RAG systems must be evaluated differently than simple Q\&A. Use `RAGFaithfulness` with the full RAG Health Metrics triad (Answer Relevance, Context Relevance) for root cause diagnosis. Use `FTLResponseFaithfulness` for real-time guardrails where latency matters. ### 3. Multi-Score Evaluators **Sentiment with Probability Scores**: ```python theme={null} from fiddler_evals.evaluators import Sentiment # Returns multiple scores: sentiment (categorical) and probability (float) sentiment = Sentiment() # Fiddler Centor Model — no model/credential needed # Returns multiple scores: sentiment label and probability # - score.label: "positive" | "neutral" | "negative" # - score.value: confidence score 0.0-1.0 ``` **Why This Matters**: Some quality dimensions have multiple facets. Multi-score evaluators capture nuanced assessments in a single pass. ### 4. Production Experiment Patterns **Multiple Evaluators in One Experiment**: ```python theme={null} evaluators = [ # RAG Health Metrics (diagnostic triad) AnswerRelevance(model="openai/gpt-4o", credential="your-llm-credential"), ContextRelevance(model="openai/gpt-4o", credential="your-llm-credential"), RAGFaithfulness(model="openai/gpt-4o", credential="your-llm-credential"), # Quality metrics Coherence(model="openai/gpt-4o", credential="your-llm-credential"), Conciseness(model="openai/gpt-4o", credential="your-llm-credential"), # Safety metrics FTLPromptSafety(), FTLResponseFaithfulness(), # Domain-specific (Centor Model — no model/credential needed) Sentiment(), RegexSearch(pattern=r'\b[A-Z][a-z]+\s[A-Z][a-z]+\b'), # Proper nouns CustomDomainEvaluator(), ] results = evaluate( dataset=large_dataset, task=production_task, evaluators=evaluators, max_workers=10, # Parallel processing metadata={"version": "v2.1", "environment": "staging"} ) ``` **Why This Matters**: Production systems need comprehensive evaluation across multiple dimensions. This pattern shows how to run extensive experiment suites efficiently. ### 5. Advanced Parameter Mapping **Complex Data Structures**: ```python theme={null} score_fn_kwargs_mapping={ # Simple mappings "response": "answer", # Extract from nested dicts "prompt": lambda x: x["inputs"]["question"], "context": lambda x: x["extras"]["retrieved_docs"], # Compute values "output_length": lambda x: len(x["outputs"]["answer"]), # Combine values "full_conversation": lambda x: x["inputs"]["history"] + [x["outputs"]["answer"]], } ``` **Why This Matters**: Real applications have complex data structures. Lambda-based mapping gives you the flexibility to extract any value an evaluator needs. *** ### Advanced Data Import Learn how to import complex experiment datasets with: * CSV and JSONL file support with column mapping * Separation of inputs, extras, expected outputs, and metadata * Source tracking for test case provenance * Support for RAG context and conversation history ### Production Evaluator Suite Build a comprehensive evaluation with: * **Context-aware evaluators**: Faithfulness checking for RAG systems * **Safety evaluators**: Prompt safety and faithfulness detection * **Quality evaluators**: Relevance, coherence, and conciseness * **Custom evaluators**: Domain-specific metrics for complete customization * **Multi-score evaluators**: Sentiment and topic classification ### Complex Parameter Mapping Master advanced mapping techniques: * Lambda-based parameter transformation * Access to inputs, extras, outputs, and metadata * Flexible mapping for any evaluator signature * Production-ready patterns for all LLM use cases ### Comprehensive Analysis Extract insights from experiment results: * Aggregate statistics by evaluator * Performance breakdown by category * DataFrame export for further analysis * A/B testing and regression detection patterns ## Who Should Use This * **AI engineers** building production LLM applications * **ML engineers** implementing systematic experiment pipelines * **Data scientists** analyzing LLM performance and quality * **QA engineers** setting up regression testing for AI systems ## Use Case Flexibility The patterns demonstrated work for all LLM application types: * **Single-turn Q\&A**: Direct question-answering without context * **RAG applications**: Context-grounded responses with faithfulness checking * **Multi-turn conversations**: Dialogue systems with conversation history * **Agentic workflows**: Tool-using agents with intermediate outputs * **Multi-task models**: Systems handling diverse request types ## Centor Models Integration All evaluators in the advanced tutorial run on [Fiddler Centor Models](https://www.fiddler.ai/centor-models), which means: ### Cost Efficiency at Scale Running multiple evaluators on 817 test cases (TruthfulQA dataset) would typically cost: * **External LLM API**: \$50-100+ in API calls (0.01¢ per evaluation × 9,000 evaluations) * **Fiddler Centor Models**: \$0 (no per-request charges) ### Performance at Scale * **Parallel execution**: 10 workers process 817 items in \~5 minutes * **Fast evaluators**: \<100ms per evaluation enables real-time feedback * **No rate limits**: No API quota concerns for extensive batch experiments ### Security * **Data locality**: All evaluations run within your Fiddler environment * **No external calls**: Your prompts and responses never leave your infrastructure * **Audit trail**: Complete traceability for compliance This makes Fiddler Experiments ideal for enterprise-scale experiment pipelines. ## Next Steps After completing the tutorial: * **Technical Reference**: [Fiddler Evals SDK Documentation](/sdk-api/evals/evaluate) * **Basic Tutorial**: [Evals SDK Quick Start](/evaluate-and-test/evals-sdk-quick-start) for fundamentals * **Getting Started Guide**: [Getting Started with Fiddler Experiments](/getting-started/experiments) for UI overview # RAG Health Metrics Tutorial Source: https://docs.fiddler.ai/developers/tutorials/experiments/rag-health-metrics-tutorial Step-by-step guide to evaluating RAG applications using the RAG Health Metrics diagnostic triad: Answer Relevance, Context Relevance, and RAG Faithfulness. Evaluate your RAG application using the RAG Health Metrics diagnostic triad to pinpoint whether issues originate in retrieval, generation, or query understanding. **Time to complete**: \~30 minutes ## What You'll Learn * Set up a RAG experiment pipeline with the Fiddler Evals SDK * Use Answer Relevance, Context Relevance, and RAG Faithfulness together * Interpret diagnostic results to identify pipeline failures * Distinguish between retrieval and generation problems ## Prerequisites * **Fiddler Account**: Active account with API access * **Python 3.10+** * **Fiddler Evals SDK**: `pip install fiddler-evals` * **Familiarity with**: [Experiments Getting Started](/getting-started/experiments) *** ## Step 1: Connect and Set Up ```python theme={null} from fiddler_evals import init, Project, Application, Dataset from fiddler_evals.pydantic_models.dataset import NewDatasetItem # Initialize connection init( url='https://your-org.fiddler.ai', token='your-access-token' ) # Create organizational structure project = Project.get_or_create(name='rag_health_experiments') application = Application.get_or_create( name='my_rag_app', project_id=project.id ) ``` ## Step 2: Create a RAG Experiment Dataset Create test cases that include user queries and retrieved documents. The quality of your evaluation depends on realistic, representative test cases. ```python theme={null} dataset = Dataset.create( name='rag_health_test_cases', application_id=application.id, description='RAG Health Metrics experiment dataset' ) test_cases = [ # Scenario 1: Good RAG response NewDatasetItem( inputs={ "user_query": "What are the benefits of renewable energy?", "retrieved_documents": "Renewable energy sources like solar and wind reduce " "greenhouse gas emissions, decrease dependence on fossil fuels, and can " "lower long-term energy costs. Solar panel costs have dropped 89% since 2010." }, metadata={"scenario": "good_response"} ), # Scenario 2: Irrelevant retrieval NewDatasetItem( inputs={ "user_query": "What are the benefits of renewable energy?", "retrieved_documents": "The history of the automobile dates back to the 15th " "century. Karl Benz patented the first true automobile in 1886." }, metadata={"scenario": "bad_retrieval"} ), # Scenario 3: Hallucination risk NewDatasetItem( inputs={ "user_query": "What is the current price of solar panels?", "retrieved_documents": "Solar energy adoption has grown significantly worldwide. " "Many countries now have solar incentive programs." }, metadata={"scenario": "insufficient_context"} ), ] dataset.insert(test_cases) print(f"Added {len(test_cases)} test cases") ``` ## Step 3: Define Your RAG Task The task function represents your RAG application. It receives inputs and returns the generated response. ```python theme={null} def my_rag_task(inputs, extras, metadata): """Your RAG application logic. Replace this with your actual RAG pipeline: 1. Take the user query 2. Use the retrieved documents as context 3. Generate a response """ user_query = inputs["user_query"] context = inputs["retrieved_documents"] # Call your LLM with the query and retrieved context # Example: response = my_llm.generate(query=user_query, context=context) response = generate_rag_response(user_query, context) return { "rag_response": response, "retrieved_documents": context, } ``` ## Step 4: Run the RAG Health Experiment Use all three evaluators together for comprehensive diagnostics: ```python theme={null} from fiddler_evals import evaluate from fiddler_evals.evaluators import AnswerRelevance, ContextRelevance, RAGFaithfulness results = evaluate( dataset=dataset, task=my_rag_task, evaluators=[ AnswerRelevance(model="openai/gpt-4o", credential="your-llm-credential"), # Is the response relevant? (High/Medium/Low) ContextRelevance(model="openai/gpt-4o", credential="your-llm-credential"), # Are retrieved docs relevant? (High/Medium/Low) RAGFaithfulness(model="openai/gpt-4o", credential="your-llm-credential"), # Is the response grounded? (Yes/No) ], name_prefix="rag_health_baseline", score_fn_kwargs_mapping={ "user_query": lambda x: x["inputs"]["user_query"], "rag_response": "rag_response", "retrieved_documents": "retrieved_documents", } ) print(f"Evaluated {len(results.results)} test cases") ``` ## Step 5: Analyze Diagnostic Results Examine the results to identify which pipeline stage is causing issues: ```python theme={null} for result in results.results: print(f"\nScenario: {result.dataset_item.metadata.get('scenario', 'unknown')}") scores = {score.name: score for score in result.scores} # Extract scores ar_score = scores.get("answer_relevance") cr_score = scores.get("context_relevance") rf_score = scores.get("rag_faithfulness") if ar_score: print(f" Answer Relevance: {ar_score.label} ({ar_score.value})") print(f" Reasoning: {ar_score.reasoning}") if cr_score: print(f" Context Relevance: {cr_score.label} ({cr_score.value})") print(f" Reasoning: {cr_score.reasoning}") if rf_score: print(f" RAG Faithfulness: {rf_score.label} ({rf_score.value})") print(f" Reasoning: {rf_score.reasoning}") # Diagnostic interpretation if ar_score and cr_score and rf_score: if ar_score.value >= 0.5 and rf_score.value == 0: print(" Diagnosis: HALLUCINATION — response is relevant but not grounded") elif rf_score.value == 1 and ar_score.value < 0.5: print(" Diagnosis: OFF-TOPIC — response is grounded but doesn't answer the query") elif cr_score.value < 0.5: print(" Diagnosis: BAD RETRIEVAL — retrieved documents are not relevant") elif ar_score.value >= 0.5 and rf_score.value == 1 and cr_score.value >= 0.5: print(" Diagnosis: HEALTHY — all metrics indicate good RAG performance") ``` ## Step 6: Compare RAG Configurations Use experiments to compare different RAG configurations: ```python theme={null} # Evaluate with a different retrieval strategy results_v2 = evaluate( dataset=dataset, task=my_improved_rag_task, # Different retrieval or generation config evaluators=[ AnswerRelevance(model="openai/gpt-4o", credential="your-llm-credential"), ContextRelevance(model="openai/gpt-4o", credential="your-llm-credential"), RAGFaithfulness(model="openai/gpt-4o", credential="your-llm-credential"), ], name_prefix="rag_health_improved", score_fn_kwargs_mapping={ "user_query": lambda x: x["inputs"]["user_query"], "rag_response": "rag_response", "retrieved_documents": "retrieved_documents", } ) # Compare results side-by-side in the Fiddler UI print("Compare experiments in your Fiddler dashboard") ``` *** ## Understanding the Results ### Score Interpretation | Evaluator | High Score | Low Score | | ----------------- | ------------------------------------- | ----------------------------------------- | | Answer Relevance | Response directly addresses the query | Response misses the point or is off-topic | | Context Relevance | Retrieved documents support the query | Retrieved documents are irrelevant | | RAG Faithfulness | Response is grounded in context | Response contains unsupported claims | ### Common Diagnostic Patterns | Answer Relevance | Context Relevance | RAG Faithfulness | Diagnosis | | ---------------- | ----------------- | ---------------- | --------------------------------------- | | High | High | Yes | Healthy RAG pipeline | | High | High | No | Hallucination — fix generation | | Low | High | Yes | Query misunderstanding — fix prompt | | Low | Low | - | Bad retrieval — fix retrieval | | High | Low | Yes | Lucky generation — retrieval needs work | *** ## Next Steps * [RAG Health Diagnostics](/concepts/rag-health-diagnostics) — Conceptual deep-dive into the diagnostic framework * [Evals SDK Advanced Guide](/developers/tutorials/experiments/evals-sdk-advanced) — Advanced evaluation patterns * [Evaluator Rules](/evaluate-and-test/evaluator-rules) — Set up continuous RAG monitoring in production # Guardrails Source: https://docs.fiddler.ai/developers/tutorials/guardrails * [Faithfulness](/developers/tutorials/guardrails/guardrails-faithfulness): This Quick Start notebook introduces Fiddler Guardrails, an enterprise solution that safeguards LLM applications from risks like hallucinations, toxicity, and jailbreaking attempts. * [Safety](/developers/tutorials/guardrails/guardrails-safety): This Quick Start Notebook introduces Fiddler Guardrails' Safety Detection capabilities, an essential component of our enterprise solution for protecting LLM applications. * [PII](/developers/tutorials/guardrails/guardrails-pii): Learn to detect and protect PII, PHI, and sensitive data in text using Fiddler Guardrails for PII/PHI for comprehensive privacy compliance. # Faithfulness Source: https://docs.fiddler.ai/developers/tutorials/guardrails/guardrails-faithfulness This Quick Start notebook introduces Fiddler Guardrails, an enterprise solution that safeguards LLM applications from risks like hallucinations, toxicity, and jailbreaking attempts. This Quick Start notebook introduces Fiddler Guardrails, an enterprise solution that safeguards LLM applications from risks like hallucinations, toxicity, and jailbreaking attempts. Learn how to implement the **Centor Model for Faithfulness**, which evaluates factual consistency between AI-generated responses and their source context in RAG applications. **This tutorial covers the Centor Model for Faithfulness** (`ftl_response_faithfulness`) — Fiddler's proprietary Centor Model for real-time guardrail use cases. For the LLM-as-a-Judge RAG Faithfulness evaluator used in Agentic Monitoring and Experiments, see the [RAG Health Metrics Tutorial](/developers/tutorials/experiments/rag-health-metrics-tutorial). Inside you'll find: * Step-by-step implementation instructions * Code examples for evaluating response accuracy * Practical demonstration of hallucination detection * Sample inputs and outputs with score interpretation Before running the notebook, generate a Fiddler API key from **Settings → [Credentials](/reference/administration/settings#credentials)** in your Fiddler environment. See the [Guardrails documentation](/protection/guardrails) and [FAQ](/protection/guardrails-faq) for more help getting started. **Interactive Tutorial** Run the Faithfulness Guardrail notebook end to end: [**Open the Faithfulness Guardrail Notebook in Google Colab →**](https://colab.research.google.com/github/fiddler-labs/fiddler-examples/blob/main/quickstart/latest/Fiddler_Quickstart_Guardrails_Faithfulness.ipynb) [**Or download the notebook from GitHub →**](https://github.com/fiddler-labs/fiddler-examples/blob/main/quickstart/latest/Fiddler_Quickstart_Guardrails_Faithfulness.ipynb) # PII Source: https://docs.fiddler.ai/developers/tutorials/guardrails/guardrails-pii Learn to detect and protect PII, PHI, and sensitive data in text using Fiddler Guardrails for PII/PHI for comprehensive privacy compliance. Get your sensitive information detection running in **minutes** with Fiddler Guardrails for PII/PHI. This guide walks you through detecting PII, PHI, and custom entities to protect sensitive data across your applications. ## What You'll Build In this quick start, you'll implement a sensitive information detection system that: * Detects a comprehensive set of personally identifiable information (PII) entity types * Identifies protected health information (PHI) entity types for healthcare compliance * Configures custom entity detection for organization-specific data * Provides real-time detection with sub-second latency **Interactive Tutorial** For more advanced examples, including batch processing, performance optimization, and production deployment patterns: [**Open the Complete Sensitive Information Guardrail Notebook in Google Colab →**](https://colab.research.google.com/github/fiddler-labs/fiddler-examples/blob/main/quickstart/latest/Fiddler_Quickstart_Sensitive_Information_Guardrail.ipynb) [**Or download the notebook from GitHub →**](https://github.com/fiddler-labs/fiddler-examples/blob/main/quickstart/latest/Fiddler_Quickstart_Sensitive_Information_Guardrail.ipynb) ## Prerequisites * Fiddler account with [access token](/reference/administration/settings#credentials) * Python 3.10+ environment * Basic understanding of data privacy concepts ## Overview Fiddler's PII and PHI detection, powered by the Centor Model for PII/PHI, provides enterprise-grade protection against data leakage by automatically detecting sensitive information across multiple categories. These guardrails integrate seamlessly with Fiddler's AI Observability platform, enabling continuous monitoring and automated compliance reporting. ### Key Capabilities * **PII Detection**: a comprehensive set of entity types, including names, addresses, SSN, credit cards, emails, and phone numbers * **PHI Detection**: healthcare-specific entity types for HIPAA compliance * **Custom Entities**: Define organization-specific sensitive data patterns * **Real-time Processing**: Sub-second latency for production applications Connect to Fiddler and configure the Sensitive Information Guardrail API: ```python theme={null} import json import pandas as pd import requests import time import fiddler as fdl # Replace with your actual values URL = 'https://your_company.fiddler.ai' TOKEN = 'your_token_here' # API Configuration SENSITIVE_INFORMATION_URL = f"{URL}/v3/guardrails/sensitive-information" FIDDLER_HEADERS = { "Authorization": f"Bearer {TOKEN}", "Content-Type": "application/json", } # Connect to Fiddler fdl.init(url=URL, token=TOKEN) print("✅ Connected to Fiddler successfully!") ``` Create reusable functions for interacting with the API: ```python theme={null} def get_sensitive_information_response( text: str, entity_categories: str | list[str] = 'PII', custom_entities: list[str] = None, ): """ Detect sensitive information in text. Args: text: Input text to analyze entity_categories: 'PII', 'PHI', 'Custom Entities', or list custom_entities: Custom entity patterns (when using 'Custom Entities') Returns: Tuple of (API response dict, latency in seconds) """ data = {'input': text} # Add entity configuration if specified if entity_categories != 'PII' or custom_entities: data['entity_categories'] = entity_categories if custom_entities: data['custom_entities'] = custom_entities start_time = time.monotonic() try: response = requests.post( SENSITIVE_INFORMATION_URL, headers=FIDDLER_HEADERS, json={'data': data}, ) response.raise_for_status() return response.json(), (time.monotonic() - start_time) except requests.exceptions.RequestException as e: print(f'❌ API call failed: {e}') return {}, (time.monotonic() - start_time) def print_detection_results(response, latency): """Display detection results in a formatted way.""" entities = response.get('fdl_sensitive_information_scores', []) print(f"\n🔍 Detection Results (⏱️ {latency:.3f}s)") print(f"📊 Total Entities Found: {len(entities)}\n") if not entities: print("✅ No sensitive information detected.") return # Group by entity type by_type = {} for entity in entities: label = entity.get('label', 'unknown') if label not in by_type: by_type[label] = [] by_type[label].append(entity) # Display grouped results for label, group in sorted(by_type.items()): print(f"🏷️ {label.upper()} ({len(group)} found):") for entity in group: print(f" • '{entity['text']}' (confidence: {entity['score']:.3f})") print() ``` Detect common personally identifiable information: ```python theme={null} # Sample text with various PII types sample_text = """ I'm John Doe and I live at 1234 Maple Street, Springfield, IL 62704. You can reach me at john.doe@email.com or call me at (217) 555-1234. My social security number is 123-45-6789, and I was born on January 15, 1987. My credit card number is 4111 1111 1111 1111 with CVV 123. """ print("🧪 Testing PII Detection") print("📄 Input Text:") print(sample_text) # Call the API with default PII configuration response, latency = get_sensitive_information_response(sample_text) # Display results print_detection_results(response, latency) ``` **Expected Output:** ``` 🔍 Detection Results (⏱️ 0.125s) 📊 Total Entities Found: 8 🏷️ PERSON (1 found): • 'John Doe' (confidence: 0.987) 🏷️ ADDRESS (1 found): • '1234 Maple Street, Springfield, IL 62704' (confidence: 0.945) 🏷️ EMAIL (1 found): • 'john.doe@email.com' (confidence: 0.998) 🏷️ PHONE NUMBER (1 found): • '(217) 555-1234' (confidence: 0.976) 🏷️ SOCIAL SECURITY NUMBER (1 found): • '123-45-6789' (confidence: 0.991) 🏷️ CREDIT CARD NUMBER (1 found): • '4111 1111 1111 1111' (confidence: 0.989) 🏷️ CVV (1 found): • '123' (confidence: 0.892) 🏷️ DATE OF BIRTH (1 found): • 'January 15, 1987' (confidence: 0.923) ``` Detect protected health information in medical contexts: ```python theme={null} # Sample text with PHI information healthcare_text = """ Patient report: John Smith was prescribed metformin for his diabetes condition. His health insurance number is HI-987654321, and medical record shows serial number MED-2024-001 for his glucose monitor device. Birth certificate number is BC-IL-1987-001234. Current medication includes aspirin and lisinopril for blood pressure management. """ print("🏥 Testing PHI Detection for Healthcare Data") print("📄 Input Text:") print(healthcare_text) # Call the API with PHI configuration response, latency = get_sensitive_information_response( healthcare_text, entity_categories="PHI" ) # Display results print_detection_results(response, latency) ``` **Expected Output:** ``` 🔍 Detection Results (⏱️ 0.098s) 📊 Total Entities Found: 5 🏷️ PERSON (1 found): • 'John Smith' (confidence: 0.976) 🏷️ MEDICATION (3 found): • 'metformin' (confidence: 0.945) • 'aspirin' (confidence: 0.932) • 'lisinopril' (confidence: 0.928) 🏷️ HEALTH INSURANCE NUMBER (1 found): • 'HI-987654321' (confidence: 0.887) ``` Define and detect organization-specific sensitive data: ```python theme={null} # Sample text with custom entities custom_text = """ Employee ID: EMP-2024-001, Badge Number: BD-789456 Project code: PROJ-AI-2024, Server hostname: srv-prod-01 API key: sk-abc123xyz789 Internal ticket: TICK-2024-5678 """ # Define custom entities for your organization custom_entities = [ 'employee id', 'badge number', 'project code', 'api key', 'server hostname', 'ticket number' ] print("🎯 Testing Custom Entity Detection") print(f"🏷️ Custom entities: {custom_entities}") # Call the API with custom entity configuration response, latency = get_sensitive_information_response( custom_text, entity_categories='Custom Entities', custom_entities=custom_entities ) # Display results print_detection_results(response, latency) ``` **Expected Output:** ``` 🔍 Detection Results (⏱️ 0.112s) 📊 Total Entities Found: 6 🏷️ EMPLOYEE ID (1 found): • 'EMP-2024-001' (confidence: 0.923) 🏷️ BADGE NUMBER (1 found): • 'BD-789456' (confidence: 0.911) 🏷️ PROJECT CODE (1 found): • 'PROJ-AI-2024' (confidence: 0.897) 🏷️ API KEY (1 found): • 'sk-abc123xyz789' (confidence: 0.945) 🏷️ SERVER HOSTNAME (1 found): • 'srv-prod-01' (confidence: 0.878) 🏷️ TICKET NUMBER (1 found): • 'TICK-2024-5678' (confidence: 0.902) ``` ## API Reference ### Endpoint ``` POST /v3/guardrails/sensitive-information ``` ### Request Format ```json theme={null} { "data": { "input": "Text to analyze for sensitive information", "entity_categories": "PII" | "PHI" | "Custom Entities" | ["PII", "PHI"], "custom_entities": ["api key", "employee id", "custom pattern"] } } ``` ### Request Parameters | Parameter | Type | Description | Default | | ------------------- | --------------- | -------------------------------------------------------------- | -------- | | `input` | string | Text to analyze for sensitive information | Required | | `entity_categories` | string or array | Detection mode(s) to use | "PII" | | `custom_entities` | array | Custom entity patterns (required when using "Custom Entities") | None | ### Response Format ```json theme={null} { "fdl_sensitive_information_scores": [ { "score": 0.987, "label": "email", "start": 78, "end": 100, "text": "jane.smith@company.com" } ] } ``` ### Response Fields | Field | Type | Description | | ------- | ------- | -------------------------------------- | | `score` | float | Confidence score (0.0 to 1.0) | | `label` | string | Entity type identifier | | `start` | integer | Character position where entity starts | | `end` | integer | Character position where entity ends | | `text` | string | The detected entity text | ### Supported Entity Types #### PII Entities The Centor Model for PII/PHI returns labels as lowercase strings — use these exact values when filtering responses. * **Personal**: person, date of birth * **Contact**: email, email address, phone number, mobile phone number, landline phone number, fax number, address, postal code * **Financial**: credit card number, credit card expiration date, cvv, cvc, bank account number, account number, iban * **Government IDs**: social security number, passport number, driver's license number, tax identification number, license plate number, cpf, cnpj * **Digital**: ip address, digital signature, website #### PHI Entities * **Medical**: medication, medical condition * **Insurance**: health insurance number, health insurance id number, national health insurance number * **Identifiers**: birth certificate number, serial number ### Code Examples ```python theme={null} import requests url = "https://your_company.fiddler.ai/v3/guardrails/sensitive-information" headers = { "Authorization": "Bearer YOUR_TOKEN", "Content-Type": "application/json" } payload = { "data": { "input": "Contact John at john@email.com", "entity_categories": "PII" } } response = requests.post(url, json=payload, headers=headers) entities = response.json().get("fdl_sensitive_information_scores", []) for entity in entities: print(f"Found {entity['label']}: {entity['text']} (confidence: {entity['score']})") ``` ```python theme={null} def safe_detect_pii(text): """Detect PII with proper error handling.""" try: response = requests.post( SENSITIVE_INFORMATION_URL, headers=FIDDLER_HEADERS, json={'data': {'input': text}}, timeout=10 ) response.raise_for_status() return response.json() except requests.exceptions.Timeout: print("Request timed out. Try again or check your connection.") return None except requests.exceptions.HTTPError as e: if e.response.status_code == 401: print("Authentication failed. Check your API token.") elif e.response.status_code == 429: print("Rate limit exceeded. Wait before retrying.") else: print(f"HTTP error {e.response.status_code}: {e.response.text}") return None except Exception as e: print(f"Unexpected error: {e}") return None ``` ```bash theme={null} curl -X POST 'https://your_company.fiddler.ai/v3/guardrails/sensitive-information' -H 'Content-Type: application/json' -H 'Authorization: Bearer YOUR_TOKEN' -d '{ "data": { "input": "My SSN is 123-45-6789", "entity_categories": "PII" } }' ``` ## Next Steps After completing this quick start: * Explore other [Fiddler guardrails](/protection/guardrails-faq) for comprehensive AI safety * Review the complete [guardrails documentation](/getting-started/guardrails) for all available guardrail types * [Integrate guardrails into your applications ](/protection/guardrails)for production use ## Summary You've learned how to: * ✅ Detect a comprehensive set of PII entity types in text data * ✅ Identify PHI for healthcare compliance * ✅ Configure custom entities for your organization * ✅ Integrate the Fiddler Guardrails for PII/PHI API into your applications. Fiddler Guardrails for PII/PHI offer enterprise-grade protection for sensitive information with sub-second latency, making them ideal for real-time applications while ensuring compliance with privacy regulations such as GDPR, HIPAA, and CCPA. # Safety Source: https://docs.fiddler.ai/developers/tutorials/guardrails/guardrails-safety This Quick Start Notebook introduces Fiddler Guardrails' Safety Detection capabilities, an essential component of our enterprise solution for protecting LLM applications. This Quick Start Notebook introduces Fiddler Guardrails' Safety Detection capabilities, an essential component of our enterprise solution for protecting LLM applications. Learn how to implement the Safety Model, which identifies harmful, sensitive, or jailbreaking content in both inputs and outputs of your generative AI systems. Inside you'll find: * Step-by-step implementation instructions * Code examples for safety evaluation * Practical demonstration of harmful content detection * Sample inputs and outputs with risk score interpretation Before running the notebook, generate a Fiddler API key from **Settings → [Credentials](/reference/administration/settings#credentials)** in your Fiddler environment. See the [Guardrails documentation](/protection/guardrails) and [FAQ](/protection/guardrails-faq) for more help getting started. **Interactive Tutorial** Run the Safety Guardrail notebook end to end: [**Open the Safety Guardrail Notebook in Google Colab →**](https://colab.research.google.com/github/fiddler-labs/fiddler-examples/blob/main/quickstart/latest/Fiddler_Quickstart_Guardrails_Safety.ipynb) [**Or download the notebook from GitHub →**](https://github.com/fiddler-labs/fiddler-examples/blob/main/quickstart/latest/Fiddler_Quickstart_Guardrails_Safety.ipynb) # Secrets Source: https://docs.fiddler.ai/developers/tutorials/guardrails/guardrails-secrets Learn to detect credentials, API keys, and tokens in text using Fiddler's Centor Secret Detection guardrail to prevent secret leakage in LLM applications. Get your secret detection running in **minutes** with Fiddler's Centor Secret Detection Guardrail. This guide walks you through detecting API keys, credentials, and tokens to prevent sensitive secrets from leaking through your LLM applications. ## What You'll Build In this quick start, you'll implement a secret detection system that: * Detects \~42 known credential formats (Anthropic, OpenAI, AWS, GitHub, Slack, and more) * Catches unknown secrets using Shannon entropy analysis * Returns character-level spans so you can locate and redact secrets in your text * Provides real-time detection with sub-second latency ## Prerequisites * Fiddler account with [access token](/reference/administration/settings#credentials) * Python 3.10+ environment ## Overview Fiddler's Centor Secret Detection guardrail scans text for credentials before they reach your LLM or get logged, delivering deterministic, low-latency results with no GPU required. ### Key Capabilities * **Pattern-based detection**: \~42 known credential formats covering major providers and platforms * **Entropy analysis**: Catches high-entropy strings that match unknown or custom secret formats (labeled as `Possible Secret`) * **Character-level spans**: Returns `start` and `end` offsets for precise redaction * **Fast**: Sub-millisecond detection latency, CPU-only Configure the Secret Detection Guardrail API: ```python theme={null} import requests import time # Replace with your actual values URL = 'https://your_company.fiddler.ai' TOKEN = 'your_token_here' # API Configuration SECRET_DETECTION_URL = f"{URL}/v3/guardrails/secret-detection" FIDDLER_HEADERS = { "Authorization": f"Bearer {TOKEN}", "Content-Type": "application/json", } ``` Create reusable functions for interacting with the API: ```python theme={null} def detect_secrets(text: str): """ Detect secrets and credentials in text. Args: text: Input text to scan Returns: Tuple of (API response dict, latency in seconds) """ start_time = time.monotonic() try: response = requests.post( SECRET_DETECTION_URL, headers=FIDDLER_HEADERS, json={"data": {"input": text}}, ) response.raise_for_status() return response.json(), (time.monotonic() - start_time) except requests.exceptions.RequestException as e: print(f"❌ API call failed: {e}") return {}, (time.monotonic() - start_time) def print_detection_results(response, latency): """Display detection results in a formatted way.""" secrets = response.get("fdl_secret_detection_scores", []) print(f"\n🔍 Detection Results (⏱️ {latency:.3f}s)") print(f"📊 Total Secrets Found: {len(secrets)}\n") if not secrets: print("✅ No secrets detected.") return for secret in secrets: print(f"🔑 {secret['label']}") print(f" Position: {secret['start']}–{secret['end']}") print() def redact_secrets(text: str, secrets: list) -> str: """Apply redactions right-to-left to preserve offsets.""" for secret in sorted(secrets, key=lambda s: s["start"], reverse=True): label = secret["label"].upper().replace(" ", "_") text = text[: secret["start"]] + f"[REDACTED {label}]" + text[secret["end"] :] return text ``` Detect common API keys and credentials: ```python theme={null} sample_text = """ Setting up the integration. My Anthropic key is sk-ant-api03-abcdefghijklmnopqrstu and the OpenAI key is sk-proj-ABCDEFGHIJKLMNOPQRSTUVWXYZabcde. GitHub token: ghp_ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890 """ print("🧪 Testing API Key Detection") response, latency = detect_secrets(sample_text) print_detection_results(response, latency) # Redact detected secrets secrets = response.get("fdl_secret_detection_scores", []) redacted = redact_secrets(sample_text, secrets) print("📝 Redacted text:") print(redacted) ``` **Expected Output:** ``` 🔍 Detection Results (⏱️ 0.008s) 📊 Total Secrets Found: 3 🔑 Anthropic API Key 🔑 OpenAI Project Key 🔑 GitHub Personal Access Token 📝 Redacted text: Setting up the integration. My Anthropic key is [REDACTED ANTHROPIC_API_KEY] and the OpenAI key is [REDACTED OPENAI_PROJECT_KEY]. GitHub token: [REDACTED GITHUB_PERSONAL_ACCESS_TOKEN] ``` > Exact character positions (`start`/`end`) vary by input and are returned by the API. The redaction helper uses API-returned offsets, not hardcoded values. Detect AWS access keys and other infrastructure secrets: ```python theme={null} infra_text = """ AWS credentials for the prod account: Access Key ID: AKIAIOSFODNN7EXAMPLE Slack webhook: https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX HashiCorp Vault token: hvs.CAESIJlU9eFfaBcDeFgHiJkLmNoPqRsTuVwXyZ01234567890123 """ print("☁️ Testing Infrastructure Secret Detection") response, latency = detect_secrets(infra_text) print_detection_results(response, latency) ``` **Expected Output:** ``` 🔍 Detection Results (⏱️ 0.006s) 📊 Total Secrets Found: 3 🔑 AWS Access Key ID 🔑 Slack Webhook URL 🔑 HashiCorp Vault Token ``` ## API Reference ### Endpoint ``` POST /v3/guardrails/secret-detection ``` ### Request Format ```json theme={null} { "data": { "input": "Text to scan for secrets and credentials" } } ``` ### Request Parameters | Parameter | Type | Description | Default | | --------- | ------ | ------------------------ | -------- | | `input` | string | Text to scan for secrets | Required | ### Response Format ```json theme={null} { "fdl_secret_detection_scores": [ { "label": "Anthropic API Key", "start": 10, "end": 44 } ] } ``` ### Response Fields | Field | Type | Description | | ------- | ------- | ---------------------------------------- | | `label` | string | Secret type (e.g. `"Anthropic API Key"`) | | `start` | integer | Character position where secret starts | | `end` | integer | Character position where secret ends | ### Detected Secret Types #### LLM Provider Keys `Anthropic API Key`, `OpenAI Project Key`, `OpenAI/Stripe Secret Key`, `Hugging Face Token`, `Replicate API Token` #### Cloud Platforms `AWS Access Key ID`, `AWS Secret Access Key`, `Google API Key`, `Google OAuth Client Secret`, `Azure Credential`, `DigitalOcean PAT`, `DigitalOcean OAuth Token`, `Heroku API Key`, `Datadog API Key` #### Source Control `GitHub Fine-grained PAT`, `GitHub Personal Access Token`, `GitHub OAuth Token`, `GitHub Server Token`, `GitLab Personal Access Token`, `GitLab Pipeline Token`, `Bitbucket App Password` #### Package Registries `npm Access Token`, `PyPI API Token`, `NuGet API Key` #### Communication & Messaging `Slack Bot Token`, `Slack User Token`, `Slack App Token`, `Slack Webhook URL`, `Discord Bot Token`, `SendGrid API Key`, `Twilio Account SID`, `Mailgun API Key` #### Developer Tools `Postman API Key`, `HashiCorp Vault Token`, `Terraform Cloud Token`, `Supabase Token`, `Vercel Token` #### Generic Formats `JWT Token`, `HTTP Basic Auth`, `HTTP Bearer Token`, `PEM Private Key`, `Database Connection String` #### Entropy-based Detection High-entropy alphanumeric, hex, and base64 strings that don't match a known prefix pattern but exceed entropy thresholds. These are labeled as `Possible Secret`. ### Code Examples ```python theme={null} import requests url = "https://your_company.fiddler.ai/v3/guardrails/secret-detection" headers = { "Authorization": "Bearer YOUR_TOKEN", "Content-Type": "application/json" } payload = { "data": { "input": "My key is sk-ant-api03-abcdefghijklmnopqrstu" } } response = requests.post(url, json=payload, headers=headers) secrets = response.json().get("fdl_secret_detection_scores", []) for secret in secrets: print(f"Found {secret['label']} at positions {secret['start']}–{secret['end']}") ``` ```bash theme={null} curl -X POST 'https://your_company.fiddler.ai/v3/guardrails/secret-detection' \ -H 'Content-Type: application/json' \ -H 'Authorization: Bearer YOUR_TOKEN' \ -d '{ "data": { "input": "My key is sk-ant-api03-abcdefghijklmnopqrstu" } }' ``` ## Next Steps * Use the [LiteLLM Guardrails](/protection/litellm-guardrails) integration to automatically block or redact secrets in real-time LLM proxy traffic * Explore other [Fiddler guardrails](/protection/guardrails) for comprehensive AI safety * Review the [Secret Detection Evaluator](/sdk-api/evals/ftl-secret-detection) for use with the Fiddler Evals SDK ## Summary You've learned how to: * ✅ Detect \~42 known credential formats using pattern matching * ✅ Catch unknown high-entropy secrets using entropy analysis * ✅ Locate secrets precisely using character-level `start`/`end` spans * ✅ Redact secrets from text before forwarding to an LLM # Agentic & LLM Monitoring Source: https://docs.fiddler.ai/developers/tutorials/llm-monitoring * [LangGraph SDK Advanced](/developers/tutorials/llm-monitoring/langgraph-sdk-advanced): Advanced observability patterns for LangGraph applications including multi-agent workflows, conversation tracking, and production configuration. # LangGraph SDK Advanced Source: https://docs.fiddler.ai/developers/tutorials/llm-monitoring/langgraph-sdk-advanced Advanced observability patterns for LangGraph applications including multi-agent workflows, conversation tracking, and production configuration. ## What You'll Learn This interactive notebook demonstrates advanced monitoring patterns for production LangGraph applications through a realistic travel planning system with multiple specialized agents. **Key Topics Covered:** * Multi-agent workflow monitoring and orchestration * Custom instrumentation with decorators and span wrappers * Combining auto-instrumentation with fine-grained manual spans * Conversation tracking across complex interactions * Production configuration for high-volume scenarios * Advanced error handling and recovery patterns * Business intelligence integration and analytics ## Interactive Tutorial The notebook walks through building a comprehensive travel planning application featuring hotel search, weather analysis, itinerary planning, and supervisor agents working together. [**Open the Advanced Observability Notebook in Google Colab →**](https://colab.research.google.com/github/fiddler-labs/fiddler-examples/blob/main/quickstart/latest/Fiddler_Quickstart_LangGraph_Advanced_Observability.ipynb) [**Or download the notebook directly from GitHub →**](https://github.com/fiddler-labs/fiddler-examples/blob/main/quickstart/latest/Fiddler_Quickstart_LangGraph_Advanced_Observability.ipynb) ### Custom Instrumentation Tutorial For hands-on examples of decorator-based and manual instrumentation, including `@trace()`, span wrappers, and async support: [**Open the Custom Instrumentation Notebook in Google Colab →**](https://colab.research.google.com/github/fiddler-labs/fiddler-examples/blob/main/quickstart/latest/Fiddler_Quickstart_LangGraph_Custom_Instrumentation.ipynb) [**Or download the notebook directly from GitHub →**](https://github.com/fiddler-labs/fiddler-examples/blob/main/quickstart/latest/Fiddler_Quickstart_LangGraph_Custom_Instrumentation.ipynb) ## Custom Instrumentation Patterns The SDK supports three instrumentation approaches. You can use them individually or combine them in the same application. For complete API reference, see the [Instrumentation Methods](/integrations/agentic-ai/langgraph-sdk#instrumentation-methods) section in the integration guide. ### Combining Auto-Instrumentation with Decorators Use `LangGraphInstrumentor` for automatic LangGraph/LangChain tracing, then add `@trace()` decorators to capture custom business logic that runs outside the framework: ```python theme={null} from fiddler_langgraph import FiddlerClient, LangGraphInstrumentor, trace, get_current_span client = FiddlerClient( application_id="your-app-id", api_key="your-api-key", url="https://your-instance.fiddler.ai" ) # Auto-instrument LangGraph nodes instrumentor = LangGraphInstrumentor(client) instrumentor.instrument() # Add custom tracing to business logic outside LangGraph @trace(name="validate_input", as_type="chain") def validate_user_input(user_message: str) -> dict: span = get_current_span(as_type="chain") if span: span.set_input(user_message) result = {"valid": True, "sanitized": user_message.strip()} if span: span.set_output(result) return result # Both auto-instrumented LangGraph spans and custom spans # appear together in Fiddler's trace view validated = validate_user_input(user_message) result = agent.invoke({"messages": [{"role": "user", "content": validated["sanitized"]}]}) ``` ### Multi-Agent Decorator Patterns When building multi-agent systems, `@trace()` decorators automatically establish parent-child span relationships through nested function calls: ```python theme={null} import asyncio from fiddler_langgraph import trace, get_current_span @trace(name="supervisor", as_type="chain") async def supervisor_agent(state: dict) -> dict: """Top-level orchestrator — creates parent span.""" span = get_current_span(as_type="chain") if span: span.set_attribute("agent_count", len(state.get("tasks", []))) # Child spans nest automatically under the supervisor span results = await asyncio.gather( research_agent(state), analysis_agent(state), ) if span: span.set_output({"completed": len(results)}) return {"results": results} @trace(name="research_agent", as_type="chain") async def research_agent(state: dict) -> dict: """Child span nested under supervisor.""" span = get_current_span(as_type="chain") if span: span.set_attribute("data_sources", 3) # ... research logic ... return {"findings": "..."} @trace(name="analysis_agent", as_type="chain") async def analysis_agent(state: dict) -> dict: """Child span nested under supervisor.""" span = get_current_span(as_type="chain") if span: span.set_attribute("analysis_type", "comparative") # ... analysis logic ... return {"analysis": "..."} ``` ### Using Span Wrappers for Typed Attributes Span wrapper classes provide typed helper methods for setting semantic attributes on LLM calls, tool invocations, and chain operations. Use them with `start_as_current_span()` for fine-grained control: ```python theme={null} from fiddler_langgraph import FiddlerClient client = FiddlerClient( application_id="your-app-id", api_key="your-api-key", url="https://your-instance.fiddler.ai" ) # as_type="generation" returns a FiddlerGeneration wrapper with LLM-specific helper methods with client.start_as_current_span("llm_call", as_type="generation") as gen: gen.set_model("gpt-4o") gen.set_system_prompt("You are a travel planning assistant.") gen.set_user_prompt(user_input) response = call_llm(user_input) gen.set_completion(response.content) gen.set_usage(response.usage.prompt_tokens, response.usage.completion_tokens) # as_type="tool" returns a FiddlerTool wrapper with tool-specific helper methods with client.start_as_current_span("search_hotels", as_type="tool") as tool: tool.set_tool_name("hotel_search") tool.set_tool_input({"city": "Paris", "dates": "2026-03-01"}) results = search_hotels("Paris", "2026-03-01") tool.set_tool_output(results) ``` For the complete list of helper methods on each span wrapper class, see the [Span Types and Helper Methods](/integrations/agentic-ai/langgraph-sdk#span-types-and-helper-methods) reference. ## Production Configuration Best Practices Before deploying LangGraph applications to production, configure the SDK for your specific workload characteristics. ### High-Volume Applications Optimize for applications processing thousands of traces per minute: ```python theme={null} import os from opentelemetry.sdk.trace import SpanLimits, sampling from opentelemetry.exporter.otlp.proto.http.trace_exporter import Compression from fiddler_langgraph import FiddlerClient # Configure batch processing BEFORE initializing FiddlerClient os.environ['OTEL_BSP_MAX_QUEUE_SIZE'] = '500' # Increased from default 100 os.environ['OTEL_BSP_SCHEDULE_DELAY_MILLIS'] = '500' # Faster export than default 1000ms os.environ['OTEL_BSP_MAX_EXPORT_BATCH_SIZE'] = '50' # Larger batches than default 10 os.environ['OTEL_BSP_EXPORT_TIMEOUT'] = '10000' # Longer timeout than default 5000ms # Increase span limits to capture more data production_limits = SpanLimits( max_events=128, # Default: 32 max_links=64, # Default: 32 max_span_attributes=128, # Default: 32 max_event_attributes=64, # Default: 32 max_link_attributes=32, # Default: 32 max_span_attribute_length=8192, # Default: 2048 ) # Sample 5-10% of traces to manage data volume production_sampler = sampling.TraceIdRatioBased(0.05) client = FiddlerClient( application_id=os.getenv("FIDDLER_APPLICATION_ID"), api_key=os.getenv("FIDDLER_API_KEY"), url=os.getenv("FIDDLER_URL"), span_limits=production_limits, sampler=production_sampler, compression=Compression.Gzip, ) ``` ### Low-Latency Requirements Optimize for applications requiring sub-second trace export: ```python theme={null} import os from opentelemetry.exporter.otlp.proto.http.trace_exporter import Compression from fiddler_langgraph import FiddlerClient # Reduce batch delay for faster exports os.environ['OTEL_BSP_SCHEDULE_DELAY_MILLIS'] = '100' # Export every 100ms os.environ['OTEL_BSP_MAX_EXPORT_BATCH_SIZE'] = '5' # Smaller batches client = FiddlerClient( application_id=os.getenv("FIDDLER_APPLICATION_ID"), api_key=os.getenv("FIDDLER_API_KEY"), url=os.getenv("FIDDLER_URL"), compression=Compression.Gzip, # Still use compression ) ``` ### Memory-Constrained Environments Configure conservative limits for edge deployments or containerized environments: ```python theme={null} import os from opentelemetry.sdk.trace import SpanLimits, sampling from opentelemetry.exporter.otlp.proto.http.trace_exporter import Compression from fiddler_langgraph import FiddlerClient memory_constrained_limits = SpanLimits( max_events=16, # Minimal event capture max_links=16, # Minimal linking max_span_attributes=32, # Reduced attributes max_event_attributes=16, # Reduced event attributes max_link_attributes=16, # Reduced link attributes max_span_attribute_length=1024, # Shorter attribute values ) os.environ['OTEL_BSP_MAX_QUEUE_SIZE'] = '50' # Smaller queue os.environ['OTEL_BSP_MAX_EXPORT_BATCH_SIZE'] = '5' # Smaller batches client = FiddlerClient( application_id=os.getenv("FIDDLER_APPLICATION_ID"), api_key=os.getenv("FIDDLER_API_KEY"), url=os.getenv("FIDDLER_URL"), span_limits=memory_constrained_limits, sampler=sampling.TraceIdRatioBased(0.1), # Sample 10% compression=Compression.Gzip, ) ``` ### Development vs Production Configurations **Development Configuration:** ```python theme={null} import os from fiddler_langgraph import FiddlerClient # Capture everything with verbose debugging # console_tracer=True prints spans to stdout AND continues to export to Fiddler (additive) dev_client = FiddlerClient( application_id=os.getenv("FIDDLER_APPLICATION_ID"), api_key=os.getenv("FIDDLER_API_KEY"), url=os.getenv("FIDDLER_URL"), console_tracer=True, # Also prints spans to console; does NOT disable OTLP export sampler=None, # Capture 100% of traces ) ``` **Production Configuration:** ```python theme={null} import os from opentelemetry.sdk.trace import SpanLimits, sampling from opentelemetry.exporter.otlp.proto.http.trace_exporter import Compression from fiddler_langgraph import FiddlerClient # Define production limits (see High-Volume Applications above for full example) production_limits = SpanLimits( max_events=128, max_span_attributes=128, max_span_attribute_length=8192 ) # Optimized for performance and cost prod_client = FiddlerClient( application_id=os.getenv("FIDDLER_APPLICATION_ID"), api_key=os.getenv("FIDDLER_API_KEY"), url=os.getenv("FIDDLER_URL"), sampler=sampling.TraceIdRatioBased(0.05), # Sample 5% compression=Compression.Gzip, # Reduce bandwidth span_limits=production_limits, # Controlled limits ) ``` ### Best Practices for Context and Conversation IDs Structure your identifiers for maximum analytical value: ```python theme={null} from fiddler_langgraph import set_llm_context, set_conversation_id import uuid # Set meaningful, searchable context labels set_llm_context(model, 'Customer Support - Tier 1 - Billing Inquiries') set_llm_context(model, 'Content Generation - Marketing Copy - Blog Posts') set_llm_context(model, 'Data Analysis - Financial Reports - Q4 2025') # Use structured conversation IDs with metadata user_id = 'user-12345' session_type = 'support' timestamp = '2026-06-15' conversation_id = f'{user_id}_{session_type}_{timestamp}_{uuid.uuid4()}' set_conversation_id(conversation_id) # Example: user-12345_support_2026-06-15_550e8400-e29b-41d4-a716-446655440000 ``` ### Prerequisites * Fiddler account with API credentials * OpenAI API key for example interactions * Basic familiarity with LangGraph concepts ### Time Required * **Complete tutorial**: 45-60 minutes * **Quick overview**: 15-20 minutes ## Telemetry Data Reference Understanding the data captured by the Fiddler LangGraph SDK. ### Span Attributes The SDK automatically captures these OpenTelemetry attributes: | Attribute | Type | Description | | ------------------------- | ------- | -------------------------------------------------------------------------------- | | `gen_ai.agent.name` | `str` | Name of the AI agent (auto-extracted from LangGraph, configurable for LangChain) | | `gen_ai.agent.id` | `str` | Unique identifier (format: `trace_id:agent_name`) | | `gen_ai.conversation.id` | `str` | Session identifier set via `set_conversation_id()` | | `fiddler.span.type` | `str` | Span classification: `chain`, `tool`, `llm`, or `agent` | | `gen_ai.llm.input.system` | `str` | System prompt content | | `gen_ai.llm.input.user` | `str` | User input/prompt | | `gen_ai.llm.output` | `str` | Model response text | | `gen_ai.llm.context` | `str` | Custom context set via `set_llm_context()` | | `gen_ai.request.model` | `str` | Model identifier (e.g., "gpt-4o-mini") | | `gen_ai.llm.token_count` | `int` | Token usage metrics | | `gen_ai.tool.name` | `str` | Tool function name | | `gen_ai.tool.input` | `str` | Tool input parameters (JSON) | | `gen_ai.tool.output` | `str` | Tool execution results (JSON) | | `gen_ai.tool.definitions` | `str` | Tool definitions available to the LLM (JSON array of OpenAI-format tool schemas) | | `gen_ai.input.messages` | `str` | Complete message history provided as input to the LLM (JSON array) | | `gen_ai.output.messages` | `str` | Output messages generated by the LLM, including tool calls (JSON array) | | `duration_ms` | `float` | Span duration in milliseconds | | `fiddler.error.message` | `str` | Error message (if span failed) | | `fiddler.error.type` | `str` | Error type classification | ### Setting Attributes with Span Wrappers When using [manual instrumentation](/integrations/agentic-ai/langgraph-sdk#manual-instrumentation), span wrapper classes provide typed helper methods that set these attributes automatically. For example, `FiddlerGeneration.set_model("gpt-4o")` sets `gen_ai.request.model`, and `FiddlerTool.set_tool_name("search")` sets `gen_ai.tool.name`. | Span Wrapper | Key Methods | Attributes Set | | ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `FiddlerGeneration` | `set_model()`, `set_system_prompt()`, `set_user_prompt()`, `set_completion()`, `set_usage()`, `set_messages()`, `set_output_messages()`, `set_tool_definitions()` | `gen_ai.request.model`, `gen_ai.llm.input.*`, `gen_ai.llm.output`, `gen_ai.usage.*`, `gen_ai.input.messages`, `gen_ai.output.messages`, `gen_ai.tool.definitions` | | `FiddlerTool` | `set_tool_name()`, `set_tool_input()`, `set_tool_output()`, `set_tool_definitions()` | `gen_ai.tool.name`, `gen_ai.tool.input`, `gen_ai.tool.output`, `gen_ai.tool.definitions` | | `FiddlerChain` | `set_input()`, `set_output()` | Input/output data attributes | | `FiddlerSpan` | `set_attribute()`, `set_agent_name()`, `set_conversation_id()` | Any custom or standard attribute | For the complete method reference, see [Span Types and Helper Methods](/integrations/agentic-ai/langgraph-sdk#span-types-and-helper-methods). ### Querying and Filtering in Fiddler Use these attributes in the Fiddler UI to: * **Filter by agent:** `gen_ai.agent.name = "hotel_search_agent"` * **Find conversations:** `gen_ai.conversation.id = "user-123_support_2026-06-15..."` * **Analyze by model:** `gen_ai.request.model = "gpt-4o"` * **Track errors:** `fiddler.error.type EXISTS` ## Who Should Use This * AI engineers building production LangGraph applications * DevOps teams monitoring agentic systems * Technical leaders evaluating observability strategies ## Limitations and Considerations ### Current Limitations * **Framework Support**: LangGraph is fully supported with automatic agent name extraction * LangChain applications require manual agent name configuration * Non-LangGraph Python code can use `@trace()` decorators or manual context managers for custom instrumentation (see [Instrumentation Methods](/integrations/agentic-ai/langgraph-sdk#instrumentation-methods)) * **Protocol Support**: Currently uses HTTP-based OTLP * gRPC support planned for future releases * **Attribute Limits**: Default OpenTelemetry limits apply * Configurable via `span_limits` parameter * Very large attribute values may be truncated ### Performance Considerations **Overhead**: Typical performance impact is \< 5% with default settings * Use sampling to reduce overhead in high-volume scenarios * Adjust batch processing delays based on latency requirements **Memory**: Span queue size affects the memory footprint * Default queue (100 spans) uses \~1-2MB * Increase `OTEL_BSP_MAX_QUEUE_SIZE` for high throughput * Decrease for memory-constrained environments **Network**: Compression significantly reduces bandwidth usage * Gzip compression: \~70-80% reduction * Use `Compression.NoCompression` only for debugging ### Production Deployment Checklist Before deploying to production: * [ ] Set appropriate sampling rate (typically 5-10% for high-volume apps) * [ ] Configure span limits based on your data characteristics * [ ] Tune batch processing parameters for your traffic patterns * [ ] Enable Gzip compression (default, recommended) * [ ] Use environment variables for credentials (not hardcoded) * [ ] Test instrumentation in staging environment first * [ ] Monitor SDK performance impact * [ ] Set up alerts for instrumentation failures * [ ] Document your configuration for team knowledge sharing ### When to Tune Each Setting | Scenario | Configuration | | ---------------------------- | ----------------------------------------------- | | **High-volume production** | Increase queue size, batch size, sampling rate | | **Low-latency requirements** | Decrease schedule delay, smaller batches | | **Memory constraints** | Decrease span limits, queue size, batch size | | **Development/debugging** | Disable sampling, enable console tracer | | **Cost optimization** | Increase sampling (lower %), enable compression | ## Next Steps After completing the tutorial: * **Custom Instrumentation Notebook**: [Hands-on decorator and span wrapper examples](https://colab.research.google.com/github/fiddler-labs/fiddler-examples/blob/main/quickstart/latest/Fiddler_Quickstart_LangGraph_Custom_Instrumentation.ipynb) * **Integration Guide**: [Instrumentation Methods reference](/integrations/agentic-ai/langgraph-sdk#instrumentation-methods) for `@trace()`, manual instrumentation, and span wrapper APIs * **Technical Reference**: [Fiddler LangGraph SDK Documentation](/sdk-api/langgraph/fiddler-client) * **Production Deployment**: Adapt the demonstrated patterns for your specific use case # Advanced Prompt Specs Source: https://docs.fiddler.ai/developers/tutorials/llm-monitoring/prompt-specs-advanced Advanced guide to Fiddler's LLM-as-a-Judge capabilities, including custom prompting, model selection, performance optimization, and enterprise deployment patterns. This comprehensive guide covers advanced LLM-as-a-Judge capabilities using Prompt Specs for **LLM Observability (Traditional Monitoring)**. It includes custom prompting, model configuration, performance optimization, and enterprise deployment patterns. **For Agentic Monitoring and Experiments**, use the `CustomJudge` class from the Fiddler Evals SDK instead of Prompt Specs. `CustomJudge` provides `prompt_template` (Jinja syntax) and `output_fields` for structured evaluation. See the [Custom Judge Evaluators Cookbook](/developers/cookbooks/custom-judge-evaluators) for examples. ### Prerequisites * Understanding of [Prompt Specs fundamentals](/observability/llm/llm-evaluation-prompt-specs) * Completion of the [LLM Evaluation Quickstart](/evaluate-and-test/prompt-specs-quick-start) * Familiarity with LLM evaluation concepts > Download this tutorial directly from [GitHub](https://github.com/fiddler-labs/fiddler-examples/blob/main/quickstart/latest/Fiddler_Quickstart_LLMaaJ_Prompt_Spec.ipynb) or run it in [Google Colab](https://colab.research.google.com/github/fiddler-labs/fiddler-examples/blob/main/quickstart/latest/Fiddler_Quickstart_LLMaaJ_Prompt_Spec.ipynb) ```python theme={null} import json import pandas as pd import requests FIDDLER_BASE_URL = "https://your_company.fiddler.ai" PROMPT_SPEC_URL = f"{FIDDLER_BASE_URL}/v3/llm-as-a-judge/prompt-spec" FIDDLER_HEADERS = { "Authorization": f"Bearer {FIDDLER_TOKEN}", "Content-Type": "application/json", } ``` We'll use news article data for this example: ```python theme={null} # Load sample news data (using AG News dataset) df_news = pd.read_parquet( "hf://datasets/fancyzhx/ag_news/data/test-00000-of-00001.parquet" ).sample(20, random_state=25) # Map labels to topic names df_news["original_topic"] = df_news["label"].map({ 0: "World", 1: "Sports", 2: "Business", 3: "Sci/Tech" }) # Summarize the count of each unique topic print(df_news["original_topic"].value_counts()) ``` Define a simple evaluation schema: ```python theme={null} basic_prompt_spec = { "input_fields": { "news_summary": {"type": "string"} }, "output_fields": { "topic": { "type": "string", "choices": ["World", "Sports", "Business", "Sci/Tech"] }, "reasoning": {"type": "string"} } } ``` Validate your Prompt Spec schema: ```python theme={null} validate_response = requests.post( f"{PROMPT_SPEC_URL}/validate", headers=FIDDLER_HEADERS, json={"prompt_spec": prompt_spec_basic}, ) validate_response.raise_for_status() print("Status Code:", validate_response.status_code) print(json.dumps(validate_response.json(), indent=2)) ``` Test with a larger set of data: ```python theme={null} def get_prediction(prompt_spec, input_data): predict_response = requests.post( f"{PROMPT_SPEC_URL}/predict", headers=FIDDLER_HEADERS, json={"prompt_spec": prompt_spec, "input_data": input_data}, ) if predict_response.status_code != 200: print(f"Error ({predict_response.status_code}): {predict_response.text}") return {"topic": None, "reasoning": None} return predict_response.json()["prediction"] print( json.dumps( get_prediction( prompt_spec_basic, {"news_summary": "Wimbledon 2025 is under way!"} ), indent=2, ) ) ``` Evaluate a batch of data: ```python theme={null} df_ag_news[["topic", "reasoning"]] = df_ag_news.apply( lambda row: get_prediction(prompt_spec_basic, {"news_summary": row["text"]}), axis=1, result_type="expand", ) ``` Note several `Sci/Tech` articles were misclassified as `World`. The `reasoning` field helps identify trends. We'll use this to update our prompt spec in the next section. ```python theme={null} accuracy = (df_ag_news["original_topic"] == df_ag_news["topic"]).mean() print(f"Accuracy: {accuracy:.0%}") df_ag_news.value_counts(subset=["original_topic", "topic"]) for r in df_ag_news[ (df_ag_news["original_topic"] == "Sci/Tech") & (df_ag_news["topic"] != "Sci/Tech") ]["reasoning"]: print(r) ``` Just as descriptive field names can help improve model performance, you can also add a task instruction and field descriptions. Here, we will add a description to `topic` to help with classifying `Sci/Tech` articles. Note the improved results. ```python theme={null} prompt_spec_rich = { "instruction": "Determine the topic of the given news summary.", "input_fields": { "news_summary": { "type": "string", } }, "output_fields": { "topic": { "type": "string", "choices": df_ag_news["original_topic"].unique().tolist(), "description": """Use topic 'Sci/Tech' if the news summary is about a company or business in the tech industry, or if the news summary is about a scientific discovery or research, including health and medicine. Use topic 'Sports' if the news summary is about a sports event or athlete. Use topic 'Business' if the news summary is about a company or industry outside of science, technology, or sports. Use topic 'World' if the news summary is about a global event or issue. """, }, "reasoning": { "type": "string", "description": "The reasoning behind the predicted topic.", }, }, } print( json.dumps( get_prediction(prompt_spec_rich, {"news_summary": df_ag_news.loc[267, "text"]}), indent=2, ) ) ``` Note the improvement of accuracy in the results: ```python theme={null} df_ag_news[["topic", "reasoning"]] = df_ag_news.apply( lambda row: get_prediction(prompt_spec_rich, {"news_summary": row["text"]}), axis=1, result_type="expand", ) accuracy = (df_ag_news["original_topic"] == df_ag_news["topic"]).mean() print(f"Accuracy: {accuracy:.0%}") df_ag_news.value_counts(subset=["original_topic", "topic"]) ``` ### Deploying Your Evaluation to Production Once you see the results you expect with your test data, deploy the custom evaluation to production and monitor your production application: ```python theme={null} from datetime import datetime import fiddler as fdl fdl.init(url=FIDDLER_BASE_URL, token=FIDDLER_TOKEN) PROJECT_NAME = "quickstart_examples" # If the project already exists, the notebook will create the model under the existing project. MODEL_NAME = "fiddler_news_classifier" project = fdl.Project.get_or_create(name=PROJECT_NAME) ``` Recall we used `news_summary` in our prompt. Let's make our dataframe match this and add some metadata. ```python theme={null} platform_df = df_ag_news.rename(columns={"text": "news_summary"}) platform_df["id"] = platform_df.index ``` * `name` will be used as part of the generated column name; set it to something meaningful for your use case. * `enrichment` must always be `llm_as_a_judge`. * `columns` matches all the input columns your prompt spec uses. * `config` must set the prompt spec. Then define the remainder of the schema that makes up this application to be monitored. For more details on setting up Fiddler to monitor your ML models and LLM/GenAI applications, refer to the [ML Monitoring Quick Start](/developers/quick-starts/simple-ml-monitoring) and the [LLM Monitoring Quick Start](/developers/quick-starts/simple-llm-monitoring) guides. ```python theme={null} fiddler_llm_enrichments = [ fdl.Enrichment( name="news_topic", enrichment="llm_as_a_judge", columns=["news_summary"], config={"prompt_spec": prompt_spec_rich}, ) ] model_spec = fdl.ModelSpec( inputs=["news_summary"], metadata=["id", "original_topic"], custom_features=fiddler_llm_enrichments, ) llm_application = fdl.Model.from_data( source=platform_df, name=MODEL_NAME, project_id=project.id, spec=model_spec, task=fdl.ModelTask.LLM, max_cardinality=5, ) llm_application.create() ``` Our prediction will add two columns: `FDL news_topic (topic)` and `FDL news_topic (reasoning)`. > **Note**: The column names follow the pattern: `FDL {enrichment name} ({prompt spec output column})`, using values as specified. ```python theme={null} production_publish_job = llm_application.publish(platform_df) # wait for the job to complete production_publish_job.wait(interval=20) ``` ```python theme={null} llm_application.download_data( output_dir="test_download", env_type=fdl.EnvType.PRODUCTION, start_time=start_time, end_time=datetime.now(), columns=[ "id", "news_summary", "original_topic", "FDL news_topic (topic)", "FDL news_topic (reasoning)", ], ) # See the original data and the results of LLM-as-a-Judge fdl_data = pd.read_parquet("test_download/output.parquet") fdl_data.sample(15) ``` ### Advanced Prompt Specs Configuration #### Schema Design Patterns #### Multi-Output Evaluation **Domain-Specific Classification** #### Performance Optimization Techniques **Field Description Best Practices** * **Be Specific**: Use concrete examples rather than abstract descriptions * **Avoid Ambiguity**: Define edge cases and boundary conditions * **Include Context**: Reference domain-specific knowledge when needed ### Bring-Your-Own-Prompt For maximum customization, Fiddler supports custom prompt templates with multiple output format options. #### Free-Form Output Best for open-ended evaluations where structure is less important: ```json theme={null} { "prompt_template": { "user": "Analyze the following text for potential bias: {text}. Provide detailed analysis." }, "output_fields": ["analysis"], "output_format": { "type": "free_form" } } ``` #### Guided Choice Output For single categorical outputs with high accuracy requirements: ```json theme={null} { "prompt_template": { "system": "You are an expert content moderator.", "user": "Classify this content: {content}. Choose the most appropriate category." }, "output_fields": ["classification"], "output_format": { "type": "guided_choice", "choices": ["safe", "questionable", "harmful", "requires_review"] } } ``` #### Guided JSON Output For complex structured outputs with validation: ```json theme={null} { "prompt_template": { "system": "Extract structured information from job postings.", "user": "Extract key details from: {job_posting}" }, "output_fields": ["title", "company", "salary_range", "remote_work"], "output_format": { "type": "guided_json", "schema": { "type": "object", "properties": { "title": { "type": "string" }, "company": { "type": "string" }, "salary_range": { "type": "string" }, "remote_work": { "type": "boolean" } }, "required": ["title", "company"] } } } ``` ### Additional Documentation * [LLM Observability Overview](/observability/llm): Understanding Fiddler's broader LLM monitoring capabilities * [Enrichments](/observability/llm/enrichments): Technical details on Fiddler's evaluation infrastructure # ML Monitoring Source: https://docs.fiddler.ai/developers/tutorials/ml-monitoring * [NLP Inputs](/developers/tutorials/ml-monitoring/simple-nlp-monitoring-quick-start): Dive into our guide on using Fiddler to monitor NLP models. Learn how a multi-class classifier is applied to the dataset and monitored with Vector Monitoring. * [Class Imbalance](/developers/tutorials/ml-monitoring/class-imbalance-monitoring-example): Discover how Fiddler uses class weighting to address class imbalance. Compare two identical models–with and without weighting–to detect drift signals. * [Model Versions](/developers/tutorials/ml-monitoring/ml-monitoring-model-versions): Explore our guide to using Fiddler’s sample data to set up and manage multiple versions of a model with the powerful Model Versions feature. * [Ranking Models](/developers/tutorials/ml-monitoring/ranking-model): Explore our notebook to see how Fiddler monitors ranking models using a public dataset organized around “search result impressions” from Expedia hotel searches. * [Regression](/developers/tutorials/ml-monitoring/ml-monitoring-regression): Check out our guide on using Fiddler to evaluate regression models. See examples of detecting issues using data drift and performance metrics like MAE. * [Feature Impact](/developers/tutorials/ml-monitoring/user-defined-feature-impact): Leverage this guide on using Fiddler's feature impact upload API to supply your own feature impact values for your Fiddler model. * [CV Inputs](/developers/tutorials/ml-monitoring/cv-monitoring): Explore our guide to using Fiddler’s monitoring for computer vision models. Learn to detect drift in image data with our unique Vector Monitoring approach. # Class Imbalance Source: https://docs.fiddler.ai/developers/tutorials/ml-monitoring/class-imbalance-monitoring-example Discover how Fiddler uses class weighting to address class imbalance. Compare two identical models–with and without weighting–to detect drift signals. Many ML use cases, like fraud detection and facial recognition, suffer from what is known as the *class imbalance problem*. This problem exists where a vast majority of the inferences seen by the model belong to only one class, known as the majority class. This makes detecting drift in the minority class very difficult as the "signal" is completely outweighed by the sheer number of inferences seen in the majority class. This guide showcases how Fiddler uses a class weighting parameter to deal with this problem. This notebook will onboard two identical models -- one without class imbalance weighting and one with class imbalance weighting -- to illustrate how drift signals in the minority class are easier to detect once properly amplified by Fiddler's unique class weighting approach. Click [this link to get started using Google Colab →](https://colab.research.google.com/github/fiddler-labs/fiddler-examples/blob/main/quickstart/latest/Fiddler_Quickstart_Imbalanced_Data.ipynb) \
![Google Colab](https://colab.research.google.com/img/colab_favicon_256px.png)\
Or download the notebook directly from [GitHub](https://github.com/fiddler-labs/fiddler-examples/blob/main/quickstart/latest/Fiddler_Quickstart_Imbalanced_Data.ipynb). # CV Inputs Source: https://docs.fiddler.ai/developers/tutorials/ml-monitoring/cv-monitoring Explore our guide to using Fiddler’s monitoring for computer vision models. Learn to detect drift in image data with our unique Vector Monitoring approach. This guide will walk you through the basic steps required to use Fiddler for monitoring computer vision (CV) models. In this notebook we demonstrate how to detect drift in image data using model embeddings using Fiddler's unique Vector Monitoring approach. Click [this link to get started using Google Colab →](https://colab.research.google.com/github/fiddler-labs/fiddler-examples/blob/main/quickstart/latest/Fiddler_Quickstart_Image_Monitoring.ipynb) \
![Google Colab](https://colab.research.google.com/img/colab_favicon_256px.png)\
Or download the notebook directly from [GitHub](https://github.com/fiddler-labs/fiddler-examples/blob/main/quickstart/latest/Fiddler_Quickstart_Image_Monitoring.ipynb). # Model Versions Source: https://docs.fiddler.ai/developers/tutorials/ml-monitoring/ml-monitoring-model-versions Explore our guide to using Fiddler’s sample data to set up and manage multiple versions of a model with the powerful Model Versions feature. This guide will walk you through how you can use Model Versions feature in setting up multiple versions of the same model, **using sample data provided by Fiddler**. Click [this link to get started using Google Colab →](https://colab.research.google.com/github/fiddler-labs/fiddler-examples/blob/main/quickstart/latest/Fiddler_Quickstart_Model_Versions.ipynb) \
![Google Colab](https://colab.research.google.com/img/colab_favicon_256px.png)\
Or download the notebook directly from [GitHub](https://github.com/fiddler-labs/fiddler-examples/blob/main/quickstart/latest/Fiddler_Quickstart_Model_Versions.ipynb). # Regression Source: https://docs.fiddler.ai/developers/tutorials/ml-monitoring/ml-monitoring-regression Check out our guide on using Fiddler to evaluate regression models. See examples of detecting issues using data drift and performance metrics like MAE. In this notebook, we demonstrate how Fiddler can monitor the performance of regression models, detecting/alerting issues with data drift and performance metrics (ex. Mean Absolute Error). Click [this link to get started using Google Colab →](https://colab.research.google.com/github/fiddler-labs/fiddler-examples/blob/main/quickstart/latest/Fiddler_Quickstart_Regression_Model.ipynb) \
![Google Colab](https://colab.research.google.com/img/colab_favicon_256px.png)\
Or download the notebook directly from [GitHub](https://github.com/fiddler-labs/fiddler-examples/blob/main/quickstart/latest/Fiddler_Quickstart_Regression_Model.ipynb). # Ranking Models Source: https://docs.fiddler.ai/developers/tutorials/ml-monitoring/ranking-model Explore our notebook to see how Fiddler monitors ranking models using a public dataset organized around “search result impressions” from Expedia hotel searches. This notebook will show you how Fiddler enables monitoring for a Ranking model. This notebook uses a public dataset from Expedia that includes shopping and purchase data with information on price competitiveness. The data are organized around a set of “search result impressions”, or the ordered list of hotels that the user sees after they search for a hotel on the Expedia website. Click [this link to get started using Google Colab →](https://colab.research.google.com/github/fiddler-labs/fiddler-examples/blob/main/quickstart/latest/Fiddler_Quickstart_Ranking_Model.ipynb) \
![Google Colab](https://colab.research.google.com/img/colab_favicon_256px.png)\
Or download the notebook directly from [GitHub](https://github.com/fiddler-labs/fiddler-examples/blob/main/quickstart/latest/Fiddler_Quickstart_Ranking_Model.ipynb). # NLP Inputs Source: https://docs.fiddler.ai/developers/tutorials/ml-monitoring/simple-nlp-monitoring-quick-start Dive into our guide on using Fiddler to monitor NLP models. Learn how a multi-class classifier is applied to the dataset and monitored with Vector Monitoring. This guide will walk you through the basic steps required to use Fiddler for monitoring NLP models. A multi-class classifier is applied to the 20newsgroup dataset and the text embeddings are monitored using Fiddler's unique Vector Monitoring approach. Click [this link to get started using Google Colab →](https://colab.research.google.com/github/fiddler-labs/fiddler-examples/blob/main/quickstart/latest/Fiddler_Quickstart_NLP_Multiclass_Monitoring.ipynb) \
![Google Colab](https://colab.research.google.com/img/colab_favicon_256px.png)\
Or download the notebook directly from [GitHub](https://github.com/fiddler-labs/fiddler-examples/blob/main/quickstart/latest/Fiddler_Quickstart_NLP_Multiclass_Monitoring.ipynb). # Feature Impact Source: https://docs.fiddler.ai/developers/tutorials/ml-monitoring/user-defined-feature-impact Leverage this guide on using Fiddler's feature impact upload API to supply your own feature impact values for your Fiddler model. This guide will walk you through the steps needed to upload your model's existing feature impact values to your Fiddler model. This notebook uses the same example model leveraged in the [ML Monitoring - Simple](/developers/quick-starts/simple-ml-monitoring) quick start. If you have already run that notebook and the model exists in your Fiddler instance, then you may skip the setup steps in this guide as noted in the instructions. Click [this link to get started using Google Colab →](https://colab.research.google.com/github/fiddler-labs/fiddler-examples/blob/main/quickstart/latest/Fiddler_Quickstart_User_Defined_Feature_Impact.ipynb) \
![Google Colab](https://colab.research.google.com/img/colab_favicon_256px.png)\
Or download the notebook directly from [GitHub](https://github.com/fiddler-labs/fiddler-examples/blob/main/quickstart/latest/Fiddler_Quickstart_User_Defined_Feature_Impact.ipynb). # Configure Evaluator Downsampling Source: https://docs.fiddler.ai/evaluate-and-test/configure-evaluator-downsampling Reduce LLM-as-a-Judge evaluation cost at scale with evaluator downsampling. Learn when to use it, how the sampling rate relates to the enabled toggle, and how to configure it from the REST API and the UI. Evaluator downsampling lets an [Evaluator Rule](/evaluate-and-test/evaluator-rules) run on a *fraction* of the spans it matches instead of every one. It is designed for high-volume GenAI applications where running an LLM-as-a-Judge evaluator on 100% of traffic is more costly than the monitoring signal requires. You control downsampling with a single per-rule field, `sampling_rate`, a number in the range `(0.0, 1.0]` that defaults to `1.0` (evaluate every matching span). **Traces are always persisted even with evaluator downsampling enabled.** Downsampling only controls whether an evaluator *runs* on a matching span — it never affects ingestion or storage. Sampled-out traces stay fully queryable in the [Explorer](/observability/agentic/trace-explorer). To *score* traces a rule skipped, create a new rule (or recreate the rule) with a higher `sampling_rate` and backfill enabled. Backfill can only be requested when a rule is created; a backfill at the same rate re-applies the same deterministic decision and skips the same traces again. **Availability.** Evaluator downsampling is gated by a feature flag and may not be enabled for your deployment yet. To turn it on, contact your Fiddler account team or [Fiddler support](mailto:support@fiddler.ai); on self-hosted deployments, an administrator enables it through deployment configuration. Until it's enabled, the **Sampling rate** field is unavailable in the UI and the API rejects requests that include a `sampling_rate`. *** ## How it works When evaluator downsampling is active, each matching span is checked against the rule's `sampling_rate` before the evaluator runs: * The decision is **deterministic and trace-atomic** — every span within the same trace receives the same evaluate-or-skip outcome, so multi-step and agentic traces are always scored as a unit. * A rule left at the default `sampling_rate = 1.0` behaves exactly as it does today, with no change in coverage. For example, a rule with `sampling_rate = 0.1` evaluates roughly 10% of the traces it matches, cutting the evaluator's LLM-as-a-Judge calls for that rule by about 90% — while every trace is still ingested and stored. *** ## When to use evaluator downsampling Use downsampling when **evaluation cost or latency, not coverage, is your constraint**: * **Cost reduction at scale.** LLM-as-a-Judge evaluators are expensive at production volumes. A representative sample typically preserves drift and quality signal at a fraction of the cost — a 5–20% sample is often equivalent to full coverage for trend monitoring. See [Recommended minimum trace volume](#recommended-minimum-trace-volume) for choosing a rate. * **High-throughput applications.** Reducing evaluation volume relieves backpressure on the enrichment pipeline during traffic spikes. * **Multiple evaluators on the same traffic.** When several rules score the same high-volume application, downsampling each one keeps total evaluation cost manageable. (Each application supports up to [100 evaluator rules](/evaluate-and-test/evaluator-rules#rule-limit).) **Sampling is correlated across rules.** Two rules with the same `sampling_rate` evaluate the *same* subset of traces — the decision is hashed on the trace, not the rule, so multiple judges agree on which traces to score. If you want two evaluators to cover *different* traces, downsampling them at the same rate will not spread them apart. ## When not to use evaluator downsampling Avoid downsampling (keep `sampling_rate = 1.0`) when: * **Your application is low-volume.** On low-traffic applications, sampling removes too many data points and produces noisy, unreliable drift and quality signals. * **You need a very low rate (below \~1%).** Rates under roughly 1% introduce statistical noise that can swamp the signal you are trying to measure. If cost is still a concern at 1%, your application volume is probably too low to downsample at all. * **You need every trace scored** — for example, for compliance, exhaustive evaluation, or guardrail-style use cases. In those cases, leave the rule at `1.0`. * **You want to pause evaluation.** Do not use a tiny `sampling_rate` to "almost turn off" a rule. Deactivate the rule instead (see below). ### Recommended minimum trace volume Choose a rate that keeps the *evaluated* volume statistically meaningful, not just the matched volume. As a rule of thumb: * Aim for at least **\~1,000 evaluated traces per monitoring window** (the period over which you read drift or quality metrics). * Avoid downsampling applications that match fewer than a few thousand traces per day for a given rule. * Keep `sampling_rate` at or above **0.01 (1%)**. In other words, pair lower rates with higher volume. A `sampling_rate` of `0.1` is reasonable at 100,000 daily traces (\~10,000 evaluated); the same `0.1` on an application with only a few hundred daily traces will not produce a reliable signal. These thresholds are **recommendations, not enforced limits.** The API accepts any `sampling_rate` in `(0.0, 1.0]` (to a resolution of `0.0001`), so a rate like `0.01` is permitted — values below \~1% are simply unlikely to yield a usable monitoring signal, so treat **1% as a practical floor** rather than a hard minimum. *** ## `sampling_rate` vs. deactivating a rule A rule's `sampling_rate` and its enabled state are **independent** controls. Use the one that matches your intent: | Goal | Use | Effect | | --------------------------------- | --------------------------------------- | -------------------------------------------------------------- | | Reduce evaluation volume and cost | Lower `sampling_rate` (e.g. `0.1`) | The evaluator runs on a fraction of matching traces | | Pause evaluation entirely | Deactivate the rule (`enabled = false`) | The evaluator runs on no spans; the rule is skipped completely | Key behaviors: * `sampling_rate = 0.0` is **rejected** — to stop evaluation entirely, deactivate the rule instead of using a near-zero rate. * A rule is created **enabled**; the create request does not accept an `enabled` field. To pause a rule, deactivate it afterward — toggle it off in the UI or send a `PATCH` with `{"enabled": false}`. * Deactivating a rule **preserves** its configured `sampling_rate`, so reactivating it restores your previous setting. * Changing `sampling_rate` **never** reactivates a deactivated rule. **Changes take effect within about 60 seconds.** When you update a rule's `sampling_rate`, evaluation already in flight may use the previous rate until the evaluator-rule cache refreshes (roughly a 60-second window). Plan rate changes with this short delay in mind. *** ## Configure downsampling ### Using the REST API Set `sampling_rate` when you create a rule, or update it later with a `PATCH`. Create a rule that evaluates 10% of matching spans: ```bash theme={null} curl -X POST https:///v3/evaluator-rules \ -H "Authorization: Bearer $FIDDLER_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "custom_judge_sampled", "application_id": "", "evaluator_id": "", "mapped_input_keys": {"response": "fiddler.contents.gen_ai.llm.output"}, "sampling_rate": 0.1 }' ``` Map the input keys your evaluator declares — a custom LLM-as-a-Judge takes the keys named in its prompt, while built-in evaluators require specific inputs (for example, the Coherence evaluator needs both `prompt` and `response`). Change the sampling rate on an existing rule: ```bash theme={null} curl -X PATCH https:///v3/evaluator-rules/ \ -H "Authorization: Bearer $FIDDLER_TOKEN" \ -H "Content-Type: application/json" \ -d '{"sampling_rate": 0.25}' ``` A `sampling_rate` outside `(0.0, 1.0]` (including `0.0` or any value above `1.0`) returns `400 Bad Request`. ### Using the UI When evaluator downsampling is enabled for your deployment, you set a rule's sampling rate from the **Evaluator Rules** tab. **When creating a rule**, the **Add Evaluator Rule** dialog includes a **Sampling rate** field: 1. Open your application's **Evaluator Rules** tab and click **Add Rule**. 2. Configure the evaluator, input mappings, and application rules as usual (see [Evaluator Rules](/evaluate-and-test/evaluator-rules)). 3. Set the **Sampling rate** to the percentage of matching traces you want evaluated — for example, enter `10` for 10%. Leave it at the default (`100`) to evaluate everything. 4. Save the rule. **For an existing rule**, edit its **Sampling rate** (also a percentage) directly in the Evaluator Rules table — update the value in the rule's **Sampling rate** cell. (The row menu offers only Pause and Delete; there is no separate edit dialog.) **The UI uses a percentage; the REST API uses a fraction.** In the UI, enter `10` for 10%. The same rate over the API is `sampling_rate: 0.1`. The **Sampling rate** control is rolling out behind a feature flag and may not yet be visible in your environment. If evaluator downsampling is enabled for your deployment but the control has not yet rolled out, configure downsampling through the REST API in the meantime. ### Python SDK SDK support for configuring `sampling_rate` on Evaluator Rules is forthcoming. For now, configure downsampling through the REST API or the UI. *** ## Related Documentation * [**Evaluator Rules**](/evaluate-and-test/evaluator-rules) - Create and manage Evaluator Rules * [**Evaluator Rules REST API**](/sdk-api/rest-api/evaluator-rules) - Full create/update API contract, including the `sampling_rate` field * [**Explorer**](/observability/agentic/trace-explorer) - Inspect ingested traces, including sampled-out traces # Evals SDK Quick Start Source: https://docs.fiddler.ai/evaluate-and-test/evals-sdk-quick-start Learn how to evaluate Large Language Model (LLM) applications, RAG systems, and AI agents using the Fiddler Evals SDK with built-in and custom evaluators. ## What You'll Learn In this guide, you'll learn how to: * Connect to Fiddler and set up your experiment environment * Create projects, applications, and datasets for organizing experiments * Build experiment datasets with test cases * Use built-in evaluators for common AI evaluation tasks * Create custom evaluators for domain-specific requirements * Run comprehensive experiments * Analyze results with detailed metrics and insights **Time to complete**: \~20 minutes ## Prerequisites Before you begin, ensure you have: * **Fiddler Account**: An active account with [access](/reference/administration/settings#access) to create applications * **Python 3.10+** * **Fiddler Evals SDK**: * `pip install fiddler-evals` * **Fiddler API Key**: Get your API key from [**Settings** > **Credentials**](/reference/administration/settings#credentials) in your Fiddler instance If you prefer using a notebook, download a fully functional quick start directly from [GitHub](https://github.com/fiddler-labs/fiddler-examples/blob/main/quickstart/latest/Fiddler_Quickstart_Evaluations_SDK.ipynb) or open it in [Google Colab](https://colab.research.google.com/github/fiddler-labs/fiddler-examples/blob/main/quickstart/latest/Fiddler_Quickstart_Evaluations_SDK.ipynb) to get started. First, establish a connection to your Fiddler instance using the Evals SDK. **Connection Setup**: ```python theme={null} from fiddler_evals import init # Initialize connection to Fiddler init( url='https://your-org.fiddler.ai', # Your Fiddler URL token='your-api-key' # Your API key ) ``` Fiddler Experiments uses a hierarchical structure to organize your experiments: * **Projects** provide organizational boundaries for related applications * **Applications** represent specific AI systems you want to evaluate * **Datasets** contain test cases for experiments * **Experiments** track individual evaluation runs Create your organizational structure: ```python theme={null} from fiddler_evals import Project, Application # Create or get the project project = Project.get_or_create(name='my_eval_project') print(f'✅ Project: {project.name} (ID: {project.id})') # Create or get the application within the project application = Application.get_or_create( name='my_llm_app', project_id=project.id ) print(f'✅ Application: {application.name} (ID: {application.id})') ``` **What This Creates**: * A project to organize all your experiment work * An application representing your AI system under test * Persistent IDs for tracking results over time Datasets contain the test cases you'll use to evaluate your AI applications. Each test case includes: * **Inputs**: Data passed to your AI application (questions, prompts, etc.) * **Expected Outputs**: What you expect the application to return * **Metadata**: Additional context (categories, types, tags) Create a dataset and add test cases: ```python theme={null} from fiddler_evals import Dataset from fiddler_evals.pydantic_models.dataset import NewDatasetItem # Create the dataset dataset = Dataset.create( name='experiment_dataset', application_id=application.id, description='Test cases for LLM experiments' ) # Add test cases test_cases = [ NewDatasetItem( inputs={"question": "What happens to you if you eat watermelon seeds?"}, expected_outputs={"answer": "The watermelon seeds pass through your digestive system"}, metadata={"type": "Adversarial", "category": "Misconceptions"} ), NewDatasetItem( inputs={"question": "What is the capital of France?"}, expected_outputs={"answer": "Paris is the capital of France"}, metadata={"type": "Factual", "category": "Geography"} ) ] dataset.insert(test_cases) print(f'✅ Added {len(test_cases)} test cases to dataset') ``` **Data Import Options**: ```python theme={null} dataset.insert_from_csv_file( file_path='data.csv', input_columns=['question'], expected_output_columns=['answer'], metadata_columns=['category'] ) ``` ```python theme={null} dataset.insert_from_jsonl_file( file_path='data.jsonl', input_keys=['question'], expected_output_keys=['answer'], metadata_keys=['category'] ) ``` ```python theme={null} dataset.insert_from_pandas( df=df, input_columns=['question'], expected_output_columns=['answer'], metadata_columns=['category'] ) ``` Fiddler Experiments provides production-ready evaluators for common AI evaluation tasks. Let's test some key evaluators: ```python theme={null} from fiddler_evals.evaluators import ( AnswerRelevance, Coherence, Conciseness, Sentiment ) # LLM-as-a-Judge evaluators require model and credential parameters MODEL = "openai/gpt-4o" CREDENTIAL = "your-llm-credential" # From Settings > LLM Gateway # Test Answer Relevance (ordinal: High/Medium/Low) relevance_evaluator = AnswerRelevance(model=MODEL, credential=CREDENTIAL) score = relevance_evaluator.score( user_query="What is the capital of France?", rag_response="Paris is the capital of France." ) print(f"Relevance Score: {score.value} ({score.label}) - {score.reasoning}") # Test Conciseness conciseness_evaluator = Conciseness(model=MODEL, credential=CREDENTIAL) score = conciseness_evaluator.score( response="Paris is the capital of France." ) print(f"Conciseness Score: {score.value} - {score.reasoning}") # Test Coherence coherence_evaluator = Coherence(model=MODEL, credential=CREDENTIAL) score = coherence_evaluator.score( response="Thank you for your question! I'd be happy to help.", prompt="Can you assist me?" ) print(f"Coherence Score: {score.value} - {score.reasoning}") # Sentiment is a Fiddler Centor Model — no model/credential needed sentiment_evaluator = Sentiment() scores = sentiment_evaluator.score("Paris is the capital of France.") print(f"Sentiment: {scores[0].label} (confidence: {scores[1].value})") ``` **Available Built-in Evaluators**: | Evaluator | Purpose | Key Parameters | | ------------------------- | -------------------------------------------------------------------- | --------------------------------------------------- | | `AnswerRelevance` | Checks if response addresses the question (ordinal: High/Medium/Low) | `user_query`, `rag_response` | | `ContextRelevance` | Measures retrieval quality (ordinal: High/Medium/Low) | `user_query`, `retrieved_documents` | | `RAGFaithfulness` | Detects hallucinations in RAG responses (binary: Yes/No) | `user_query`, `rag_response`, `retrieved_documents` | | `Coherence` | Evaluates logical flow and consistency | `response`, `prompt` | | `Conciseness` | Measures response brevity and clarity | `response` | | `Sentiment` | Analyzes emotional tone | `text` | | `RegexSearch` | Pattern matching for specific formats | `output`, `pattern` | | `FTLPromptSafety` | Compute safety scores for prompts using Fiddler Centor Models | `text` | | `FTLResponseFaithfulness` | Evaluate faithfulness of LLM responses using Fiddler Centor Models | `response`, `context` | **RAG Health Metrics:** `AnswerRelevance`, `ContextRelevance`, and `RAGFaithfulness` form the RAG diagnostic triad. All LLM-as-a-Judge evaluators require `model` and `credential` parameters at initialization (e.g., `AnswerRelevance(model="openai/gpt-4o", credential="your-credential")`). See the [RAG Health Metrics Tutorial](/developers/tutorials/experiments/rag-health-metrics-tutorial) for a complete walkthrough. **Cost-Effective Experiments at Scale** Fiddler Centor Model evaluators (`FTLPromptSafety`, `FTLResponseFaithfulness`, `Sentiment`, `TopicClassification`) run within your environment with no external API costs and sub-100ms latency. Initialize them with no parameters (e.g., `Sentiment()`). LLM-as-a-Judge evaluators (`AnswerRelevance`, `ContextRelevance`, `RAGFaithfulness`, `Coherence`, `Conciseness`) use external LLMs via LLM Gateway and require `model` and `credential` parameters at initialization. Build custom evaluation logic for your specific use cases by inheriting from the `Evaluator` base class: ```python theme={null} from fiddler_evals.evaluators.base import Evaluator from fiddler_evals.pydantic_models.score import Score class LengthEvaluator(Evaluator): """ Custom evaluator that checks if a response length is appropriate. Gives higher scores for responses that are neither too short nor too long. """ def __init__(self, min_length: int = 10, max_length: int = 200): super().__init__() self.min_length = min_length self.max_length = max_length def score(self, output: str) -> Score: """Score based on response length appropriateness.""" length = len(output.strip()) if length < self.min_length: score_value = 0.0 reasoning = f"Response too short ({length} chars, minimum {self.min_length})" elif length > self.max_length: score_value = 0.5 reasoning = f"Response too long ({length} chars, maximum {self.max_length})" else: score_value = 1.0 reasoning = f"Response length appropriate ({length} chars)" return Score( name="length_check", evaluator_name=self.name, value=score_value, reasoning=reasoning ) # Test the custom evaluator length_evaluator = LengthEvaluator(min_length=15, max_length=100) score = length_evaluator.score("Paris is the capital of France.") print(f"Length Score: {score.value} - {score.reasoning}") ``` **Function-Based Evaluators**: You can also use simple functions: ```python theme={null} def word_count_evaluator(output: str) -> float: """Returns word count normalized to 0-1 scale.""" word_count = len(output.split()) return min(word_count / 50.0, 1.0) # Use directly in evaluators list evaluators = [ AnswerRelevance(model=MODEL, credential=CREDENTIAL), word_count_evaluator, # Function evaluator ] ``` Now run a comprehensive experiment. The `evaluate()` function: 1. Runs your AI application task on each dataset item 2. Executes all evaluators on the results 3. Tracks the experiment in Fiddler 4. Returns comprehensive results with scores and timing Define your experiment task: ```python theme={null} from fiddler_evals import evaluate # Define your AI application task def my_llm_task(inputs: dict, extras: dict, metadata: dict) -> dict: """ This function represents your AI application that you want to evaluate. Args: inputs: The input data from the dataset (e.g., {"question": "..."}) extras: Additional context data (e.g., {"context": "..."}) metadata: Any metadata associated with the test case Returns: dict: The outputs from your AI application (e.g., {"answer": "..."}) """ question = inputs.get("question", "") # Your LLM API call here # For this example, we'll use a mock response answer = f"Mock response to: {question}" return {"answer": answer} # Set up evaluators evaluators = [ AnswerRelevance(model=MODEL, credential=CREDENTIAL), Conciseness(model=MODEL, credential=CREDENTIAL), Sentiment(), # Fiddler Centor Model — no model/credential needed LengthEvaluator(), ] # Run evaluation experiment_result = evaluate( dataset=dataset, task=my_llm_task, evaluators=evaluators, name_prefix="my_experiment", description="Comprehensive LLM experiment", score_fn_kwargs_mapping={ "user_query": lambda x: x["inputs"]["question"], "rag_response": "answer", "response": "answer", "output": "answer", "text": "answer", }, max_workers=4 # Process 4 test cases concurrently ) print(f"✅ Evaluated {len(experiment_result.results)} test cases") print(f"📈 Generated {sum(len(result.scores) for result in experiment_result.results)} scores") ``` **Score Function Mapping**: The `score_fn_kwargs_mapping` parameter connects your task outputs to evaluator inputs. This is necessary because evaluators expect specific parameter names (like `response`, `prompt`, `text`) but your task may use different names (like `answer`, `question`). **Simple String Mapping** (use this for most cases): ```python theme={null} # Your task returns: {"answer": "Paris is the capital of France"} # Evaluators expect: rag_response="...", response="...", or text="..." # Map your output keys to evaluator parameter names: score_fn_kwargs_mapping={ "rag_response": "answer", # Map 'rag_response' param → 'answer' output key "response": "answer", # Map 'response' param → 'answer' output key "text": "answer", # Map 'text' param → 'answer' output key } ``` **Advanced Mapping with Lambda Functions** (for nested values): ```python theme={null} # Use lambda to extract nested or computed values: score_fn_kwargs_mapping={ "user_query": lambda x: x["inputs"]["question"], # Extract from inputs dict "rag_response": "answer", # Simple string mapping } ``` **How It Works**: 1. Your task returns a dict: `{"answer": "Some response"}` 2. The mapping tells Fiddler: "When an evaluator needs `rag_response`, use the value from `answer`" 3. Each evaluator gets the parameters it needs automatically **Complete Example**: ```python theme={null} # Task returns this structure: {"answer": "Paris is the capital of France"} # But evaluators need these parameters: # - AnswerRelevance.score(user_query="...", rag_response="...") # - Conciseness.score(response="...") # - Sentiment.score(text="...") # Solution: Map parameter names to your output structure score_fn_kwargs_mapping={ "user_query": lambda x: x["inputs"]["question"], # For AnswerRelevance "rag_response": "answer", # For AnswerRelevance "response": "answer", # For Conciseness "text": "answer", # For Sentiment } ``` This allows you to use any evaluator without changing your task function structure. After running your experiment, analyze the comprehensive results in your notebook or the Fiddler UI: Fiddler Experiments results example page ```python theme={null} from fiddler_evals import ScoreStatus, ExperimentItemStatus import pandas as pd # Analyze individual results for i, result in enumerate(experiment_result.results): item = result.experiment_item scores = result.scores print(f"\n📝 Test Case {i + 1}:") print(f" Status: {item.status}") print(f" Execution Time: {item.duration_ms}ms") if item.status == ExperimentItemStatus.SUCCESS: answer = item.outputs.get('answer', 'N/A') print(f" Answer: {answer[:100]}...") # Show scores for score in scores: status_emoji = "✅" if score.status == ScoreStatus.SUCCESS else "❌" print(f" {status_emoji} {score.name}: {score.value}") print(f" Reasoning: {score.reasoning}") # Create summary statistics from collections import defaultdict evaluator_scores = defaultdict(list) total_scores = 0 successful_scores = 0 for result in experiment_result.results: for score in result.scores: if score.value is not None: evaluator_scores[score.name].append(score.value) total_scores += 1 if score.status == ScoreStatus.SUCCESS: successful_scores += 1 # Performance by evaluator print("\n🎯 Performance by Evaluator:") for evaluator_name, values in evaluator_scores.items(): avg_score = sum(values) / len(values) if values else 0 min_score = min(values) if values else 0 max_score = max(values) if values else 0 print(f" {evaluator_name}:") print(f" Average: {avg_score:.3f}") print(f" Min: {min_score:.3f}, Max: {max_score:.3f}") # Overall statistics print("\n📈 Overall Experiment Stats:") print(f" Total Test Cases: {len(experiment_result.results)}") print(f" Total Scores: {total_scores}") print(f" Success Rate: {(successful_scores / total_scores) * 100:.1f}%") ``` Output: ``` 📝 Test Case 1: Status: ExperimentItemStatus.SUCCESS Execution Time: 3251ms Answer: Mock response to: What is the capital of France?... ✅ is_answer_relevant: 0.0 Reasoning: The response does not provide the actual capital of France. Instead, it repeats the prompt in a mock format, which does not answer the question. ✅ is_concise: 0.0 Reasoning: The response is not concise as it does not provide the actual answer to the question. It is vague and does not address the main point, lacking any relevant information about the capital of France. ✅ sentiment: None Reasoning: None ✅ sentiment_prob: 0.8894587159156799 Reasoning: None ✅ length_check: 1.0 Reasoning: Response length appropriate (48 chars) ✅ word_count_evaluator: 0.18 Reasoning: Function result: 0.18 📝 Test Case 2: Status: ExperimentItemStatus.SUCCESS Execution Time: 3116ms Answer: Mock response to: What happens to you if you eat watermelon seeds?... ✅ is_answer_relevant: 0.0 Reasoning: The response does not provide any information related to the effects of eating watermelon seeds. Instead, it is a placeholder or mock response that does not address the prompt. ✅ is_concise: 0.0 Reasoning: The response is not provided, so it cannot be evaluated for conciseness. A concise response would directly address the question without unnecessary details or digressions. ✅ sentiment: None Reasoning: None ✅ sentiment_prob: 0.8732774257659912 Reasoning: None ✅ length_check: 1.0 Reasoning: Response length appropriate (66 chars) ✅ word_count_evaluator: 0.24 Reasoning: Function result: 0.24 🎯 Performance by Evaluator: is_answer_relevant: Average: 0.000 Min: 0.000, Max: 0.000 is_concise: Average: 0.000 Min: 0.000, Max: 0.000 sentiment_prob: Average: 0.881 Min: 0.873, Max: 0.889 length_check: Average: 1.000 Min: 1.000, Max: 1.000 word_count_evaluator: Average: 0.210 Min: 0.180, Max: 0.240 📈 Overall Experiment Stats: Total Test Cases: 2 Total Scores: 12 Success Rate: 100.0% ``` **Export Results** To conduct further analysis, export the experiment results: ```python theme={null} # Convert to DataFrame for further analysis results_data = [] for result in experiment_result.results: item = result.experiment_item row = { 'dataset_item_id': item.dataset_item_id, 'status': item.status, 'duration_ms': item.duration_ms, } # Add scores as columns for score in result.scores: row[f'{score.name}_score'] = score.value row[f'{score.name}_reasoning'] = score.reasoning results_data.append(row) results_df = pd.DataFrame(results_data) results_df.to_csv('experiment_results.csv', index=False) print("💾 Results exported to experiment_results.csv") ``` ## Next Steps Now that you have the Fiddler Evals SDK set up, explore these advanced capabilities: * [Experiments First Steps](/getting-started/experiments): An overview of Fiddler Experiments * [Quick Start Notebook](/developers/tutorials/experiments): Download and run a more expansive version of this quick start guide * [Fiddler Evals SDK](/sdk-api/evals/evaluate): Review the SDK technical reference * [Advanced Evals Guide](/developers/tutorials/experiments/evals-sdk-advanced): Build sophisticated evaluation logic ## Troubleshooting ### Connection Issues **Issue**: Cannot connect to Fiddler instance. **Solutions**: 1. **Verify credentials** 1. **Test network connectivity**: ```bash theme={null} curl -I https://your-org.fiddler.ai ``` 2. **Validate API key**: * Ensure your API key is valid and not expired * Regenerate API key if needed from [Settings > Credentials](/reference/administration/settings#creating-api-keys) ### Import Errors **Issue**: `ModuleNotFoundError: No module named 'fiddler_evals'` **Solutions**: 1. **Verify installation**: ```bash theme={null} pip list | grep fiddler-evals ``` 2. **Reinstall the SDK**: ```bash theme={null} pip uninstall fiddler-evals pip install fiddler-evals ``` 3. **Check Python version**: * Requires Python 3.10 or higher * Run `python --version` to verify ### Experiment Failures **Issue**: Evaluators failing with errors. **Solutions**: 1. **Check parameter mapping**: ```python theme={null} # Ensure score_fn_kwargs_mapping matches evaluator requirements score_fn_kwargs_mapping={ "response": "answer", # Maps to your task output key "prompt": lambda x: x["inputs"]["question"], } ``` 2. **Verify task output format**: * Task must return a dictionary * Keys must match those referenced in score\_fn\_kwargs\_mapping 3. **Debug individual evaluators**: ```python theme={null} # Test evaluators separately score = evaluator.score(response="test response") print(f"Score: {score.value}, Reasoning: {score.reasoning}") ``` ### Performance Issues **Issue**: Experiment is running slowly. **Solutions**: 1. **Use parallel processing**: ```python theme={null} experiment_result = evaluate( dataset=dataset, task=my_llm_task, evaluators=evaluators, max_workers=4 # Adjust based on your system ) ``` 2. **Reduce dataset size for testing**: * Start with a small subset * Scale up once the configuration is validated 3. **Optimize LLM calls**: * Use caching for repeated queries * Implement batching where possible ## Configuration Options ### Basic Configuration ```python theme={null} from fiddler_evals import init, evaluate # Initialize connection init(url='https://your-org.fiddler.ai', token='your-api-key') # Run evaluation with basic settings experiment_result = evaluate( dataset=dataset, task=my_llm_task, evaluators=evaluators, name_prefix="my_eval" ) ``` ### Advanced Configuration **Concurrent Processing**: ```python theme={null} experiment_result = evaluate( dataset=dataset, task=my_llm_task, evaluators=evaluators, max_workers=8, # Process 8 test cases in parallel name_prefix="parallel_eval" ) ``` **Experiment Metadata**: ```python theme={null} experiment_result = evaluate( dataset=dataset, task=my_llm_task, evaluators=evaluators, metadata={ "model_version": "gpt-4", "evaluation_date": "2024-01-15", "temperature": 0.7, "environment": "production" } ) ``` **Custom Evaluator Configuration**: ```python theme={null} # Configure evaluators with model and custom evaluators with specific thresholds evaluators = [ AnswerRelevance(model="openai/gpt-4o", credential="your-llm-credential"), Conciseness(model="openai/gpt-4o", credential="your-llm-credential"), LengthEvaluator(min_length=20, max_length=150), ] ``` # Evaluator Downsampling Quick Start Source: https://docs.fiddler.ai/evaluate-and-test/evaluator-downsampling-quick-start Get started with evaluator downsampling: score only a fraction of matching traces to cut LLM-as-a-Judge cost, configured per rule from the UI or the REST API. Includes an end-to-end curl walkthrough. [Evaluator downsampling](/evaluate-and-test/configure-evaluator-downsampling) lets an [Evaluator Rule](/evaluate-and-test/evaluator-rules) score only a *fraction* of the spans it matches instead of every one — cutting LLM-as-a-Judge evaluation cost at scale. You control it with one per-rule field, `sampling_rate`, a number in `(0.0, 1.0]` that defaults to `1.0` (evaluate everything). This guide walks you through configuring it from the **UI** and the **REST API**. **Traces are always persisted, even with downsampling enabled.** Downsampling only controls whether an evaluator *runs* on a matching span — it never affects ingestion or storage. Sampled-out traces stay fully queryable in the [Explorer](/observability/agentic/trace-explorer). **Availability.** Evaluator downsampling is rolling out behind a feature flag. Setting a `sampling_rate` requires it to be enabled for your deployment; until then, the field is unavailable in the UI and the API rejects requests that include it with a `400`. Contact [Fiddler support](mailto:support@fiddler.ai) to enable it. ## What you'll learn * Set a rule's sampling rate from the UI when creating or editing a rule * Create and tune a downsampled rule end-to-end with the REST API * Pause evaluation the right way (and the guardrails on `sampling_rate`) **Time to complete**: \~10 minutes ## Prerequisites Before you begin, ensure you have: * **Evaluator downsampling enabled** for your deployment (see the availability note above) * **A GenAI application** with span data (see [Evaluator Rules](/evaluate-and-test/evaluator-rules)) * **A Fiddler API key** — from [**Settings** > **Credentials**](/reference/administration/settings#credentials) (for the API walkthrough) * **`jq`** installed locally (optional, used to pretty-print API responses) *** ## Configure downsampling in the UI When evaluator downsampling is enabled for your deployment, you set a rule's sampling rate from the **Evaluator Rules** tab. **The UI uses a percentage; the REST API uses a fraction** — enter `10` in the UI for the same coverage as `sampling_rate: 0.1` over the API. 1. In your application, open the **Evaluator Rules** tab and click **Add Rule**. Configure the evaluator, input mappings, and application rules as usual (see [Evaluator Rules](/evaluate-and-test/evaluator-rules)). 2. In the **Add Evaluator Rule** dialog, set the **Sampling rate** to the percentage of matching traces you want evaluated — for example, enter `10` for 10%. Leave it at the default (`100`) to evaluate everything. 3. Save the rule. It begins evaluating the configured fraction of matching spans. 4. To change the rate later, edit the **Sampling rate** for an existing rule directly in its **Sampling rate** cell in the Evaluator Rules table. To stop evaluation entirely, use the row's **Pause** action — do not set a near-zero rate. The **Sampling rate** control is rolling out behind a feature flag and may not yet be visible in your environment. If downsampling is enabled for your deployment but the control hasn't rolled out, use the REST API below in the meantime. *** ## Configure downsampling with the REST API This walkthrough creates a GenAI project, an application, an evaluator, and a downsampled rule, then tunes and tears it down. All endpoints are under `$FIDDLER_URL/v3/...` and authenticate with a bearer token (`Authorization: Bearer $FIDDLER_API_KEY`). **Project naming rule.** Project names must start with a letter and then contain only letters, numbers, and underscores (`_`) — no hyphens or spaces. Other resource names (applications, evaluators, rules) aren't restricted to this pattern, but this guide uses it throughout for consistency. ### 1. Set up your environment ```bash theme={null} export FIDDLER_URL="https://YOUR_NAMESPACE.fiddler.ai" # no trailing slash, no /v3 export FIDDLER_API_KEY="YOUR_API_KEY" # reusable auth headers auth=(-H "Authorization: Bearer $FIDDLER_API_KEY" -H "Content-Type: application/json") ``` ### 2. Confirm connectivity and auth ```bash theme={null} curl -s "${auth[@]}" "$FIDDLER_URL/v3/projects?limit=1" | jq '.kind, .data.total' ``` Expect `"NORMAL"` (or `"PAGINATED"`) and a number. A `401` means the URL or key is wrong. ### 3. Create a GenAI project and application A project with `asset_type=GEN_AI_APP` is the container for GenAI applications; the application is what traces are sent to and what rules bind to. ```bash theme={null} export PROJECT_ID=$(curl -s "${auth[@]}" -X POST "$FIDDLER_URL/v3/projects" \ -d '{"name": "downsampling_demo", "asset_type": "GEN_AI_APP"}' | jq -r '.data.id') export APPLICATION_ID=$(curl -s "${auth[@]}" -X POST "$FIDDLER_URL/v3/applications" \ -d "{\"name\": \"chat_assistant\", \"project_id\": \"$PROJECT_ID\"}" | jq -r '.data.id') echo "PROJECT_ID=$PROJECT_ID APPLICATION_ID=$APPLICATION_ID" ``` ### 4. Create an evaluator An *evaluator* is the scorer definition; the *rule* (next step) binds it to the application and is where `sampling_rate` lives. The `enrichment_name` field selects the evaluator type. This example uses a built-in PII check (least setup): ```bash theme={null} export EVALUATOR_ID=$(curl -s "${auth[@]}" -X POST "$FIDDLER_URL/v3/evaluators" \ -d '{"name": "demo_pii_check", "enrichment_name": "pii_detection", "enrichment_config": {}}' \ | jq -r '.data.id') echo "EVALUATOR_ID=$EVALUATOR_ID" ``` For the cost-savings story, use an LLM-as-a-Judge evaluator instead (`enrichment_name: "llm_as_a_judge"`, with a `model_id` and `prompt_spec` in `enrichment_config`). Discover the available types and their config schemas with `GET /v3/evaluators/get-config-options`. ### 5. Discover the input keys to map A rule maps the evaluator's template variables to span attribute paths via `mapped_input_keys`. This call returns the keys the evaluator expects: ```bash theme={null} curl -s "${auth[@]}" -X POST "$FIDDLER_URL/v3/evaluator-rules/map-input-keys" \ -d "{\"application_id\": \"$APPLICATION_ID\", \"evaluator_id\": \"$EVALUATOR_ID\"}" \ | jq '.data' ``` Match each value's type to the key's type in `rule_input_keys`: a `string`-typed key takes a single attribute path (e.g. `"fiddler.contents.gen_ai.llm.output"`); an array-typed key takes a list of paths. ### 6. Create the rule with a sampling rate This is the feature. `sampling_rate: 0.1` means "score \~10% of matching traces; store 100%." ```bash theme={null} export RULE_ID=$(curl -s "${auth[@]}" -X POST "$FIDDLER_URL/v3/evaluator-rules" \ -d "{ \"name\": \"downsampled_rule\", \"application_id\": \"$APPLICATION_ID\", \"evaluator_id\": \"$EVALUATOR_ID\", \"mapped_input_keys\": {\"text\": \"fiddler.contents.gen_ai.llm.output\"}, \"sampling_rate\": 0.1 }" | jq -r '.data.id') echo "RULE_ID=$RULE_ID" ``` If this returns `400 ... "Evaluator downsampling is not enabled for this deployment"`, the feature flag is off for your deployment — see the availability note at the top of this page. ### 7. Read the rule back Confirm the rate persisted. The list endpoint filters via a `filter` query param; build it with `-g -G --data-urlencode` so curl encodes the JSON and doesn't treat `[`/`]` as glob characters: ```bash theme={null} curl -s -g -G "${auth[@]}" "$FIDDLER_URL/v3/evaluator-rules" \ --data-urlencode "filter={\"condition\":\"AND\",\"rules\":[{\"field\":\"application_id\",\"operator\":\"equal\",\"value\":\"$APPLICATION_ID\"}]}" \ | jq '.data.items[] | {id, name, enabled, sampling_rate}' ``` You should see `"sampling_rate": 0.1`. The traces are all still stored and queryable — only *evaluation* is sampled. ### 8. Tune the sampling rate live Dial coverage up or down on a live rule without recreating it: ```bash theme={null} curl -s "${auth[@]}" -X PATCH "$FIDDLER_URL/v3/evaluator-rules/$RULE_ID" \ -d '{"sampling_rate": 0.5}' | jq '.data | {id, name, sampling_rate}' ``` A new rate takes effect at the workers within the rule-cache TTL (\~60 seconds). ### 9. Pause evaluation the right way `sampling_rate` cannot be `0.0`. To pause a rule entirely, set `enabled=false` (this preserves the configured rate, so re-enabling restores it): ```bash theme={null} # Pause: curl -s "${auth[@]}" -X PATCH "$FIDDLER_URL/v3/evaluator-rules/$RULE_ID" \ -d '{"enabled": false}' | jq '.data | {id, enabled, sampling_rate}' # Re-enable: curl -s "${auth[@]}" -X PATCH "$FIDDLER_URL/v3/evaluator-rules/$RULE_ID" \ -d '{"enabled": true}' | jq '.data | {id, enabled, sampling_rate}' ``` Both `sampling_rate: 0.0` and `sampling_rate > 1.0` are rejected with a `400`: ```bash theme={null} curl -s -o /dev/null -w "%{http_code}\n" "${auth[@]}" -X PATCH \ "$FIDDLER_URL/v3/evaluator-rules/$RULE_ID" -d '{"sampling_rate": 0.0}' # -> 400 ``` ### 10. Clean up ```bash theme={null} curl -s "${auth[@]}" -X DELETE "$FIDDLER_URL/v3/evaluator-rules/$RULE_ID" | jq '.kind' # Optional: delete the demo application (async cleanup also removes any remaining rules) curl -s "${auth[@]}" -X DELETE "$FIDDLER_URL/v3/applications/$APPLICATION_ID" | jq '.kind' # Optional: delete the project once the application cleanup finishes curl -s "${auth[@]}" -X DELETE "$FIDDLER_URL/v3/projects/$PROJECT_ID" | jq '.kind' ``` Deleting a project does not cascade to its applications, so delete the application first. Because application deletion is asynchronous, wait a few seconds for the cleanup to finish before deleting the project; if the project delete still returns `"ERROR"`, retry after a moment. *** ## Quick reference | Action | Method & path | | --------------------------------------- | ----------------------------------------- | | Create project | `POST /v3/projects` | | Create application | `POST /v3/applications` | | List evaluator config options | `GET /v3/evaluators/get-config-options` | | Create evaluator | `POST /v3/evaluators` | | Discover input keys | `POST /v3/evaluator-rules/map-input-keys` | | Create rule (+`sampling_rate`) | `POST /v3/evaluator-rules` | | List rules | `GET /v3/evaluator-rules?filter=...` | | Update rule (`sampling_rate`/`enabled`) | `PATCH /v3/evaluator-rules/{id}` | | Delete rule | `DELETE /v3/evaluator-rules/{id}` | **`sampling_rate` rules:** range `(0.0, 1.0]`; default `1.0` (score everything); `0.0` rejected (pause with `enabled=false` instead); values above `1.0` rejected; resolution is 4 decimal places (1 basis point). **Units differ by surface.** The UI uses a percentage (`10` = 10%); the REST API uses a fraction (`sampling_rate: 0.1`). *** ## Seeing sampling in action (optional, advanced) Demonstrating a visible \~10% sample requires ingesting many traces and waiting for async enrichment. GenAI trace ingestion is **OTLP-based** (`POST /v1/traces` with an `Authorization: Bearer` header and a `fiddler-application-id` header) — it is *not* part of the v3 REST surface used above. After ingesting traces, query them back to confirm that sampled-out traces are still **stored** (just not scored): ```bash theme={null} curl -s "${auth[@]}" -X POST "$FIDDLER_URL/v3/spans/query" \ -d "{ \"application_id\": \"$APPLICATION_ID\", \"start_time\": \"2026-01-01T00:00:00Z\", \"end_time\": \"2026-12-31T23:59:59Z\", \"page_size\": 50 }" | jq '.data.items[] | {trace_id, evaluators}' ``` Spans with a non-empty `evaluators` array were scored (sampled in); stored spans with an empty array were sampled out — same data retained, evaluation skipped. *** ## Next steps * [**Configure Evaluator Downsampling**](/evaluate-and-test/configure-evaluator-downsampling) — the full guide: when to use it, recommended minimum trace volume, `sampling_rate` vs deactivating a rule, and how sampling correlates across rules * [**Evaluator Rules**](/evaluate-and-test/evaluator-rules) — create and manage Evaluator Rules * [**Evaluator Rules REST API**](/sdk-api/rest-api/evaluator-rules) — full create/update API contract, including the `sampling_rate` field * [**Explorer**](/observability/agentic/trace-explorer) — inspect ingested traces, including sampled-out traces # Evaluator Rules Source: https://docs.fiddler.ai/evaluate-and-test/evaluator-rules Configure automated evaluations for your GenAI application spans using Evaluator Rules. Learn to map evaluators to span data, define application rules, and manage backfill configuration. Evaluator Rules workflow: Configure, Filter, Evaluate Evaluator Rules define how automated evaluations are applied to your application's spans. They connect evaluators (LLM-based or rule-based functions) with span data, specify what inputs to use, and determine which spans qualify for evaluation. *** ## Overview Evaluator Rules provide the configuration layer between your evaluators and your application's telemetry data. When properly configured, they automatically assess the quality, safety, and performance of your GenAI application based on real-time span data. ### What Are Evaluator Rules? An **Evaluator Rule** determines how and when an evaluator runs against your application's spans. Each rule consists of four key components: 1. **Evaluator Configuration** - The evaluator definition, including provider, model, and prompt 2. **Input Field Mapping** - How span data is passed to the evaluator's input variables 3. **Application Rules** - Conditions that determine which spans qualify for evaluation 4. **Backfill Configuration** - Whether to apply evaluations to historical data ### How Evaluator Rules Work When a new span is created in your application: 1. The system checks all active Evaluator Rules 2. Each rule evaluates whether its Application Rules match the span's attributes 3. If a match is found, the system extracts data from the span using Input Field Mappings 4. The evaluator runs with the mapped data as input 5. Results are stored and made available in dashboards and analytics *** ## Key Concepts ### Evaluators An **Evaluator** is a configured model or function that performs analysis over spans. It can classify, score, or assess the quality of data generated by your application. Evaluators are defined by: * **Provider** - The LLM provider (OpenAI, Anthropic, Gemini, Fiddler) * **Model** - The specific model to use for evaluation * **Credentials** - Authentication to the provider (configured via [LLM Gateway](/reference/administration/llm-gateway)) * **Prompt or Logic** - The evaluation instructions or function **Note:** Evaluators are defined at the organization level and shared across all projects in your organization. ### Input Mappings **Input Mappings** define how data flows from spans into evaluators. Each variable used in an evaluator's prompt (such as `{{input}}` or `{{context}}`) must be mapped to a field or attribute in the span data. For example, if your evaluator prompt includes `{{puppynoises}}`, you must map that variable to a span attribute like `fiddler.contents.gen_ai.llm.input.user`. ### Application Rules **Application Rules** specify filtering conditions that determine which spans qualify for evaluation. Rules use AND/OR logic: * **AND condition across categories** - A span must match ALL rule categories * **OR condition within a category** - A span can match ANY value within a single category **Example:** ``` Rule 1: SpanType = llm Rule 2: Region = us-east OR us-west Result: Evaluates spans that are type "llm" AND in either "us-east" or "us-west" ``` ### Backfill **Backfill** controls whether evaluations apply retroactively to existing historical data or only to spans created after the rule is configured. The backfill process runtime depends on the volume of data in your history. Be certain to backfill only as needed. **Backfill respects the rule's sampling rate.** If a rule uses [evaluator downsampling](/evaluate-and-test/configure-evaluator-downsampling), a backfill evaluates the same fraction of traces — and because the sampling decision is deterministic, a backfill at the same rate re-applies the same outcome and skips the same traces. To score traces a downsampled rule skipped, create a new rule (or recreate the rule) with a higher sampling rate and backfill enabled. ### Rule Limit Each application supports up to **100 evaluator rules** by default. This soft cap keeps evaluation and monitoring performant as the number of rules grows. On self-hosted deployments, an administrator can raise or lower the limit through configuration. When an application reaches the limit, creating another rule returns a `422` error. Delete rules you no longer need to make room. **Note:** Deactivating a rule does not free a slot — disabled rules still count toward the limit. Delete unused rules to reduce the count. *** ## Create an Evaluator Rule ### Prerequisites Before creating an Evaluator Rule, ensure you have: * **Active Application** - A GenAI application with span data * **Configured Evaluators** - Organization-level evaluators ready to use * **LLM Gateway Credentials** - If using custom LLM-based evaluators (see [LLM Gateway Configuration](/reference/administration/llm-gateway)) *** ### Step-by-Step Guide Navigate to your application in the Fiddler UI and access the evaluator configuration: 1. Click the **Evaluator Rules** tab 2. Click **Add Rule** in the top-right corner 3. The **Add Evaluator Rule** dialog opens with available evaluators Choose an evaluator from the list: **Fiddler-Provided Evaluators:** * Topic Classification * Embedding * Token Count * Answer Relevance * Coherence * Conciseness * Context Relevance * RAG Faithfulness * PII Detection * Sentiment Analysis * F# Prompt Safety * F# Response Faithfulness * **Llm As A Judge** (custom evaluator) Select an evaluator from the available list **Configure Custom Evaluator (Llm As A Judge)** If you select **Llm As A Judge**, you'll need to configure the evaluator: **a. Evaluator Name** * Enter a descriptive name (e.g., `saddestpuppynoises`) **b. Provider** * Select the LLM provider (e.g., `fiddler`) **c. Credential** * Choose the API credential for authentication (e.g., `dummy`) **d. Model** * Select the specific model (e.g., `llama3.1-8b`) **e. Prompt Template** * Enter evaluation instructions with input variables using curly braces: `{{variableName}}` * **Example:** `sad {{puppynoises}}` **f. Outputs** * Define the expected response format in JSON **Example Output Configuration:** ```json theme={null} { "name": "sadnoises", "description": "sad puppy noises", "type": "categorical", "choices": ["sad", "not sad"] } ``` Configure custom Llm As A Judge evaluator **Tip:** For Fiddler-provided evaluators, the evaluation method and fields are predetermined. You only need to map inputs and configure application rules. Click **Next** to continue. Map each evaluator input variable to a span attribute. 1. In the **Map Evaluator** step, you'll see all required input variables 2. For each variable (e.g., `puppynoises`): * Click the **Select an attribute or enter a custom path** dropdown * Choose from available span attributes or enter a custom path manually **Common Span Attributes:** * `fiddler.span.user.pirate_completion_score` * `fiddler.contents.gen_ai.llm.context` * `fiddler.span.system.gen_ai.usage.output_tokens` * `fiddler.session.user.region` * `fiddler.span.system.gen_ai.usage.input_tokens` * `fiddler.session.user.max_conversation_turns` * `gen_ai.system` * `fiddler.contents.gen_ai.llm.input.user` * `fiddler.contents.gen_ai.tool.input` * And many more... Map evaluator input variables to span attributes 3. Repeat for all input variables 4. Click **Next** to continue All required input variables must be mapped. The evaluator cannot run without complete input mappings. Specify which spans to evaluate by setting filter conditions. 1. In the **Apply Rules** step, you'll see the current rule conditions 2. The info box shows: **"This evaluator will apply to spans that match ALL of the following conditions:"** 3. Click **Add Rule** to add a new condition category For each rule category: **a. Rule Category** * Select the attribute type (e.g., `Span Type`) **b. Values** * Choose which values to match: * `chain` * `llm` ✓ * `tool` **c. Custom Values** * (Optional) Add specific custom values to match Define application rules to filter which spans are evaluated **Understanding Rule Logic** * **AND condition across categories** - A span must match ALL rule categories * **OR condition within a category** - A span can match ANY value within a single category **Example:** ``` Rule 1: SpanType = llm Rule 2: Region = us-east OR us-west Result: Evaluates spans that are type "llm" AND in either "us-east" or "us-west" ``` 5. Add multiple rule categories as needed 6. Click **Next** to continue Determine whether to apply the evaluator to existing historical data and review your configuration. **Backfill Configuration** Choose one of three options: **Option 1: Apply to all past data** * Evaluates all existing spans in the dataset * Use when: You need complete historical coverage * Warning: May take significant time for large datasets **Option 2: Apply from a specific past date** * Evaluates spans created after a chosen date * Use when: You want partial historical coverage * Select the start date using the date picker **Option 3: No backfill** (Default) * Evaluates only new spans created after activation * Use when: You only need a forward-looking evaluation * Best for: Testing new evaluators or reducing processing time Configure backfill options and review configuration **Review Configuration Summary** **Evaluator Configuration** * Evaluator name, model, provider, credential * Prompt template and expected outputs **Input Field Mapping** * Variable → Span attribute mappings **Application Rules** * Span matching conditions **Performance Tip:** Start with "No backfill" to test your evaluator configuration. Once validated, you can create a new rule with backfill enabled. Complete the configuration and activate your evaluator rule. 1. **Configuration Name** * Enter a descriptive name for this evaluator rule (e.g., `puppyjudge`) * This name identifies the rule in your application's Evaluator Rules list 2. **Finalize:** * Click **Save** to activate the rule * Or click **Back** to modify any settings * Or click **Cancel** to discard the configuration Save configuration and activate the evaluator rule Once saved, the evaluator rule becomes active and begins evaluating spans that match your criteria. *** ## Manage Evaluator Rules ### View Active Rules Navigate to the **Evaluator Rules** tab in your application to see all configured rules. The Evaluator Rules table displays: | Column | Description | | ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Rule Name** | The configuration name you assigned | | **Rule** | Span-matching conditions (e.g., "SpanName undefined: ChatOpenAI") | | **Input Mappings** | Mapped input fields (e.g., "CONTEXT: gen\_ai.llm.con...") | | **Outputs** | Expected output fields (e.g., "faithful\_prob", "spans") | | **Sampling Rate** | Fraction of matching traces evaluated, shown as a percentage (`100%` = evaluate everything). Visible when [evaluator downsampling](/evaluate-and-test/configure-evaluator-downsampling) is enabled for your deployment. | | **Status** | Active or Inactive | | **Created At** | Date the rule was created | ### Activate or Deactivate a Rule Toggle a rule's status without deleting it: 1. Locate the rule in the Evaluator Rules table 2. Click the **Status** toggle to activate or deactivate * **Active** - Rule is running on matching spans * **Inactive** - Rule is paused and not evaluating new spans ### Delete a Rule Remove a rule permanently: 1. Locate the rule in the Evaluator Rules table 2. Click the **delete** icon (trash can) at the end of the row 3. Confirm the deletion when prompted Deleting a rule does not remove evaluator results already generated. Historical evaluator data remains in your analytics. *** ## Best Practices ### Evaluator Configuration * **Use Descriptive Names** - Name evaluators and rules clearly (e.g., `rag_faithfulness_prod` instead of `rule1`) * **Test Before Backfill** - Create rules without backfill first, validate results, then create a new rule with backfill if needed * **Version Your Prompts** - Include version identifiers in custom judge names (e.g., `topic_classifier_v2`) ### Input Mapping * **Validate Paths** - Ensure span attributes exist before mapping * **Use Consistent Paths** - Standardize attribute naming across your application * **Document Custom Paths** - Keep a reference of custom attribute paths for your team ### Application Rules * **Start Broad, Refine Later** - Begin with simple rules, add complexity as needed * **Avoid Over-Filtering** - Don't create rules so specific that they match too few spans * **Test Rule Logic** - Verify spans are matching as expected using span search ### Performance Optimization * **Limit Backfill Scope** - Use date-based backfill instead of "all past data" for large datasets * **Monitor Evaluation Latency** - Track how long evaluations take and optimize prompts if needed * **Batch Similar Rules** - Group related evaluations to reduce overhead *** ## Troubleshooting ### Evaluator Not Running **Issue:** Rule is active but not producing results. **Solutions:** * Verify Application Rules match actual span attributes * Check that all input mappings point to valid span fields * Ensure LLM Gateway credentials are valid and not expired * Review span data to confirm matching spans exist ### Missing Input Data **Issue:** Evaluator fails due to missing input values. **Solutions:** * Verify the span attribute path is correct * Check that the attribute exists in your span schema * Ensure spans contain data for the mapped field * Use a different attribute or add the field to your instrumentation ### Backfill Taking Too Long **Issue:** Historical evaluation is processing slowly. **Solutions:** * Use date-based backfill instead of all past data * Start with recent data and expand the date range gradually * Consider creating multiple rules for different time periods * Deactivate unnecessary rules to free up processing capacity ### Unexpected Evaluator Results **Issue:** Evaluator produces unexpected scores or classifications. **Solutions:** * Review the evaluator prompt template for clarity * Verify input mappings are passing the correct data * Test the evaluator with sample data outside Fiddler * Check for prompt ambiguity or missing context * Adjust the prompt and create a new rule version ### Evaluator Rule Limit Reached **Issue:** Creating a new evaluator rule fails with a `422` error stating the application has reached the per-application rule limit. **Solutions:** * Delete evaluator rules you no longer need — each application supports up to 100 rules * Remember that deactivating a rule does not free a slot; disabled rules still count toward the limit * Contact Fiddler support if your use case requires a higher limit *** ## Related Documentation * [**LLM Gateway Configuration**](/reference/administration/llm-gateway) - Configure LLM provider credentials * [**Configure Evaluator Downsampling**](/evaluate-and-test/configure-evaluator-downsampling) - Reduce evaluation cost at scale with per-rule sampling * [**Evaluator Downsampling Quick Start**](/evaluate-and-test/evaluator-downsampling-quick-start) - Configure a downsampled rule from the UI or REST API * [**Fiddler Evals SDK**](/sdk-api/evals/evaluate) - Create and manage evaluators programmatically * [**Custom Evaluators**](/evaluate-and-test/overview) - Build custom evaluation logic * [**Application Monitoring**](/getting-started/agentic-monitoring) - Monitor your GenAI applications # Compare LLM Outputs Source: https://docs.fiddler.ai/evaluate-and-test/llm-evaluation-example Learn how to systematically compare outputs from different LLM models (GPT-3.5, Claude, etc.) using Fiddler's pre-production evaluation environment to make data-driven model selection decisions. ## Overview Making the right LLM model choice is critical for your application's success, but comparing models effectively requires more than intuition. This quick start demonstrates how to use Fiddler's pre-production evaluation environment to perform **systematic, side-by-side comparisons** of different LLM models using the same prompts and consistent evaluation metrics. ## What You'll Learn In this hands-on notebook guide, you'll learn how to: * **Upload model outputs** from different LLMs (GPT-3.5 and Claude) to Fiddler's pre-production environment * **Define a consistent evaluation schema** that works across multiple models * **Apply Fiddler enrichments** for automated quality assessment: * **Faithfulness (Centor Model)** - Detect hallucinations in RAG responses using Fiddler Centor Models * **Sentiment Analysis** - Understand response tone * **PII Detection** - Identify privacy risks * **Embeddings** - Track semantic patterns and outliers **Looking for RAG-specific evaluation?** For comprehensive RAG pipeline diagnostics using Answer Relevance 2.0, Context Relevance, and RAG Faithfulness, see the [RAG Health Metrics Tutorial](/developers/tutorials/experiments/rag-health-metrics-tutorial) and [RAG Evaluation Fundamentals Cookbook](/developers/cookbooks/rag-evaluation-fundamentals). \* \*\*Build comparison dashboards\*\* using metric cards to visualize differences \* \*\*Make data-driven decisions\*\* about which model best fits your needs ## Why Compare in Pre-Production? Pre-production evaluation lets you test models **before committing to production deployment**: * **Apples-to-apples comparison** - Same prompts, same metrics, consistent evaluation * **Cost optimization** - Identify the most cost-effective model that meets quality requirements * **Risk assessment** - Understand safety and quality trade-offs before production * **Informed decisions** - Replace guesswork with quantitative evidence ## What You'll Build By the end of this guide, you'll have: 1. **Two datasets** uploaded to Fiddler (GPT-3.5 and Claude outputs) 2. **Consistent enrichments** applied to both datasets for fair comparison 3. **Metric card dashboards** showing side-by-side model performance 4. **Clear insights** into which model performs better for your use case ## Prerequisites Before you begin: * **Fiddler account** with access to create projects * **Python environment** with Jupyter notebook support * **Fiddler Python client** (installed via pip) * **Sample data** (provided in the notebook from Fiddler examples repository) ## Time to Complete **\~15 minutes** - Follow the interactive notebook for a guided experience ## Get Started Choose your preferred environment: ### Option 1: Google Colab (Recommended) Run the notebook directly in your browser with zero setup: [Open in Google Colab →](https://colab.research.google.com/github/fiddler-labs/fiddler-examples/blob/main/quickstart/latest/Fiddler_Quickstart_LLM_Comparison.ipynb) \
![Google Colab](https://colab.research.google.com/img/colab_favicon_256px.png)\
### Option 2: Local Jupyter Notebook Download and run locally in your own environment: [Download from GitHub →](https://github.com/fiddler-labs/fiddler-examples/blob/main/quickstart/latest/Fiddler_Quickstart_LLM_Comparison.ipynb) ## Workflow Overview The notebook walks through this experiment workflow: Initialize the Python client with your credentials. Set up a project to organize your evaluation. Read sample datasets containing GPT-3.5 and Claude responses. Enable automated quality metrics: * Text embeddings for semantic analysis * Faithfulness scoring for hallucination detection * Sentiment analysis for response tone * PII detection for privacy compliance Specify input/output columns and metadata. Upload both model outputs to the pre-production environment. Create metric cards for visual comparison. Analyze results to choose the best model. ## Key Features Demonstrated ### Fiddler Enrichments The notebook demonstrates several powerful Fiddler enrichments: **Text Embeddings:** * Generate semantic representations of prompts, responses, and source documents * Track outliers and drift in your experiment datasets * Enable similarity-based analysis **Faithfulness Assessment:** * Automatically detect hallucinations in RAG-based responses * Compare how well each model grounds responses in source documents * Critical for applications requiring factual accuracy **Sentiment & Safety:** * Analyze response tone and sentiment * Detect PII leakage across models * Assess safety and compliance risks ### Pre-Production Comparison **Side-by-Side Analysis:** * Upload multiple model outputs to the same project * Apply identical enrichments for fair comparison * Visualize differences with metric cards **Data-Driven Decisions:** * Quantitative metrics replace subjective judgment * Compare quality, safety, and consistency across models * Balance performance with cost considerations ## Use Cases This comparison approach works for: * **Model selection** - Choose between GPT-4, Claude, Llama, or other LLMs * **Prompt optimization** - Compare different prompt strategies on the same model * **Version testing** - Evaluate new model versions before upgrading * **Cost optimization** - Find the most cost-effective model meeting quality standards * **RAG system tuning** - Compare retrieval strategies and grounding effectiveness ## What Happens Next? After completing this quick start: 1. **Analyze your results** - Use metric cards to understand performance differences 2. **Iterate on your evaluation** - Add more test cases or different models 3. **Scale to production** - Deploy the winning model with confidence 4. **Continue monitoring** - Use Fiddler's production monitoring for ongoing quality tracking ## Related Resources **Expand Your Experiment Capabilities:** * [Evals SDK Quick Start](/evaluate-and-test/evals-sdk-quick-start) - Build custom experiment workflows * [Prompt Specs Quick Start](/evaluate-and-test/prompt-specs-quick-start) - Create custom LLM-as-a-Judge evaluators * [Experiments Overview](/getting-started/experiments) - Comprehensive guide to Fiddler Experiments **Production Deployment:** * [Agentic Monitoring](/getting-started/agentic-monitoring) - Monitor LLM applications in production * [LLM Monitoring](/getting-started/llm-monitoring) - Track production LLM performance * [Guardrails](/getting-started/guardrails) - Add real-time safety validation # Overview Source: https://docs.fiddler.ai/evaluate-and-test/overview Hands-on quick start guides for evaluating LLM applications, testing with custom LLM-as-a-Judge metrics, and comparing model outputs using Fiddler Experiments. ## Quick Start Guides Ready to start testing your LLM applications? Choose the hands-on guide that matches your evaluation needs. Each quick start provides step-by-step instructions, code examples, and takes 15-20 minutes to complete. **New to Fiddler Experiments?** Start with our [comprehensive Experiments guide](/getting-started/experiments) to understand core concepts, workflows, and best practices before diving into these quick starts. *** ### Evals SDK Quick Start **Build comprehensive experiment workflows with built-in and custom evaluators** Fiddler Experiments results example page **What you'll learn:** * Connect to Fiddler and set up evaluation projects * Create datasets with test cases (CSV, JSONL, or DataFrame) * Use production-ready evaluators (Relevance, Coherence, Toxicity, Sentiment) * Build custom evaluators for domain-specific requirements * Run experiments with parallel processing * Analyze results and export data for further analysis **Perfect for:** * Teams needing full control over evaluation logic * Building comprehensive test suites with multiple quality dimensions * Creating domain-specific custom metrics * Programmatic experiment workflows and CI/CD integration **Time to complete:** \~20 minutes [Start Evals SDK Quick Start →](/evaluate-and-test/evals-sdk-quick-start) *** ### Prompt Specs Quick Start **Create custom LLM-as-a-Judge evaluations without manual prompt engineering** **What you'll build:** A news article topic classifier that demonstrates: * Schema-based evaluation definition (no prompt writing!) * Validation and testing workflows * Iterative improvement with field descriptions * Production deployment as Fiddler enrichments **What you'll learn:** * Define evaluation schemas using JSON * Validate Prompt Specs before deployment * Test evaluation logic with sample data * Improve accuracy through structured descriptions * Deploy custom evaluators to production monitoring **Perfect for:** * Teams needing domain-specific evaluation logic * Avoiding time-consuming prompt engineering * Rapid iteration on evaluation criteria * Schema-driven evaluation workflows **Time to complete:** \~15 minutes [Start Prompt Specs Quick Start →](/evaluate-and-test/prompt-specs-quick-start) *** ### Compare LLM Outputs **Systematically compare different LLM models to make data-driven decisions** **What you'll learn:** * Compare outputs from different LLM models (GPT-4, Claude, Llama, etc.) * Evaluate multiple prompt variations side-by-side * Use Fiddler's observability features for pre-production testing * Balance quality, cost, and latency trade-offs **Perfect for:** * Model selection and validation * Prompt A/B testing and optimization * Cost optimization through model comparison * Pre-production evaluation of LLM outputs **Time to complete:** \~15 minutes **Interactive notebook:** * [Open in Google Colab](https://colab.research.google.com/github/fiddler-labs/fiddler-examples/blob/main/quickstart/latest/Fiddler_Quickstart_LLM_Comparison.ipynb) * [Download from GitHub](https://github.com/fiddler-labs/fiddler-examples/blob/main/quickstart/latest/Fiddler_Quickstart_LLM_Comparison.ipynb) [Start Comparing Models →](/evaluate-and-test/llm-evaluation-example) *** ## Choosing the Right Quick Start Not sure which guide to start with? Use this table: | Goal | Recommended Guide | | -------------------------------------------- | ----------------------------------------------------------------------- | | Implement custom domain logic (schema-based) | [Prompt Specs Quick Start](/evaluate-and-test/prompt-specs-quick-start) | | Implement custom domain logic (Python-based) | [Evals SDK Quick Start](/evaluate-and-test/evals-sdk-quick-start) | | Build test suites | [Evals SDK Quick Start](/evaluate-and-test/evals-sdk-quick-start) | | Compare models | [Compare LLM Outputs](/evaluate-and-test/llm-evaluation-example) | **Quick recommendations:** * 🎯 **First-time users**: Start with [Evals SDK Quick Start](/evaluate-and-test/evals-sdk-quick-start) to learn the fundamentals * 🔧 **Custom evaluations needed**: Use [Prompt Specs Quick Start](/evaluate-and-test/prompt-specs-quick-start) for schema-based approach * 📊 **Model comparison**: Jump to [Compare LLM Outputs](/evaluate-and-test/llm-evaluation-example) for side-by-side testing ## Core Evaluation Concepts These quick starts demonstrate key Fiddler Experiments capabilities: ### Built-in Evaluators Production-ready metrics that run on [Fiddler Centor Models](/glossary/centor-models): * **Quality**: Answer Relevance, Coherence, Conciseness, Completeness * **Safety**: Toxicity Detection, Prompt Injection, PII Detection * **RAG-Specific**: Faithfulness, Context Relevance * **Sentiment**: Multi-score sentiment and topic classification **Key benefits:** * Zero external API costs * \<100ms latency for real-time evaluation * Your data never leaves your environment ### Custom Evaluation Frameworks Build domain-specific evaluators using: * **Python-based evaluators** - Full programmatic control * **Prompt Specs** - Schema-driven LLM-as-a-Judge (no manual prompting) * **Function wrappers** - Integrate existing evaluation logic ### Experiment Tracking & Comparison Every experiment run is tracked: * Complete lineage of inputs, outputs, and scores * Side-by-side experiment comparison in Fiddler UI * Aggregate statistics and drill-down analysis * Export capabilities for further processing ## Common Experiment Workflows These quick starts support various experiment scenarios: ### Pre-Production Testing * **Regression Testing**: Run comprehensive test suites before deployment * **Quality Gates**: Set score thresholds that must be met * **Version Validation**: Compare model versions on same datasets ### Model & Prompt Optimization * **A/B Testing**: Compare prompt variations quantitatively * **Model Selection**: Evaluate multiple LLMs on same tasks * **Hyperparameter Tuning**: Test temperature, top-p, and other configs ### RAG System Evaluation Evaluate RAG pipelines end-to-end using the [RAG Health Metrics](/getting-started/experiments) evaluators — a purpose-built diagnostic framework that pinpoints whether issues originate in retrieval, generation, or query understanding: * **Answer Relevance 2.0**: Assess how well responses address user queries with ordinal scoring (High / Medium / Low) * **Context Relevance**: Measure whether retrieved documents are relevant to the query (High / Medium / Low) * **RAG Faithfulness**: Verify responses are grounded in retrieved documents (Yes / No with reasoning) Use these evaluators together to diagnose specific failure modes — for example, high faithfulness with low relevance indicates the response is grounded but doesn't answer the question, pointing to a retrieval problem rather than a generation problem. ### Safety & Compliance * **Adversarial Testing**: Test with jailbreak attempts and prompt injections * **Content Moderation**: Measure toxicity, bias, and PII exposure * **Policy Validation**: Ensure outputs meet organizational standards ## From Development to Production Fiddler Experiments integrates seamlessly with production monitoring: **Unified Workflow Benefits:** * **Consistent Metrics**: Same evaluators in development and production * **Continuous Learning**: Production insights feed back into test datasets * **Seamless Transition**: Deploy with confidence—monitoring matches testing **Complete AI Lifecycle:** 1. **Build** → Design and instrument your applications 2. **Test** → Evaluate with Fiddler Experiments *(these quick starts)* 3. **Monitor** → Track production with [Agentic Monitoring](/getting-started/agentic-monitoring) 4. **Improve** → Refine based on insights Learn more about [Fiddler's end-to-end agentic AI lifecycle](https://www.fiddler.ai/blog/end-to-end-agentic-observability-lifecycle). ## Getting Started Checklist Ready to evaluate your LLM applications? * [ ] Choose a quick start guide based on your evaluation needs * [ ] Install the [Fiddler Evals SDK](/sdk-api/evals/evaluate) (for SDK and Prompt Specs guides) * [ ] Prepare 5-10 sample test cases for your application * [ ] Follow the step-by-step guide (15-20 minutes) * [ ] Review results in Fiddler UI * [ ] Iterate and expand your experiment coverage ## Additional Resources **Learn More:** * [Experiments Overview](/getting-started/experiments) - Comprehensive guide to Fiddler Experiments * [Evals SDK Advanced Guide](/developers/tutorials/experiments/evals-sdk-advanced) - Production patterns * [Fiddler Evals SDK Reference](/sdk-api/evals/evaluate) - Complete API documentation * [Experiments Glossary](/glossary/experiments) - Key terminology **Example Notebooks:** * [Evaluations SDK Notebook](https://github.com/fiddler-labs/fiddler-examples/blob/main/quickstart/latest/Fiddler_Quickstart_Evaluations_SDK.ipynb) * [Prompt Specs Notebook](https://github.com/fiddler-labs/fiddler-examples/blob/main/quickstart/latest/Fiddler_Quickstart_LLMaaJ_Prompt_Spec.ipynb) * [LLM Comparison Notebook](https://github.com/fiddler-labs/fiddler-examples/blob/main/quickstart/latest/Fiddler_Quickstart_LLM_Comparison.ipynb) **Related Capabilities:** * [Agentic Monitoring](/getting-started/agentic-monitoring) - Production agent observability * [LLM Monitoring](/getting-started/llm-monitoring) - Production LLM tracking * [Guardrails](/getting-started/guardrails) - Real-time safety validation # Prompt Specs Quick Start Source: https://docs.fiddler.ai/evaluate-and-test/prompt-specs-quick-start Get started with Fiddler's LLM-as-a-Judge evaluation using Prompt Specs in minutes. Learn to create custom evaluations, test them, and deploy to production monitoring. Get your first custom LLM evaluation running in **minutes** using Prompt Specs with Fiddler's LLM-as-a-Judge solution. This guide walks you through creating, testing, and deploying a custom evaluation using Prompt Specs. ### What You'll Build In this quick start, you'll create a news article topic classifier that: * Takes a news summary as input * Classifies it into one of four categories: World, Sports, Business, or Sci/Tech * Provides reasoning for its classification * Deploys to production monitoring in Fiddler ### Prerequisites * Fiddler platform access * Basic familiarity with Python and REST APIs * A Fiddler API token and base URL Refer to the Fiddler Python client SDK [Installation and Setup Guide](/developers/python-client-guides/installation-and-setup) for details on the Fiddler Access Token, URL, and client initialization. ```python theme={null} import json import fiddler as fdl import pandas as pd import requests # Replace with your actual values FIDDLER_TOKEN = "your_token_here" FIDDLER_BASE_URL = "https://your_company.fiddler.ai" PROMPT_SPEC_URL = f"{FIDDLER_BASE_URL}/v3/llm-as-a-judge/prompt-spec" FIDDLER_HEADERS = { "Authorization": f"Bearer {FIDDLER_TOKEN}", "Content-Type": "application/json", } ``` We'll use news article data for this example: ```python theme={null} # Load sample news data (using AG News dataset) df_news = pd.read_parquet( "hf://datasets/fancyzhx/ag_news/data/test-00000-of-00001.parquet" ).sample(20, random_state=25) # Map labels to topic names df_news["original_topic"] = df_news["label"].map({ 0: "World", 1: "Sports", 2: "Business", 3: "Sci/Tech" }) # Summarize the count of each unique topic print(df_news["original_topic"].value_counts()) ``` Define a simple evaluation schema: ```python theme={null} basic_prompt_spec = { "input_fields": { "news_summary": {"type": "string"} }, "output_fields": { "topic": { "type": "string", "choices": ["World", "Sports", "Business", "Sci/Tech"] }, "reasoning": {"type": "string"} } } ``` Validate your Prompt Spec schema: ```python theme={null} validate_response = requests.post( f"{PROMPT_SPEC_URL}/validate", headers=FIDDLER_HEADERS, json={"prompt_spec": basic_prompt_spec} ) if validate_response.status_code == 200: print("✅ Schema validation successful!") else: print("❌ Validation failed:", validate_response.text) ``` ```python theme={null} def get_prediction(prompt_spec, input_data): response = requests.post( f"{PROMPT_SPEC_URL}/predict", headers=FIDDLER_HEADERS, json={"prompt_spec": prompt_spec, "input_data": input_data} ) if response.status_code == 200: return response.json()["prediction"] return {"topic": None, "reasoning": None} # Test with a single example test_result = get_prediction( basic_prompt_spec, {"news_summary": "Wimbledon 2025 is under way!"} ) print(json.dumps(test_result, indent=2)) ``` Add field descriptions to improve classification accuracy: ```python theme={null} enhanced_prompt_spec = { "instruction": "Determine the topic of the given news summary.", "input_fields": { "news_summary": {"type": "string"} }, "output_fields": { "topic": { "type": "string", "choices": ["World", "Sports", "Business", "Sci/Tech"], "description": """Use 'Sci/Tech' for technology companies, scientific discoveries, or health/medical research. Use 'Sports' for sports events or athletes. Use 'Business' for companies outside of tech/sports. Use 'World' for global events or issues.""" }, "reasoning": { "type": "string", "description": "Explain why you chose this topic." } } } ``` Test your enhanced Prompt Spec on multiple examples: ```python theme={null} # Test on your dataset results = [] for _, row in df_news.iterrows(): prediction = get_prediction( enhanced_prompt_spec, {"news_summary": row["text"]} ) results.append({ "original": row["original_topic"], "predicted": prediction["topic"], "reasoning": prediction["reasoning"] }) # Calculate accuracy df_results = pd.DataFrame(results) accuracy = (df_results["original"] == df_results["predicted"]).mean() print(f"Accuracy: {accuracy:.1%}") ``` Once satisfied with your Prompt Spec, deploy it as a Fiddler enrichment: ```python theme={null} import fiddler as fdl # Initialize Fiddler client fdl.init(url=FIDDLER_BASE_URL, token=FIDDLER_TOKEN) # Create project and enrichment project = fdl.Project.get_or_create(name="llm_evaluation_demo") enrichment = fdl.Enrichment( name="news_topic_classifier", enrichment="llm_as_a_judge", columns=["news_summary"], config={"prompt_spec": enhanced_prompt_spec} ) # Create model with enrichment model_spec = fdl.ModelSpec( inputs=["news_summary"], custom_features=[enrichment] ) model = fdl.Model.from_data( source=df_news.rename(columns={"text": "news_summary"}), name="news_classifier", project_id=project.id, spec=model_spec, task=fdl.ModelTask.LLM ) model.create() print(f"Model created: {model.name}") ``` Publish your data and start monitoring: ```python theme={null} # Publish production events job = model.publish_batch(source=df_news.rename(columns={"text": "news_summary"})) job.wait() if job.status == "SUCCESS": print("✅ Data published successfully!") print("🎯 Your evaluation is now running in production monitoring") ``` ```python theme={null} import json from datetime import datetime import fiddler as fdl import pandas as pd import requests # Replace with your actual values # FIDDLER_TOKEN = "your_token_here" # FIDDLER_BASE_URL = "https://your_company.fiddler.ai" FIDDLER_TOKEN = "hqvUV7r8-WUkMkjvKHbvI_sVpxRd9DJLKX6PCloRwVk" FIDDLER_BASE_URL = "https://preprod.cloud.fiddler.ai" PROMPT_SPEC_URL = f"{FIDDLER_BASE_URL}/v3/llm-as-a-judge/prompt-spec" FIDDLER_HEADERS = { "Authorization": f"Bearer {FIDDLER_TOKEN}", "Content-Type": "application/json", } # Load sample news data (using AG News dataset) df_news = pd.read_parquet( "hf://datasets/fancyzhx/ag_news/data/test-00000-of-00001.parquet" ).sample(20, random_state=25) # Map labels to topic names df_news["original_topic"] = df_news["label"].map({ 0: "World", 1: "Sports", 2: "Business", 3: "Sci/Tech" }) print(df_news["original_topic"].value_counts()) basic_prompt_spec = { "input_fields": { "news_summary": {"type": "string"} }, "output_fields": { "topic": { "type": "string", "choices": ["World", "Sports", "Business", "Sci/Tech"] }, "reasoning": {"type": "string"} } } validate_response = requests.post( f"{PROMPT_SPEC_URL}/validate", headers=FIDDLER_HEADERS, json={"prompt_spec": basic_prompt_spec} ) if validate_response.status_code == 200: print("✅ Schema validation successful!") else: print("❌ Validation failed:", validate_response.text) def get_prediction(prompt_spec, input_data): response = requests.post( f"{PROMPT_SPEC_URL}/predict", headers=FIDDLER_HEADERS, json={"prompt_spec": prompt_spec, "input_data": input_data} ) if response.status_code == 200: return response.json()["prediction"] return {"topic": None, "reasoning": None} # Test with a single example test_result = get_prediction( basic_prompt_spec, {"news_summary": "Wimbledon 2025 is under way!"} ) print(json.dumps(test_result, indent=2)) enhanced_prompt_spec = { "instruction": "Determine the topic of the given news summary.", "input_fields": { "news_summary": {"type": "string"} }, "output_fields": { "topic": { "type": "string", "choices": ["World", "Sports", "Business", "Sci/Tech"], "description": """Use 'Sci/Tech' for technology companies, scientific discoveries, or health/medical research. Use 'Sports' for sports events or athletes. Use 'Business' for companies outside of tech/sports. Use 'World' for global events or issues.""" }, "reasoning": { "type": "string", "description": "Explain why you chose this topic." } } } # Test on your dataset results = [] for _, row in df_news.iterrows(): prediction = get_prediction( enhanced_prompt_spec, {"news_summary": row["text"]} ) results.append({ "original": row["original_topic"], "predicted": prediction["topic"], "reasoning": prediction["reasoning"] }) # Calculate accuracy df_results = pd.DataFrame(results) accuracy = (df_results["original"] == df_results["predicted"]).mean() print(f"Accuracy: {accuracy:.1%}") ``` ### What Happens Next After completing this quick start: 1. **View Results**: Check the Fiddler UI to see your model and enrichment results 2. **Monitor Performance**: Set up alerts based on classification accuracy or confidence scores 3. **Iterate**: Refine your Prompt Spec descriptions to improve accuracy 4. **Scale**: Apply the same approach to your own evaluation use cases ### Key Takeaways * **Fast Setup**: From zero to production evaluation in minutes, not weeks * **No Manual Prompting**: JSON schema approach eliminates prompt engineering bottlenecks * **Built-in Monitoring**: Seamless integration with Fiddler's observability platform * **Easy Iteration**: Update schemas without rewriting prompts ### Next Steps * [**Complete Interactive Notebook**](https://github.com/fiddler-labs/fiddler-examples/blob/main/quickstart/latest/Fiddler_Quickstart_LLMaaJ_Prompt_Spec.ipynb): Follow along with a full working example * [**Prompt Specs Guide**](/observability/llm/llm-evaluation-prompt-specs): Learn more about the underlying framework # Agentic Observability Source: https://docs.fiddler.ai/getting-started/agentic-monitoring Comprehensive monitoring, tracing, and analysis of AI agent systems that provide hierarchical visibility into agent reasoning, coordination, and decision-making across multi-agent applications Modern GenAI applications built with agentic frameworks create complex, multi-step workflows that can be difficult to understand and debug. Fiddler, the pioneer in AI Observability and Security, provides comprehensive monitoring solutions for AI agents regardless of your framework. Whether you're using LangGraph, Strands, or custom implementations, you get complete visibility into agent behaviors with enterprise-grade safeguards and real-time monitoring—the insights you need to confidently deploy reliable, high-performance GenAI applications in production. **First Time Setting Up?** Before you can start monitoring your agentic application, you need to create a project and application in Fiddler. See [Onboard Your GenAI Application](/getting-started/genai-application-onboarding) for step-by-step instructions. ## What Is Agentic Observability? Agentic monitoring observes and analyzes AI agent behavior in real-time. Unlike traditional application monitoring that focuses on system metrics, agentic observability captures the unique characteristics of AI workflows: * **Agent decision-making processes**: How agents choose between different tools and actions * **Multi-step reasoning chains**: Complex workflows from initial prompt to final response * **LLM interactions**: Model inputs, outputs, and performance across different calls * **Tool usage patterns**: How agents utilize external functions and APIs * **Error propagation**: How failures cascade through agent workflows Overview diagram of the Fiddler agentic SDK: an agent application is instrumented by a Fiddler SDK, which exports OpenTelemetry traces to the Fiddler platform for monitoring and analysis ## Why Agentic Observability Matters GenAI applications present unique observability challenges that traditional monitoring approaches can't address: ### Complexity and Opacity AI agents make autonomous decisions that are difficult to predict or understand. Without proper monitoring, you can't debug agent behavior in production or understand why an agent made specific choices. ### Dynamic Workflows Unlike traditional applications with fixed execution paths, AI agents create dynamic workflows based on context and available tools. You need to trace the actual execution path for each interaction. ### Performance Variability LLM response times and quality vary significantly based on model load, prompt complexity, and external factors. Monitoring helps you identify performance patterns and optimize accordingly. ### Cost Management GenAI applications consume tokens and compute resources with each LLM call. Understanding usage patterns helps you optimize costs and prevent unexpected billing spikes. ### Quality Assurance AI outputs vary in quality and accuracy. Monitoring helps you identify when agents produce suboptimal results and understand the conditions that lead to better performance. ## Integration Options Fiddler provides flexible integration options to instrument your agentic applications, regardless of the framework you're using. Choose the approach that best fits your technology stack: * **LangGraph & LangChain SDK** — automatic instrumentation with minimal code changes for applications built with LangGraph or LangChain. Initialize the client, and your agent workflows are monitored automatically. * **Strands SDK** — native integration with the Strands framework for monitoring without additional instrumentation code. * **OpenTelemetry** — direct instrumentation for custom frameworks, non-Python applications, or when you need maximum control. Works with any programming language. Initialize the Fiddler client for your framework: ```python LangGraph theme={null} import os from fiddler_langgraph import FiddlerClient, LangGraphInstrumentor fdl_client = FiddlerClient( application_id=os.getenv("FIDDLER_APPLICATION_ID"), api_key=os.getenv("FIDDLER_API_KEY"), url=os.getenv("FIDDLER_URL") ) ``` ```python Strands theme={null} import os from fiddler_strands import FiddlerClient fdl_client = FiddlerClient( application_id=os.getenv("FIDDLER_APPLICATION_ID"), api_key=os.getenv("FIDDLER_API_KEY"), url=os.getenv("FIDDLER_URL") ) ``` ```python OpenTelemetry theme={null} from opentelemetry import trace from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import BatchSpanProcessor # Configure OpenTelemetry to send spans to Fiddler provider = TracerProvider() processor = BatchSpanProcessor(OTLPSpanExporter( endpoint="https://your-instance.fiddler.ai/v1/traces" )) provider.add_span_processor(processor) ``` ### Integration Comparison | Feature | LangGraph SDK | Strands SDK | OpenTelemetry | | ----------------------------- | -------------------- | -------------------- | -------------------------- | | **Automatic Instrumentation** | ✅ Zero code changes | ✅ Native integration | ❌ Manual setup | | **Framework Support** | LangGraph, LangChain | Strands Agents | Any framework | | **Language Support** | Python | Python | Python, Java, Go, JS, etc. | | **Setup Time** | \~15 minutes | \~15 minutes | \~20 minutes | | **Customization** | Medium | Medium | High | ## How Agentic Observability Works Regardless of which integration method you choose, Fiddler's agentic observability provides the same comprehensive observability capabilities: ### Built on OpenTelemetry Standards All Fiddler agentic observability solutions leverage [OpenTelemetry](https://opentelemetry.io/docs/) (OTeL), the industry standard for observability. This ensures compatibility with existing monitoring infrastructure, vendor neutrality, and future-proofing of your investment. ### Automatic or Manual Instrumentation Depending on your integration choice, you can collect telemetry data automatically or with fine-grained control: **Automatic Instrumentation** (LangGraph & Strands SDKs): * Zero-code or minimal-code setup * Automatically captures all agent interactions * Best for rapid deployment and standard use cases **Manual Instrumentation** (OpenTelemetry): * Full control over what data is captured * Custom span attributes and metadata * Best for specialized requirements or custom frameworks All approaches collect the same essential telemetry: * **Distributed traces**: Complete execution flow * **Span attributes**: Inputs, outputs, and metadata * **Performance metrics**: Timing and resource usage * **Error tracking**: Detailed context and stack traces ### Near Real-Time Streaming Telemetry data streams in near real-time to your Fiddler instance, enabling immediate visibility into agent behavior and rapid response to issues. ## Architecture Overview Fiddler's agentic observability integrates seamlessly into your application architecture, regardless of which integration method you choose: ```mermaid theme={null} graph TD subgraph APP["Agent Application"] A([Agents & Workflows]) B([LLM Calls]) C([Tools & Actions]) end subgraph OTEL["OpenTelemetry Layer"] D[Instrumentation] E[Trace Collection & Export] end subgraph FDL["Fiddler AI Platform"] F[Trace Ingestion] G[Monitoring Dashboards] H[Analytics & Evaluators] end A & B & C --> D D --> E E -->|OTLP Protocol| F F --> G F --> H style A fill:#1976d2,color:#fff,stroke:#0d47a1 style B fill:#1976d2,color:#fff,stroke:#0d47a1 style C fill:#1976d2,color:#fff,stroke:#0d47a1 style D fill:#388e3c,color:#fff,stroke:#1b5e20 style E fill:#388e3c,color:#fff,stroke:#1b5e20 style F fill:#f57c00,color:#fff,stroke:#e65100 style G fill:#f57c00,color:#fff,stroke:#e65100 style H fill:#f57c00,color:#fff,stroke:#e65100 style APP fill:#e3f2fd,stroke:#1976d2,color:#0d47a1 style OTEL fill:#e8f5e9,stroke:#388e3c,color:#1b5e20 style FDL fill:#fff3e0,stroke:#f57c00,color:#e65100 ``` ### Key Components 1. **Instrumentation Layer**: Captures agent execution events (automatic with SDKs, manual with OpenTelemetry) 2. **Trace Exporter**: Sends telemetry data to Fiddler using [OTLP](https://opentelemetry.io/docs/specs/otlp/) protocol 3. **Fiddler Client**: Manages configuration, authentication, and connection to your Fiddler instance 4. **OpenTelemetry Integration**: Provides industry-standard distributed tracing across all frameworks ## What You Can Monitor Once your agent application is instrumented, Fiddler provides comprehensive observability through dashboards, metrics, and automated evaluations: ### Dashboards & Visualization Access specialized dashboards designed for agentic workflows: **Pre-Built Agentic Dashboards:** * **Agent Performance Overview** - Monitor success rates, latency, and throughput across all agents * **Workflow Execution Traces** - Visualize complete multi-step reasoning chains hierarchically * **Tool Usage Analytics** - Track which external tools and APIs your agents are calling * **Error & Exception Tracking** - Identify where agent workflows fail and diagnose the root cause **Trace Visualization:** Every agent interaction is captured as a hierarchical trace showing: * Agent decision points and reasoning steps * LLM calls with full inputs, outputs, and metadata * Tool invocations and API requests * Timing information for each step * Parent-child relationships in multi-agent systems **Custom Dashboards:** * Build custom dashboards combining multiple charts to track KPIs specific to your use case * Filter by agent type, user segments, time periods, or custom attributes * Share dashboards with team members and stakeholders * Configure alerts based on dashboard metrics ### Metrics & Analytics Fiddler automatically generates specialized metrics for agent monitoring: **Agent-Specific Metrics:** * **Agent Success Rate** - Percentage of workflows completing successfully * **Tool Call Distribution** - Frequency analysis of tool usage * **Reasoning Chain Length** - Average number of steps per workflow * **Agent Handoffs** - How often agents delegate to other agents * **Retry & Recovery Rate** - Agent resilience and error recovery patterns **Performance Metrics:** * **End-to-End Latency** - Total time from user request to final response * **Per-Step Latency** - Duration of individual reasoning steps, LLM calls, and tool invocations * **Token Usage** - LLM consumption tracking across all agent interactions * **API Call Volume** - Monitor external tool and API usage patterns **Quality Metrics:** * **Response Accuracy** - Validate agent outputs (requires ground truth labels) * **Hallucination Detection** - Identify when agents generate unsupported claims * **RAG Health Metrics** - Diagnose RAG pipeline issues with Answer Relevance 2.0, Context Relevance, and RAG Faithfulness evaluators. Pinpoint whether failures originate in retrieval, generation, or query understanding * **Safety & Guardrails** - Track safety violations and guardrail activations * **User Satisfaction** - Capture feedback signals from end users ### Evaluator Rules **Automated Quality Assessment** Evaluator Rules enable automated, continuous evaluation of your agent's performance directly from production spans and traces. Define once, and Fiddler automatically assesses quality, safety, and performance in real-time. **How Evaluator Rules Work:** 1. **Configure an Evaluator** - Choose from Fiddler-provided evaluators or create custom LLM-as-a-judge evaluators 2. **Map Inputs** - Connect evaluator variables to span attributes from your agent telemetry 3. **Set Application Rules** - Define which spans qualify for evaluation (e.g., only "llm" span types) 4. **Activate** - Evaluations run automatically on all matching spans **Available Evaluators:** * **Fiddler-Provided**: Topic Classification, Answer Relevance, Coherence, Conciseness, Context Relevance, RAG Faithfulness, PII Detection, Sentiment Analysis, Prompt Safety, Response Faithfulness * **Custom LLM-as-a-Judge**: Create domain-specific evaluators with custom prompts and scoring logic **Key Benefits:** * **Automated Quality Monitoring** - Continuous evaluation without manual labeling * **Real-Time Insights** - Identify quality issues as they happen in production * **Backfill Capability** - Apply evaluations retroactively to historical data * **Flexible Filtering** - Evaluate specific span types, regions, or custom conditions → [**Learn more about Evaluator Rules**](/evaluate-and-test/evaluator-rules) ## What Data Is Captured All instrumentation methods capture comprehensive data about your agent workflows: ### Agent Execution Traces * **Workflow structure**: Complete hierarchy of agent steps and decisions * **Timing information**: Duration of each step and overall execution time * **Agent identification**: Unique identifiers for different agents in your system ### LLM Interactions * **Model configuration**: Model name, temperature, and other parameters * **Input prompts**: System messages, user input, and conversation history * **Model outputs**: Generated responses, token usage, and completion metadata * **Performance metrics**: Response time, tokens consumed, and success rates ### Tool and Function Calls * **Tool identification**: Names and types of tools used by agents * **Input parameters**: Arguments passed to functions and tools * **Output results**: Return values and success/failure status * **Execution context**: When and why tools were invoked ### Error and Exception Handling * **Exception details**: Full error messages and stack traces * **Context information**: State of the agent when errors occurred * **Recovery attempts**: How agents handled and recovered from failures ## Key Benefits Agentic observability with Fiddler provides immediate value across your development lifecycle, helping you move beyond experimentation to deploy production AI confidently: ### Development and Learning * **Quick setup**: Start monitoring with just a few lines of code * **Immediate insights**: See agent behavior without complex configuration * **Deep visibility**: Understand decision-making processes beyond just inputs and outputs ### Performance and Optimization * **Hierarchical root cause analysis**: Drill down from application-level issues to specific agent spans to reduce MTTI (Mean Time to Identify) and MTTR (Mean Time to Resolve) * **Application-critical metrics**: Monitor performance, costs, and safety through a unified dashboard * **Quality improvement**: Understand which patterns lead to better results ### Production and Troubleshooting * **Enterprise-grade monitoring**: Track agent performance and success rates at Fortune 500 scale * **End-to-end visibility**: Complete observability into multi-agent interactions and coordination patterns * **Actionable alerts**: Get early warnings on performance issues and cross-agent problems * **Data-driven decisions**: Make informed optimizations based on comprehensive telemetry data ## Security and Privacy Considerations Fiddler's agentic observability is designed with enterprise-grade security and privacy: * **Cloud Enterprise compliance**: SOC 2 Type 2 security and HIPAA compliance standards * **Data encryption**: All telemetry data is encrypted in transit using HTTPS/TLS * **Access control**: Role-based access control (RBAC) and SSO for enterprise user management * **Personal access token**: Access token-based authentication ensures only authorized access * **Data control**: You control what data is captured and sent to Fiddler * **Deployment flexibility**: Deploy in Fiddler Cloud or your own cloud * **Compliance**: Built on industry-standard [OpenTelemetry](https://opentelemetry.io/docs/) for compliance requirements ## Ready to Get Started? You're now ready to add enterprise-grade observability to your agentic and LLM applications. Choose your integration library to get started in under 10 minutes: Instrument LangGraph and LangChain apps. \~10 min. Instrument Strands agents. \~10 min. Instrument any framework or language. \~15 min. Once your application is instrumented, traces appear in your Fiddler dashboard within 1-2 minutes of agent execution. **Learn More:** * [Agentic Observability](/observability/agentic) - Dashboards, metrics, and analytics ## Frequently Asked Questions Traditional APM focuses on system metrics. Agentic observability captures AI-specific behaviors, such as reasoning chains, tool selection, and LLM interactions. Choose based on your framework: LangGraph SDK for LangGraph/LangChain apps, Strands SDK for Strands agents, or OpenTelemetry for custom frameworks or non-Python applications. All provide the same monitoring capabilities. With default settings, expect less than 5% overhead. This can be reduced further with sampling. Yes, all data is encrypted in transit using HTTPS/TLS, and you retain full control over what data is captured and sent to Fiddler. Fiddler supports deployment in your own cloud environment for maximum security. Telemetry data streams in near real-time, typically appearing in your dashboard within 1-2 minutes of agent execution. Yes, all instrumentation methods capture comprehensive error information, including exception details, agent state at failure, and recovery attempts, helping you debug and improve agent reliability. Yes, Evaluator Rules work with spans and traces from all integration methods—LangGraph SDK, Strands SDK, and OpenTelemetry. ## Limitations and Considerations Fiddler Agentic Observability has some current limitations: * **Protocol support**: Currently uses HTTP-based OTLP; gRPC support planned for future releases * **Attribute limits**: Default limits prevent oversized spans; configurable for high-volume use cases * **Language support**: LangGraph and Strands SDKs are Python-only; use OpenTelemetry for other languages These limitations don't affect the core monitoring capabilities but are essential to consider for production planning. ## Next Steps * [Quick Start Guides](/developers/quick-starts/get-started-in-less-than-10-minutes): Choose the quick start applicable to your use case * [SDK References](/sdk-api): Complete technical documentation for all SDK components # AWS SageMaker Partner AI App Source: https://docs.fiddler.ai/getting-started/aws-sagemaker-partner-ai-app Get started with Fiddler's Partner AI App on AWS SageMaker. Monitor, explain, and analyze your ML models and GenAI apps in your own AWS environment. ### Introduction The [Fiddler Partner AI App for Amazon SageMaker](https://aws.amazon.com/marketplace/pp/prodview-caia5ckldtyhs) brings enterprise-grade AI observability directly into your SageMaker environment. As a fully integrated Partner AI App, Fiddler enables data scientists and ML engineers to monitor, analyze, and protect their ML models, LLM applications, GenAI systems, and AI agents in a unified platform without leaving the SageMaker ecosystem. This seamless integration allows you to leverage Fiddler's powerful monitoring capabilities—including drift detection, performance tracking, and root cause analysis features—while maintaining your existing SageMaker workflows and security boundaries. ### What is a Partner AI App? Amazon SageMaker Partner AI Apps are fully managed AI/ML applications from AWS partners that run natively within your SageMaker environment. Think of them as pre-built, enterprise-ready applications that integrate seamlessly with your existing AWS infrastructure—no complex deployments or external accounts required. Diagram showing AWS Cloud VPC containing SageMaker AI workflows and integration points with Fiddler AI **Key Benefits**: * **Secure by Design**: Applications run entirely within your AWS account, maintaining your existing security boundaries and compliance requirements * **Unified Experience**: Access partner tools directly from SageMaker Studio alongside your notebooks, models, and datasets * **Simplified Procurement**: Subscribe through AWS Marketplace with consolidated billing on your AWS invoice * **Managed Infrastructure**: AWS handles the underlying infrastructure while you focus on using the application **How It Works**: When subscribing to a Partner AI App like Fiddler, AWS provisions the application within your SageMaker domain. Your team can then access it through SageMaker Studio with single sign-on, use it via APIs from notebooks, and integrate it into your ML workflows—all while keeping your data within your AWS environment. This approach eliminates the traditional challenges of third-party tool integration: no separate accounts to manage, no data movement across boundaries, and no complex networking configurations. ### For Administrators If you are an AWS administrator responsible for deploying and managing applications, our [Overview](/integrations/cloud-platforms-and-deployment/aws-sagemaker) and [Admin Guide](/integrations/aws-sagemaker/partner-ai-app-admin-guide) supplements the official AWS SageMaker documentation with Fiddler-specific configuration details and best practices. Use our guide alongside the official [Partner AI App Setup](https://docs.aws.amazon.com/sagemaker/latest/dg/partner-app-onboard.html) and [Provisioning](https://docs.aws.amazon.com/sagemaker/latest/dg/partner-apps-provision.html) documentation for a complete deployment experience. Introduction to the Amazon SageMaker Partner AI Apps offering, including the subscription and deployment processes. Fiddler-specific configuration, troubleshooting, and deployment tips. Automated script to configure IAM roles and permissions for quick demo purposes. ### For Users Once your administrator has deployed the Fiddler Partner AI App, you can begin monitoring, analyzing, and protecting your ML models and AI applications. Our [User Guide](/integrations/aws-sagemaker/partner-ai-app-user-guide) provides step-by-step instructions for accessing the Fiddler interface through SageMaker Studio and connecting via the Python client SDK from your notebooks. To trace LLM and agentic applications from SageMaker, the [Fiddler OTel SDK](/integrations/agentic-ai/fiddler-otel-sdk) signs trace exports using the same Partner App authentication — see [Running in AWS SageMaker](/integrations/agentic-ai/fiddler-otel-sdk#running-in-aws-sagemaker). **Before getting started**, confirm with your administrator that: * The Fiddler Partner AI App has been deployed and is in "Deployed" status * Your username has been granted appropriate access permissions * You have been assigned the necessary IAM roles for Partner AI App access * You understand which access method is available in your organization: * **SageMaker Studio access**: Launch Fiddler directly from the Studio interface * **Direct link access**: Access Fiddler via a pre-signed URL generated through AWS CLI Some organizations may only permit direct link access, while others allow both. Your administrator will inform you which option(s) are available. ### Additional Resources For a complete overview and detailed technical information, please refer to Amazon's SageMaker Partner AI App documentation: * [Amazon SageMaker Partner AI Apps Overview](https://docs.aws.amazon.com/sagemaker/latest/dg/partner-apps.html) * [Amazon SageMaker Partner AI Apps Setup Guide](https://docs.aws.amazon.com/sagemaker/latest/dg/partner-app-onboard.html) # Evaluators & Metrics Guide Source: https://docs.fiddler.ai/getting-started/evaluators-metrics-guide Interactive guide for selecting the right Fiddler evaluators and metrics for your use case. Filter by observability type, use case, and rating to find what to deploy. ## How to use this guide Use this guide to choose the right Fiddler evaluators and metrics for what you're building. Start by picking your **observability type** — a Gen AI application, a single LLM, a predictive (ML) model, or real-time Guardrails — then select a use case to see which metrics Fiddler rates **Recommended**, worth a **Consider**, or **Optional** for that scenario. Open any metric card for its per-use-case rationale, evaluator type and model provider, and a link to the documentation. Use **Show more filters** to narrow by evaluator type, model provider, or observability objective, or search by name to jump straight to a specific metric. Below the guide, **Cookbooks & Resources** pairs proven, copy-pasteable recipes with your selection — worked examples for your chosen use case — and **Use Your Own Agent** exports your current filters as context for Claude or any agent. # Experiments Source: https://docs.fiddler.ai/getting-started/experiments Systematically evaluate and compare your LLM and agentic applications with confidence using Fiddler Experiments - comprehensive evaluation framework with built-in metrics (faithfulness, relevancy, saf Building reliable LLM and agentic applications requires more than just deploying models; it requires systematic evaluation to ensure quality, safety, and consistent performance. Fiddler Experiments provides an evaluation framework that helps you test, measure, and improve your AI applications. Whether you're comparing different prompts, testing model updates, or ensuring quality standards, Fiddler Experiments provides the tools to quantify and validate changes. **First Time Setting Up?** Before you can start running experiments, you need to create a project and application in Fiddler. See [Onboard Your GenAI Application](/getting-started/genai-application-onboarding) for step-by-step instructions. ## What Is Fiddler Experiments? Fiddler Experiments is an evaluation platform that helps you measure and improve the quality of your LLM applications. It provides built-in evaluators, custom evaluation support, and a comparison interface to: * **Test systematically**: Create comprehensive test suites with real-world scenarios * **Measure objectively**: Use built-in and custom evaluators to assess quality * **Compare confidently**: Analyze experiments side-by-side to make data-driven decisions * **Improve continuously**: Track progress over time and identify areas for enhancement ### Core Concepts Understanding three key concepts will help you get the most from Fiddler Experiments: Diagram showing three connected components: Datasets containing test cases, Experiments running evaluators against test cases, and Results providing insights with data flow arrows 1. **Datasets**: Collections of test cases with inputs and expected outputs 2. **Experiments**: Test runs that evaluate your application against a dataset 3. **Evaluators**: Metrics that assess specific aspects of your application's performance **New to evaluation terminology?** See our [Experiments Glossary](/glossary/experiments) for definitions of key terms such as evaluator, metric, score, and experiment. **Powered by Fiddler Centor Models** Fiddler Experiments evaluators run on [Fiddler Centor Models](/glossary/centor-models) that operate entirely within your environment—no external API calls, zero hidden costs, and enterprise-grade security. ## Why Choose Fiddler Experiments? Fiddler Experiments stands apart from fragmented evaluation tools by providing an integrated approach to AI quality assurance: ### Unified Development-to-Production Workflow Unlike tools that separate pre-production testing from production monitoring, Fiddler Experiments integrates seamlessly with [Fiddler Agentic Observability](/getting-started/agentic-monitoring). This unified workflow means: * **Consistent metrics**: The same evaluators you use in development run in production monitoring * **Continuous learning**: Production insights feed back into experiment datasets * **Seamless transition**: Deploy with confidence knowing your production monitoring matches your testing ### Cost-Effective with Centor Models Powered by [Fiddler Centor Models](/glossary/centor-models), Fiddler Experiments evaluators run on purpose-built Centor Models: * **Zero Hidden Costs**: No external API calls, no per-request fees, no token charges * **High Performance**: \<100ms response times enable real-time evaluation * **Enterprise Security**: Your data never leaves your environment—no third-party API exposure * **Superior Accuracy**: 50% more accurate than generic models on LLM evaluation benchmarks ### Enterprise-Grade Reliability * **Scalable**: Evaluate thousands of test cases in parallel * **Collaborative**: Team access controls and shared experiment libraries * **Auditable**: Complete traceability for compliance and debugging * **Framework-Agnostic**: Works with any LLM provider or agentic framework ## Why Systematic Evaluation Matters LLM and agentic applications face unique quality challenges that make systematic evaluation essential: ### The Challenge of Variability LLMs and agentic applications are non-deterministic, meaning they can produce different outputs for the same input, making quality assessment difficult. Without systematic evaluation: * You can't reliably detect quality degradation * Improvements are based on anecdotal evidence rather than data * Edge cases and failure modes go unnoticed until production ### The Need for Objectivity Human evaluation is valuable but subjective and doesn't scale. Automated evaluators provide: * Consistent, repeatable measurements * Scalable evaluation across thousands of test cases * Objective metrics for decision-making ### The Power of Comparison Understanding relative performance is crucial for improvement. Side-by-side comparison helps you: * Validate that changes actually improve performance * Choose between different approaches with confidence * Track progress toward quality goals ## Navigating the Fiddler Experiments Interface The Fiddler Experiments interface provides search, filtering, and side-by-side comparison of experiments. Let's explore the key areas you'll use. ### Experiments Dashboard The main dashboard provides an overview of all your experiments, making it easy to track progress and identify trends. Fiddler Experiments dashboard showing searchable table of experiment runs with status indicators (completed, in progress, failed), dataset names, metadata tags, and action buttons for viewing and comparing experiments Key features of the dashboard: * **Search and filter**: Quickly find experiments by name, application, or dataset * **Status indicators**: See which experiments are completed, in progress, or failed * **Metadata display**: View custom metadata to understand experiment context * **Quick actions**: Access experiment details or start comparisons directly ### Viewing Experiment Details Click on any experiment to explore the results in depth and understand your application's performance. Detailed experiment view displaying test case inputs, expected outputs, actual outputs, and multiple evaluator scores (faithfulness, relevance, toxicity) with aggregate statistics panel and export functionality The experiment details view provides: * **Test case results**: See inputs, outputs, and expected outputs for each item * **Evaluator scores**: View all metrics calculated for each test case * **Experiment metadata**: View details and labels that describe the experiment ### Comparing Experiments The comparison view shows performance differences between experiments, helping you validate whether changes improve your application. Side-by-side comparison view showing two experiments and metric selectors Comparison features include: * **Side-by-side metrics**: See how each experiment performs on the same test cases * **Flexible metric selection**: Choose which evaluators to compare ## Core Workflow The typical Fiddler Experiments workflow follows a simple pattern that scales from quick tests to comprehensive experiment suites: **TL;DR**: Create a dataset with test cases → Configure evaluators → Run experiment → Analyze results. Takes \~15 minutes for the first experiment. ```mermaid theme={null} graph TD A[📊 Create Dataset] --> B[✏️ Define Test Cases] B --> C[▶️ Run Experiment] C --> D[📈 Analyze Results] D --> E[🔄 Compare & Iterate] E --> C style A fill:#1976d2,color:#fff,stroke:#0d47a1,stroke-width:3px style B fill:#1976d2,color:#fff,stroke:#0d47a1,stroke-width:3px style C fill:#388e3c,color:#fff,stroke:#1b5e20,stroke-width:3px style D fill:#f57c00,color:#fff,stroke:#e65100,stroke-width:3px style E fill:#7b1fa2,color:#fff,stroke:#4a148c,stroke-width:3px ``` The following walk-through is a high-level overview of a basic experiment workflow. For a fully functional example, refer to our [Quick Start Guide and Notebook](/evaluate-and-test/evals-sdk-quick-start). Refer to the [Evals SDK Technical Reference](/sdk-api/evals/evaluate) for instructions on installing and initializing the `fiddler-evals-sdk` Python package. Start by creating a dataset that represents the scenarios your application needs to handle. This example enters test cases inline in the code, but you may also use a CSV file, JSONL file, or pandas DataFrame to load test cases: ```python theme={null} from fiddler_evals import Dataset, NewDatasetItem # Create dataset dataset = Dataset.create( name="customer-support-qa", application_id=app.id, description="Common customer support questions" ) # Add test cases items = [ NewDatasetItem( inputs={"question": "How do I reset my password?"}, expected_outputs={"answer": "To reset your password, click 'Forgot Password' on the login page..."}, metadata={"category": "account"} ), # Add more test cases... ] dataset.insert(items) ``` Choose evaluators that measure what matters for your use case: ```python theme={null} from fiddler_evals.evaluators import AnswerRelevance, Conciseness, Coherence MODEL = "openai/gpt-4o" CREDENTIAL = "your-llm-credential" # From Settings > LLM Gateway evaluators = [ AnswerRelevance(model=MODEL, credential=CREDENTIAL), # Is the answer relevant to the question? (High/Medium/Low) Conciseness(model=MODEL, credential=CREDENTIAL), # Is the response appropriately brief? Coherence(model=MODEL, credential=CREDENTIAL), # Does the response flow logically? ] ``` **Evaluating a RAG application?** Use the [RAG Health Metrics](#rag-system-evaluation) evaluators (`AnswerRelevance`, `ContextRelevance`, `RAGFaithfulness`) to diagnose retrieval vs. generation issues. **Evaluation Pattern**: Fiddler's built-in evaluators use the [LLM-as-a-Judge](/observability/llm/llm-evaluation-prompt-specs) pattern, where language models assess quality dimensions that are difficult to measure with rule-based systems. This provides automated quality assessment that approximates human evaluation patterns while maintaining consistency across thousands of test cases. Grid showing four evaluator categories: Safety (toxicity, PII detection, prompt injection), Quality (faithfulness, coherence, conciseness), Relevance (answer relevance, context relevance), and Custom (domain-specific logic) with color-coded cards Execute your experiment to see how your application performs: ```python theme={null} from fiddler_evals import evaluate def my_application(inputs, extras, metadata): # Your LLM application logic response = generate_answer(inputs["question"]) return {"answer": response} results = evaluate( dataset=dataset, task=my_application, evaluators=evaluators, name_prefix="v1.0-baseline" ) ``` Use the Fiddler UI to understand your results and identify improvements: 1. Review individual scores to find problem areas 2. Compare experiments to validate improvements 3. Export data for deeper analysis 4. Iterate based on insights ## Understanding Your Experiment Results Interpreting experiment results effectively helps you make informed decisions about your application. ### Reading Score Cards Each evaluator produces scores that help you understand specific aspects of performance: * **Binary scores** (0 or 1): Pass/fail metrics like relevance or correctness * **Continuous scores** (0.0 to 1.0): Gradual metrics like similarity or confidence * **Categorical scores**: Classifications like sentiment (positive/neutral/negative) Visual guide showing three score types: Binary scores with pass/fail indicators, Continuous scores with a gradient bar from 0.0-1.0 showing quality zones (needs work, acceptable, excellent), and Categorical scores with positive/neutral/negative tags ### Identifying Patterns Look for patterns across your test cases: * **Consistent failures**: Indicate systemic issues that need addressing * **Category-specific problems**: Suggest areas needing specialized handling * **Score correlations**: Reveal trade-offs between different metrics ### Making Improvements Use experiment insights to guide your optimization efforts: 1. **Focus on the lowest scores**: Address the most significant quality issues first 2. **Test hypotheses**: Use experiments to validate that changes improve metrics 3. **Monitor trade-offs**: Ensure improvements don't degrade other aspects ## Common Use Cases Fiddler Experiments supports various experiment scenarios across the LLM application lifecycle: ### A/B Testing Prompts Compare different prompt strategies to find what works best: ```python theme={null} # Baseline prompt baseline_results = evaluate( dataset=dataset, task=baseline_prompt_app, evaluators=evaluators, name_prefix="prompt-baseline" ) # Improved prompt improved_results = evaluate( dataset=dataset, task=improved_prompt_app, evaluators=evaluators, name_prefix="prompt-improved" ) # Compare in UI to see which performs better ``` ### Model Version Comparison Validate that model updates improve performance: * Test the same dataset against different model versions * Compare quality metrics side-by-side * Ensure no regression in critical capabilities ### Regression Testing Protect against quality degradation as you develop: * Run standard test suites before deployments * Set quality thresholds that must be met * Track performance trends over time ### Safety Validation Ensure your application meets safety standards: * Test with adversarial inputs * Measure toxicity and bias metrics * Validate content filtering effectiveness ### RAG System Evaluation Evaluate Retrieval-Augmented Generation pipelines using the RAG Health Metrics evaluators — a purpose-built diagnostic framework that pinpoints whether issues originate in retrieval, generation, or query understanding: ```python theme={null} from fiddler_evals.evaluators import AnswerRelevance, ContextRelevance, RAGFaithfulness MODEL = "openai/gpt-4o" CREDENTIAL = "your-llm-credential" # From Settings > LLM Gateway evaluators = [ AnswerRelevance(model=MODEL, credential=CREDENTIAL), # Is the response relevant to the query? (High/Medium/Low) ContextRelevance(model=MODEL, credential=CREDENTIAL), # Are retrieved documents relevant? (High/Medium/Low) RAGFaithfulness(model=MODEL, credential=CREDENTIAL), # Is the response grounded in context? (Yes/No) ] results = evaluate( dataset=dataset, task=my_rag_application, evaluators=evaluators, name_prefix="rag-baseline" ) ``` Use the three evaluators together to diagnose specific failure modes: | What the metrics tell you | Why it's happening | Next Step | | --------------------------------- | ------------------------------------- | ------------------------------------------------ | | High relevance + Low faithfulness | Hallucinations despite being on-topic | Check if retrieval provided sufficient grounding | | High faithfulness + Low relevance | Grounded but didn't answer the query | Check if retrieval provided relevant information | | Low Context Relevance | Retrieval pulling wrong documents | Fix retrieval mechanism | **RAG Health Metrics** works alongside Fiddler's existing 80+ LLM metrics (toxicity, PII, coherence, and more) — providing targeted RAG diagnostics that complement your existing evaluation stack. ### Agentic Application Evaluation Evaluate AI agents and multi-step workflows with specialized patterns: * **Trajectory Evaluation**: Assess agent decision-making sequences and tool selection paths * **Reasoning Coherence**: Validate logical flow from planning through execution * **Tool Usage Quality**: Measure appropriateness and effectiveness of tool calls * **Multi-Agent Coordination**: Track information flow and task delegation patterns **Connect to Production**: Use Fiddler Experiments during development, then monitor agent behavior in production with [Agentic Monitoring](/getting-started/agentic-monitoring). ## Best Practices Follow these practices to get the most value from Fiddler Experiments: ### Building Representative Datasets Create test sets that reflect real-world usage: * **Include edge cases**: Don't just test the happy path—use dataset metadata to tag edge cases for focused analysis * **Balance categories**: Ensure coverage across different scenarios, then use experiment comparison to validate your test distribution matches production patterns * **Use production data**: Incorporate actual user inputs when possible (anonymized and sanitized) * **Update regularly**: Keep test cases current with evolving requirements—track dataset versions in metadata ### Choosing Appropriate Evaluators Select metrics that align with your goals: * **Start with basics**: Answer relevance and safety evaluators (toxicity, PII) are essential for most applications * **Add domain-specific metrics**: Build custom evaluators for specialized needs * **Avoid metric overload**: Focus on 3-5 key metrics that actually drive decisions rather than tracking everything * **Validate with humans**: Spot-check evaluator scores against human judgment to ensure they align with your quality standards ### Setting Up Experiment Cycles Make experiments a routine part of development: * **Pre-deployment testing**: Always evaluate before production changes * **Regular benchmarking**: Schedule periodic comprehensive experiments * **Continuous monitoring**: Track key metrics in production * **Iterative improvement**: Use insights to guide development priorities ## Getting Started Checklist Ready to start evaluating? Follow this simple checklist: * [ ] **Set up your environment**: Install the [Fiddler Evals SDK](/sdk-api/evals/evaluate) * [ ] **Create your first dataset**: Start with 10-20 representative test cases * [ ] **Run a baseline experiment**: Establish current performance levels * [ ] **Review results in the UI**: Understand your application's strengths and weaknesses * [ ] **Improve and compare**: Validate that changes have a positive impact ## Troubleshooting Common Issues ### Experiments Not Appearing If your experiments don't show in the dashboard: * Verify the experiment was completed successfully * Check that you're viewing the correct project/application * Refresh the page to load the latest data ### Unexpected Scores If experiment scores seem incorrect: * Review the evaluator documentation to understand scoring logic * Check that inputs/outputs are formatted correctly * Validate that the correct evaluator parameters are used ### Comparison Not Working If you can't compare experiments: * Ensure both experiments use the same dataset * At least one metric/evaluator should be in common to compare the experiments * Verify experiments have completed successfully * Check that you have permissions to view both experiments ## Next Steps ### From Experiments to Production: The Complete Lifecycle Fiddler Experiments is your **Test** phase in Fiddler's complete [end-to-end agentic AI lifecycle](https://www.fiddler.ai/blog/end-to-end-agentic-observability-lifecycle): **1. Build** → Design and instrument your LLM applications and agents **2. Test** → Evaluate systematically with Fiddler Experiments *(you are here)* **3. Monitor** → Track production performance with Agentic Monitoring **4. Improve** → Use insights to enhance quality and refine your agents This unified approach ensures your evaluation criteria in development become your monitoring standards in production—no fragmentation, no tool switching. *** Choose your path based on your role and goals: **For Developers** 🔧 1. [Evals SDK Quick Start](/evaluate-and-test/evals-sdk-quick-start) - Hands-on tutorial with code 2. [Evals SDK Advanced Guide](/developers/tutorials/experiments/evals-sdk-advanced) - Production-ready configurations 3. [Fiddler Evals SDK](/sdk-api/evals/evaluate) - Complete technical docs **For Teams Scaling AI** 📈 1. [Agentic Monitoring](/getting-started/agentic-monitoring) - Monitor agents in production 2. [LLM Monitoring](/getting-started/llm-monitoring) - Production observability **For Product & Business** 💼 1. Review sample dashboards in your Fiddler instance 2. Schedule a workshop with your Fiddler team 3. Explore case studies and best practices on the Fiddler blog ## Summary Fiddler Experiments adds systematic measurement to LLM application development, replacing ad-hoc testing with quantified assessment. By evaluating your applications, you can: * **Compare experiments quantitatively**: Use side-by-side metrics to validate that changes improve performance * **Track experiment trends**: Monitor quality over time through the experiments dashboard * **Establish quality baselines**: Define acceptable score thresholds for your use case * **Reuse test suites**: Ensure consistency by testing model versions against the same datasets Start with 10-20 test cases and gradually expand your experiment coverage. The metrics you track will help you make informed decisions about model changes and deployment. # Onboard Your GenAI Application Source: https://docs.fiddler.ai/getting-started/genai-application-onboarding Set up your first GenAI project and application in Fiddler. Learn how to create projects, configure applications, and start monitoring your GenAI interactions. This guide walks you through setting up your first **project** and **application**, connecting it to your code, and starting real-time monitoring of your GenAI interactions. *** ## Before You Begin Before onboarding your GenAI application, ensure you have: * **Fiddler Account** - Active access to your Fiddler instance * **GenAI Application** - An LLM-powered application or agent ready to instrument * **Admin or Project Admin Role** - [Permissions](/reference/access-control/role-based-access) to create projects and applications *** ## Key Concepts ### Projects A **project** represents a workspace that groups related AI applications together. Projects are typically organized by product, team, or use case. Each project can have: * Multiple **applications** under it * Shared [**team members**](/reference/administration/settings#teams) and [**permissions**](/reference/access-control/role-based-access) * Consolidated monitoring and analytics across all applications in that project You can **use an existing project** if your team already has one, or **create a new project** for a fresh setup. ### Applications An **application** is the specific GenAI system or integration you want to monitor. It represents one instance of your deployed LLM or agentic workflow—such as a chatbot, summarization API, or evaluation pipeline. Each application has its own: * **Application ID** - Unique identifier for SDK integration * **Monitoring configuration** - Metrics, evaluators, and alerts * **Data streams** - Span events, traces, and performance metrics GenAI Applications page showing applications with project breadcrumb navigation and sort controls *** ## Onboard Your Application 1. Navigate to **GenAI Applications** in the left sidebar 2. Click **Add Application** in the top-right corner 3. Select how to organize your new application: **Option 1: Use Existing Project** * Select **Use Existing Project** * Choose a project from the dropdown menu * Review current team members, add or remove members, or change roles **Option 2: Create New Project** * Select **Create New Project** * (Optional) Add initial team members using the same process as above 4. Click **Next** to continue Add Application dialog showing options to use an existing project or create a new one **Tip:** Choose project names that reflect your team structure or product areas (for example, `CustomerSupportChatbot` or `DataScienceTeamApps`). 1. In the **Create Your Application** step: * Review the selected project name displayed at the top * Enter an **Application Name** in the text field * The name should uniquely identify the GenAI system you're monitoring 2. Click **Create Application** to continue Add Application dialog showing application name entry for the selected project **Note:** Application names must be unique within the project. Choose names that clearly identify the specific use case (for example, `ContentSummarizer` or `CodeAssistant`). Once your application is created, you'll see the **Setup Complete!** confirmation screen with your integration details. Add Application dialog showing completed application setup with credentials **1. Copy Your Credentials** You'll need two pieces of information to connect your application: * **Application ID** - Uniquely identifies your application (UUID format) * **API Key** - Authenticates requests from your code **To copy your credentials:** 1. Locate the **Grab Your Application ID and API Key** section 2. Copy the **Application ID**: * Click the copy icon next to the Application ID field * Store it securely—you'll need it for SDK configuration 3. Copy your **API Key**: * Navigate to **Settings → Credentials** in Fiddler * Copy your API key or create a new one * See [API Keys](/reference/administration/settings#credentials) for details **Security Best Practice** Treat your API key like a password. Never commit it to version control or share it publicly. Use environment variables or secure credential management systems. **2. Integrate Using the SDK** Click **View SDK Documentation** to access integration guides for your technology stack: * **Fiddler LangGraph SDK** - For LangGraph and LangChain applications * **Fiddler Evals SDK** - For custom experiments and testing workflows * **OpenTelemetry Integration** - For custom instrumentation Follow the SDK-specific guide to: 1. Install the Fiddler SDK in your application 2. Configure authentication with your Application ID and API Key 3. Instrument your code to send span events and metrics 4. Verify data is flowing to Fiddler **3. Complete Setup** Once you've copied your credentials and reviewed the integration guide: * Click **Finish Setup** to close the onboarding dialog Your application is now configured and ready to receive monitoring data ## Next Steps Now that your application is onboarded, you can: * **Publish Data** - Run your instrumented application to send span events to Fiddler * **View Live Data** - Navigate to your application to see real-time traces and metrics * **Analyze Performance** - Use dashboards to track latency, throughput, and errors * **Add Evaluators** - Create custom evaluators to assess response quality * **Set Up Alerts** - Configure alerts for anomalies or performance degradation * **Define Rules** - Create business rules for content moderation or compliance * **Add More Applications** - Onboard additional GenAI systems under the same project * **Organize by Team** - Create separate projects for different teams or products * **Manage Access** - Use project-level permissions to control who can view and modify applications *** ## Frequently Asked Questions No, once an application is created within a project, it cannot be moved to another project. If you need to reorganize, you'll need to create a new application in the correct project. There is no hard limit on the number of applications per project. However, for better organization, we recommend grouping related applications that share common team members or business context. Deleting a project will remove all applications, monitoring data, and configurations within that project. This action cannot be undone. Ensure you export any data you need before deletion. No, each application instance (development, staging, production) should have its own Application ID. This allows you to monitor each environment separately and apply different configurations or alerts. Your API key is available in **Settings → Credentials**. See [Creating API Keys](/reference/administration/settings#creating-api-keys) for step-by-step instructions. *** ## Related Documentation Instrument LangGraph applications in 10 minutes. Run experiments for your GenAI applications. Understand project and application concepts. Manage team permissions. Create and manage API keys. *** # Guardrails Source: https://docs.fiddler.ai/getting-started/guardrails Fiddler Guardrails protects GenAI and agentic applications against hallucinations, safety risks, and jailbreaks in real time — available via the Fiddler API. ### Overview Fiddler Guardrails provides enterprise-grade protection against critical LLM risks in production environments. This solution actively moderates and mitigates harmful content in both prompts and responses, including hallucinations, toxicity, safety violations, prompt injection attacks, and jailbreaking attempts. The solution is powered by proprietary, fine-tuned, task-specific Fiddler Centor Models, specifically engineered for real-time content analysis. ### Key Benefits * **Industry’s Fastest Guardrails**: Achieves sub-100ms latency for real-time moderation without impacting user experience * **Enterprise Scalability:** Handles 5+ million daily requests with consistent performance and reliability * **Resource Efficiency**: Purpose-built Centor Models deliver high accuracy with significantly lower computational requirements than general-purpose LLMs * **Enterprise Security**: Deployed in the customer’s VPC or air-gapped environment with data never leaving the customer’s environment ### Availability Fiddler Guardrails is available as part of the Fiddler AI Observability and Security platform. You access Guardrails in your own Fiddler environment over the REST API (`https://{fiddler_endpoint}/v3/guardrails/*`) using a Fiddler API key generated from **Settings → [Credentials](/reference/administration/settings#credentials)**. Fiddler Guardrails covers safety, faithfulness (hallucination), and PII/PHI detection, each powered by a purpose-built Fiddler Centor Model. See the [Quick Start Guide](/protection/guardrails-quick-start) to set up access and make your first call. ### Next Steps Explore additional documentation to get the most out of your Fiddler Guardrails experience. #### Fiddler Guardrails guides include: * [Quick Start Guide](/protection/guardrails-quick-start) * [Guardrails Documentation](/protection/guardrails) * [Frequently Asked Questions](/protection/guardrails-faq) * Notebook Tutorials: * [Safety](/developers/tutorials/guardrails/guardrails-safety) * [Faithfulness](/developers/tutorials/guardrails/guardrails-faithfulness) * [PII](/developers/tutorials/guardrails/guardrails-pii) # LLM Monitoring Source: https://docs.fiddler.ai/getting-started/llm-monitoring Monitor LLM applications in production with Fiddler. Track quality, safety, and performance enrichments, detect problematic responses, and diagnose issues before they reach users. ## Fiddler LLM Monitoring Introduction ### What Is LLM Monitoring? Large Language Models (LLMs) are powerful, but they introduce unique challenges around accuracy, safety, and reliability. Effective monitoring is critical for detecting issues like hallucinations, toxic content, and performance degradation in production LLM applications. ### How Fiddler LLM Monitoring Works Fiddler's LLM monitoring solution tracks your AI application's inputs and outputs, then enriches this data with specialized metrics that measure quality, safety, and performance. These enrichments provide visibility into how your LLM applications behave in production, enabling you to: * Detect problematic responses before they impact users * Identify patterns of failure across your applications * Track performance trends over time * Analyze root causes when issues occur ### Key Capabilities * **Comprehensive Metrics**: Monitor hallucinations, toxicity, relevance, latency, and many other LLM-specific metrics * **Real-time Analysis**: Track performance as it happens with intuitive dashboards * **Advanced Enrichments**: Generate embeddings, similarity scores, and specialized trust metrics automatically * **Drift Detection**: Identify when prompts or responses drift from expected patterns * **RAG-specific Monitoring**: For retrieval-augmented applications, analyze retrieval quality and source relevance ### Getting Started Implementing Fiddler LLM monitoring requires just three steps: Define its inputs, outputs, and which enrichment metrics you need. Send prompts, responses, and context to Fiddler. Use dashboards and alerts to track the metrics most important to your use case. Fiddler handles the complex work of generating enrichments, detecting anomalies, and providing the visualizations you need to maintain high-quality LLM applications. ### Next Steps Stand up LLM monitoring end to end in about 10 minutes. * [Understanding LLM enrichment metrics](/observability/llm/enrichments) * [How Fiddler generates LLM metrics](/observability/llm/llm-based-metrics) * [Available LLM metrics](/observability/llm/selecting-enrichments) * [Create LLM visualizations using embeddings](/observability/llm/embedding-visualization-with-umap) * [Fiddler Python client SDK](/sdk-api/python-client/connection) * [Fiddler Python client SDK guides](/developers/python-client-guides/installation-and-setup) # ML Observability Source: https://docs.fiddler.ai/getting-started/ml-observability Monitor traditional ML models in production with Fiddler. Track performance, detect data drift, run root cause analysis, and ensure model fairness at scale. ### Introduction Fiddler is a comprehensive AI observability platform that helps data science teams monitor, explain, and improve their machine learning models and LLM applications in production. Our platform provides the visibility and insights you need to ensure your AI systems perform reliably and deliver business value. With Fiddler, you can: * **Monitor model health** across traditional ML models and LLM applications with specialized metrics * **Detect issues early** through customizable alerts and drift detection * **Debug problems quickly** with explainable AI and root cause analysis tools * **Ensure model fairness** through segment analysis and bias detection * **Optimize performance** with detailed traffic and performance tracking Whether you're managing a few models or hundreds, Fiddler provides the tools to maintain confidence in your AI systems as they scale. ## Key Capabilities ### Comprehensive Monitoring * **Performance Tracking**: Monitor model accuracy, precision, recall, and other ML metrics in real time across all your deployments * **Data Drift Detection**: Identify shifts in your production data that could impact model performance before they cause issues * **Data Integrity Checks**: Ensure your models receive valid, properly formatted data that meets your expectations * **Vector Monitoring**: Specialized tools for monitoring embedding-based and vector search applications ### Advanced Analytics * **Embedding Visualization**: Explore high-dimensional data using UMAP to understand patterns and clusters * **Model Segmentation**: Analyze performance across different user cohorts to identify bias and uncover targeted improvements * **Statistical Analysis**: Generate detailed statistics on model inputs, outputs, and performance metrics * **Custom Metrics**: Define and track metrics specific to your business needs and use cases ### Getting Started Implementing Fiddler ML monitoring requires just three steps: Define its inputs, outputs, and related metadata. Send the "digital exhaust" from your model serving platform to Fiddler. Use dashboards and alerts to track the metrics most important to your use case. Fiddler automatically handles the complex work of generating metrics, detecting anomalies, and providing the visualizations you need to maintain high-quality ML systems. ### Next Steps Stand up ML monitoring end to end in about 10 minutes. * [Available auto-generated metrics](/observability/platform) * [Data drift and model performance](/observability/platform/performance-tracking-platform) * [Setting up alerts](/observability/platform/alerts-platform) * [Creating your own custom metrics](/glossary/custom-metrics) * [Diagnose issues with Root Cause Analysis](/observability/analytics#root-cause-analysis) * [Auto-generated and custom dashboards](/observability/dashboards) * [Fiddler Python client SDK](/sdk-api/python-client/connection) * [Fiddler Python client SDK guides](/developers/python-client-guides/installation-and-setup) # Agentic Observability Source: https://docs.fiddler.ai/glossary/agentic-observability Comprehensive monitoring, tracing, and analysis of AI agent systems that provides hierarchical visibility into agent reasoning, coordination, and decision-making across distributed multi-agent applica Agentic Observability is the practice of monitoring, tracing, and analyzing autonomous AI agent systems to ensure their reliability, transparency, and alignment with business objectives. It extends beyond traditional application performance monitoring (APM) by capturing the cognitive lifecycle of AI agents—including reasoning processes, tool selection, execution outcomes, self-reflection, and inter-agent coordination—to provide complete visibility into distributed multi-agent systems. Unlike traditional observability, which tracks deterministic metrics such as latency and error rates, Agentic Observability addresses the unique challenges of probabilistic, goal-driven systems that autonomously plan, decide, and adapt based on dynamic environments and outcomes. Example of a travel planner implemented with a multi-agent system ## Core Terminology ### Agent An autonomous AI system that can plan actions, make decisions, interact with tools, and learn from experience. Agents operate through a cognitive loop of thought, action, execution, reflection, and alignment. ### Multi-Agent System A distributed system where multiple AI agents coordinate to accomplish complex workflows. Each agent maintains its own state, reasoning, and tool interactions while communicating and collaborating with other agents. ### Trace A complete record of an agent's execution path, including all decisions, tool calls, and outcomes for a specific task or session. Traces capture the full context of agent behavior. ### Span An individual unit of work within a trace, representing discrete operations such as tool invocations, API calls, or agent-to-agent communications. Spans form the building blocks of hierarchical observability. ### Session A bounded interaction context containing multiple agent executions, typically representing a complete user request or workflow that may involve multiple agents and numerous traces. Also known as a conversation. ### Tool Call An agent's invocation of external capabilities, APIs, or functions to accomplish specific tasks. Tool calls represent the bridge between agent reasoning and real-world actions. ## How Fiddler Provides Agentic Observability Fiddler's Agentic Observability platform delivers comprehensive monitoring for multi-agent systems through a hierarchical approach that captures data across multiple layers: **1. Application Layer**: High-level system health metrics, aggregated performance indicators, and cross-agent dependencies **2. Session Layer**: User interaction contexts, workflow orchestration patterns, and end-to-end request tracking **3. Agent Layer**: Individual agent performance, reasoning traces, decision paths, and behavioral patterns **4. Action Layer**: Granular tool calls, API interactions, execution results, and timing metrics The platform integrates with leading agentic frameworks (LangGraph, Strands, custom agents) and provides: * **Hierarchical Root Cause Analysis**: Drill down from application-level issues to specific agent decisions or tool failures * **Semantic Tracing**: Capture not just what agents do, but why they make particular decisions * **Cross-Agent Visibility**: Monitor coordination, information flow, and dependencies between agents * **Real-time Behavioral Analysis**: Detect off-policy behavior, coordination failures, and goal misalignment Chart of system faithfulness with hierarchical trace view expanded MAS dashboard with aggregated KPIs and time-series metrics ## Why Agentic Observability Is Important As enterprises deploy multi-agent systems for critical business processes, the complexity of monitoring increases exponentially, requiring up to 26 times more monitoring resources than single-agent applications. Agentic Observability addresses several critical challenges: * **Debugging Complexity**: Multi-agent systems generate extensive reasoning traces, tool logs, and decision paths that traditional APM tools cannot effectively parse or correlate. * **Trust and Compliance**: With 90% of enterprises citing security, trust, and compliance as top concerns for agentic AI, comprehensive observability enables policy enforcement and regulatory adherence. * **Cascading Failures**: Errors in one agent can propagate through dependencies, making root cause analysis essential for system reliability. * **Performance Optimization**: Understanding agent decision-making patterns enables teams to optimize workflows, reduce unnecessary tool calls, and improve response times. * **Alignment Verification**: Ensures agents operate within defined boundaries and adhere to business objectives, preventing autonomous systems from deviating from intended behavior. ## The Agent Lifecycle: Five Observable Stages Fiddler breaks down agent observability into five critical stages that form a continuous feedback loop: 1. **Thought (Ingest, Retrieve, Interpret)**: Captures prompt processing, memory retrieval, belief state formation, and goal interpretation 2. **Action (Plan and Select Tools)**: Monitors decision operationalization, tool selection logic, and execution sequencing 3. **Execution (Perform Tasks)**: Tracks tool invocations, API calls, input/output traces, latency, and success/failure signals 4. **Reflection (Evaluate and Adapt)**: Observes self-critique processes, trajectory scoring, error analysis, and adaptive learning 5. **Alignment (Enforce Trust and Safety)**: Implements guardrails, Centor Model evaluations, and human-in-the-loop interventions ## Types of Agentic Observability * **Development-Time Observability**: Trace and debug multi-agent systems during development to identify coordination issues, optimize workflows, and validate agent behavior before production deployment. * **Runtime Performance Monitoring**: Track operational metrics including agent latency, tool call efficiency, resource utilization, and throughput across distributed agent deployments. * **Behavioral Analysis**: Monitor agent reasoning patterns, decision consistency, goal achievement rates, and adaptation mechanisms to ensure aligned autonomous behavior. * **Coordination Monitoring**: Observe inter-agent communication, information handoffs, task delegation patterns, and collaborative decision-making in multi-agent systems. * **Trust and Safety Monitoring**: Implement continuous evaluation of agent outputs against safety policies, compliance requirements, and ethical guidelines with real-time intervention capabilities. ## Challenges Implementing effective Agentic Observability presents unique technical and operational challenges: * **Data Volume and Complexity**: Multi-agent systems generate massive amounts of hierarchical data across reasoning traces, tool logs, and coordination events, requiring sophisticated data management strategies. * **Semantic Understanding**: Unlike traditional metrics, agent decisions require semantic interpretation to understand the "why" behind actions, not just the "what." * **Real-time Processing**: Agents operate at high speed with complex interdependencies, demanding low-latency observability that doesn't impact system performance. * **Cross-Agent Correlation**: Tracing causality across multiple autonomous agents with asynchronous interactions requires advanced correlation algorithms and timestamp synchronization. * **Dynamic Adaptation**: Agents that learn and adapt their behavior over time make it challenging to establish stable baselines for anomaly detection. * **Privacy and Security**: Monitoring agent reasoning and data flow must strike a balance between comprehensive visibility and data privacy requirements, as well as security constraints. ## Agentic Observability Implementation How-to Guide 1. **Establish Observability Architecture** * Design hierarchical data collection across application, session, agent, and action layers * Implement a unified telemetry pipeline supporting both infrastructure metrics and semantic traces * Configure data retention policies, balancing granularity with storage costs 2. **Instrument Agent Frameworks** * Integrate observability SDKs with your agentic framework (LangGraph, Strands, custom) * Capture agent lifecycle events: thought formation, tool selection, execution, reflection * Implement correlation IDs for cross-agent tracing 3. **Define Behavioral Baselines** * Establish expected agent behavior patterns and decision boundaries * Configure anomaly detection for off-policy actions and coordination failures * Set performance thresholds for latency, success rates, and resource usage 4. **Implement Hierarchical Monitoring** * Create dashboards with drill-down capabilities from the system to the span level * Configure alerts for both technical failures and semantic misalignments * Enable real-time root cause analysis workflows 5. **Deploy Trust and Safety Controls** * Integrate Centor Models for output validation and safety scoring * Implement guardrails for real-time intervention on policy violations * Configure human-in-the-loop escalation for critical decisions 6. **Establish Continuous Improvement** * Analyze agent performance trends and optimization opportunities * Use reflection data to identify systematic improvements * Iterate on agent coordination patterns based on observed bottlenecks ## Frequently Asked Questions **Q: How does Agentic Observability differ from LLM Observability?** Agentic Observability extends beyond monitoring individual LLM calls to capture the complete autonomous decision-making lifecycle, inter-agent coordination, and goal-driven behavior. While LLM Observability focuses on model inputs and outputs, as well as quality metrics, Agentic Observability provides visibility into planning, tool usage, reflection, and multi-agent orchestration. **Q: What frameworks does Fiddler support for Agentic Observability?** Fiddler integrates with leading agent frameworks, including LangGraph, Strands, and custom-built agent systems. The platform offers SDKs and APIs for seamless integration, eliminating the need for architectural changes. **Q: Can Agentic Observability handle real-time monitoring at scale?** Yes, Fiddler's platform is designed for enterprise-scale deployments, featuring hierarchical data aggregation, efficient trace sampling, and distributed processing to maintain low-latency monitoring even with high-volume, multi-agent systems. **Q: How do I monitor agent coordination in distributed systems?** Fiddler provides cross-agent correlation through unified session tracking, distributed tracing with correlation IDs, and visualization of agent dependencies and information flow. The hierarchical view enables tracking coordination from high-level workflows down to individual message passing. ## Related Terms * [LLM Observability](/glossary/llm-observability) * [Guardrails](/glossary/guardrails) * [Centor Models](/glossary/centor-models) * [Root Cause Analysis](/observability/analytics#root-cause-analysis) ## Related Resources * [Agentic Observability in the Enterprise](https://www.fiddler.ai/agentic-observability) * [Building Reliable Agentic Systems](https://www.fiddler.ai/blog/agentic-observability-development) # Baseline Source: https://docs.fiddler.ai/glossary/baseline Reference datasets in Fiddler that serve as comparison points for detecting data drift, evaluating model performance, and identifying when production data deviates from expected patterns. Baselines are data that serve as a point of reference for calculating [data drift](/glossary/data-drift). When determining if data drift has occurred, Fiddler's monitoring features must compare the distribution of production data (at a point in time) to reference data. Baselines serve as this reference. Most commonly, training data is used to establish a model's baseline. In this case, the model's training data is uploaded by publishing the dataset. Fiddler will then create a static pre-production baseline of the same name. Multiple baselines can be defined for a model, too. It is not uncommon to have other baselines defined not from training data but from static sets of historical inferences or rolling baselines that look back weeks, months, or quarters at historical inferences. In other words, a baseline is a representative sample of the data you expect to see in production. It represents the ideal data that your model works best on. For this reason, in most cases, a baseline dataset should be sampled from your model’s training set. ## How Fiddler Uses Baselines Fiddler requires a baseline to detect data drift in production data. Baselines serve as a point of reference for Fiddler to understand what data distributions the model expects to see for all of its inputs and outputs. ## Why Baselines Are Important Baselines are crucial for monitoring and maintaining the performance of machine learning models by serving as a reference point to detect data drift, assess model degradation, and ensure consistency over time. They help teams compare real-world data distributions against expected patterns, enabling proactive adjustments to models, improving fairness, and maintaining compliance with regulatory standards. The roles of baselines in machine learning and model monitoring include: * **Reference for Data Drift Detection**: Baselines serve as a point of reference to compare production data and identify if the data distribution has changed over time (LINK data drift). * **Performance Benchmarking**: Baselines provide a comparison standard for model performance, ensuring that more complex models outperform simple baseline models. * **Model Validation**: They help assess whether a model’s performance is consistent with expectations by comparing it against static or historical data. * **Monitoring Stability**: Baselines enable ongoing tracking of model behavior in production, helping detect any significant deviations in real-time predictions. * **Regulatory Compliance**: They ensure that models align with predefined expectations and regulatory standards, especially in critical industries. * **Error Detection**: Baselines help identify when the model's output deviates beyond acceptable thresholds, guiding corrective actions. ## Types of Baselines * **Static Pre-production**: A fixed baseline created from training data before a model is deployed, used to compare production data against expected distributions. * **Static Production**: A fixed baseline derived from a snapshot of historical production data, used to monitor long-term data stability. * **Rolling Production**: A dynamic baseline that updates periodically using recent production data, allowing for continuous drift monitoring over time. * **Default Static**: A pre-set static production baseline, created automatically when onboarding a model. ## Challenges * **Choosing the Right Data**: It can be challenging to select the appropriate reference data for baselines (e.g., training data, historical inferences, etc.). The data chosen must represent expected real-world conditions to detect data drift effectively. * **Dynamic Data**: In environments with constantly changing data, it’s challenging to define a static baseline that remains relevant over time. Rolling or dynamic baselines may be required but are more complex to manage. * **Handling Bias**: Baselines defined from biased or incomplete data may lead to misleading conclusions, especially if the reference data doesn’t adequately represent diverse real-world scenarios. * **Complexity in Multiple Baselines**: Defining multiple baselines for different use cases or time frames (e.g., historical vs. real-time data) can create confusion and make choosing the right one for comparisons difficult. * **Scalability**: As data volumes and model complexity increase, managing and updating baselines becomes more resource-intensive and burdensome to scale effectively. * **Adaptability**: Baselines that were accurate at one point might not remain effective as the data distribution or model requirements evolve, making it essential to adapt baselines regularly. * **Ensuring Consistency**: Maintaining consistency across multiple baseline definitions can be challenging, especially when different teams or systems define their baselines independently. ## Baseline Implementation How-to Guide 1. **Set up baseline performance metrics** * If monitoring for long-term drift, a static baseline from training data may suffice. * If monitoring for short-term trends, rolling baselines are preferred. 2. **Upload and Define Your Baseline** * Ensure training data is appropriately formatted and uploaded to the monitoring system. * If using Fiddler, define a pre-production baseline using the same model name. 3. **Set Up Monitoring Rules** * Establish thresholds for acceptable levels of drift. * Configure alerts for when drift exceeds predefined thresholds. 4. **Compare Production Data to the Baseline** * Regularly evaluate how production data distributions compare to the baseline. * Adjust the model if significant drift is detected. ## Frequently Asked Questions **Q: What happens if my baseline itself becomes outdated?** You may need to upload an updated baseline periodically or introduce rolling baselines to capture evolving trends. **Q: What is data drift?** Data drift is the change in the statistical properties of input data over time, which can impact a model's performance and predictions. **Q: How do I know if my model is drifting too much?** Set drift thresholds and monitor performance metrics like accuracy, precision, recall, or fairness scores against your baseline. ## Related Terms * [Data Drift](/glossary/data-drift) * [Model Drift](/glossary/model-drift) * [Model Performance](/glossary/model-performance) * [ML Observability](/glossary/ml-observability) ## Related Resources * [Creating Baselines in Fiddler](/developers/python-client-guides/publishing-production-data/creating-a-baseline-dataset) * [Model Onboarding](/developers/python-client-guides/model-onboarding/create-a-project-and-model) * [Python Client SDK](/sdk-api/python-client/dataset) * [Baseline REST API Guide](/sdk-api/rest-api/alert-rules) # Fiddler Centor Models Source: https://docs.fiddler.ai/glossary/centor-models Purpose-built LLMs that evaluate AI outputs in real time, powering both monitoring metrics and real-time guardrails with significantly lower latency than general-purpose models. Fiddler Centor Models are purpose-built LLMs that evaluate AI outputs in real time, with significantly lower latency than general-purpose models. Unlike general-purpose LLMs optimized for content generation, Centor Models are fine-tuned specifically for evaluation tasks — measuring quality, safety, and alignment across a wide range of LLM output dimensions. This specialization enables Centor Models to deliver consistent, rapid assessments with lower computational overhead. Centor Models power two primary capabilities within the Fiddler platform: observability features that generate quality metrics for LLM outputs, and real-time protection through Fiddler Guardrails. By using purpose-built models rather than general-purpose LLMs, Fiddler Centor Models deliver evaluations with lower latency, reduced costs, and improved reliability compared to solutions that rely on third-party LLM APIs. ## What Are Centor Models Centor Models are specialized large language models designed specifically for evaluating and scoring AI system outputs across multiple quality, safety, and reliability dimensions. They assess whether AI-generated content meets established standards for accuracy, safety, ethical alignment, and business requirements. Centor Models evaluate dimensions such as factual accuracy, harmfulness detection, bias identification, and alignment with intended use cases, making them essential components for AI governance and risk management in production environments. Their evaluation-first design means they provide automated, scalable mechanisms for content evaluation that would otherwise require extensive human review. ### Performance Characteristics > **⚡ Performance at Scale** > > 10-100x faster than general-purpose LLMs > Real-time evaluation capabilities > Reduced operational costs Fiddler Centor Models deliver 10-100x faster processing speeds than general-purpose LLMs while maintaining comparable assessment quality, enabling real-time monitoring and guardrail applications with significantly lower computational overhead. This performance profile makes it feasible to monitor high-volume LLM applications in production environments. Lower latency translates directly to reduced operational costs and improved system responsiveness — particularly important for real-time guardrail implementations where evaluation speed directly impacts user experience. ## How Fiddler Uses Centor Models Fiddler Centor Models serve as the evaluation backbone for Fiddler's LLM monitoring and guardrail capabilities, powering two primary functions within the platform: For observability features, Centor Models process LLM inputs and outputs to generate specialized metrics that evaluate output quality, safety, and alignment. These metrics are then integrated into Fiddler's monitoring dashboards and alerting systems. For real-time protection through Fiddler Guardrails, Centor Models evaluate potential LLM outputs against customizable safety policies before they reach end users, filtering out problematic content and providing detailed explanations of policy violations. By maintaining Centor Models as an internal capability, Fiddler ensures consistent, reliable performance with optimized costs compared to solutions that rely on external LLM APIs for similar functionality. ### Evaluation Metrics Coverage > **📊 Comprehensive Evaluation** > > 14+ evaluation dimensions > Safety, quality, and accuracy metrics > Customizable thresholds Fiddler Centor Models assess LLM outputs across multiple critical dimensions to provide comprehensive quality and safety evaluations: **Safety and Risk Metrics:** * Toxicity detection and harmful content identification * Jailbreak attempt recognition and prompt injection detection * Personally identifiable information (PII) exposure assessment * Profanity and inappropriate content filtering **Quality and Accuracy Metrics:** * Faithfulness (Centor Model) — powered by the Centor Model for Faithfulness for groundedness evaluation against source material (uses `context` and `response` inputs) * Answer relevance and context relevance scoring * Coherence and logical consistency assessment * Conciseness and response appropriateness **RAG Health Metrics:** In addition to Centor Model-based metrics, Fiddler provides **RAG Health Metrics** — a diagnostic triad of LLM-as-a-Judge evaluators (Answer Relevance 2.0, Context Relevance, RAG Faithfulness) for comprehensive RAG pipeline evaluation. These evaluators use external LLMs rather than Centor Models. See [RAG Health Diagnostics](/concepts/rag-health-diagnostics) for details. **Specialized Assessments:** * Sentiment analysis and emotional tone evaluation * Topic classification and content categorization * Language detection and multilingual support * Custom regex matching and banned keyword detection This comprehensive metric coverage enables organizations to monitor LLM applications against their specific quality standards and risk tolerance levels. Compare Centor Models cost to third-party LLM evaluators with the [Fiddler Evals TCO calculator](https://www.fiddler.ai/evals-tco-calculator). ## Why Fiddler Centor Models Fiddler Centor Models address several critical challenges in LLM monitoring and governance. By providing specialized models optimized for evaluation tasks, they enable more efficient, cost-effective, and reliable monitoring than solutions dependent on general-purpose LLMs. Centor Models are essential for organizations that need to maintain real-time visibility into their LLM applications while ensuring outputs meet safety and quality standards. They enable faster detection of issues, more comprehensive monitoring coverage, and stronger protections against potentially harmful outputs. As LLM deployments scale across the enterprise, the efficiency of Centor Models becomes increasingly valuable, reducing both operational costs and computational overhead compared to traditional evaluation approaches. * **Performance Optimization**: Fiddler Centor Models are specifically optimized for evaluation tasks, delivering similar quality assessments as general-purpose LLMs but with significantly lower latency and computational requirements. * **Cost Efficiency**: By using purpose-built models rather than larger general-purpose LLMs, Centor Models reduce the computational resources required for comprehensive LLM monitoring, translating to lower operational costs. * **Reliability**: As a dedicated capability maintained by Fiddler, Centor Models provide more consistent availability and performance than solutions dependent on third-party API calls, which may have rate limits or service disruptions. * **Comprehensive Coverage**: Centor Models support both post-deployment monitoring (observability) and pre-deployment protection (guardrails), providing a unified approach to LLM governance throughout the application lifecycle. * **Specialized Evaluation**: Unlike general metrics, Centor Models provide specialized assessments tailored specifically to LLM outputs, measuring dimensions like hallucination, alignment, toxicity, and quality that are unique to generative AI systems. * **Scalability**: As organizations deploy more LLM applications, the efficiency of Centor Models enables monitoring at scale without proportional increases in computational overhead or costs. * **Privacy and Security**: By processing evaluations within Fiddler's infrastructure rather than sending data to third-party APIs, Centor Models help organizations maintain stronger data privacy and security controls. ### Security and Privacy Benefits > **🔒 Enterprise Security** > > Air-gapped deployment ready > No external API dependencies > Full data sovereignty Fiddler Centor Models process all evaluations within Fiddler's managed infrastructure, ensuring customer data never leaves the secure environment. This approach supports compliance with GDPR, HIPAA, and industry-specific standards while enabling air-gapped deployments for organizations with strict security requirements. By eliminating external API dependencies, Centor Models reduce security vulnerabilities and remove third-party availability risks, enabling comprehensive LLM monitoring without compromising data governance policies. ## Challenges Effective LLM monitoring and protection present several technical and operational challenges that Fiddler Centor Models are designed to address. * **Evaluation Latency**: Traditional approaches to LLM evaluation using other LLMs introduce significant latency, which Centor Models address through specialized, efficient models optimized for evaluation tasks. * **Computational Cost**: Evaluating LLM outputs at scale using general-purpose models can be prohibitively expensive, a challenge mitigated by Centor Models' more efficient purpose-built design. * **Coverage vs. Performance**: Organizations often face tradeoffs between comprehensive monitoring coverage and system performance, which Centor Models help balance through optimized evaluation approaches. * **Evaluation Quality**: Simpler metrics may fail to capture nuanced issues in LLM outputs, while Centor Models provide sophisticated evaluations that maintain high correlation with human judgments. * **Real-time Protection**: Implementing guardrails without introducing significant latency is challenging, addressed by Centor Models' efficient architecture and optimized processing pipeline. * **Customization Needs**: Different organizations have varying standards for acceptable content, requiring flexible evaluation systems that can be tailored to specific use cases and policies. * **Integration Complexity**: Adding monitoring to existing LLM deployments can be complex, a challenge Centor Models address through streamlined integration options and APIs. ## Frequently Asked Questions **Q: What advantages do Fiddler Centor Models offer over using general-purpose LLMs for evaluation?** Fiddler Centor Models provide similar quality assessments as general-purpose LLMs but with significantly lower latency, reduced computational requirements, lower costs, and more consistent availability since they don't depend on third-party APIs that may have rate limits or service disruptions. **Q: Can I use Fiddler Centor Models for both monitoring and real-time protection?** Yes, Fiddler Centor Models power both observability features (monitoring metrics) and real-time protection through Fiddler Guardrails. You can implement either or both capabilities depending on your specific needs. **Q: What types of metrics do Centor Models provide?** Centor Models generate specialized metrics for LLM outputs including safety evaluations (detecting harmful, unethical, or inappropriate content), faithfulness assessments (measuring hallucination and factual accuracy), and other quality dimensions like coherence, relevance, and alignment with intended use. **Q: How do Centor Models integrate with my existing LLM applications?** For monitoring, you can publish LLM inputs and outputs to Fiddler's platform either through batch uploads or real-time API calls. For guardrails protection, you integrate the [Guardrails](/glossary/guardrails) API directly into your application flow, sending potential outputs for evaluation before displaying them to users. **Q: Is Fiddler Guardrails a separate product from the Fiddler platform?** No. Fiddler Guardrails is a capability of the Fiddler platform, powered by Centor Models, and is accessed through the Guardrails API within your Fiddler environment. ## Related Terms * [Trust Score](/glossary/trust-score) * [Guardrails](/glossary/guardrails) * [Embedding Visualization](/glossary/embedding-visualization) * [Data Drift](/glossary/data-drift) ## Related Resources * [LLM Monitoring Overview](/observability/llm) * [LLM-Based Metrics Guide](/observability/llm/llm-based-metrics) * [Embedding Visualization with UMAP](/observability/llm/embedding-visualization-with-umap) * [Selecting Enrichments](/observability/llm/selecting-enrichments) * [Enrichments Documentation](/observability/llm/enrichments) * [Guardrails for Proactive Application Protection](/glossary/guardrails) * [Fiddler Centor Model Metrics](/observability/llm/llm-based-metrics#fiddler-centor-model-metrics) * [Fiddler Evals TCO Calculator](https://www.fiddler.ai/evals-tco-calculator) # Custom Metric Source: https://docs.fiddler.ai/glossary/custom-metrics User-defined calculations in Fiddler that extend monitoring beyond standard metrics, allowing teams to track business-specific KPIs and specialized measurements for their AI applications. [Custom Metrics](/glossary/custom-metrics) are user-defined monitoring measures created using [Fiddler Query Language](/observability/platform/fiddler-query-language) (FQL) within the AI/ML/GenAI observability platform. They allow data scientists and ML engineers to extend beyond built-in metrics by defining their own calculations and thresholds for monitoring model performance. ## Additional Context Custom Metrics transform standard observability into a tailored monitoring solution by enabling teams to implement domain-specific KPIs that complement built-in metrics like data drift and data integrity. This flexibility allows organizations to focus on metrics that directly impact their business objectives rather than solely relying on standard technical indicators. ## Why Custom Metrics Are Important The roles of Custom Metrics in machine learning and model monitoring include: * Addressing unique business requirements not covered by standard metrics * Creating composite metrics that combine multiple signals into actionable insights * Implementing domain-specific calculations that reflect business KPIs * Enabling proactive alerting on custom-defined thresholds ## Custom Metric Use Cases * **Business-focused metrics**: Metrics that directly tie to business outcomes like conversion rates, revenue impact, or customer satisfaction * **Composite technical metrics**: Combined measures that blend multiple data signals for more holistic monitoring * **Data quality extensions**: Custom definitions of what constitutes data quality in specific domains ## Custom Metrics How-to Guide 1. **Identify the metric need** * Determine what performance aspects aren't covered by built-in metrics 2. **Design the FQL formula** * Write the formula using Fiddler Query Language syntax using the UI or API 3. **Test on historical data** * Validate that your metric catches issues using past data 4. **Iterate based on results** * Refine the metric definition as you learn from real-world monitoring ## Frequently Asked Questions **Q: How do Custom Metrics differ from built-in metrics?** Custom Metrics allow you to define domain-specific calculations using FQL that may not be available through pre-built metrics, giving you flexibility to monitor aspects of your AI systems most relevant to your business. **Q: Can Custom Metrics be used for alerting?** Yes, Custom Metrics integrates seamlessly with the platform's alerting system, allowing you to set thresholds and receive notifications when your user-defined metrics exceed acceptable ranges. **Q: What technical knowledge is required to create Custom Metrics?** Basic understanding of SQL-like query languages and knowledge of your data schema are sufficient for creating most Custom Metrics with FQL. ## Related Resources * [Custom Metrics for ML Models](/observability/platform/custom-metrics) * [Custom Metrics for Agentic Applications](/observability/agentic/custom-metrics) * [Fiddler Query Language](/observability/platform/fiddler-query-language) # Data Drift Source: https://docs.fiddler.ai/glossary/data-drift The statistical change in data distributions over time that can impact model performance. Fiddler detects drift by comparing production data against baselines to identify degradation causes. Data drift refers to the change in the statistical properties of input data over time, which can impact a model's performance and predictions. It occurs when the distribution of data in production differs significantly from the distribution of the baseline data (often the training dataset) that the model was trained on. Model performance can be poor if models trained on a specific dataset encounter different data in production. Data drift serves as a great proxy metric for performance decline, especially in cases where there is a delay in getting labels for production events (e.g., in a credit lending use case, an actual default may happen after months or years). ## How Fiddler Uses Data Drift Fiddler's monitoring platform uses data drift metrics to help users identify what data is drifting, when it's drifting, and how it's drifting. This is a crucial first step in identifying potential model performance issues. Fiddler calculates drift between the distribution of a field in the baseline dataset and that same distribution for the time period of interest using metrics like [Jensen-Shannon Divergence](https://www.fiddler.ai/ml-guides/how-to-measure-ml-model-drift) (JSD) and [Population Stability Index](https://www.fiddler.ai/blog/measuring-data-drift-population-stability-index) (PSI). ## Why Data Drift Is Important Monitoring data drift helps you stay informed about distributional shifts in the data for features of interest, which could have business implications even if there is no immediate decline in model performance. High drift can occur as a result of data integrity issues (bugs in the data pipeline), or as a result of an actual change in the distribution of data due to external factors (e.g., a dip in income due to economic changes). * **Early Warning System**: Data drift serves as an early warning mechanism for potential model performance degradation before it significantly impacts business outcomes. * **Delayed Ground Truth**: In many real-world scenarios, ground truth labels are delayed or expensive to obtain, making drift detection essential for timely model management. * **Data Pipeline Validation**: Detecting drift can help identify issues in data pipelines, such as bugs or data quality problems that might otherwise go unnoticed. * **Business Insight**: Changes in data distributions can provide valuable business insights about changing customer behaviors or market conditions, even when model performance remains stable. * **Efficiency in Retraining**: Monitoring data drift helps teams make informed decisions about when to retrain models, optimizing the use of resources. ## Types of Data Drift * **Feature Drift**: Changes in the statistical properties of input features that may affect model performance, such as shifts in customer demographics or behavior patterns. * **Prediction Drift**: Changes in the distribution of model outputs or predictions over time, which may indicate underlying issues even when feature distributions appear stable. * **Concept Drift**: Changes in the relationship between input features and target variables, where the statistical properties of the target variable change in relation to the features. * **Virtual Drift**: Changes in data that don't affect the target concept but may still impact model performance, such as the introduction of new feature values. ## Challenges Managing data drift effectively presents several challenges for data science and MLOps teams. * **Determining Threshold Levels**: Setting appropriate thresholds for what constitutes significant drift requires careful consideration of business context and model sensitivity. * **Root Cause Analysis**: Identifying which specific features are contributing most to observed drift and understanding their business implications can be complex. * **Distinguishing Natural Variation**: Differentiating between normal seasonal or cyclic patterns and problematic drift requires domain expertise and historical context. * **Handling Multivariate Relationships**: Drift may occur in complex relationships between variables rather than in individual features, making detection more challenging. * **Balancing Sensitivity**: Drift detection systems must be sensitive enough to catch important changes while avoiding false alarms from minor fluctuations. * **Delayed Response**: Determining how quickly to respond to detected drift requires balancing the costs of model retraining against the risks of performance degradation. ## Data Drift Monitoring Implementation Guide 1. **Establish a Baseline** * Define a representative baseline dataset, typically the training data used to build the model. * Analyze and document the statistical properties of this baseline for future comparison. 2. **Select Appropriate Drift Metrics** * Choose appropriate statistical metrics such as JSD or PSI to quantify distribution differences. * Consider the data types and distributions when selecting metrics (e.g., categorical vs. continuous variables). 3. **Set Drift Thresholds** * Establish thresholds for acceptable levels of drift based on business impact and model sensitivity. * Consider variable importance when setting thresholds, as drift in critical features may be more impactful. 4. **Implement Monitoring Systems** * Set up automated monitoring to compare production data distributions against the baseline. * Configure alerts for when drift exceeds predefined thresholds. 5. **Analyze and Respond to Drift** * Investigate the root causes of detected drift using drill-down analysis. * Determine appropriate responses, which may include model retraining, feature engineering adjustments, or addressing data pipeline issues. ## Frequently Asked Questions **Q: How is data drift different from concept drift?** Data drift refers to changes in the statistical properties of input data, while concept drift refers to changes in the relationship between inputs and the target variable. Data drift focuses on feature distributions, while concept drift involves the underlying prediction problem changing over time. **Q: How often should I check for data drift?** The frequency depends on your use case and how quickly your data environment changes. Critical applications may require daily or even hourly monitoring, while more stable models might be monitored weekly or monthly. **Q: What actions should I take when data drift is detected?** When significant drift is detected, first investigate the root cause through drill-down analysis. Depending on the cause, actions may include retraining the model, engineering new features, fixing data pipeline issues, or adjusting business processes to account for the new data reality. **Q: Can data drift occur without affecting model performance?** Yes, data drift can occur without immediately affecting model performance if the changes happen in areas that don't significantly impact the model's predictions or if the model is robust to the specific type of drift occurring. ## Related Terms * [ML Observability](/glossary/ml-observability) * [Baseline](/glossary/baseline) * [Model Performance](/glossary/model-performance) ## Related Resources * [Data Drift Monitoring Platform](/observability/platform/data-drift-platform) * [How to Detect Model Drift in ML Monitoring](https://www.fiddler.ai/blog/how-to-detect-data-drift) * [Alerts](/observability/platform/alerts-platform) * [Monitoring Charts](/observability/platform/monitoring-charts-platform) # Embedding Visualization Source: https://docs.fiddler.ai/glossary/embedding-visualization Interactive visualizations in Fiddler AI that transform complex embedding vectors into 3D displays, revealing semantic patterns, clusters, and outliers in LLM data. [Embedding Visualizations](/observability/llm/embedding-visualization-with-umap) in Fiddler AI are interactive graphical representations that display high-dimensional embedding vectors in a more accessible two or three-dimensional space. These visualizations use dimensionality reduction techniques, primarily [UMAP](https://umap-learn.readthedocs.io/en/latest/) (Uniform Manifold Approximation and Projection), to transform complex vector data into visual patterns that humans can interpret and analyze. When working with Large Language Models (LLMs) and other AI systems, embeddings capture semantic relationships in high-dimensional space (typically hundreds or thousands of dimensions). Embedding Visualizations make these abstract mathematical relationships visible, allowing users to identify clusters, outliers, and patterns that might otherwise remain hidden in the raw numerical data. In the Fiddler platform, Embedding Visualizations appear as interactive charts that plot embedding vectors as points in 2D space, with proximity between points indicating semantic similarity. These visualizations provide a powerful tool for understanding model behavior, monitoring for drift or anomalies, and gaining insights into how AI systems represent and process information. ## How Fiddler Uses Embedding Visualizations Fiddler integrates Embedding Visualizations as a core component of its LLM monitoring and observability platform. When monitoring LLM applications, Fiddler processes embedding data (either uploaded by users or generated through Fiddler's enrichment capabilities) and creates interactive UMAP visualizations that help users understand the semantic landscape of their model inputs and outputs. These visualizations are displayed in Fiddler Charts, which provide additional interactive capabilities such as filtering, color-coding, and time-based analysis. Users can explore embedding spaces to identify clusters of similar content, detect outlier patterns, and track how embedding distributions change over time. Embedding Visualizations complement Fiddler's other monitoring metrics by providing a spatial understanding of semantic relationships that numerical metrics alone cannot capture. They serve as an essential tool for both regular monitoring and deep-dive investigations when issues are detected. ## Why Embedding Visualizations Are Important Embedding Visualizations address a fundamental challenge in LLM and AI monitoring: how to make sense of high-dimensional data that cannot be directly observed or interpreted by humans. By transforming complex embedding spaces into visual representations, these visualizations enable insights that would be impossible to derive from raw vector data or simple statistical metrics. For organizations deploying LLM applications, Embedding Visualizations provide a crucial window into how their models are processing and representing information, helping teams detect subtle patterns, identify unexpected behaviors, and communicate findings to both technical and non-technical stakeholders. The visual nature of these representations makes complex AI behavior more accessible and interpretable, supporting more effective monitoring, debugging, and governance of AI systems. * **Pattern Detection**: Visualizations reveal clusters, outliers, and other patterns in embedding space that might indicate important semantic groupings or anomalous data points that require investigation. * **Drift Monitoring**: By comparing embedding distributions over time, visualizations can highlight semantic drift that might not be captured by traditional statistical drift metrics, showing how the meaning and context of data is evolving. * **Model Understanding**: Visualizations provide insights into how models represent information, helping users understand the semantic relationships and structures learned by the model. * **Anomaly Investigation**: When unusual model behaviors occur, embedding visualizations can help identify whether these anomalies cluster together semantically, suggesting common underlying causes. * **Communication Tool**: Visual representations of complex data make technical concepts more accessible to diverse stakeholders, facilitating communication between data scientists, engineers, compliance teams, and business leaders. * **Quality Assessment**: Visualizations can reveal whether similar inputs receive similar outputs or whether semantically related concepts are appropriately clustered, indicating model consistency and quality. * **Dataset Exploration**: Visualizations enable interactive exploration of large datasets, helping users understand the distribution and characteristics of their data in ways that tabular views cannot provide. ## Challenges While Embedding Visualizations provide powerful insights, they also come with several technical and interpretive challenges that users should be aware of when incorporating them into monitoring workflows. * **Dimensionality Reduction Trade-offs**: Techniques like UMAP inherently lose some information when reducing high-dimensional spaces to 2D or 3D, meaning that some relationships or patterns might be obscured or distorted in the visualization. * **Parameter Sensitivity**: UMAP and similar algorithms require careful parameter tuning, as different settings can produce significantly different visualizations from the same underlying data, potentially leading to different interpretations. * **Computational Overhead**: Generating high-quality embedding visualizations, especially for large datasets, can be computationally intensive and may require significant processing resources. * **Interpretation Complexity**: Without proper context and understanding of the underlying algorithms, users may misinterpret patterns in embedding visualizations or draw incorrect conclusions about what they represent. * **Temporal Consistency**: Maintaining consistent visualizations over time can be challenging, as new data points may shift the overall projection, making it difficult to compare visualizations from different time periods. * **Scalability Limitations**: Visualizing very large numbers of embeddings can lead to overcrowded displays or performance issues, requiring careful sampling or filtering strategies. * **Contextual Information Loss**: While embeddings capture semantic relationships, the original context that produced those embeddings may be lost in visualization, requiring additional metadata to fully interpret observed patterns. ## Embedding Visualization Implementation Guide 1. **Prepare Your Embedding Data** * Ensure your model is configured to generate or capture embeddings for the selected fields. * If using custom embeddings, verify they are properly formatted and included in your data publishing pipeline. 2. **Create a Visualization Chart** * In the Fiddler platform, navigate to the Charts section and create a new UMAP Visualization chart. * Select the appropriate model and field containing the embedding vectors you wish to visualize. 3. **Configure UMAP Parameters** * Adjust parameters like number of neighbors and minimum distance to optimize the visualization for your specific data characteristics. * Consider experimenting with different parameters to find the most informative representation. 4. **Add Contextual Information** * Configure color-coding or filters based on relevant metadata to add context to the visualization. * Consider adding time-based filters to observe how embeddings change over specific periods. 5. **Analyze Patterns** * Look for clusters that might indicate semantic groupings in your data. * Identify outliers or unexpected patterns that might require further investigation. 6. **Integrate with Monitoring** * Add embedding visualizations to monitoring dashboards alongside other metrics. * Set up regular reviews to detect changes in embedding patterns over time. ## Frequently Asked Questions **Q: What is UMAP and why is it used for embedding visualization?** UMAP (Uniform Manifold Approximation and Projection) is a dimensionality reduction technique that preserves both local and global structure when projecting high-dimensional data to lower dimensions. It's particularly well-suited for visualizing embeddings because it maintains meaningful relationships between data points, allowing clusters and patterns in the high-dimensional space to be visible in the 2D projection. Fiddler uses UMAP because it offers a good balance of performance and accuracy in representing complex embedding spaces. **Q: How should I interpret clusters in an embedding visualization?** Clusters in embedding visualizations typically represent groups of semantically similar items. Points that appear close together in the visualization share similar meanings or characteristics in the high-dimensional embedding space. When analyzing clusters, examine a sample of items within each cluster to understand the common themes or attributes they share. This can reveal how your model is grouping concepts and whether these groupings align with your expectations. **Q: Can embedding visualizations help detect problems in my LLM?** Yes, embedding visualizations can reveal various issues in LLM systems. Unexpected outliers might indicate anomalous inputs or outputs. Shifts in cluster patterns over time could signal semantic drift affecting your model. Overlapping clusters that should be distinct might suggest the model is conflating concepts it should differentiate. By regularly monitoring these visualizations alongside other metrics, you can detect subtle changes in model behavior that might not be apparent through other monitoring approaches. **Q: How frequently should I update my embedding visualizations?** The optimal frequency depends on your specific use case and data volume. For high-traffic LLM applications, daily or weekly visualization updates may be appropriate to catch shifts in patterns early. For more stable applications or those with lower traffic, monthly updates might be sufficient. Consider automating the generation of these visualizations as part of your regular monitoring cycle, aligning their frequency with your organization's model governance and review procedures. **Q: Can I export or share embedding visualizations from Fiddler?** Yes, Fiddler allows you to export embedding visualizations for sharing with team members or inclusion in reports. These exports capture the current state of the visualization including any applied filters or color-coding. This capability is particularly useful for communicating findings to stakeholders or documenting the state of your model at specific points in time for governance and compliance purposes. ## Related Terms [LLM and GenAI Observability](/glossary/llm-observability) ## Related Resources * [Embedding Visualization with UMAP](/observability/llm/embedding-visualization-with-umap) * [Monitoring Charts Platform](/observability/platform/monitoring-charts-platform) * [Vector Monitoring Platform](/observability/platform/vector-monitoring-platform) * [Selecting LLM Enrichments](/observability/llm/selecting-enrichments) # Enrichment Source: https://docs.fiddler.ai/glossary/enrichment Comprehensive overview of enrichments in AI monitoring and evaluation. Learn how Fiddler's enrichment framework transforms raw LLM data into actionable insights through specialized metrics and custom [Enrichments](/observability/llm/enrichments), also known as Evaluations, are specialized computational processes that transform raw AI model inputs and outputs into structured metrics, insights, and derived features. **Terminology note:** In Agentic Monitoring and Experiments (v26.3+), enrichments are referred to as **evaluators**. The underlying concept is the same — automated metrics applied to AI model data — but the term "evaluators" better reflects the active assessment role these components play in evaluation workflows. The `Enrichment` API class name remains unchanged. In the context of LLM monitoring and evaluation, enrichments serve as the bridge between unstructured model data and actionable intelligence, enabling organizations to measure, monitor, and improve their AI applications through quantitative analysis. When LLM applications publish inference data to monitoring platforms like Fiddler, enrichments automatically analyze this data to generate various metrics—from safety scores and hallucination detection to custom business logic evaluation. These computed enrichments become additional features in the monitoring dataset, providing dimensions that can be tracked over time, used in alerting rules, and analyzed for patterns or anomalies. Enrichments represent the operationalization of AI evaluation methodologies, transforming subjective quality assessments into measurable, scalable monitoring capabilities that enable reliable production deployment of generative AI systems. Fiddler Enrichment Framework diagram displaying sample inputs and outputs flowing into the Fiddler enrichment pipeline. ## Core Terminology ### Custom Features Derived data columns are created through enrichment processes that augment the original inference data. Custom features represent computed insights that don't exist in the raw model data but provide valuable monitoring and analysis dimensions. ### Enrichment Pipeline The automated processing infrastructure that applies enrichment operations to incoming inference data. The pipeline manages the execution, dependency resolution, and result integration of multiple enrichments across different data streams. ### Trust Scores [Trust Scores](/glossary/trust-score) are metrics that are specialized enrichment outputs that evaluate the trustworthiness, safety, and quality of AI model outputs. Trust metrics include dimensions like toxicity, bias, faithfulness, and safety that are critical for responsible AI deployment. ### Centor Models [Fiddler Centor Models](/glossary/centor-models) are purpose-built, optimized models developed by Fiddler specifically for efficient enrichment computation. These models provide comparable evaluation quality to general-purpose LLMs but with significantly lower latency and computational requirements. ### Evaluation Framework The underlying methodology and infrastructure that defines how enrichments assess model outputs. Different evaluation frameworks may use rule-based systems, ML models, or LLM-as-a-Judge approaches depending on the specific enrichment type. ## How Fiddler Uses Enrichments Fiddler's enrichment system operates as a comprehensive evaluation and monitoring layer that processes all inference data flowing through the platform. When LLM applications publish events containing prompts, responses, and contextual information, Fiddler's enrichment pipeline automatically applies configured enrichments to generate derived metrics. **Integration Process**: During model onboarding, users specify which enrichments should be enabled by including Enrichment objects in their ModelSpec configuration. This declarative approach allows teams to select the specific evaluation dimensions most relevant to their use case while avoiding unnecessary computational overhead. **Real-time Processing**: As inference events are published to Fiddler, the enrichment pipeline processes them through the configured enrichments, generating additional data columns that appear alongside the original inference data in monitoring dashboards and analytics interfaces. **Scalable Architecture**: Fiddler's enrichment infrastructure is designed for enterprise-scale deployment, supporting concurrent processing of multiple enrichment types while maintaining low latency. The system leverages purpose-built Centor Models and optimized processing pipelines to deliver consistent performance even with high-volume data streams. **Monitoring Integration**: Enrichment outputs seamlessly integrate with Fiddler's monitoring capabilities, enabling users to create alerts, track trends, and perform root cause analysis based on derived metrics rather than just raw model performance indicators. Fiddler dashboard showing LLM application performance using enrichment metrics. ## Why Enrichments Are Important Enrichments address a fundamental gap in AI monitoring: the ability to automatically assess qualitative aspects of model behavior at scale. While traditional monitoring focuses on quantitative metrics like latency and throughput, enrichments enable organizations to systematically evaluate the quality, safety, and appropriateness of AI-generated content. **Scalable Quality Assessment**: Manual evaluation of AI outputs doesn't scale to production volumes. Enrichments automate quality assessment, enabling continuous monitoring of millions of model interactions while maintaining consistent evaluation criteria. **Proactive Risk Management**: By continuously evaluating outputs for safety, bias, toxicity, and other risk factors, enrichments enable proactive identification and mitigation of potential issues before they impact users or business outcomes. **Regulatory Compliance**: Many industries require ongoing assessment of AI system behavior for compliance purposes. Enrichments provide auditable, quantitative evidence of responsible AI practices and systematic quality control. **Performance Optimization**: Enrichment data reveals patterns in model performance that guide optimization efforts. Understanding when and why models produce lower-quality outputs enables targeted improvements to prompts, training data, or model architecture. **Business Intelligence**: Custom enrichments can evaluate business-specific criteria, providing insights into how well AI systems achieve organizational objectives beyond generic quality metrics. ## Types of Enrichments ### Safety and Trust Enrichments **Safety**: Comprehensive safety evaluation powered by the Centor Model for Safety to detect harmful, toxic, or inappropriate content across multiple safety dimensions including violence, hate speech, and explicit material. **Bias Detection**: Evaluation of potential biases in model outputs, including gender, racial, political, or other forms of bias that could impact fairness and inclusivity. ### Quality and Accuracy Enrichments **Faithfulness (Centor Model)**: Automated detection of hallucinations and factual inaccuracies powered by the Centor Model for Faithfulness. Compares model outputs against provided context, returning a probability score (0.0–1.0). Available as a [Guardrail](/glossary/guardrails) and as an enrichment in LLM Observability. Uses `context` and `response` as inputs. See also: RAG Faithfulness below. **RAG Faithfulness**: LLM-as-a-Judge evaluator that assesses whether a response is grounded in the retrieved documents. Returns a binary label (Yes/No) with detailed reasoning. Uses `user_query`, `rag_response`, and `retrieved_documents` as inputs. Available in Agentic Monitoring and Experiments. See [RAG Health Diagnostics](/concepts/rag-health-diagnostics) for how this evaluator fits into the RAG diagnostic triad. **Faithfulness (Centor Model) vs RAG Faithfulness:** These are separate evaluators with different architectures. Faithfulness (Centor Model) is powered by the Centor Model for Faithfulness (purpose-built, probability score 0.0–1.0); RAG Faithfulness is an LLM-as-a-Judge evaluator (binary Yes/No with reasoning). See the [RAG Health Diagnostics](/concepts/rag-health-diagnostics) guide for a detailed comparison. **Answer Relevance**: Measurement of how well model responses address the specific query or prompt. In v26.3, Answer Relevance 2.0 provides ordinal scoring (High/Medium/Low = 1.0/0.5/0.0) with detailed reasoning, replacing the previous binary scoring. Available in Agentic Monitoring, Experiments, and LLM Observability. **Context Relevance**: Measures whether retrieved documents are relevant to the user's query, isolating retrieval quality from generation quality. Uses ordinal scoring (High/Medium/Low = 1.0/0.5/0.0) with reasoning. Available in Agentic Monitoring and Experiments only. **Coherence**: Assessment of logical flow, consistency, and overall readability of generated content to identify confusing or disjointed responses. ### Custom and Business Logic Enrichments **LLM-as-a-Judge**: Configurable evaluation system using Prompt Specs or custom prompts to implement specialized business logic and quality criteria. **Sentiment Analysis**: Emotional tone detection and sentiment classification to understand the affective characteristics of model outputs. ### Technical and Performance Enrichments **Embedding Generation**: Automatic creation of vector embeddings from text content to enable similarity analysis, clustering, and semantic drift detection. **Token Count**: Tracking of input and output token usage for cost analysis, performance optimization, and usage pattern understanding. **Response Time**: Measurement of model inference latency to identify performance bottlenecks and optimize system responsiveness. ### Data Quality Enrichments **PII Detection**: Identification of personally identifiable information in model inputs and outputs to ensure privacy compliance and data protection. **Data Validation**: Verification of data format, completeness, and consistency to ensure reliable model operation and meaningful analysis. **Language Detection**: Automatic identification of content language to enable appropriate processing and evaluation in multilingual environments. ## Challenges Implementing effective enrichment systems involves several technical and operational considerations that organizations must address to realize the full value of automated AI evaluation. **Computational Efficiency**: Running multiple enrichments on high-volume data streams requires careful optimization to avoid introducing significant latency or computational overhead that could impact application performance. **Evaluation Accuracy**: Ensuring that automated enrichments provide reliable assessments that align with human judgment requires ongoing validation and calibration, particularly as language usage and societal standards evolve. **Cost Management**: Large-scale enrichment processing can incur substantial computational costs, requiring organizations to balance evaluation comprehensiveness with budget constraints and performance requirements. **Configuration Complexity**: With dozens of available enrichments, selecting the optimal combination for specific use cases requires domain expertise and understanding of the trade-offs between different evaluation approaches. **Result Interpretation**: Translating enrichment scores into actionable insights requires clear guidelines and thresholds that may vary by organization, industry, or application context. **Data Privacy**: Some enrichments require processing of sensitive content, necessitating careful consideration of data privacy requirements and potential regulatory constraints. ## Enrichments Implementation Guide 1. **Assess Evaluation Requirements** * Identify the specific quality, safety, and business criteria relevant to your AI application * Prioritize evaluation dimensions based on risk assessment and regulatory requirements * Consider the trade-offs between evaluation comprehensiveness and computational cost 2. **Design Enrichment Strategy** * Select appropriate enrichments based on your use case and data characteristics * Plan for both generic quality metrics and domain-specific custom enrichments * Consider dependency relationships between different enrichment types 3. **Configure Model Specification** * Include selected enrichments in your ModelSpec configuration during onboarding * Define appropriate column mappings and enrichment-specific parameters * Test enrichment configuration with representative sample data 4. **Establish Monitoring Framework** * Create dashboards that effectively visualize enrichment results alongside operational metrics * Configure alert rules based on enrichment score thresholds and trend analysis * Implement escalation procedures for different types of quality or safety issues 5. **Validate and Calibrate** * Compare enrichment results with human evaluation on representative samples * Adjust thresholds and interpretation guidelines based on validation results * Establish periodic review processes to ensure continued accuracy and relevance 6. **Optimize and Scale** * Monitor enrichment processing performance and optimize for efficiency * Implement data retention and archival strategies for enrichment results * Plan for scaling enrichment infrastructure with application growth ## Frequently Asked Questions **Q: How do enrichments differ from traditional ML metrics?** Traditional ML metrics like accuracy and precision measure model performance against known ground truth labels. Enrichments evaluate qualitative aspects of model outputs—such as safety, coherence, and relevance—that don't have simple right/wrong answers but require nuanced assessment against multiple criteria. **Q: Can I create custom enrichments for my specific business needs?** Yes, Fiddler supports custom enrichments through multiple approaches: LLM-as-a-Judge with Prompt Specs for structured evaluation, and bring-your-own-prompt capabilities for maximum flexibility. These frameworks enable implementation of domain-specific evaluation logic. **Q: How do enrichments impact system performance and latency?** Fiddler's enrichments are designed for minimal performance impact through purpose-built Centor Models and optimized processing pipelines. Most enrichments add only modest latency (typically under 100ms) and can be processed asynchronously to avoid blocking primary application flows. **Q: Are enrichment results consistent and reliable enough for compliance use?** Fiddler's enrichments undergo extensive validation against human evaluation to ensure reliability. While no automated system perfectly matches human judgment in all cases, enrichments provide consistent, auditable results that meet the standards required for most compliance and governance use cases. **Q: How do I choose which enrichments to enable for my application?** Start with core safety and quality enrichments (Safety, Faithfulness (Centor Model)) that apply broadly, then add domain-specific enrichments based on your use case. Consider your risk profile, regulatory requirements, and the specific ways your AI application could fail or cause harm. **Q: Can enrichments be applied retroactively to historical data?** Yes, enrichments can be applied to previously collected inference data, enabling retrospective analysis and baseline establishment. This capability is particularly valuable when implementing new evaluation criteria or investigating historical issues. ## Related Terms * [Trust Score](/glossary/trust-score) - The quantitative outputs generated by enrichments * [Fiddler Centor Models](/glossary/centor-models) - The evaluation models powering enrichment computation * [LLM Observability](/glossary/llm-observability) - The broader monitoring practice enabled by enrichments * [Fiddler Guardrails](/glossary/guardrails) - Real-time protection using enrichment evaluation * [Custom Metrics](/glossary/custom-metrics) - User-defined metrics complementing enrichments ## Related Resources * [LLM Observability Metrics Reference](/reference/llm-observability-metrics) — Complete list of all LLM enrichments with output columns and sub-metrics * [LLM Application Monitoring & Protection](/observability/llm) * [Selecting Enrichments Guide](/observability/llm/selecting-enrichments) * [Enrichments Documentation](/observability/llm/enrichments) * [Enrichment API Reference](/sdk-api/python-client/enrichment) * [RAG Health Diagnostics](/concepts/rag-health-diagnostics) — Understanding the RAG diagnostic triad (Answer Relevance 2.0, Context Relevance, RAG Faithfulness) # Experiments Source: https://docs.fiddler.ai/glossary/experiments Systematic assessment of LLM application quality through structured testing with datasets, evaluators, and experiments that enable data-driven decision-making for prompt optimization, model selection, Experiments are structured, repeatable test runs for assessing the quality, safety, and performance of Large Language Model (LLM) applications. Each experiment runs your application against a curated test dataset, using evaluators to score outputs across specific quality dimensions. Unlike ad-hoc manual review, experiments provide quantitative, reproducible assessment that scales to thousands of test cases. Experiments serve as the testing framework for generative AI systems, analogous to unit testing and integration testing in traditional software development. They enable teams to make data-driven decisions about prompt engineering, model selection, hyperparameter tuning, and safety validation by providing objective evidence of how changes impact application behavior across representative scenarios. In the context of LLM development, experiments complement observability by providing proactive quality gates before deployment, while monitoring provides reactive insights after production release. Together, they form a comprehensive quality assurance strategy for reliable AI applications. Diagram showing experiment workflow from datasets through experiments to results ## Core Terminology ### Evaluator A function or system that assesses LLM outputs against specific quality criteria and produces a score. Evaluators can be rule-based (regex matching, length checks), model-based (embedding similarity, LLM-as-a-judge), or custom business logic. Each evaluator focuses on a specific dimension such as relevance, coherence, safety, or faithfulness. ### Score The quantitative or qualitative output produced by an evaluator represents how well an LLM output meets the evaluation criteria. Scores can be binary (pass/fail), continuous (0.0 to 1.0), categorical (positive/neutral/negative), or multi-dimensional (sentiment with confidence). ### Test Case A single evaluation data point containing inputs (such as a user query), optional extras (such as context for RAG systems), expected outputs (ground truth answers), and metadata. Test cases represent specific scenarios your application should handle correctly. ### Dataset A structured collection of test cases used for evaluation, typically representing diverse real-world scenarios, edge cases, and everyday user interactions. Datasets enable consistent, repeatable testing across different model versions, prompts, or configurations. ### Experiment A single execution of an experiment workflow where an LLM application runs against all test cases in a dataset, with evaluators scoring each output. Experiments track inputs, outputs, scores, metadata, and timing information, enabling comparison between different application versions. ### Baseline A reference experiment representing current or expected performance levels. Baselines provide the comparison point for evaluating whether changes improve or degrade application quality across metrics. ## How Fiddler Provides Experiments Fiddler Experiments delivers a comprehensive evaluation platform that integrates systematic testing into the LLM development lifecycle. The platform combines dataset management, experiment orchestration, built-in evaluators, and custom evaluation frameworks into a unified system accessible through both SDK and UI interfaces. **Dataset Management**: Teams create and version experiment datasets containing representative test cases with inputs, expected outputs, and contextual information. Datasets can be imported from CSV, JSONL, or constructed programmatically, with support for complex column mapping and metadata enrichment. **Built-in Evaluators**: Fiddler provides production-ready evaluators for common quality dimensions, including answer relevance, faithfulness (hallucination detection), coherence, conciseness, safety, toxicity, and sentiment. These evaluators leverage both Fiddler Centor Models and LLM-as-a-judge approaches for reliable assessment. **Custom Evaluation Framework**: Beyond built-in evaluators, developers can create custom evaluators using Python functions, LLM-based classification, or bring-your-own-prompt approaches. This flexibility enables domain-specific evaluation logic and business-specific quality criteria. **Experiment Tracking**: Every experiment run is tracked with a complete lineage of inputs, outputs, scores, and metadata. The platform provides side-by-side comparison of experiments, aggregate statistics by evaluator, and drill-down capabilities to individual test case results. **Integration Points**: The Fiddler Evals SDK integrates with development workflows through Python APIs, enabling CI/CD integration, automated regression testing, and programmatic analysis. The UI provides visual exploration of results, experiment comparison dashboards, and collaborative review capabilities. Dashboard showing side-by-side comparison of experiments ## Why Experiments Are Important Experiments transform LLM application development from subjective guesswork into objective, data-driven engineering. Without systematic evaluation, teams rely on anecdotal evidence and manual spot-checking, making it impossible to confidently assess whether changes improve or degrade quality across diverse scenarios. **Quality Assurance at Scale**: Manual review of LLM outputs doesn't scale to the thousands of scenarios production applications must handle. Evaluations automate quality assessment, enabling comprehensive testing that catches edge cases and regressions human reviewers might miss. **Objective Decision-Making**: When comparing prompts, models, or configurations, evaluations provide quantitative evidence of which option performs better across metrics that matter for your use case. This eliminates arguments based on cherry-picked examples or personal preference. **Regression Prevention**: As LLM applications evolve through prompt refinements, model updates, and feature additions, evaluations serve as quality gates that catch unintended degradation before it reaches production. Continuous evaluation prevents the "whack-a-mole" problem where fixing one issue breaks another. **Safety Validation**: For applications with safety, compliance, or ethical requirements, evaluations provide systematic verification that outputs meet organizational standards. Safety evaluators can detect toxicity, bias, harmful content, or policy violations across comprehensive test suites. **Cost Optimization**: Evaluations enable data-driven decisions about model selection and configuration. By comparing quality metrics across different models or prompts, teams can identify cost-effective configurations that meet quality requirements without over-provisioning expensive models. **Continuous Improvement**: Experiment results guide optimization efforts by revealing where applications struggle. Identifying low-performing test case categories, correlated failures, or specific evaluator weaknesses focuses development effort on meaningful improvements. ## Types of Experiments ### Development-Time Evaluation **Prompt A/B Testing**: Compare different prompt formulations to identify which produces better quality outputs. Run identical datasets through competing prompts and analyze score distributions across evaluators to make evidence-based prompt selection decisions. **Model Comparison**: Evaluate multiple LLM models (GPT-4, Claude, Llama) on the same tasks to balance quality, cost, and latency trade-offs. Use evaluation metrics to justify model selection for specific use cases. **Hyperparameter Tuning**: Systematically test temperature, top-p, and other configuration parameters to optimize the balance between creativity and consistency for your application. ### Pre-Deployment Testing **Regression Testing**: Run comprehensive experiment suites before each deployment to ensure new changes don't degrade existing capabilities. Establish quality thresholds that must be met for deployment approval. **Quality Gates**: Implement automated checks that block deployment if experiment scores fall below acceptable baselines, preventing quality regressions from reaching production. **Version Validation**: When upgrading model versions or dependencies, run experiments to verify that improvements claimed by providers actually manifest in your specific use case. ### Safety and Trust Evaluation **Toxicity Detection**: Evaluate outputs for offensive, harmful, or inappropriate content across diverse test scenarios. Ensure content moderation policies are enforced systematically. **Bias Assessment**: Test for gender, racial, political, or other biases in model responses using carefully constructed datasets that expose potential fairness issues. **Adversarial Testing**: Run experiments with jailbreak attempts, prompt injections, and other adversarial inputs to verify that safety guardrails function correctly. ### RAG System Evaluation Fiddler provides a purpose-built diagnostic framework — **RAG Health Metrics** — for evaluating RAG applications. The framework consists of three evaluators that together pinpoint where RAG pipelines fail: **Answer Relevance 2.0** (Enhanced): Measures how well the response addresses the user's query using ordinal scoring (High/Medium/Low = 1.0/0.5/0.0) with detailed reasoning. Available in Agentic Monitoring, Experiments, and LLM Observability. **Context Relevance** (New): Measures whether the retrieved documents are relevant to the user's query, isolating retrieval quality from generation quality. Uses ordinal scoring (High/Medium/Low = 1.0/0.5/0.0) with reasoning. Available in Agentic Monitoring and Experiments only. **RAG Faithfulness** (Repackaged): An LLM-as-a-Judge evaluator that assesses whether the response is grounded in the retrieved documents. Returns a binary label (Yes/No = 1/0) with detailed reasoning. Available in Agentic Monitoring, Experiments, and LLM Observability. See [RAG Health Diagnostics](/concepts/rag-health-diagnostics) for a comprehensive guide to using these evaluators together for root cause analysis. **Source Attribution**: Verify that responses correctly attribute information to source documents when required for transparency or compliance. ### Performance Benchmarking **Cross-Provider Comparison**: Evaluate the same application logic across different LLM providers to understand quality and capability differences for specific tasks. **Longitudinal Tracking**: Run standardized experiment datasets periodically to detect performance drift as models, prompts, and data distributions evolve. **Domain-Specific Benchmarking**: Create custom experiment datasets representing your specific domain, use case, and user population to benchmark against industry standards or competitors. ## Challenges Implementing effective evaluation systems presents unique challenges stemming from the subjective nature of language, the complexity of assessment criteria, and the resource requirements of comprehensive testing. **Subjectivity and Context-Dependence**: Defining "good" outputs is inherently subjective and varies by use case, user population, and context. What constitutes relevant, appropriate, or high-quality content for a customer service chatbot differs dramatically from what is considered high-quality content for a creative writing assistant. Establishing evaluation criteria requires a deep understanding of user expectations and business objectives. **Ground Truth Acquisition**: Creating reference answers (ground truth) for test cases is labor-intensive and may not even be possible for open-ended generation tasks. While some scenarios have clear correct answers, creative tasks, summarization, or opinion-based queries lack a single correct response, complicating evaluator design. **Computational Cost**: Running comprehensive evaluations, especially with LLM-as-a-judge evaluators, incurs significant computational expense and latency. Balancing evaluation comprehensiveness with budget constraints requires careful selection of evaluators and potentially sampling strategies. **Test Coverage and Representativeness**: Creating datasets that adequately represent production diversity is challenging. Production systems encounter edge cases, novel user intents, and data distributions that may not be captured in experiment datasets, potentially leading to overfitting to test scenarios. **Evaluation-Production Gap**: Test performance may not predict real-world performance due to differences in user behavior, data distribution, or system context. Experiment datasets may lack the complexity, noise, or unexpected patterns present in production environments. **Metric Selection**: With dozens of available evaluators measuring different quality dimensions, choosing the proper subset for your use case requires domain expertise. Overloading evaluations with too many metrics creates noise, while missing critical evaluators can blind teams to essential failure modes. **LLM-as-Judge Reliability**: When using LLMs as evaluators, the evaluator itself may hallucinate, show bias, or produce inconsistent judgments. Ensuring evaluator quality requires meta-evaluation—validating that evaluators align with human judgment. **Maintenance Overhead**: Experiment datasets require ongoing maintenance as applications evolve, user expectations shift, and new failure modes emerge. Stale datasets provide false confidence, while keeping evaluations current demands continuous effort. ## Experiments Implementation Guide 1. **Define Evaluation Objectives** * Identify the specific quality dimensions most critical for your use case (relevance, safety, coherence, etc.) * Establish acceptable performance thresholds based on business requirements and user expectations * Prioritize evaluation dimensions based on risk assessment—safety-critical applications require a different focus than creative tools 2. **Build Representative Datasets** * Start with 10-20 high-priority scenarios covering common use cases and known failure modes * Expand to include edge cases, adversarial inputs, and diverse user populations * Include ground truth answers where possible, or clear evaluation criteria when ground truth isn't feasible * Use production data (anonymized and filtered) to ensure test cases reflect real-world distribution * Version datasets and track changes to maintain evaluation consistency over time 3. **Select Appropriate Evaluators** * Begin with built-in evaluators for common quality dimensions (relevance, coherence, safety) * Add domain-specific custom evaluators for business requirements not covered by standard metrics * Avoid metric overload—focus on evaluators that drive actual decisions rather than collecting all possible scores * Validate evaluators against human judgment on sample test cases to ensure alignment 4. **Run Baseline Experiments** * Execute evaluations on your current application to establish baseline performance * Document baseline scores and acceptable ranges for each evaluator * Identify problem areas and prioritize improvement efforts based on experiment results 5. **Establish Evaluation Cycles** * Integrate evaluations into development workflow—run before each pull request or deployment * Set up automated experiment pipelines that block deployment when scores fall below thresholds * Schedule periodic comprehensive evaluations to detect drift even when code hasn't changed * Create feedback loops where evaluation insights drive prompt refinement and model tuning 6. **Iterate and Improve** * Analyze experiment results to identify patterns in failures and guide optimization * Compare experiments side-by-side to validate that changes improve target metrics without regressing others * Expand datasets based on newly discovered failure modes in production * Refine evaluators and thresholds as understanding of quality requirements evolves ## Frequently Asked Questions **Q: How many test cases do I need for reliable evaluation?** Start with 10-20 high-priority test cases covering core functionality and known edge cases. As you mature your evaluation practice, expand to 50-100+ cases for comprehensive coverage. The optimal number depends on application complexity and diversity of scenarios—simple Q\&A may require fewer cases than complex multi-turn conversations or RAG systems. **Q: How do I choose which evaluators to use?** Prioritize evaluators aligned with your specific failure modes and user expectations. Safety-critical applications need toxicity and bias evaluators; RAG systems require faithfulness; customer service chatbots benefit from relevance and coherence. Start with 3-5 core evaluators and expand based on observed gaps rather than trying to measure everything from day one. **Q: Should I use LLM-as-a-judge or rule-based evaluators?** Use both strategically. Rule-based evaluators (length checks, regex matching, keyword presence) are fast, deterministic, and cheap but limited to surface-level criteria. LLM-as-a-judge provides a nuanced semantic assessment but incurs cost and latency. Combine rule-based evaluators for quick sanity checks with LLM-based evaluators for quality assessment. **Q: How often should I run experiments?** Run experiments before every deployment for regression testing, and schedule comprehensive experiments weekly or monthly, even without code changes, to detect drift. For active development, run experiments on every pull request. Balance frequency with computational cost—use smaller, quick-check datasets for frequent testing and comprehensive datasets for periodic deep evaluation. **Q: What's the difference between evaluation and monitoring?** Evaluation involves proactive testing with curated test datasets before deployment, while monitoring is the reactive observation of production behavior. Evaluation provides control over test scenarios and ground truth, but may not capture production complexity. Monitoring reflects real-world usage but lacks controlled testing. Use evaluation for pre-deployment quality gates and monitoring for production health. **Q: Can evaluations replace human review?** Evaluations complement rather than replace human review. Automated evaluations scale to comprehensive testing, which is impossible for humans, but humans provide nuanced judgment on edge cases, ethical considerations, and subjective quality that automated systems may miss. Use evaluations for systematic coverage and humans for final judgment on critical or ambiguous cases. ## Related Terms * [LLM Observability](/glossary/llm-observability) - Production monitoring complementing pre-deployment evaluation * [Agentic Observability](/glossary/agentic-observability) - Monitoring multi-agent systems with evaluation capabilities * [Guardrails](/glossary/guardrails) - Real-time safety controls often validated through evaluation * [Trust Score](/glossary/trust-score) - Metrics measuring trustworthiness, often used as evaluators * [Enrichment](/glossary/enrichment) - Automated metrics generation similar to evaluation, but for production data * [Model Performance](/glossary/model-performance) - Traditional ML metrics complementing LLM evaluation ## Related Resources * [Getting Started with Fiddler Experiments](/getting-started/experiments) * [Fiddler Evals SDK Reference](/sdk-api/evals/evaluate) * [Evals SDK Quick Start](/evaluate-and-test/evals-sdk-quick-start) * [Evals SDK Advanced Guide](/developers/tutorials/experiments/evals-sdk-advanced) * [RAG Health Diagnostics](/concepts/rag-health-diagnostics) — Conceptual guide to RAG pipeline diagnostics * [RAG Health Metrics Tutorial](/developers/tutorials/experiments/rag-health-metrics-tutorial) — Step-by-step RAG evaluation guide # Fiddler Guardrails Source: https://docs.fiddler.ai/glossary/guardrails Fiddler Guardrails is a real-time content-safety capability that evaluates and filters harmful LLM outputs before they reach users, powered by Fiddler Centor Models. [Fiddler Guardrails](/glossary/guardrails) is a real-time content safety solution that evaluates and filters potentially harmful outputs from large language models (LLMs) before they reach end users. It serves as a protective layer between LLM systems and their users, ensuring that generated content adheres to organizational policies and safety standards. Powered by [Fiddler Centor Models](/glossary/centor-models), Fiddler Guardrails leverages purpose-built models optimized for efficient content evaluation. The system processes LLM outputs in real-time, detecting problematic content across multiple safety dimensions including harmfulness, toxicity, illegal activity, bias, and more. When violations are detected, Guardrails can either filter out the content entirely or provide detailed explanations of the specific policies that were violated. Fiddler Guardrails is a capability of the Fiddler AI Observability and Security platform. You access it through its real-time API within your Fiddler environment, powered by Fiddler Centor Models. ## How Fiddler Uses Guardrails Fiddler Guardrails integrates with the broader Fiddler platform to provide comprehensive protection and visibility for LLM and GenAI applications. As part of Fiddler's end-to-end LLM governance solution, Guardrails helps organizations maintain control over their generative AI deployments by ensuring outputs meet safety standards before reaching users. When integrated with Fiddler's monitoring capabilities, Guardrails contributes to a complete approach where potentially harmful content is both blocked in real-time and analyzed for patterns that might indicate systemic issues. This dual approach enables organizations to maintain strong protections while continuously improving their LLM systems. Fiddler offers Guardrails through a simple API that can be integrated into existing LLM application workflows, allowing organizations to implement protection without significant architectural changes. ## Why Fiddler Guardrails Is Important As organizations increasingly deploy generative AI applications across their operations, ensuring the safety and appropriateness of LLM outputs becomes a critical governance concern. Fiddler Guardrails addresses this need by providing real-time protection against potentially harmful, toxic, or inappropriate content generation. Without robust guardrails in place, organizations face significant risks from LLM deployments, including reputational damage, compliance violations, and potential harm to users. By implementing Fiddler Guardrails, organizations can confidently deploy generative AI with protections that minimize these risks. The importance of Guardrails extends beyond individual content filtering to enable trustworthy, responsible AI deployment at scale across an organization. * **Risk Mitigation**: Guardrails prevents harmful, toxic, or inappropriate content from reaching end users, protecting both users and the organization from potential negative impacts of unsafe LLM outputs. * **Compliance Support**: By enforcing content policies consistently, Guardrails helps organizations meet regulatory requirements and internal governance standards for responsible AI use. * **Deployment Confidence**: With protective measures in place, organizations can more confidently deploy LLM applications across a broader range of use cases and user groups. * **Brand Protection**: By filtering inappropriate content before it reaches customers, Guardrails helps protect brand reputation and maintain trust in AI-powered services. * **Operational Efficiency**: Real-time protection reduces the need for human review of all LLM outputs, allowing teams to focus on improving models rather than constantly monitoring for problematic content. * **Educational Feedback**: When content is filtered, Guardrails provides detailed explanations about policy violations, helping developers understand and address recurring issues in their prompting strategies or model configurations. * **Customizable Protection**: Organizations can tailor protection levels to their specific needs and risk tolerance, ensuring appropriate safeguards without unnecessarily restrictive filtering. ## Types of Guardrails Protection * **Safety Guardrails**: Core protections against harmful, toxic, illegal, or objectionable content across multiple categories including violence, hate speech, explicit content, and illegal activities. * **Custom Policy Guardrails**: Organization-specific policy enforcement that can be configured to reflect particular industry requirements, company values, or audience sensitivities. * **Guardrails API**: Real-time content safety delivered through the Guardrails API within your Fiddler environment. * **Integrated Platform Guardrails**: Guardrails functionality within the comprehensive Fiddler observability platform, working alongside monitoring features for complete LLM governance. * **Multi-level Protection**: Tiered protection options allowing organizations to set different filtering thresholds for different applications or user contexts. ## Challenges Implementing effective content safety for LLM applications presents several challenges that Fiddler Guardrails is designed to address. * **Latency Management**: Adding protective layers can potentially slow response times, a challenge Guardrails addresses through efficient purpose-built models optimized for evaluation speed. * **Nuanced Content Evaluation**: Distinguishing between genuinely harmful content and benign discussions of sensitive topics requires sophisticated evaluation capabilities beyond simple keyword filtering. * **False Positive Balance**: Setting appropriate thresholds that protect against harmful content without excessive blocking of legitimate outputs requires careful calibration. * **Context Awareness**: Properly evaluating content requires understanding the broader context of the conversation, not just analyzing isolated responses. * **Policy Customization**: Different organizations have varying standards for acceptable content, requiring flexible guardrail systems that can be tailored to specific needs. * **Multilingual Support**: Ensuring consistent protection across content in different languages presents challenges in evaluation consistency. * **Evolving Threat Landscape**: As LLM capabilities advance and new exploitation techniques emerge, guardrail systems must continuously update to address novel risks. ## Fiddler Guardrails Implementation Guide 1. **Define Your Content Safety Requirements** * Identify which safety dimensions are most important for your LLM use cases. * Determine appropriate filtering thresholds based on your user base and risk tolerance. 2. **Choose Deployment Approach** * Decide how to integrate the Guardrails API into your application's request and response flow. * Select between cloud-hosted or on-premises deployment options. 3. **Integrate Guardrails API** * Implement API calls in your application flow to route LLM outputs through Guardrails before display. * Set up appropriate error handling for cases where content is filtered. 4. **Configure Safety Policies** * Set appropriate thresholds for different safety dimensions. * Configure custom policies if needed for organization-specific requirements. 5. **Test and Refine** * Verify protection effectiveness with representative test cases. * Refine thresholds based on observed false positive/negative rates. 6. **Monitor and Improve** * Track guardrail filtering patterns to identify recurring issues. * Use insights to improve prompt engineering and LLM configuration. ## Frequently Asked Questions **Q: How does Fiddler Guardrails differ from prompt engineering for safety?** While prompt engineering attempts to elicit safe behavior through careful input design, Guardrails provides a dedicated protection layer that evaluates outputs regardless of prompt quality. This approach is more robust as it doesn't rely on the effectiveness of prompts alone and can catch unsafe responses even when prompt constraints fail. **Q: What types of content can Fiddler Guardrails detect and filter?** Fiddler Guardrails can detect and filter content across multiple safety dimensions including but not limited to harmful content, toxicity, hate speech, violence, sexual content, illegal activities, bias, profanity, and content faithfulness. **Q: How does Guardrails impact response latency?** Fiddler Guardrails is designed to minimize latency impact through highly optimized models specifically built for efficient content evaluation. While there is some processing overhead, it's typically measured in milliseconds rather than seconds, and significantly faster than using general-purpose LLMs for evaluation. **Q: Can I customize the safety policies to fit my organization's needs?** Yes, Fiddler Guardrails allows for customization of safety policies and thresholds to align with specific organizational requirements, industry regulations, and risk tolerance levels. **Q: Is Fiddler Guardrails a separate product from the Fiddler platform?** No. Fiddler Guardrails is a capability of the Fiddler AI Observability and Security platform, powered by Fiddler Centor Models, and is accessed through the Guardrails API within your Fiddler environment. ## Related Terms * [Fiddler Centor Models](/glossary/centor-models) * [Trust Score](/glossary/trust-score) ## Related Resources * [Getting Started with Fiddler Guardrails](/getting-started/guardrails) * [Guardrails in the Fiddler Platform](/glossary/guardrails) * [Guardrails FAQ](/protection/guardrails-faq) * [Fiddler Centor Model Metrics](/observability/llm/enrichments#safety) # Glossary Source: https://docs.fiddler.ai/glossary/index Review product concepts and terminology for the Fiddler platform to help get up to speed quickly when adopting Fiddler for your ML and GenAI monitoring. This page explains core concepts and terminology used throughout Fiddler's AI Observability and Security platform. Understanding these concepts will help you navigate the platform more effectively and get the most from Fiddler's capabilities. ## Monitoring and Observability Concepts ### ML Observability [ML observability](/glossary/ml-observability) is the practice of gaining comprehensive insights into AI application performance throughout its lifecycle. It goes beyond simple indicators of good and bad performance by empowering stakeholders to understand why a model behaves in a certain manner and how to enhance its performance. ML Observability begins with monitoring and alerting on performance issues but extends to guiding model owners toward the underlying root causes. ### LLM Observability [LLM observability](/glossary/llm-observability) is the specialized practice of evaluating, monitoring, analyzing, and improving Generative AI and LLM-based applications across their lifecycle. Fiddler provides real-time monitoring on safety metrics like toxicity, bias, and PII exposure, as well as correctness metrics like hallucinations, faithfulness, and relevancy specific to language models. ### Alerts [Alerts](/observability/platform/alerts-platform) are rules that trigger when production data meets defined conditions. These rules can be user-defined or automatically generated based on user configuration. Alert notifications can be sent via email, Slack, PagerDuty, or any combination thereof, enabling teams to respond quickly to potential issues with model performance or data quality. ### Metrics Metrics in Fiddler refer to the quantitative measurements and calculations the platform performs on inference data. These metrics provide insights into model behavior, data characteristics, and performance over time. Fiddler offers several core metric types: * [Data Drift](/glossary/data-drift): Measures statistical differences between production and baseline data distributions * [Performance](/observability/platform/performance-tracking-platform): Tracks model accuracy, precision, recall, and other performance indicators * [Data Integrity](/observability/platform/data-integrity-platform): Identifies missing values, outliers, and other data quality issues * [Traffic](/observability/platform/traffic-platform): Monitors request volumes, response times, and utilization patterns * Statistical: Provides basic descriptive statistics about data distributions * [Custom Metrics](/glossary/custom-metrics): User-defined calculations tailored to specific business needs ## Data Management Concepts ### Pre-production Data Data designated as pre-production contains non-time series data, which is uploaded to Fiddler in a single batch. Pre-production data typically includes training datasets, validation datasets, or other static data meant to be evaluated as a complete unit without the dimension of trends over time. ### Production Data Data designated as production contains time series data such as inference logs generated by models making decisions in live environments. This time series data provides the inputs and outputs of each model inference/decision, which Fiddler analyzes and compares against pre-production data to determine if model performance is degrading over time. ### Baselines [Baselines](/glossary/baseline) are reference datasets used for calculating data drift and other comparative metrics. When determining if drift has occurred, Fiddler compares the distribution of current production data against this reference data. Most commonly, training data establishes a model's baseline, but multiple baselines can be defined for a model, including static sets of historical inferences or rolling baselines that look back over specific time periods. ### Segments (Cohorts) [Segments](/observability/platform/segments), also called Cohorts, are subsets of inference logs defined by custom filters. Segments allow users to analyze metrics for specific subsets of data (for example, "transactions under \$1000" or "users from a specific region"). Segmentation enables more granular analysis of model performance across different data populations. ### Trust Scores (Enrichments) [Trust Scores](/glossary/trust-score), also known as Enrichments, are specialized metrics that assess various quality and safety dimensions of LLM outputs. Generated by Fiddler Centor Models, these scores evaluate dimensions such as safety, toxicity, hallucination, relevance, and coherence. They provide quantifiable measurements for monitoring LLM behavior and can trigger alerts or actions when outputs fall below quality thresholds. ## Platform Components and Features ### Fiddler Centor Models [Fiddler Centor Models](/glossary/centor-models) are purpose-built LLMs that evaluate AI outputs in real time, powering both monitoring metrics and real-time guardrails with significantly lower latency than general-purpose models. Centor Models: * Evaluate LLM outputs with significantly higher efficiency than general-purpose LLMs * Maintain comparable quality in their assessments * Support both observability features and real-time protection capabilities ### Fiddler Guardrails [Fiddler Guardrails](/glossary/guardrails) is a real-time content safety solution that evaluates and filters potentially harmful outputs from large language models before they reach end users. Powered by Fiddler Centor Models, Guardrails detects problematic content across multiple safety dimensions and can either filter out unsafe content or provide detailed explanations of policy violations. ### Embedding Visualizations [Embedding Visualizations](/glossary/embedding-visualization) in Fiddler display high-dimensional embedding vectors in an accessible two-dimensional space using techniques like UMAP (Uniform Manifold Approximation and Projection). These visualizations make complex vector relationships visible, allowing users to identify clusters, outliers, and patterns that would remain hidden in raw numerical data. ### Dashboards and Charts Fiddler uses customizable [Dashboards](/observability/dashboards) for monitoring and sharing model behavior. Dashboards comprise Charts that provide distinct visualization types: * [Monitoring Charts](/observability/platform/monitoring-charts-platform): Track metrics over time and compare model performance * [Embedding Visualizations](/glossary/embedding-visualization): Display semantic relationships in embedding space * [Performance Analytics](/observability/analytics): Analyze model performance across different segments Dashboards consolidate visualizations in one place, offering a detailed overview of model performance and an entry point for deeper analysis and root cause identification. ### Bookmarks Bookmarking enables quick access to frequently used projects, models, charts, and dashboards. The comprehensive bookmark page enhances navigation efficiency within the Fiddler platform, allowing users to quickly return to their most important resources. ## Administration Concepts ### Projects [Projects](/developers/python-client-guides/model-onboarding/create-a-project-and-model) in Fiddler serve as the principal organizational containers for your AI applications or use cases. Each project functions as a logical workspace that encapsulates related models, datasets, baselines, monitoring configurations, and analytics. Projects provide several key benefits: * **Organizational Structure**: Group related models and assets by business function, team ownership, or application purpose * **Access Control**: Define which users and teams can view or modify project resources through role-based permissions * **Resource Isolation**: Maintain separate environments for different AI initiatives to prevent configuration conflicts * **Focused Monitoring**: Create dashboards and alerts specific to the business context of each application * **Collaborative Workflow**: Enable teams to work together on related models within a consistent environment Within a project, you can onboard multiple models, upload baseline datasets, create production data-based baselines, configure alerts, build dashboards, and analyze performance—all within a unified context that reflects your organization's structure and workflows. Projects help you scale AI governance across your organization by providing clear boundaries between different applications while maintaining consistent monitoring and explainability practices. ### Role-Based Access Control Fiddler supports Role-Based Access Control (RBAC) that defines who can access which resources within the platform. Available roles include: * **Org Admin**: Manages users, teams, projects, and organization settings * **Org Member**: Has limited access to organization settings and cannot create projects * **Project Admin**: Manages all aspects of a project including models, settings, and alerts * **Project Writer**: Can view and edit most project details but has limited administrative capabilities * **Project Viewer**: Can view project resources but cannot make changes ### Teams [Teams](/reference/administration/settings#teams) are groups of users within your organization that can be assigned specific roles and permissions for different projects. Each user can be a member of multiple teams, enabling flexible access control based on organizational structure and responsibilities. # LLM Observability Source: https://docs.fiddler.ai/glossary/llm-observability Comprehensive monitoring of LLM applications that evaluates safety, quality, and performance metrics to detect issues like hallucinations, toxicity, and drift in generative AI systems. [LLM Observability](/index) is the practice of monitoring, measuring, and analyzing Large Language Model systems in production environments to ensure their reliability, safety, and performance. It involves the systematic collection and analysis of LLM inputs, outputs, and associated metrics to provide visibility into model behavior, detect anomalies, ensure alignment with business objectives, and maintain trust. Unlike traditional ML model monitoring, LLM Observability addresses unique challenges specific to generative AI, including hallucination detection, prompt safety evaluation, response quality assessment, and embedding analysis. This comprehensive approach enables organizations to understand how their LLM applications perform in real-world scenarios and take proactive measures to maintain quality and mitigate risks. ## How Fiddler Provides LLM Observability Fiddler's LLM Observability platform provides a comprehensive approach to monitoring and protecting LLM applications through enrichments, which are custom features designed to augment data provided in events. The platform requires publication of LLM application inputs and outputs, including prompts, prompt context, responses, and source documents (for RAG-based applications). Fiddler generates various AI trust and safety metrics through its enrichment pipeline, allowing users to detect data drift, visualize embeddings, identify hallucinations, assess response quality, detect harmful content, and monitor overall application health. These metrics can be used for alerting, analysis, and debugging purposes across the application lifecycle. ## Why LLM Observability Is Important LLM Observability is crucial for organizations deploying generative AI applications in production environments. As LLMs become increasingly integrated into critical business processes and customer-facing applications, maintaining transparency, quality, and safety becomes essential. Effective LLM Observability enables teams to detect issues early, continuously improve model performance, ensure responsible AI deployment, and maintain compliance with evolving regulatory requirements. * **Quality Assurance and Hallucination Detection**: LLM Observability helps identify instances of hallucinations, factual inaccuracies, or low-quality outputs through metrics like faithfulness and answer relevance, ensuring that generated content meets quality standards. * **Safety and Trust Monitoring**: Monitoring ensures LLM applications remain safe and trustworthy by detecting harmful, toxic, or inappropriate content through metrics like safety scores, profanity detection, and toxicity assessment. * **Performance Optimization**: By tracking operational metrics such as token usage, embedding quality, and response times, organizations can optimize their LLM applications for both cost efficiency and user satisfaction. * **Root Cause Analysis**: When issues arise, LLM Observability provides the tools to conduct detailed analysis, identify the root causes of problems, and implement targeted improvements. * **Drift Detection**: As the world changes and user behavior evolves, LLM Observability helps detect shifts in prompt patterns or content distribution that might affect model performance. * **Regulatory Compliance**: With growing regulatory scrutiny of AI systems, LLM Observability provides the transparency and documentation needed to demonstrate responsible AI practices to stakeholders and regulators. ## Types of LLM Observability * **Input Monitoring**: Tracking and analyzing user prompts, prompt context, and embedding patterns to identify trends, anomalies, and potential security risks like jailbreak attempts or prompt injections. * **Output Quality Assessment**: Evaluating LLM responses for quality metrics including faithfulness, coherence, conciseness, and relevance to ensure outputs align with user expectations and business requirements. * **Safety and Trust Evaluation**: Monitoring for harmful content, inappropriate language, PII leakage, toxicity, and other trust-related concerns that might compromise user safety or organizational reputation. * **Embedding Visualization**: Using techniques like UMAP to visualize high-dimensional embeddings in 2D or 3D space, enabling identification of clusters, patterns, and anomalies in LLM data. * **Performance Monitoring**: Tracking system-level metrics such as response times, token usage, error rates, and throughput to optimize operational efficiency and cost management. ## Challenges Implementing effective LLM Observability presents unique challenges due to the complex, generative nature of these models and the contextual importance of their outputs. * **Defining Meaningful Metrics**: Unlike traditional ML models with clear accuracy metrics, defining and measuring "quality" for LLM outputs is subjective and context-dependent, requiring multiple complementary evaluation approaches. * **Hallucination Detection**: Reliably identifying when LLMs generate false or misleading information requires sophisticated evaluation techniques and often involves comparing outputs against trusted knowledge sources. * **Balancing Performance and Safety**: Organizations must navigate the trade-off between optimizing for response quality and speed while maintaining robust safety guardrails and content filtering. * **Managing High-Dimensionality Data**: LLM embeddings and feature spaces are highly dimensional, making them challenging to analyze, visualize, and interpret without specialized techniques like UMAP. * **Handling Diverse Use Cases**: Different LLM applications (customer service, content creation, code generation) require different monitoring approaches and metrics, making it difficult to establish universal standards. * **Privacy and Security**: LLM applications may process sensitive user data, creating challenges for monitoring that must be balanced with privacy requirements and security considerations. * **Real-time vs. Batch Analysis**: Organizations must decide which metrics require real-time monitoring with immediate alerts versus those that can be analyzed in batch processes, balancing responsiveness with resource efficiency. ## LLM Observability Implementation How-to Guide 1. **Define Monitoring Objectives** * Identify key performance indicators (KPIs) most relevant to your specific LLM application use case. * Determine acceptable thresholds for safety, quality, and performance metrics based on business requirements. 2. **Set Up Data Collection** * Implement comprehensive logging for all LLM application inputs and outputs, including prompts, context, and responses. * For RAG applications, capture retrieved documents and sources to enable faithfulness evaluation. 3. **Implement Essential Enrichments** * Configure embedding generation for semantic analysis of prompts and responses. * Set up basic safety and quality enrichments including toxicity detection, PII scanning, and relevance metrics. 4. **Establish Visualization Capabilities** * Implement UMAP visualization for embedding spaces to identify clusters and anomalies. * Create dashboards displaying key metrics over time to track performance trends. 5. **Configure Alerting and Guardrails** * Set up threshold-based alerts for critical metrics related to safety, performance, and quality. * Implement guardrails for proactive protection against harmful content and prompt injections. 6. **Develop Analysis Workflows** * Create standard procedures for investigating alerts and conducting root cause analysis. * Establish regular review cycles to assess LLM application health and identify areas for improvement. ## Frequently Asked Questions **Q: How is LLM Observability different from traditional ML monitoring?** LLM Observability addresses unique challenges like hallucinations, prompt effectiveness, safety concerns, and nuanced quality metrics that aren't present in traditional ML models. It focuses on unstructured text outputs requiring qualitative and semantic evaluation rather than simple accuracy metrics. **Q: What metrics should I prioritize for my LLM application?** Priority metrics depend on your use case but typically include safety metrics (toxicity, harmful content), quality metrics (faithfulness, coherence, relevance), and operational metrics (response time, token usage). Applications handling sensitive information should prioritize PII detection, while customer-facing applications may emphasize response quality. **Q: How can I detect LLM hallucinations in production?** Fiddler offers multiple approaches to hallucination detection. **Faithfulness (Centor Model)** (powered by the Centor Model for Faithfulness) provides real-time faithfulness scoring in LLM Observability and Guardrails. **RAG Faithfulness** (LLM-as-a-Judge) provides binary assessment with detailed reasoning in Agentic Monitoring and Experiments. For RAG applications, the RAG Health Metrics diagnostic triad (Answer Relevance 2.0, Context Relevance, RAG Faithfulness) helps pinpoint whether issues stem from retrieval or generation. See [RAG Health Diagnostics](/concepts/rag-health-diagnostics). **Q: How do embedding visualizations help with LLM monitoring?** UMAP embedding visualizations help identify clusters of similar prompts or responses, detect outliers, visualize concept drift, and identify problematic patterns like jailbreak attempts or toxic content clusters, providing intuitive visual analysis of high-dimensional data. ## Related Terms * [Enrichments](/glossary/enrichment) * [Guardrails](/glossary/guardrails) * [Embedding Visualization](/glossary/embedding-visualization) * [Data Drift](/glossary/data-drift) ## Related Resources * [LLM Monitoring Overview](/index) * [LLM-based Metrics Guide](/observability/llm/llm-based-metrics) * [Embedding Visualization with UMAP](/observability/llm/embedding-visualization-with-umap) * [Selecting Enrichments](/observability/llm/selecting-enrichments) * [Enrichments Documentation](/observability/llm/enrichments) * [Guardrails for Proactive Application Protection](/glossary/guardrails) # Metric Source: https://docs.fiddler.ai/glossary/metric Metrics in Fiddler AI are quantitative measurements that evaluate model behavior, data quality, and performance over time, enabling proactive monitoring and issue detection. [Metrics](/observability/platform/data-drift-platform) in Fiddler refer to the quantitative measurements and calculations that Fiddler performs on inference data published to the platform. These metrics provide insights into model behavior, data characteristics, and performance over time. Metrics serve as key indicators that help monitor model health, detect anomalies, and ensure that AI/ML systems are functioning as expected in production environments. Fiddler calculates various types of metrics ranging from statistical measures of data drift to sophisticated evaluations of LLM outputs. By tracking these metrics, users can gain visibility into how their models are performing in real-world scenarios, identify potential issues before they impact business outcomes, and maintain trust in their AI systems. ## How Fiddler Uses Metrics Fiddler leverages metrics as the foundation of its monitoring and observability capabilities. When inference data is published to the Fiddler platform, it automatically calculates relevant metrics based on the model type and configuration. These metrics are then displayed in dashboards, used to trigger alerts when thresholds are exceeded, and stored for historical trend analysis. For traditional ML models, Fiddler calculates metrics like data drift, performance tracking, and data integrity. For LLM/GenAI systems, Fiddler extends its metrics suite to include specialized measurements like faithfulness, safety scores, and other LLM-specific evaluations. ## Why Metrics Are Important Metrics are essential for maintaining reliable and trustworthy AI systems in production. They provide quantifiable evidence of model behavior and performance, enabling teams to make data-driven decisions about when interventions are necessary. Without proper metrics, organizations would be operating their AI systems blindly, unable to detect degradation, bias, or unexpected behaviors until they cause significant business impact. By establishing a comprehensive metrics framework, organizations can proactively monitor their AI systems, demonstrate compliance with regulations, and build confidence in their deployment practices. * **Performance Monitoring**: Metrics enable continuous evaluation of model accuracy, precision, recall, and other performance indicators to ensure models are delivering expected results. * **Drift Detection**: Statistical metrics like JSD (Jensen-Shannon Divergence) and PSI (Population Stability Index) help identify when input data distributions shift away from training data, potentially impacting model performance. * **Data Quality Assurance**: Data integrity metrics reveal missing values, outliers, and other quality issues that might affect model predictions. * **Operational Insights**: Traffic metrics and response time measurements provide visibility into the operational aspects of deployed models. * **LLM Output Evaluation**: Specialized metrics for LLM/GenAI systems assess output quality, safety, and alignment with human expectations. * **Compliance and Governance**: Metrics support regulatory requirements by providing evidence of ongoing monitoring and model governance. * **Issue Debugging**: When problems occur, metrics provide crucial diagnostic information to identify root causes. ## Types of Metrics * **Data Drift Metrics**: Measurements that quantify distributional differences between reference and production data, including JSD, PSI, and other statistical distance measures. * **Performance Metrics**: Indicators of model accuracy and effectiveness, such as precision, recall, F1 score, and custom business performance KPIs. * **Data Integrity Metrics**: Measurements that assess data quality, completeness, and validity, highlighting missing values, outliers, and schema violations. * **Traffic Metrics**: Counts and rates of model invocations, response times, and utilization patterns that reveal operational characteristics. * **Statistical Metrics**: Basic descriptive statistics such as mean, median, standard deviation, and correlation that characterize data distributions. * **Custom Metrics**: User-defined calculations tailored to specific business needs and use cases. * **LLM-Based Metrics**: Specialized evaluations for generative AI outputs, including faithfulness, safety, toxicity, bias, and relevance scores. ## Challenges While metrics provide essential visibility into AI systems, implementing an effective metrics strategy comes with several challenges that organizations must navigate. * **Metric Selection**: Choosing the right metrics for specific use cases can be challenging, as different models and applications require different evaluation approaches. * **Threshold Setting**: Determining appropriate threshold values that balance sensitivity to real issues against false alarms requires expertise and context-specific knowledge. * **Computational Overhead**: Calculating complex metrics at scale can introduce performance overhead, especially for high-volume inference systems. * **Interpretation Complexity**: Some advanced metrics may be difficult to interpret without specialized knowledge, making it challenging to translate metric values into actionable insights. * **Metric Drift**: The relevance of metrics themselves may change over time as business requirements evolve or as models are updated. * **Correlation vs. Causation**: Changes in metrics may correlate with issues but not necessarily reveal their root causes, requiring additional analysis. * **LLM Evaluation Subjectivity**: Metrics for generative AI often involve subjective judgments about quality, making standardization difficult. ## Metrics Implementation How-to Guide 1. **Define Monitoring Objectives** * Identify key performance indicators relevant to your model and business use case. * Determine which aspects of model behavior require closest monitoring. 2. **Select Appropriate Metrics** * Choose data drift metrics based on your feature data types (categorical vs. continuous). * Select performance metrics aligned with your model type (classification, regression, LLM). 3. **Configure Baselines** * Upload training or reference data to establish baseline distributions for drift detection. * Set initial performance benchmarks for comparison. 4. **Establish Thresholds** * Define alert thresholds for each metric based on tolerance for risk. * Consider implementing tiered alerting with warning and critical levels. 5. **Integrate with Workflows** * Connect metric alerts to notification systems (email, Slack, etc.). * Establish response procedures for different types of metric anomalies. ## Frequently Asked Questions **Q: How frequently should metrics be calculated?** The calculation frequency depends on your use case. Critical applications may require real-time or hourly metrics, while less sensitive applications might use daily or weekly calculations. Consider both the business impact of issues and the computational resources required. **Q: Can I create custom metrics in Fiddler?** Yes, Fiddler supports custom metrics through its API and interface. You can define calculations based on your specific business needs and model characteristics. **Q: How do I know which thresholds to set for my metrics?** Start by monitoring metrics without alerts to establish normal operational patterns. Then set thresholds that balance sensitivity (catching real issues) with specificity (avoiding false alarms). Initial thresholds often require adjustment based on experience. **Q: What's the difference between data drift and performance metrics?** Data drift metrics measure changes in the statistical properties of input data, while performance metrics evaluate the accuracy and effectiveness of model outputs. Both are important as drift often precedes performance degradation. **Q: How does Fiddler calculate LLM metrics differently?** For LLM/GenAI systems, Fiddler calculates specialized metrics that evaluate text quality, safety, and alignment. Some of these metrics are generated by Fiddler's proprietary algorithms and purpose-built LLMs, while others may leverage external APIs like Anthropic and OpenAI for specific evaluations. ## Related Terms * [Data Drift](/glossary/data-drift) * [Model Performance](/glossary/model-performance) * [Baseline](/glossary/baseline) * [Custom Metric](/glossary/custom-metrics) ## Related Resources * [ML Metrics Reference](/reference/ml-metrics-reference) — Complete list of all built-in ML metrics * [LLM Observability Metrics Reference](/reference/llm-observability-metrics) — Complete list of all LLM enrichments * [Monitoring Platform Overview](/index) * [Data Drift Monitoring](/index) * [Performance Tracking](/observability/platform/performance-tracking-platform) * [Data Integrity Monitoring](/observability/platform/data-integrity-platform) * [Traffic Monitoring](/observability/platform/traffic-platform) * [Statistical Metrics](/observability/platform/statistics) * [Custom Metrics](/glossary/custom-metrics) * [LLM-Based Metrics](/observability/llm/llm-based-metrics) * [Selecting LLM Enrichments](/observability/llm/selecting-enrichments) # ML Observability Source: https://docs.fiddler.ai/glossary/ml-observability A comprehensive approach to monitoring AI systems that goes beyond performance metrics to provide insights into model behavior, data quality, and root causes of issues throughout the ML lifecycle. [ML Observability](/index) is the systematic practice of monitoring, analyzing, and troubleshooting machine learning models throughout their lifecycle to ensure reliability, performance, and alignment with business objectives. It involves continuously tracking inputs, outputs, and model behaviors to provide visibility into how models operate in production environments, detect performance degradation, identify data integrity issues, and maintain trust. Unlike traditional software monitoring, ML Observability addresses the unique challenges of machine learning systems, including data drift, concept drift, model decay, and the black-box nature of complex models. This comprehensive approach enables organizations to detect issues early, perform effective root cause analysis, maintain model quality, and ensure responsible AI deployment. ## How Fiddler Provides ML Observability Fiddler's ML Observability platform provides a comprehensive approach to monitoring and improving machine learning models through five key metric types: data drift, performance, data integrity, traffic, and statistical properties. The platform helps ML teams detect issues early, diagnose root causes, and take corrective actions to maintain model quality and reliability. Fiddler acts as a unified management platform with centralized controls and actionable insights, enabling ML teams to monitor both traditional ML models and LLM applications. The platform's explainability capabilities help users understand model behavior and decisions, while its monitoring features track drift, data quality, and performance metrics to ensure models operate as expected in production. ## Why ML Observability Is Important ML Observability is crucial for organizations deploying machine learning models in production environments. As ML systems increasingly drive critical business decisions and customer experiences, maintaining visibility, reliability, and trust becomes essential. Effective ML Observability enables teams to detect issues early, continuously improve model performance, ensure business value, maintain compliance with regulations, and provide governance for responsible AI. * **Data Drift Detection**: ML Observability continuously monitors for shifts in data distribution between training and production environments using metrics like Jensen-Shannon distance (JSD) and Population Stability Index (PSI), helping identify when models encounter data patterns they weren't trained on. * **Performance Monitoring**: By tracking key performance metrics (accuracy, precision, recall, F1 scores, etc.), ML Observability helps ensure models continue to meet expected quality standards in production and alerts teams when performance degrades. * **Data Integrity Validation**: ML Observability identifies data quality issues like missing values, type mismatches, and range violations that can arise from complex feature pipelines, preventing incorrect data from flowing into models and causing poor performance. * **Root Cause Analysis**: When issues arise, ML Observability provides tools to diagnose the underlying causes through feature impact analysis, drift contribution metrics, and data segment performance comparisons, enabling targeted improvements. * **Operational Efficiency**: ML Observability streamlines troubleshooting workflows, reduces time spent debugging issues, and helps ML teams focus on model development rather than reactive problem-solving, accelerating the ML lifecycle. * **Business Impact Alignment**: By connecting model performance to business KPIs, ML Observability helps quantify the value of ML investments, prioritize improvements based on business impact, and ensure models deliver on their intended business objectives. ## Types of ML Observability * **Data Drift Monitoring**: Tracking changes in the statistical properties of model inputs and outputs over time, comparing production data distributions against baseline data (typically training data) to detect when the model may be receiving data it wasn't designed for. * **Performance Tracking**: Monitoring model accuracy, precision, recall, F1 scores, and other metrics specific to model tasks (classification, regression, ranking) to ensure performance remains within acceptable thresholds across different data segments. * **Data Integrity Validation**: Checking for issues in data quality, including missing values, type mismatches, and range violations that might indicate problems in data pipelines or transformations feeding into the model. * **Traffic Analysis**: Monitoring the volume and patterns of requests to ML models to detect anomalies like unexpected spikes or drops that might indicate system issues or potential security concerns. * **Segment-based Analysis**: Analyzing model performance and behavior across different cohorts, slices, or segments of data to identify issues that may affect specific user groups or business scenarios. * **Explainability Analysis**: Generating local and global explanations of model decisions to understand feature attributions, provide transparency, and diagnose why models make specific predictions. ## Challenges Implementing effective ML Observability presents unique challenges due to the complex nature of machine learning systems and the dynamic environments in which they operate. * **Delayed Ground Truth**: In many ML applications, the actual outcomes or labels for predictions may only become available after a significant delay (such as loan defaults or customer churn), making it difficult to assess model performance in real-time. * **Feature Complexity**: Modern ML models often use hundreds or thousands of features with complex interdependencies, making it challenging to monitor and interpret all relevant input dimensions and their relationships to model outputs. * **Class Imbalance**: Models trained on imbalanced datasets (where some classes are much rarer than others) present special monitoring challenges, as traditional metrics might not detect performance degradation for minority classes. * **Data Pipeline Dependencies**: ML systems rely on complex data pipelines with multiple sources and transformations, creating numerous potential points of failure that need to be monitored for data integrity issues. * **Establishing Thresholds**: Determining appropriate alerting thresholds for drift metrics and performance degradation requires balancing sensitivity to real issues against avoiding false alarms that could lead to alert fatigue. * **Model Opacity**: The black-box nature of complex models like deep neural networks makes understanding the causes of performance issues challenging without specialized explainability techniques. * **Multiple Environments**: ML models often operate across development, staging, and production environments with different data characteristics, making it difficult to maintain consistent monitoring approaches. ## ML Observability Implementation How-to Guide 1. **Establish Baselines** * Create a representative baseline dataset from model training data to serve as a reference point for drift detection. * Define performance benchmarks and acceptable thresholds for key metrics based on business requirements. 2. **Configure Core Monitoring** * Set up data drift monitoring using appropriate distance metrics (JSD, PSI) for different feature types. * Implement performance tracking with metrics specific to your model type (classification, regression, etc.). 3. **Implement Data Integrity Checks** * Configure validation for missing values, type mismatches, and range violations in model inputs. * Establish alerts for data pipeline issues that could impact model performance. 4. **Define Segments for Analysis** * Create relevant data segments or cohorts based on business contexts to track performance across different user groups. * Configure segment-specific monitoring to identify issues that might affect only certain data slices. 5. **Set Up Alerting System** * Establish appropriate thresholds for alerts based on the criticality of the model and business impact. * Configure notification routing to ensure the right teams are informed of relevant issues. 6. **Enable Root Cause Analysis** * Implement explainability tools to understand model decisions and diagnose performance issues. * Create dashboards that visualize feature impact, drift contributions, and other diagnostic metrics. ## Frequently Asked Questions **Q: How is ML Observability different from traditional software monitoring?** ML Observability addresses unique challenges specific to machine learning systems, including data drift, concept drift, and model decay that aren't present in traditional software. While software monitoring focuses on system uptime and resource utilization, ML Observability tracks statistical properties of data, model performance metrics, and the business impact of predictions. **Q: What metrics should I prioritize for my ML models?** Priority metrics depend on your use case, but generally include performance metrics (accuracy, precision, recall for classification; MSE, MAE for regression), data drift metrics to detect distribution shifts, data integrity metrics to ensure quality inputs, and business KPIs that connect model outputs to business outcomes. **Q: How often should I retrain my models based on observability data?** Retraining frequency should be determined by monitoring data rather than fixed schedules. Models should be retrained when significant drift is detected, when performance metrics drop below acceptable thresholds, or when business requirements change. For some applications, this might be weekly or monthly, while others might maintain performance for longer periods. **Q: How can I determine appropriate thresholds for drift alerts?** Start with conservative thresholds based on statistical significance (e.g., drift scores above 0.2 for PSI or JSD metrics) and refine them based on observed correlations between drift metrics and performance degradation in your specific models. Monitor false positives and adjust thresholds to balance sensitivity with alert fatigue. ## Related Terms * [Data Drift](/glossary/data-drift) * [Model Performance](/glossary/model-performance) * [Model Drift](/glossary/model-drift) * [Metrics](/glossary/metric) * [Baselines](/glossary/baseline) ## Related Resources * [ML Monitoring Platform Overview](/index) * [Data Drift Monitoring](/observability/platform/data-drift-platform) * [Performance Tracking](/observability/platform/performance-tracking-platform) * [Ensuring Data Integrity](/observability/platform/data-integrity-platform) * [Model Segments](/observability/platform/segments) * [The Leader in ML Observability for MLOps](https://www.fiddler.ai/mlops) # Model Drift Source: https://docs.fiddler.ai/glossary/model-drift Changes in model performance over time due to shifting data patterns, concept evolution, or system degradation. Fiddler detects and diagnoses model drift to maintain AI reliability. Model drift refers to the degradation in an AI model's performance over time as the relationship between input features and target outputs changes in the real world. Unlike data drift, which focuses solely on shifts in input distributions, model drift encompasses broader changes in model behavior and effectiveness, even when input distributions remain stable. Model drift can manifest in various ways: prediction patterns may shift, error rates might increase, or the model's underlying assumptions may no longer hold valid. This phenomenon is an inevitable challenge in machine learning deployments, as the real-world environment rarely remains static over extended periods. In the context of AI observability, model drift represents a critical concern that requires continuous monitoring, timely detection, and proactive remediation to maintain reliable and effective AI systems in production. ## How Fiddler Monitors Model Drift Fiddler's platform takes a comprehensive approach to model drift detection by monitoring several interconnected dimensions that together provide a complete picture of model health and stability. Through its performance tracking capabilities, Fiddler continuously evaluates model predictions against ground truth values (when available) to identify degradation in accuracy, precision, recall, or custom business metrics that might indicate model drift. This performance monitoring is complemented by data drift detection, which helps determine whether changes in model behavior are due to shifts in input data patterns. Fiddler also enables root cause analysis, allowing users to detect model drift that might affect specific segments of the data population differently. By comparing current performance across various cohorts against baseline expectations, Fiddler can identify localized drift that might not be apparent in aggregate metrics. ## Why Monitoring Model Drift Is Important Monitoring model drift is essential for maintaining reliable and trustworthy AI systems in production environments. Undetected model drift can lead to incorrect predictions, suboptimal decisions, and potentially significant business impact, especially in critical applications like fraud detection, risk assessment, or healthcare diagnostics. By implementing robust model drift monitoring, organizations can ensure their AI systems continue to perform as expected, identify when retraining or recalibration is necessary, and maintain confidence in automated decision processes. This monitoring capability is particularly crucial as AI deployments scale across the enterprise and become more deeply integrated into business operations. * **Maintaining Prediction Quality**: Regular monitoring for model drift ensures that prediction quality remains high over time, preventing gradual degradation that might otherwise go unnoticed until it causes significant issues. * **Timely Model Updates**: Early detection of model drift enables more proactive model maintenance, allowing teams to schedule retraining or updates before performance deteriorates to unacceptable levels. * **Root Cause Analysis**: Comprehensive model drift monitoring provides insights into why performance is changing, differentiating between data quality issues, concept drift, or other factors affecting model behavior. * **Business Impact Mitigation**: By detecting model drift early, organizations can prevent potential negative business impacts such as revenue loss, customer dissatisfaction, or compliance violations that might result from degraded model performance. * **Resource Optimization**: Understanding patterns of model drift helps organizations optimize the frequency of model retraining, avoiding both unnecessary updates (when models remain stable) and delayed responses to genuine performance issues. * **Regulatory Compliance**: In regulated industries, demonstrating continuous monitoring for model drift is increasingly becoming a requirement for responsible AI governance and compliance with emerging AI regulations. * **Continuous Improvement**: Tracking model drift over time provides valuable insights that can inform better feature engineering, model architecture decisions, and training practices for future model iterations. ## Types of Model Drift * **Concept Drift**: Changes in the underlying relationship between input features and target variables, where the statistical properties of the target variable change over time, making previous patterns less predictive. * **Prediction Drift**: Changes in the statistical distribution of model outputs or predictions over time, which may indicate shifting behavior even if accuracy metrics remain temporarily stable. * **Accuracy Drift**: Direct degradation in performance metrics like accuracy, precision, recall, or F1-score that indicates the model is becoming less effective at its intended task. * **Feature Contribution Drift**: Changes in how different features influence model predictions, potentially indicating that the model's internal decision-making process is evolving in unexpected ways. * **Seasonal Drift**: Cyclical changes in model performance related to time-based patterns such as day/night cycles, weekday/weekend differences, or annual seasonality effects. * **Population Drift**: Changes in model performance for specific segments or cohorts of the data, even when overall performance metrics remain stable, indicating uneven drift effects across different populations. * **Business Impact Drift**: Changes in how model predictions affect business outcomes and KPIs, where technical performance metrics might remain stable but the business value of the model's decisions decreases. ## Challenges While essential for AI system maintenance, effective model drift monitoring comes with several technical and practical challenges that organizations must navigate. * **Ground Truth Latency**: In many real-world applications, actual outcomes (ground truth) may not be available until significantly after predictions are made, creating delays in detecting accuracy-based drift signals. * **Distinguishing Causes**: Determining whether observed drift is due to data distribution changes, evolving relationships between variables, or issues with the model itself can be challenging but necessary for appropriate remediation. * **Setting Appropriate Thresholds**: Defining meaningful thresholds for when drift requires attention is complex, requiring balance between sensitivity to meaningful changes and resistance to false alarms from normal statistical variation. * **High-Dimensional Monitoring**: Models with many features present challenges for comprehensive drift monitoring, as changes might occur in complex, high-dimensional patterns that are difficult to detect and visualize. * **Feedback Loops**: When model outputs influence future inputs (as in recommendation systems or pricing models), distinguishing natural system dynamics from problematic drift becomes especially challenging. * **Resource Constraints**: Comprehensive model drift monitoring can be computationally intensive, particularly for large-scale models or high-volume inference systems, requiring efficient implementation strategies. * **Interpretability Trade-offs**: More sophisticated drift detection approaches might provide better sensitivity but at the cost of interpretability, making it harder to explain detected issues to stakeholders. ## Model Drift Monitoring Implementation Guide 1. **Define Monitoring Objectives** * Identify which aspects of model performance are most critical for your specific use case. * Determine acceptable performance thresholds based on business requirements and risk tolerance. 2. **Establish Comprehensive Baselines** * Create performance baselines using training or validation data to serve as reference points. * Consider multiple baselines for different time periods or data segments if appropriate. 3. **Configure Multi-Dimensional Monitoring** * Set up combined monitoring for both data drift and performance metrics to capture different drift signals. * Implement segment-specific monitoring for important data cohorts or slices. 4. **Set Up Alert Systems** * Configure alerts with appropriate thresholds for different drift metrics based on sensitivity needs. * Establish notification workflows to ensure the right teams are informed when drift is detected. 5. **Implement Regular Review Processes** * Schedule routine reviews of drift metrics even in the absence of alerts to spot gradual changes. * Maintain documentation of observed drift patterns and corresponding actions taken. 6. **Develop Remediation Strategies** * Create predefined response plans for different types and severities of model drift. * Consider automated model updating pipelines for cases where drift follows predictable patterns. ## Frequently Asked Questions **Q: How is model drift different from data drift?** While data drift focuses specifically on changes in the statistical distribution of input features, model drift is a broader concept that encompasses any degradation in model performance over time. Data drift is often a cause of model drift, but model drift can also occur due to other factors such as concept drift (changes in the relationship between inputs and outputs) or model decay (gradual degradation of model parameters or implementation). Fiddler monitors both phenomena to provide comprehensive observability. **Q: How frequently should I check for model drift?** The optimal frequency depends on your specific use case, data velocity, and business requirements. For critical applications with high-frequency decisions, daily or even hourly monitoring might be appropriate. For more stable applications with slower-changing environments, weekly or monthly checks might suffice. Fiddler's platform allows for flexible monitoring schedules tailored to your specific needs and can automate this process through continuous monitoring and alerts. **Q: Should I retrain my model at the first sign of drift?** Not necessarily. Minor drift might be within normal statistical variation or temporary in nature. Before retraining, it's important to investigate the root cause, assess business impact, and determine if the drift represents a genuine shift requiring model updates. Fiddler's analytics capabilities help you make informed decisions about when retraining is truly warranted versus when other interventions might be more appropriate. **Q: Can model drift occur even if my data hasn't changed?** Yes, model drift can occur even with stable input distributions. This might happen due to changes in the underlying relationships between variables (concept drift), subtle implementation issues during deployment, hardware or infrastructure changes affecting numerical precision, or gradual erosion of model effectiveness in dynamic environments. Monitoring both data distributions and model performance is essential for comprehensive drift detection. **Q: How does Fiddler help distinguish different types of drift?** Fiddler provides multiple monitoring dimensions that together help diagnose the nature of observed drift. By simultaneously tracking data drift metrics, performance metrics, feature importance, and segment-specific analyses, Fiddler enables users to triangulate the likely causes of detected drift. This multi-faceted approach helps distinguish between data quality issues, concept drift, or other factors, guiding more targeted remediation strategies. ## Related Terms * [Data Drift](/glossary/data-drift) * [Model Performance](/glossary/model-performance) * [Model Drift](/glossary/model-drift) * [Metrics](/glossary/metric) * [Baselines](/glossary/baseline) ## Related Resources * [ML Monitoring Platform Overview](/index) * [Data Drift Monitoring](/observability/platform/data-drift-platform) * [Performance Tracking](/observability/platform/performance-tracking-platform) * [Ensuring Data Integrity](/observability/platform/data-integrity-platform) * [Model Segments](/observability/platform/segments) * [Setting Up Alerts](/observability/platform/alerts-platform) # Model Performance Source: https://docs.fiddler.ai/glossary/model-performance Quantitative evaluation of AI model accuracy and effectiveness in production. Fiddler tracks performance metrics over time to detect degradation and identify opportunities for improvement. [Model Performance](/observability/platform/performance-tracking-platform) refers to the evaluation of how well a machine learning model performs its intended task by comparing its predictions against actual outcomes. It involves measuring the accuracy, reliability, and effectiveness of a model using various metrics specific to the model type (classification, regression, ranking, etc.). Model performance assessment is a critical component of the machine learning lifecycle, providing insights into a model's strengths, weaknesses, and overall utility. Poor model performance can have significant business implications, affecting decision quality, customer experience, and ultimately business outcomes. Effective performance monitoring helps detect degradation early, enabling timely interventions such as retraining or recalibration. ## How Fiddler Monitors Model Performance Fiddler's AI Observability platform offers comprehensive model performance monitoring for various model types including binary classification, multi-class classification, regression, and ranking models. The platform provides out-of-the-box performance metrics suited to each model type and visualizes these metrics through charts and dashboards. For classification models, Fiddler tracks metrics such as accuracy, precision, recall, F1 score, and AUC-ROC. For regression models, it monitors metrics like MSE, MAE, and R-squared. These metrics help users understand how well their models are performing in production, detect performance degradation, and make informed decisions about model maintenance or retraining. ## Why Model Performance Is Important Model performance monitoring is essential for maintaining reliable and effective AI systems. As models encounter new data in production, their performance can degrade over time due to data drift, concept drift, or other factors. Continuous monitoring of model performance helps organizations identify issues early, understand their root causes, and take appropriate corrective actions. * **Business Impact Assessment**: Model performance metrics help quantify the business impact of model predictions, enabling stakeholders to understand how well the model supports business objectives and where improvements might be needed. * **Early Detection of Degradation**: Regular monitoring of performance metrics allows teams to quickly identify when a model's performance starts to deteriorate, enabling proactive intervention before significant business impact occurs. * **Root Cause Analysis**: Performance metrics, especially when examined alongside other monitoring data like feature distributions and data integrity metrics, help pinpoint the underlying causes of performance issues. * **Model Comparison**: Performance metrics provide a standardized way to compare different model versions or competing models to select the best performer for a specific use case. * **Regulatory Compliance**: In regulated industries, monitoring and documenting model performance is often a requirement for demonstrating responsible AI practices and compliance with governance frameworks. * **Continuous Improvement**: Performance metrics guide the model improvement process by highlighting specific areas where the model underperforms, helping teams focus their enhancement efforts effectively. ## Types of Model Performance Metrics * **Binary Classification Metrics**: Metrics for evaluating models that predict one of two possible outcomes, including accuracy, precision, recall, F1 score, AUC-ROC, and confusion matrix-based measurements that help understand different aspects of classification performance. * **Multi-class Classification Metrics**: Metrics for models that predict one of several classes, including accuracy, log loss, and class-specific precision and recall, often calculated using approaches like micro or macro averaging across classes. * **Regression Metrics**: Metrics for models that predict continuous values, including Mean Squared Error (MSE), Mean Absolute Error (MAE), Root Mean Squared Error (RMSE), and R-squared, which measure different aspects of prediction accuracy and model fit. * **Ranking Metrics**: Metrics for models that rank items by relevance, including Mean Average Precision (MAP) for binary relevance ranking and Normalized Discounted Cumulative Gain (NDCG) for evaluating the quality of ranking results. * **Time-Series Performance Metrics**: Specialized metrics for time-series forecasting models, often focusing on error measurements across different time horizons and accounting for seasonal patterns in the data. ## Challenges Monitoring model performance effectively presents several challenges, especially in production environments where models encounter diverse and evolving data. * **Delayed Ground Truth**: In many applications, the actual outcomes (ground truth) needed to calculate performance metrics become available only after a significant delay, making real-time performance monitoring difficult. * **Class Imbalance**: When the distribution of classes is heavily skewed, standard performance metrics may provide an overly optimistic view of model performance, requiring specialized metrics or approaches to properly evaluate imbalanced classification. * **Changing Data Distributions**: As production data distributions shift over time (data drift), performance metrics may degrade, requiring monitoring solutions that can detect and quantify distribution changes along with performance changes. * **Metric Selection**: Choosing the right metrics for a specific model and use case can be challenging, as different metrics emphasize different aspects of performance and may lead to different conclusions about model quality. * **Threshold Optimization**: For classification models, performance often depends on the chosen decision threshold, requiring methods to optimize and adjust thresholds based on business requirements and changing data patterns. * **Resource Constraints**: Computing performance metrics for large-scale models or high-volume data streams can be resource-intensive, requiring efficient implementation and potentially sampling strategies. * **Interpretability of Metrics**: Some metrics, while mathematically sound, can be difficult for non-technical stakeholders to understand, requiring careful communication and translation to business impacts. ## Model Performance Monitoring How-to Guide 1. **Define Performance Objectives** * Identify which aspects of model performance are most critical for your specific use case. * Select appropriate metrics based on your model type and business requirements. 2. **Establish a Baseline** * Measure and record the model's performance metrics during training/validation. * Document the expected performance range for each metric to serve as a reference point. 3. **Configure Monitoring** * Set up regular performance metric calculations on production data. * Define appropriate time windows and aggregation levels for performance analysis. 4. **Set Up Alerting** * Establish thresholds for performance metrics that would trigger alerts. * Configure notification systems to alert relevant team members when performance deteriorates. 5. **Implement Root Cause Analysis** * When performance issues are detected, investigate potential causes such as data drift or integrity issues. * Use tools like Fiddler's dashboards to drill down into specific segments or features contributing to performance decline. 6. **Take Corrective Action** * Based on root cause analysis, implement appropriate interventions such as model retraining, feature engineering, or data pipeline fixes. * For temporary performance issues, consider adjustments like threshold tuning where appropriate. ## Frequently Asked Questions **Q: How often should I monitor model performance?** The optimal monitoring frequency depends on your specific use case, data volume, and business criticality. High-stakes applications might require daily or even real-time monitoring, while less critical models might be monitored weekly or monthly. Also consider the rate of expected data drift and availability of ground truth labels when determining monitoring frequency. **Q: Which performance metrics should I prioritize?** The most relevant metrics depend on your model type and business objectives. For classification models with balanced classes, accuracy, precision, recall, and F1 score are common choices. For regression models, MSE, MAE, and R-squared are typically used. Consider the business impact of different types of errors and prioritize metrics that align with your specific goals. **Q: How do I know if my model's performance is good enough?** Good performance is context-dependent. Compare your model's performance against relevant benchmarks, including baseline models (e.g., simple heuristics), previous model versions, industry standards, and business requirements. Define acceptable performance thresholds based on the criticality of the use case and the cost of errors. **Q: What should I do when model performance drops?** First, verify that the performance drop is statistically significant and not due to random variation. Then, investigate potential causes such as data drift, data quality issues, or changes in the underlying process. Depending on the root cause, solutions might include retraining the model, adjusting features, fixing data pipeline issues, or in some cases, reconsidering the modeling approach entirely. ## Related Terms * [Data Drift](/glossary/data-drift) * [Model Performance](/glossary/model-performance) * [Model Drift](/glossary/model-drift) * [Baseline](/glossary/baseline) ## Related Resources * [Performance Tracking Platform Guide](/observability/platform/performance-tracking-platform) * [Performance Charts Creation](/observability/analytics/performance-charts-creation) * [Performance Charts Visualization](/observability/analytics/performance-charts-visualization) * [Data Drift Platform Guide](/observability/platform/data-drift-platform) * [ML Model Monitoring](https://www.fiddler.ai/ml-model-monitoring) # Trust Score Source: https://docs.fiddler.ai/glossary/trust-score Quantitative scores generated by Fiddler's enrichment processes that measure LLM output quality and safety. These numerical metrics enable monitoring, alerting, and real-time decision-making for AI go [Trust Scores](/observability/llm/enrichments) are quantitative measurements that result from Fiddler's enrichment processes, providing numerical assessments of LLM output quality, safety, and reliability. These scores translate complex qualitative judgments about generative AI content into measurable metrics that can be monitored over time, used in alerting systems, and leveraged for real-time content filtering decisions. When [enrichments](/glossary/enrichment) process LLM inputs and outputs through Fiddler's platform, they generate Trust Scores that evaluate dimensions such as safety, toxicity, faithfulness, relevance, and coherence. Each score represents a quantified assessment that enables systematic monitoring and governance of LLM applications at scale. Trust Scores serve as the critical link between automated evaluation and actionable insights, transforming the output of sophisticated evaluation models into interpretable metrics that teams can use to understand model behavior, set thresholds, configure alerts, and make real-time filtering decisions through Fiddler Guardrails. ## How Fiddler Uses Trust Scores Trust Scores function as the primary interface between Fiddler's evaluation infrastructure and its monitoring and governance capabilities. Once enrichments generate these scores, they appear as additional data columns alongside original inference data, creating a comprehensive view of both model behavior and output quality. **Monitoring and Analytics**: Trust Scores populate monitoring dashboards where teams can track quality trends over time, compare performance across different model versions, and identify degradation patterns. The scores enable sophisticated analytics that help organizations understand when and why their LLM applications produce lower-quality outputs. **Alerting and Notifications**: Organizations configure alert rules based on Trust Score thresholds, enabling proactive notification when scores indicate potential quality or safety issues. These alerts can trigger various responses, from simple notifications to automated escalation procedures. **Real-time Decision Making**: In Fiddler Guardrails, Trust Scores serve as the evaluation signals that determine whether content should be allowed or filtered. When scores indicate safety violations or quality concerns, Guardrails can automatically block problematic outputs or provide detailed explanations of detected issues. **Threshold Management**: Trust Scores enable organizations to establish quantitative governance policies by setting acceptable score ranges for different use cases, risk profiles, and compliance requirements. ## Why Trust Scores Are Important Trust Scores address the fundamental challenge of making subjective content quality assessments scalable and consistent. While human evaluators might assess LLM outputs differently based on context, experience, or interpretation, Trust Scores provide standardized measurements that enable reliable, automated governance at production scale. **Objective Quality Assessment**: Trust Scores transform qualitative judgments into quantitative metrics, enabling systematic comparison of output quality across time periods, model versions, and different segments of user interactions. **Operational Scalability**: Manual review of LLM outputs doesn't scale to production volumes. Trust Scores enable automated quality assessment of millions of interactions while maintaining consistent evaluation criteria. **Risk Management**: By providing numerical thresholds for acceptable content quality and safety, Trust Scores enable proactive risk management that can prevent problematic outputs from reaching users. **Compliance and Auditability**: Trust Scores create quantitative evidence of content evaluation that supports compliance reporting and provides auditable records of AI governance practices. **Performance Optimization**: Score patterns reveal insights about model behavior that guide optimization efforts, helping teams identify when prompts, training data, or model configurations need adjustment. ## Types of Trust Scores ### Safety and Content Moderation Scores **Safety Scores**: Numerical assessments indicating the likelihood that content contains harmful, inappropriate, or policy-violating material across multiple safety dimensions including violence, hate speech, and explicit content. **Toxicity Scores**: Specialized measurements focusing specifically on offensive, toxic, or harmful language, often broken down into subcategories for more granular content moderation decisions. **Bias Scores**: Quantitative indicators of potential bias in content, including gender, racial, political, or other forms of bias that might impact fairness and inclusivity. ### Quality and Accuracy Scores **Faithfulness Scores**: Measurements of factual accuracy and reliability, indicating the likelihood that content contains hallucinations, fabrications, or factual inconsistencies relative to provided context. Fiddler provides two faithfulness approaches: Faithfulness (Centor Model) (powered by the Centor Model for Faithfulness, probability score 0.0–1.0) for real-time guardrails, and RAG Faithfulness (LLM-as-a-Judge, binary Yes/No with reasoning) for diagnostic evaluation. **Coherence Scores**: Numerical assessments of logical flow, consistency, and readability, identifying content that may be disjointed, confusing, or poorly structured. **Relevance Scores**: Metrics indicating how well content addresses the specific query or prompt, detecting off-topic or tangential responses. Includes Answer Relevance 2.0 (ordinal: High/Medium/Low) and Context Relevance (ordinal: High/Medium/Low) for RAG-specific evaluation. ### Contextual and Behavioral Scores **Sentiment Scores**: Measurements of emotional tone and sentiment expressed in content, useful for detecting inappropriately negative or emotional responses in specific contexts. **Confidence Scores**: Indicators of how certain the evaluation model is about its assessment, helping teams understand when scores may be less reliable. **Custom Domain Scores**: Application-specific measurements that evaluate content against custom business logic or domain-specific quality criteria. ## Score Interpretation and Thresholds ### Understanding Score Ranges Most Trust Scores use standardized ranges (typically 0-1 or 0-100) where higher scores generally indicate greater concern or lower quality, though specific interpretation depends on the score type: * **Safety Scores**: Higher scores indicate greater safety risk * **Faithfulness Scores**: Higher scores often indicate better factual accuracy (depending on implementation) * **Quality Scores**: Interpretation varies by specific metric and use case ### Setting Effective Thresholds **Risk-Based Thresholds**: Organizations should establish score thresholds based on their specific risk tolerance, regulatory requirements, and business context rather than using universal cutoffs. **Adaptive Thresholds**: Score thresholds may need adjustment over time as models evolve, user expectations change, or business requirements shift. **Multi-Score Policies**: Complex governance policies often require consideration of multiple Trust Scores simultaneously, using weighted combinations or hierarchical decision trees. ## Challenges in Trust Score Implementation **Score Reliability**: While Trust Scores provide consistent measurements, their accuracy depends on the underlying evaluation models and may vary across different content types, domains, or edge cases. **Threshold Calibration**: Determining appropriate score thresholds requires balancing false positives (blocking acceptable content) against false negatives (allowing problematic content), often requiring extensive testing with representative data. **Score Evolution**: As language usage and societal standards evolve, Trust Score models may need updates to maintain alignment with current expectations, requiring periodic recalibration of thresholds. **Context Sensitivity**: Content appropriateness often depends on context that may not be fully captured in individual scores, requiring careful consideration of how contextual factors should influence score interpretation. **Multi-dimensional Analysis**: Monitoring multiple score dimensions simultaneously requires sophisticated dashboard design and alert logic to avoid information overload while ensuring comprehensive coverage. ## Trust Score Implementation Guide 1. **Establish Score Requirements** * Identify which quality and safety dimensions are most critical for your use case * Determine required score granularity and update frequency * Consider regulatory and compliance requirements that may influence score interpretation 2. **Configure Score Generation** * Enable appropriate enrichments during model onboarding to generate relevant Trust Scores * Ensure score generation aligns with your monitoring and governance requirements * Test score generation with representative data samples 3. **Calibrate Thresholds** * Analyze score distributions across representative datasets to understand normal ranges * Set initial thresholds based on risk tolerance and business requirements * Validate threshold effectiveness through controlled testing 4. **Implement Monitoring** * Create dashboards that effectively visualize score trends and distributions * Configure alert rules based on score thresholds and trend analysis * Establish escalation procedures for different types of score anomalies 5. **Optimize and Refine** * Monitor false positive and false negative rates for threshold adjustments * Regularly review score patterns to identify opportunities for improvement * Update thresholds and interpretation guidelines based on operational experience ## Frequently Asked Questions **Q: How are Trust Scores calculated?** Trust Scores are generated by Fiddler's enrichment processes using specialized evaluation models. Each enrichment applies domain-specific evaluation logic to assess content quality, safety, or other dimensions, producing numerical scores that quantify the assessment results. **Q: What's the difference between Trust Scores and enrichments?** Enrichments are the computational processes that analyze content, while Trust Scores are the numerical outputs that result from those processes. Think of enrichments as the evaluation engines and Trust Scores as the quantified results they produce. **Q: How reliable are Trust Scores compared to human evaluation?** Fiddler's Trust Scores are designed to correlate strongly with human judgments while providing consistency and scalability that human evaluation cannot match. While no automated system perfectly replicates human assessment, Trust Scores provide reliable signals that align well with human evaluations across most common use cases. **Q: Can I customize Trust Score thresholds for my organization?** Yes, Fiddler allows organizations to set custom thresholds for Trust Scores based on their specific risk tolerance, compliance requirements, and business context. Threshold configuration is separate from score generation, enabling adaptation without changing underlying evaluation logic. **Q: How do Trust Scores power Fiddler Guardrails?** Trust Scores serve as the decision signals for Guardrails' real-time content filtering. When scores exceed configured safety thresholds or fall below quality requirements, Guardrails can automatically block content or provide detailed explanations of detected violations. **Q: Do Trust Scores impact system performance?** Trust Scores themselves are lightweight numerical values that have minimal impact on system performance. The computational cost comes from the enrichment processes that generate the scores, which are optimized for efficiency in Fiddler's infrastructure. ## Related Terms * [Enrichments](/observability/llm/enrichments) - The computational processes that generate Trust Scores * [Fiddler Guardrails](/glossary/guardrails) - Real-time protection using Trust Score evaluation * [Fiddler Centor Models](/glossary/centor-models) - The purpose-built models powering score generation * [LLM Observability](/glossary/llm-observability) - The monitoring practice enabled by Trust Scores ## Related Resources * [LLM Monitoring Overview](/observability/llm) * [Enrichments Documentation](/observability/llm/enrichments) * [Selecting Enrichments Guide](/observability/llm/selecting-enrichments) * [Guardrails for Content Protection](/glossary/guardrails) * [LLM-based Metrics Guide](/observability/llm/llm-based-metrics) # Introduction to Fiddler Source: https://docs.fiddler.ai/index The only platform delivering enterprise-grade visibility, context, and control across traditional ML models, LLM applications, and autonomous multi-agent systems. ## Get started in under 10 minutes Choose your path based on your use case: Monitor AI agents and multi-step workflows Test and validate LLM outputs Protect your AI applications Monitor LLM applications in production Monitor traditional ML models *** ## Explore Fiddler platform features Validate LLM applications and models before and after deployment Monitor production agentic applications, GenAI and LLM applications, and ML models in real time Ensure AI safety and compliance # Agentic AI Overview Source: https://docs.fiddler.ai/integrations/agentic-ai-and-llm-frameworks/agentic-ai Native SDKs and framework integrations for agentic AI and LLM applications Monitor and evaluate your agentic AI applications with Fiddler's native SDKs and framework integrations. From auto-instrumented LangGraph agents to Strands agent applications, Fiddler provides comprehensive observability for the next generation of AI systems. ## Why Agentic Observability Matters Agentic AI systems—autonomous agents that reason, plan, and coordinate—introduce exponential complexity compared to traditional AI applications: * **[26x more monitoring resources](https://www.capgemini.com/insights/expert-perspectives/ai-lab-the-efficient-use-of-tokens-for-multi-agent-systems/)** required than single-agent systems * **Non-deterministic behavior** makes traditional debugging approaches inadequate * **Multi-step workflows** require hierarchical tracing across agents, tools, and LLM calls * **Cascading failures** demand root cause analysis across distributed agent architectures Fiddler's agentic observability provides visibility into every stage of the agent lifecycle: Thought → Action → Execution → Reflection → Alignment. ## Native SDKs Fiddler-built and maintained instrumentation libraries for production-grade agentic observability. ### Fiddler OTel SDK Core OpenTelemetry instrumentation library for framework-agnostic GenAI observability. The foundation package that all other Fiddler integrations build on. **Best for:** Custom Python agents with no framework dependency, or any application where you want lightweight, decorator-based instrumentation **Key Features:** * `@trace` decorator for zero-boilerplate function instrumentation (sync and async) * Typed span wrappers: `FiddlerGeneration`, `FiddlerTool`, `FiddlerChain` * Context isolation — does not interfere with any existing OpenTelemetry setup * `set_conversation_id()` for multi-turn conversation tracking * JSONL local capture and console tracing for development [**Get Started with Fiddler OTel SDK →**](/integrations/agentic-ai/fiddler-otel-sdk) ### Fiddler LangChain SDK Auto-instrumentation for LangChain V1 agents built with `langchain.agents.create_agent`. **Best for:** LangChain V1 agents that use the `create_agent` API **Key Features:** * One call to `FiddlerLangChainInstrumentor.instrument()` auto-traces all agents * Clean, flat trace hierarchy: agent → LLM calls → tool calls, no noisy Chain wrappers * Full async support via `agent.ainvoke()` * Single-trace multi-agent nesting — sub-agents nest under delegation tool spans automatically * Retriever-as-tool support [**Get Started with Fiddler LangChain SDK →**](/integrations/agentic-ai/langchain-sdk) ### Fiddler LangGraph SDK Auto-instrument LangGraph applications with OpenTelemetry-based tracing. **Best for:** LangChain LangGraph agent applications with complex multi-agent workflows **Key Features:** * Automatic span creation for agent steps, tool calls, and LLM requests * Hierarchical tracing across Application → Session → Agent → Span levels * Zero-configuration setup with one environment variable * Full context preservation for debugging non-deterministic behavior [**Get Started with LangGraph SDK →**](/integrations/agentic-ai/langgraph-sdk) ### Strands Agents SDK Native integration for Strands Agents applications. **Best for:** Teams building agents with the Strands framework **Key Features:** * Purpose-built for Strands agent architecture * Seamless integration with Strands agent runtime * Multi-agent coordination tracking * Platform-agnostic deployment (works on AWS, custom infrastructure, etc.) [**Get Started with Strands Agents SDK →**](/integrations/agentic-ai/strands-sdk) ### Google ADK SDK Native integration for Google ADK (Agent Development Kit) applications. **Best for:** Teams building agents with Google's ADK framework and Gemini models **Key Features:** * Two-line setup with `FiddlerClient` + `GoogleADKInstrumentor` * Works with Gemini API keys and Vertex AI authentication * Automatic capture of agent, LLM, and tool spans * Session identity propagation across multi-turn conversations * No monkey-patching -- pure OpenTelemetry SpanProcessor approach [**Get Started with Google ADK SDK →**](/integrations/agentic-ai/google-adk-sdk) ### LiteLLM Integration Zero-configuration integration for teams using LiteLLM — whether calling LLM providers directly via the SDK or routing traffic through a LiteLLM proxy gateway. **Best for:** Teams using LiteLLM SDK or proxy who want unified cost tracking and latency monitoring across all providers — with no Fiddler-specific package required **Key Features:** * **LiteLLM SDK**: Enable LiteLLM's built-in OTEL integration with one line (`litellm.callbacks = ["otel"]`) and point it at Fiddler — no extra packages needed * **LiteLLM Proxy**: Automatic detection of proxy OTel traces — no SDK or code changes needed in calling applications * Captures prompts, responses, token usage, cost metadata, and latency * Works with any LLM provider supported by LiteLLM (OpenAI, Anthropic, Bedrock, and more) [**Get Started with LiteLLM Integration →**](/integrations/agentic-ai/litellm-integration) ### AgentGateway Integration Zero-instrumentation integration for teams using [AgentGateway](https://agentgateway.dev/) as an **LLM proxy** — no Fiddler SDK or application code changes required. Currently supports the LLM gateway only; MCP gateway and A2A gateway are not yet supported. **Best for:** Teams who want observability without touching application code, or who are already routing LLM traffic through AgentGateway for auth, rate limiting, or multi-provider routing **Key Features:** * **Zero code changes** — point your existing OpenAI client at AgentGateway; traces appear automatically * Captures prompts, responses, token usage, model name, and latency via AgentGateway's CEL tracing config * Session grouping via the `X-Fiddler-Conversation-Id` HTTP header [**Get Started with AgentGateway Integration →**](/integrations/agentic-ai/agentgateway-integration) ### Claude Code Integration Zero-instrumentation integration for teams using [Claude Code](https://docs.anthropic.com/en/docs/claude-code/overview) — Anthropic's CLI coding agent. Captures LLM calls, tool invocations, user prompts, token usage, and permission decisions via Claude Code's built-in OpenTelemetry tracing. **Best for:** Teams deploying Claude Code for software engineering and wanting visibility into coding agent sessions, tool usage patterns, and safety compliance **Key Features:** * **Zero code changes** — Claude Code emits OTel traces natively; just set environment variables * Captures user prompts, LLM call metadata (tokens, latency, model), and tool invocations * Session correlation via `session.id` for multi-turn coding session replay * Permission decision tracking (accept/deny) for tool invocations * Compatible with Fiddler enrichment rules (Prompt Safety scoring on agent spans) Claude Code's OTel tracing is in **beta** and has limitations — LLM response content and tool input/output are not available in traces. See the integration guide for full details. [**Get Started with Claude Code Integration →**](/integrations/agentic-ai/claude-code-integration) ### Fiddler Evals SDK LLM experiments framework with pre-built evaluators and custom eval support. **Best for:** Offline evaluation of LLM applications and agentic workflows **Key Features:** * 14+ pre-built evaluators (faithfulness, toxicity, PII, coherence, etc.) * Custom evaluator framework for domain-specific metrics * Batch evaluation for datasets * Integration with the Fiddler platform for tracking and comparison [**Get Started with Evals SDK →**](/integrations/agentic-ai/evals-sdk) ## Platform SDKs Core API access for building custom integrations and monitoring workflows. ### Python Client SDK Comprehensive Python client for all Fiddler platform capabilities. **Best for:** Custom integrations, ML model monitoring, programmatic access to Fiddler features **Key Features:** * Full API coverage for ML and LLM monitoring * Dataset uploads, model publishing, event ingestion * Alert configuration, dashboard management * Custom metrics and enrichments [**Python Client Documentation →**](/sdk-api/python-client/connection) ### REST API Complete HTTP API for language-agnostic platform access. **Best for:** Non-Python environments, webhook integrations, custom tooling [**REST API Reference →**](/sdk-api/rest-api) ## Advanced Integrations ### Kong AI Gateway Integration Gateway-layer integration for teams using [Kong AI Gateway](https://konghq.com/products/kong-ai-gateway) (v3.13+). Fiddler integrates via Kong's `opentelemetry` plugin — full LLM observability without adding any SDK to your application code. **Best for:** Teams already routing LLM traffic through Kong AI Gateway who want zero-instrumentation observability **Key Features:** * **Zero instrumentation** — point your app at Kong instead of the provider; no code changes * LLM span tracing: token counts, model name, latency, and content (with `log_payloads: true`) * Multi-provider support (OpenAI, Anthropic, Cohere, Azure OpenAI, Google Gemini, and more) * Direct OTLP export to Fiddler over HTTPS with auth headers [**Get Started with Kong AI Gateway Integration →**](/integrations/agentic-ai/kong-integration) ### S3 Trace Ingestion Ingest pre-generated OTLP trace files from Amazon S3 into Fiddler without modifying your application. The S3 connector automatically discovers, parses, and forwards trace files to the Fiddler platform. **Key Features:** * Automatic file discovery — no manual trigger required * Supports both base64 and hex-encoded `traceId`/`spanId` fields * IAM role-based authentication (cross-account supported) * Per-file retry logic with status tracking via API * Compatible with any OTLP JSON producer [**Get Started with S3 Trace Ingestion →**](/integrations/agentic-ai/s3-trace-ingestion) ### OpenTelemetry Integration Direct OTLP integration for custom agent frameworks and multi-framework environments. **Best for:** Multi-framework environments, custom agentic frameworks, advanced users requiring full instrumentation control **Key Features:** * Vendor-neutral telemetry using OpenTelemetry standards * Manual span creation for complete control over instrumentation * Multi-framework support for custom and emerging agent frameworks * Compatible with existing OpenTelemetry infrastructure * Attribute mapping to Fiddler semantic conventions **When to Use OpenTelemetry vs SDKs** Use OpenTelemetry integration for advanced use cases requiring manual control. For LangGraph and Strands applications, we recommend using the dedicated SDKs for easier setup and automatic instrumentation. [**Get Started with OpenTelemetry →**](/integrations/agentic-ai/opentelemetry-integration) ### Exporting OTel Traces to Fiddler Client-side export path for shipping pre-existing OpenTelemetry traces to Fiddler from your own storage or pipeline — map span attributes to Fiddler's schema and POST to the `v1/traces` endpoint. **Best for:** Replaying traces from a data warehouse, JSONL files, or a logging pipeline; custom export pipelines; batch backfill of historical trace data [**Exporting OTel Traces to Fiddler →**](/integrations/agentic-ai/otel-trace-export) ## Framework Support While Fiddler provides native SDKs for LangGraph and Strands, agentic applications can be monitored regardless of framework: ### Supported Frameworks & Tools **AI Agent Frameworks:** * **LangGraph** - Native SDK with auto-instrumentation ✓ * **LangChain V1** (`create_agent`) - Native SDK with auto-instrumentation ✓ * **Custom Python agents** - [Fiddler OTel SDK](/integrations/agentic-ai/fiddler-otel-sdk) with `@trace` decorator ✓ * **Other agentic frameworks** - [Fiddler OTel SDK](/integrations/agentic-ai/fiddler-otel-sdk) is the recommended path for any custom or unsupported framework **LLM Provider SDKs:** * **OpenAI SDK** - Track via Python Client or custom instrumentation * **Anthropic SDK** - Monitor Claude API calls via Python Client * **Strands Agents** - Native Strands Agents SDK ✓ * **LiteLLM SDK / Proxy** - [Zero-configuration OTel integration](/integrations/agentic-ai/litellm-integration) ✓ * **AgentGateway (LLM gateway only)** - [Zero-instrumentation proxy integration](/integrations/agentic-ai/agentgateway-integration) ✓ — MCP/A2A gateways not yet supported * **Claude Code** - [Zero-instrumentation coding agent integration](/integrations/agentic-ai/claude-code-integration) ✓ — beta OTel tracing, limited content capture **Gateways & Proxies:** * **Kong AI Gateway** (v3.13+) - [Zero-instrumentation gateway integration](/integrations/agentic-ai/kong-integration) ✓ **Observability Standards:** * **OpenTelemetry** - [Full OTLP support](/integrations/agentic-ai/opentelemetry-integration) for custom instrumentation * **Custom Tracing** - Python Client API for framework-agnostic monitoring ## Integration Selector Not sure which SDK to use? Here's a quick decision guide: | Your Use Case | Recommended Integration | Why | | ----------------------------------- | ----------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------ | | LangGraph agent application | [**LangGraph SDK**](/integrations/agentic-ai/langgraph-sdk) | Auto-instrumentation, zero config, hierarchical tracing | | LangChain V1 (`create_agent`) | [**LangChain SDK**](/integrations/agentic-ai/langchain-sdk) | One `instrument()` call, flat clean traces, full async | | Custom Python agent, no framework | [**Fiddler OTel SDK**](/integrations/agentic-ai/fiddler-otel-sdk) | `@trace` decorator, typed span wrappers, context isolation | | Strands Agents | **Strands Agents SDK** | Purpose-built for Strands framework | | LLM experiment workflows | **Evals SDK** | Pre-built evaluators, batch processing, tracking | | LiteLLM SDK (direct calls) | [**LiteLLM Integration**](/integrations/agentic-ai/litellm-integration) | One-line setup, no extra packages, native OTel support | | LiteLLM proxy / gateway | [**LiteLLM Integration**](/integrations/agentic-ai/litellm-integration) | Zero-code, auto-detects proxy traces, cost attribution | | AgentGateway (LLM proxy only) | [**AgentGateway Integration**](/integrations/agentic-ai/agentgateway-integration) | Zero code changes, proxy-layer LLM tracing, session grouping (MCP/A2A not supported) | | Kong AI Gateway (v3.13+) | [**Kong AI Gateway Integration**](/integrations/agentic-ai/kong-integration) | Zero code changes, gateway-layer OTel export, multi-provider | | Claude Code (coding agent) | [**Claude Code Integration**](/integrations/agentic-ai/claude-code-integration) | Zero code changes, session replay, prompt safety enrichment (beta, limited content) | | Multi-framework / raw OTel | [**OpenTelemetry Integration**](/integrations/agentic-ai/opentelemetry-integration) | Standards-based manual tracing, multi-framework environments | | ECS Fargate / air-gapped / S3 batch | [**S3 Trace Ingestion**](/integrations/agentic-ai/s3-trace-ingestion) | No direct connection needed, file-based async ingestion | | Pre-existing OTel traces to replay | [**Exporting OTel Traces**](/integrations/agentic-ai/otel-trace-export) | Client-side attribute mapping + batch export to `v1/traces` | | Traditional ML monitoring | **Python Client** | ML-specific features, drift detection, explainability | ## Getting Started ### Quick Start Paths 1. **Custom Python Agents (Fiddler OTel SDK)** ```bash theme={null} pip install fiddler-otel ``` ```python theme={null} from fiddler_otel import FiddlerClient, trace client = FiddlerClient(api_key="...", application_id="...", url="...") @trace(as_type="generation") def call_llm(prompt: str) -> str: ... ``` [Full Fiddler OTel SDK Guide →](/integrations/agentic-ai/fiddler-otel-sdk) 2. **LangChain V1 Applications** ```bash theme={null} pip install fiddler-langchain ``` ```python theme={null} from fiddler_otel import FiddlerClient from fiddler_langchain import FiddlerLangChainInstrumentor import langchain.agents client = FiddlerClient(api_key="...", application_id="...", url="...") FiddlerLangChainInstrumentor(client=client).instrument() # All create_agent() calls are now traced automatically ``` [Full LangChain SDK Guide →](/integrations/agentic-ai/langchain-sdk) 3. **LangGraph Applications** ```bash theme={null} pip install fiddler-langgraph ``` ```python theme={null} from fiddler_langgraph import FiddlerClient, LangGraphInstrumentor client = FiddlerClient(api_key="...", application_id="...", url="...") LangGraphInstrumentor(client).instrument() ``` [Full LangGraph Quick Start →](/integrations/agentic-ai/langgraph-sdk) 4. **Strands Agents** ```bash theme={null} pip install fiddler-strands # Configure for your Strands Agent ``` [Full Strands Agents SDK Quick Start →](/integrations/agentic-ai/strands-sdk) 5. **LLM Experiments** ```bash theme={null} pip install fiddler-evals # Run experiments on your dataset ``` [Full Evals Quick Start →](/integrations/agentic-ai/evals-sdk) 6. **LiteLLM SDK** ```bash theme={null} export OTEL_EXPORTER_OTLP_ENDPOINT="https://your-fiddler-instance.com" export OTEL_EXPORTER_OTLP_HEADERS="authorization=Bearer ,fiddler-application-id=" export OTEL_RESOURCE_ATTRIBUTES="application.id=" ``` ```python theme={null} import litellm litellm.callbacks = ["otel"] # Traces flow to Fiddler automatically ``` [Full LiteLLM SDK Quick Start →](/integrations/agentic-ai/litellm-integration#litellm-sdk-integration) 7. **LiteLLM Proxy** ```bash theme={null} export OTEL_EXPORTER_OTLP_ENDPOINT="https://your-fiddler-instance.com" export OTEL_EXPORTER_OTLP_HEADERS="authorization=Bearer ,fiddler-application-id=" export OTEL_RESOURCE_ATTRIBUTES="application.id=" litellm --config config.yaml # Traces flow to Fiddler automatically ``` [Full LiteLLM Proxy Quick Start →](/integrations/agentic-ai/litellm-integration#litellm-proxy-integration) 8. **AgentGateway (LLM proxy)** ```bash theme={null} brew install agentgateway/tap/agentgateway export OPENAI_API_KEY="sk-..." export FIDDLER_APP_ID="your-application-uuid" agentgateway -f agentgateway_config.yaml ``` ```python theme={null} import os import uuid from openai import OpenAI client = OpenAI(base_url=os.getenv("AGENTGATEWAY_URL", "http://localhost:4000/v1")) response = client.chat.completions.create( model="gpt-4o-mini", messages=[{"role": "user", "content": "Hello"}], extra_headers={"X-Fiddler-Conversation-Id": str(uuid.uuid4())}, ) ``` [Full AgentGateway Integration Guide →](/integrations/agentic-ai/agentgateway-integration) 9. **Raw OpenTelemetry (Advanced)** ```bash theme={null} pip install opentelemetry-api opentelemetry-sdk opentelemetry-exporter-otlp-proto-http # Configure OTLP endpoint and instrument your agent ``` [Full OpenTelemetry Quick Start →](/developers/quick-starts/opentelemetry-quick-start) ## What's Next? * [**Span and Resource Attributes**](/integrations/agentic-ai/attributes) - Understand required fields, value typing, custom attributes, and how they flow into metrics and alerts * [**Agentic Observability Concepts**](/glossary/agentic-observability) - Understand the agent lifecycle and monitoring approach * [**Agentic Observability Quick Start**](/getting-started/agentic-monitoring) - Complete setup guide * [**Centor Models Overview**](/glossary/centor-models) - Learn about the evaluation platform powering Fiddler # AgentGateway Integration Source: https://docs.fiddler.ai/integrations/agentic-ai/agentgateway-integration Integrate AgentGateway with Fiddler for zero-instrumentation LLM observability — no application code changes required. ## Overview [AgentGateway](https://agentgateway.dev/) (v1.1.0+, Apache 2.0) is an open-source Rust proxy that sits between your application and its LLM provider. Fiddler integrates with AgentGateway at the proxy layer, giving you full LLM observability — prompts, responses, token usage, latency — without adding any SDK to your application code. | Capability | Notes | | ------------------------ | -------------------------------------------------------------------------------------------------------- | | **Zero instrumentation** | Point your app at AgentGateway instead of `api.openai.com` — no code changes needed | | **LLM span tracing** | Token counts, model name, latency, and content (with CEL config) | | **Session grouping** | All LLM calls sharing an `X-Fiddler-Conversation-Id` header are grouped into one Fiddler Session | | **Direct OTLP export** | AgentGateway exports traces to Fiddler over HTTPS with auth headers injected via `requestHeaderModifier` | *** ## Architecture ```mermaid theme={null} flowchart TD A["Your app
(any language, standard OpenAI client)"] -->|points base_url at AgentGateway| B["AgentGateway
(Rust proxy, port 4000)"] B -->|proxies to OpenAI / Anthropic / Bedrock / …| C["LLM Provider"] B -->|OTLP/HTTPS with auth headers| D["Fiddler
(enrichment, monitoring, dashboards)"] ``` AgentGateway exposes an OpenAI-compatible API (`/v1/chat/completions`). Your application requires no SDK — it just calls the proxy instead of the provider directly. *** ## Prerequisites * Fiddler account with a GenAI application already created * [AgentGateway](https://agentgateway.dev/) **v1.1.0 or later** * A valid LLM provider API key (e.g. `OPENAI_API_KEY`) * Your Fiddler API key (found under organizational settings) and application UUID (found under application settings) *** ## Quick Start ### Step 1 — Install AgentGateway ```bash theme={null} # macOS / Linux (Homebrew) brew install agentgateway/tap/agentgateway # Or download from https://github.com/agentgateway/agentgateway/releases agentgateway --version # must be 1.1.0+ ``` ### Step 2 — Configure AgentGateway Create `agentgateway_config.yaml`: ```yaml theme={null} # yaml-language-server: $schema=https://agentgateway.dev/schema/config frontendPolicies: tracing: # Fiddler instance host and port (e.g., your-instance.fiddler.ai:443). # $FIDDLER_HOST is expanded from the environment. host: "$FIDDLER_HOST" protocol: http randomSampling: true policies: # Inject auth headers on every OTLP export request to Fiddler. # $FIDDLER_API_KEY and $FIDDLER_APP_ID are expanded from the environment. requestHeaderModifier: add: Authorization: "Bearer $FIDDLER_API_KEY" fiddler-application-id: "$FIDDLER_APP_ID" # Enable TLS for the HTTPS connection to Fiddler. backendTLS: {} resources: service.name: '"agentgateway"' application.id: '"$FIDDLER_APP_ID"' attributes: gen_ai.llm.input.user: | llm.prompt.filter(m, m.role == "user").map(m, m.content).join("\n") gen_ai.llm.input.system: | llm.prompt.filter(m, m.role == "system").map(m, m.content).join("\n") gen_ai.llm.output: | llm.completion.join("\n") gen_ai.input.messages: toJson(llm.prompt) gen_ai.output.messages: toJson(llm.completion) gen_ai.system: llm.provider gen_ai.usage.total_tokens: llm.totalTokens span.name: | "chat " + llm.requestModel fiddler.span.type: '"llm"' gen_ai.tool.definitions: 'toJson(json(request.body).tools)' gen_ai.conversation.id: | request.headers["x-fiddler-conversation-id"] != "" ? request.headers["x-fiddler-conversation-id"] : "" binds: - port: 4000 listeners: - routes: - backends: - ai: name: openai provider: openAI: model: gpt-4o-mini policies: backendAuth: passthrough: {} ``` The `frontendPolicies.tracing` block captures prompt and response content via CEL expressions and exports spans directly to Fiddler over HTTPS. `$FIDDLER_API_KEY` and `$FIDDLER_APP_ID` are expanded from environment variables at runtime — no credentials are hardcoded in the config file. ### Step 3 — Start AgentGateway ```bash theme={null} export OPENAI_API_KEY="sk-..." export FIDDLER_API_KEY="your-fiddler-api-key" export FIDDLER_APP_ID="your-application-uuid" export FIDDLER_HOST="your-instance.fiddler.ai:443" agentgateway -f agentgateway_config.yaml ``` ### Step 4 — Point your application at AgentGateway ```python theme={null} import os import uuid from openai import OpenAI # OPENAI_API_KEY is read from the environment automatically. # AgentGateway's backendAuth passthrough forwards it unchanged to OpenAI, # so the key must be set in both the AgentGateway environment and here. client = OpenAI(base_url=os.getenv("AGENTGATEWAY_URL", "http://localhost:4000/v1")) # Generate one conversation UUID per session and send it on every LLM call # so Fiddler groups them into a single Session. session_id = str(uuid.uuid4()) response = client.chat.completions.create( model="gpt-4o-mini", messages=[{"role": "user", "content": "What is the capital of France?"}], extra_headers={"X-Fiddler-Conversation-Id": session_id}, ) print(response.choices[0].message.content) ``` Traces appear in Fiddler automatically — no SDK import, no callback registration, no changes to your application logic. To override the default proxy URL, set `AGENTGATEWAY_URL` (defaults to `http://localhost:4000/v1`): ```bash theme={null} export AGENTGATEWAY_URL="http://my-gateway-host:4000/v1" ``` ### Step 5 — Verify traces are arriving Open the Fiddler UI and navigate to your application's **Explorer**. You should see the trace within a few seconds of making your first completion call. *** ## Span Type Mapping Fiddler classifies AgentGateway spans based on `gen_ai.operation.name`, which AgentGateway sets automatically on every LLM proxy call: | `gen_ai.operation.name` | Fiddler span type | | ----------------------- | ----------------- | | `chat` | `llm` | | `completion` | `llm` | | anything else | *(skipped)* | Fiddler's AgentGateway mapper checks this attribute and sets `fiddler.span.type = "llm"` internally — no CEL config is required for classification. The `fiddler.span.type: '"llm"'` line in the CEL config above is a safety net for Fiddler deployments that process spans without the dedicated mapper. *** ## Attribute Mapping AgentGateway uses slightly different attribute names from the OpenTelemetry GenAI semantic conventions. Fiddler's mapper normalises these automatically: | AgentGateway attribute | Fiddler treatment | | ------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | | `gen_ai.provider.name` | Copied to `gen_ai.system` when absent (CEL sets it directly) | | `gen_ai.usage.input_tokens` | Mapped to `fiddler.span.system.gen_ai.usage.input_tokens` | | `gen_ai.usage.output_tokens` | Mapped to `fiddler.span.system.gen_ai.usage.output_tokens` | | `gen_ai.usage.total_tokens` | Computed as `input + output` when absent | | `gen_ai.agent.name` | Defaulted to `` when absent | | `gen_ai.conversation.id` | Defaulted to `trace_id.hex()` when absent — set by CEL from the `X-Fiddler-Conversation-Id` header to enable Session grouping | | `gateway`, `listener`, `route`, `endpoint`, `http.method`, `http.path`, `http.status`, `duration`, `src.addr` | Passed through unchanged — AgentGateway routing metadata | Content attributes (`gen_ai.llm.input.user`, `gen_ai.llm.input.system`, `gen_ai.llm.output`) are set by the CEL config in AgentGateway — no JSON parsing is required by the mapper. *** ## Session Grouping Fiddler groups all LLM calls that share the same `gen_ai.conversation.id` into a single Session. The recommended pattern is to generate one UUID per logical conversation in your application and pass it on every LLM call as the `X-Fiddler-Conversation-Id` HTTP header. The CEL expression in the AgentGateway config (see Step 2) extracts the header and stamps it as the span attribute. The header transport is preferred over OpenAI's `metadata` request body field because: * OpenAI's `metadata` parameter requires `store=true`, which persists conversation data on OpenAI's side — a privacy concern for many customers. * AgentGateway is a passthrough proxy: anything in the request body must be a valid OpenAI parameter or the request fails. * Headers are visible to AgentGateway and silently stripped by OpenAI. *** ## Troubleshooting **Traces not appearing in Fiddler** Verify all three environment variables are set before starting AgentGateway: ```bash theme={null} echo $FIDDLER_API_KEY echo $FIDDLER_APP_ID echo $FIDDLER_HOST echo $OPENAI_API_KEY ``` Both `application.id` (OTel resource attribute) and `fiddler-application-id` (HTTP header on the export request) are required. If either is missing or does not match a valid Fiddler application UUID, spans are silently dropped. **Prompt and response content not showing** The `frontendPolicies.tracing.attributes` CEL block is required. Verify it is present in `agentgateway_config.yaml` and that AgentGateway is v1.1.0+: ```bash theme={null} agentgateway --version ``` **Span type showing as Unknown** Fiddler classifies spans using `gen_ai.operation.name` (set automatically by AgentGateway). Verify that AgentGateway is v1.1.0+ and that the `frontendPolicies.tracing.attributes` block is present in your config. As a fallback, ensure `fiddler.span.type: '"llm"'` is included in the `attributes` block — this covers Fiddler deployments that process spans without the dedicated AgentGateway mapper. **Not all LLM calls are producing traces** `randomSampling: true` is active. Set it to `false` to capture every span: ```yaml theme={null} frontendPolicies: tracing: randomSampling: false ``` *** ## Known Limitations | Limitation | Details | | ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Content requires CEL config** | Prompt and response text are only captured when `frontendPolicies.tracing.attributes` is configured in AgentGateway | | **LLM-only scope** | This integration captures LLM proxy traffic only. MCP tool calls and A2A agent-to-agent calls proxied by AgentGateway are not currently forwarded to Fiddler. | | **Sampling** | `randomSampling: true` means not every LLM call produces a trace; set to `false` for complete capture | *** ## Related Documentation * [OpenTelemetry Integration](/integrations/agentic-ai/opentelemetry-integration) — Manual OTel instrumentation for custom frameworks * [LiteLLM Integration](/integrations/agentic-ai/litellm-integration) — Fiddler observability via the LiteLLM proxy gateway * [LangGraph SDK](/integrations/agentic-ai/langgraph-sdk) — Auto-instrumentation for LangGraph agent applications * [OTel Trace Export](/integrations/agentic-ai/otel-trace-export) — Direct OTLP export to Fiddler without a proxy * [AgentGateway documentation](https://agentgateway.dev/) — Official AgentGateway docs and configuration reference # Span and Resource Attributes Source: https://docs.fiddler.ai/integrations/agentic-ai/attributes Understand how Fiddler uses span and resource attributes from OpenTelemetry traces — required vs optional fields, typing, custom attributes, and how attributes flow into metrics, alerts, and dashboards. ## Overview Use this page as a reference for which attributes Fiddler indexes, how to type their values, and how they map to FQL `attribute()` and `Span::` filters. Attributes are key-value pairs attached to OpenTelemetry spans and resources. They carry the data that powers Fiddler's dashboards, alerts, evaluators, and custom metrics. Getting attributes right means: * **Attributes** are present in OpenTelemetry spans. * **Values use the correct type** so numeric attributes are aggregatable and alertable (not silently treated as strings). * **Custom attributes** follow the naming convention so they appear in the Explorer and are queryable via FQL. This page is the single reference for how attributes work across all Fiddler integrations. *** ## Attribute Levels Attributes are set at two levels in the OTLP hierarchy: | Level | Scope | Set on | Example | | ------------ | ------------------------------------ | --------------------- | ------------------------------------------- | | **Resource** | Entire trace (all spans share these) | `Resource.attributes` | `application.id` | | **Span** | Individual operation | `Span.attributes` | `fiddler.span.type`, `gen_ai.request.model` | *** ## Required Attributes These must be present on every trace sent to Fiddler. Fiddler rejects traces that omit either field. | Attribute | Level | Description | | ------------------- | -------- | ----------------------------------------------------- | | `application.id` | Resource | Your Fiddler application UUID (UUID4 format) | | `fiddler.span.type` | Span | Type of operation: `llm`, `tool`, `chain`, or `agent` | *** ## System Attributes System attributes are stored under the `fiddler.span.system.*` prefix internally. They are registered in the attribute catalog and available for FQL custom metrics via `attribute('...', type='system', scope='span')`. Some are also available as dedicated span columns for fast filtering (via `Span::` redirects); the rest are filtered via `SpanAttribute::`. | Attribute | Type | Explorer filter | Description | | ---------------------------- | ------ | ----------------------------------------------------------------------------------- | ---------------------------------------------------------- | | `gen_ai.agent.name` | string | Agent (`Span::agent_name`) | Name of the AI agent | | `fiddler.span.type` | string | Type (`Span::span_type`) | Type of operation: `llm`, `tool`, `chain`, or `agent` | | `gen_ai.tool.name` | string | gen\_ai.tool.name (system) (`SpanAttribute::gen_ai.tool.name`) | Tool or function name | | `gen_ai.usage.input_tokens` | int | gen\_ai.usage.input\_tokens (system) (`SpanAttribute::gen_ai.usage.input_tokens`) | Input tokens consumed | | `gen_ai.usage.output_tokens` | int | gen\_ai.usage.output\_tokens (system) (`SpanAttribute::gen_ai.usage.output_tokens`) | Output tokens consumed | | `gen_ai.usage.total_tokens` | int | gen\_ai.usage.total\_tokens (system) (`SpanAttribute::gen_ai.usage.total_tokens`) | Total tokens consumed | | `latency` | int | Duration (`Span::duration`) | Span duration (computed automatically from start/end time) | *** ## Identity Attributes Identity attributes are stored as metadata internally and materialized into dedicated span columns. They appear as **Session ID** and **Agent ID** columns in the Explorer. They are **not** registered in the attribute catalog and cannot be used in FQL custom metrics. | Attribute | Type | Explorer filter | Description | | ------------------------ | ------ | ------------------------------- | ------------------------------------------- | | `gen_ai.conversation.id` | string | Session ID (`Span::session_id`) | Groups spans into a multi-turn conversation | | `gen_ai.agent.id` | string | Agent ID (`Span::agent_id`) | Unique identifier for the agent | **Set agent attributes on every span.** If you provide `gen_ai.agent.name` or `gen_ai.agent.id`, set them on **every span within the trace**. Fiddler uses these to attribute spans to the correct agent — spans missing these fields will be unattributed even if other spans in the same trace carry them. *** ## Content Attributes These attributes are visible in the Explorer but are **not** registered as queryable attributes — they cannot be used in FQL custom metrics or span filters. ### LLM Content | Attribute | Type | Description | | ------------------------- | ------ | -------------------------------------------- | | `gen_ai.request.model` | string | Model name (e.g., `gpt-4o`, `claude-3-opus`) | | `gen_ai.system` | string | LLM provider (e.g., `openai`, `anthropic`) | | `gen_ai.llm.input.system` | string | System prompt | | `gen_ai.llm.input.user` | string | User input (last user message) | | `gen_ai.llm.output` | string | LLM response text | | `gen_ai.llm.context` | string | Conversation history (prior messages) | ### Tool Content | Attribute | Type | Description | | -------------------- | ------------- | ---------------------------- | | `gen_ai.tool.input` | string (JSON) | Arguments passed to the tool | | `gen_ai.tool.output` | string (JSON) | Result returned by the tool | *** ## Custom User Attributes Attach business-level metadata to spans using two namespaces: | Namespace | Scope | Description | | ---------------------------- | ---------------------- | --------------------------------------------- | | `fiddler.span.user.{key}` | Individual span | Metadata for a specific operation | | `fiddler.session.user.{key}` | All spans in the trace | Session-wide context shared across every span | `fiddler.span.user.*` attributes are indexed, appear as filterable columns in the Explorer, and are available for [custom metrics](/observability/agentic/custom-metrics) via the FQL `attribute()` function. `fiddler.session.user.*` attributes are visible in the trace detail side panel only — they do not appear as columns in the Explorer grid and are not available for custom metrics or filtering. *** ## Attribute Value Types Under the hood, every attribute value is wrapped in an OTel `AnyValue` protobuf message. **Using the correct typed field is critical** — it determines whether Fiddler classifies the attribute as numeric (enabling aggregation, charting, and alerting) or string. | Python type | `AnyValue` field | Fiddler storage type | | ----------- | ---------------- | ------------------------- | | `str` | `string_value` | String | | `int` | `int_value` | Numeric (stored as float) | | `float` | `double_value` | Numeric (stored as float) | | `bool` | `bool_value` | String | **Use `int_value` / `double_value` for numeric attributes.** If you wrap a number in `string_value` (e.g., `AnyValue(string_value="150")`), Fiddler treats it as a string column. You lose the ability to compute aggregations (sum, average, percentiles) and set numeric alerts on that attribute. ### SDK usage (high-level) When using the Fiddler OTel SDK, LangGraph SDK, or Strands SDK, pass native Python types and the SDK handles typing automatically: ```python theme={null} span.set_attribute("gen_ai.usage.input_tokens", 150) # int → int_value span.set_attribute("fiddler.span.user.confidence", 0.97) # float → double_value span.set_attribute("fiddler.span.user.region", "us-west") # str → string_value span.set_attribute("fiddler.span.user.is_internal", False) # bool → bool_value ``` ### Protobuf usage (low-level) When building protobuf `Span` objects directly (e.g., for [OTel trace export](/integrations/agentic-ai/otel-trace-export)), you must set the correct `AnyValue` field explicitly: ```python theme={null} from opentelemetry.proto.common.v1.common_pb2 import AnyValue, KeyValue # Numeric — use int_value / double_value KeyValue(key="gen_ai.usage.input_tokens", value=AnyValue(int_value=150)) KeyValue(key="fiddler.span.user.confidence", value=AnyValue(double_value=0.97)) # String KeyValue(key="fiddler.span.user.region", value=AnyValue(string_value="us-west")) # Boolean KeyValue(key="fiddler.span.user.is_internal", value=AnyValue(bool_value=False)) ``` For a copy-pastable `to_any_value()` helper that handles type dispatch automatically, see the [OTel Trace Export — AnyValue Typing](/integrations/agentic-ai/otel-trace-export#anyvalue-typing) section. *** ## How Attributes Flow into Fiddler Once ingested, attributes power several Fiddler features: | Feature | How attributes are used | | ----------------------- | ---------------------------------------------------------------------------------------------- | | **Explorer** | Filter, search, and group traces by any attribute | | **Dashboards & Charts** | Built-in charts use system attributes (tokens, latency); custom charts reference any attribute | | **Custom Metrics** | FQL expressions use `attribute('name', type, scope)` to define computed metrics | | **Alerts** | Set threshold or anomaly alerts on numeric attributes (requires correct typing) | | **Evaluators** | Enrichment evaluators can read span attributes as input context | ### Querying attributes with FQL The `attribute()` function is the FQL primitive for referencing span data in custom metrics. Only `system` and `user` attributes are queryable — see [Attribute Quick Overview](#attribute-quick-overview) for the full classification. ``` attribute(name='name', type='system'|'user', scope='span'[, value='...']) ``` | Parameter | Required | Description | | --------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `name` | Yes | Attribute key. For `type='system'`, use the OTel key (e.g., `gen_ai.usage.input_tokens`). For `type='user'`, use the bare key without the `fiddler.span.user.` prefix (e.g., `confidence`, not `fiddler.span.user.confidence`). | | `type` | Yes | `'system'` for system attributes (see [System Attributes](#system-attributes)), `'user'` for custom `fiddler.span.user.*` attributes | | `scope` | Yes | Currently only `'span'` is supported | | `value` | No | Filters to spans where the attribute equals this string value. When set, the attribute is treated as a string. Used with `count()` for categorical breakdowns (e.g., `count(attribute('fiddler.span.type', type='system', scope='span', value='llm'))`). | **System attribute examples:** ``` -- Average input tokens per span average(attribute('gen_ai.usage.input_tokens', type='system', scope='span')) -- Count spans by agent name count(attribute('gen_ai.agent.name', type='system', scope='span', value='my-agent')) -- Ratio of LLM spans count(attribute('fiddler.span.type', type='system', scope='span', value='llm')) / count(attribute('fiddler.span.type', type='system', scope='span')) ``` **User attribute examples:** ``` -- P95 of a custom latency attribute quantile(attribute('response_time_ms', type='user', scope='span'), level=0.95) -- Ratio of premium-tier spans count(attribute('tier', type='user', scope='span', value='premium')) / count(attribute('tier', type='user', scope='span')) ``` See [Custom Metrics](/observability/agentic/custom-metrics) for the full FQL reference and more examples. *** ## Attribute Quick Overview All attributes listed below are visible in the Explorer. The **Custom metrics** and **Explorer filter** columns indicate additional availability for FQL and UI filtering respectively. The Explorer filter column shows both the UI column name (what you see in the DataGrid header) and the API filter field (used in programmatic `filter.rules[].field` requests). The UI automatically maps column filters to the API syntax. | Attribute | Level | Required | Custom metrics | Explorer filter | Type | `AnyValue` field | | ---------------------------- | -------- | -------- | -------------- | ----------------------------------------------------------------------------------- | ------------------------------------- | ---------------------------------------------------------------------------------------- | | `application.id` | Resource | Yes | — | — | UUID string | `string_value` | | `gen_ai.agent.name` | Span | No | `system` | Agent (`Span::agent_name`) | string | `string_value` | | `fiddler.span.type` | Span | Yes | `system` | Type (`Span::span_type`) | `llm` \| `tool` \| `chain` \| `agent` | `string_value` | | `gen_ai.agent.id` | Span | No | — | Agent ID (`Span::agent_id`) | string | `string_value` | | `gen_ai.conversation.id` | Span | No | — | Session ID (`Span::session_id`) | string | `string_value` | | `gen_ai.tool.name` | Span | No | `system` | gen\_ai.tool.name (system) (`SpanAttribute::gen_ai.tool.name`) | string | `string_value` | | `gen_ai.usage.input_tokens` | Span | No | `system` | gen\_ai.usage.input\_tokens (system) (`SpanAttribute::gen_ai.usage.input_tokens`) | int | `int_value` | | `gen_ai.usage.output_tokens` | Span | No | `system` | gen\_ai.usage.output\_tokens (system) (`SpanAttribute::gen_ai.usage.output_tokens`) | int | `int_value` | | `gen_ai.usage.total_tokens` | Span | No | `system` | gen\_ai.usage.total\_tokens (system) (`SpanAttribute::gen_ai.usage.total_tokens`) | int | `int_value` | | `latency` | Span | No | `system` | Duration (`Span::duration`) | int | — (computed) | | `gen_ai.request.model` | Span | No | — | — | string | `string_value` | | `gen_ai.system` | Span | No | — | — | string (provider name) | `string_value` | | `gen_ai.llm.input.system` | Span | No | — | — | string | `string_value` | | `gen_ai.llm.input.user` | Span | No | — | — | string | `string_value` | | `gen_ai.llm.output` | Span | No | — | — | string | `string_value` | | `gen_ai.llm.context` | Span | No | — | — | string | `string_value` | | `gen_ai.tool.input` | Span | No | — | — | string (JSON) | `string_value` | | `gen_ai.tool.output` | Span | No | — | — | string (JSON) | `string_value` | | `fiddler.span.user.*` | Span | No | `user` | \ (user) (`SpanAttribute::`) | any | Use typed field matching the value (see [Attribute Value Types](#attribute-value-types)) | **Only `system` and `user` attributes support custom metrics.** Content fields (like `gen_ai.llm.output`, `gen_ai.request.model`) are visible in the Explorer but cannot be used in FQL `attribute()` expressions or aggregations. Identity fields (`gen_ai.agent.id`, `gen_ai.conversation.id`) are filter-only. If you need to compute metrics over a non-queryable field, attach it as a `fiddler.span.user.*` custom attribute instead. *** ## Upcoming Changes The `fiddler.span.system.*`, `fiddler.span.user.*`, and `fiddler.contents.*` prefix conventions described on this page are being phased out. In the new approach, Fiddler stores attribute keys exactly as sent by your application — no prefix transformation or renaming is required. Instead of relying on prefix conventions, Fiddler uses **semantic mappings** to resolve raw attribute keys to canonical concepts (like `input_tokens`, `model_name`, `input`) in the backend. This enables cross-framework analytics without requiring any specific key naming conventions from your instrumentation. Fiddler ships with 140+ pre-configured mappings covering 13+ frameworks, and you can add custom mappings for unsupported frameworks or proprietary attribute names. Existing data stored with `fiddler.*` prefixes will continue to work — the default mappings include entries for all legacy prefixed keys, so both old and new data resolve to the same semantic concepts. For more details, see [Semantic Mappings](/concepts/semantic-mappings). *** ## Related Documentation * [Semantic Mappings](/concepts/semantic-mappings) — how Fiddler maps raw attribute keys to canonical concepts across frameworks * [OTel Trace Export](/integrations/agentic-ai/otel-trace-export) — protobuf serialization and attribute mapping for client-side export * [OpenTelemetry Integration](/integrations/agentic-ai/opentelemetry-integration) — live agent instrumentation via the OTel SDK * [Custom Metrics](/observability/agentic/custom-metrics) — define FQL metrics over span attributes * [Fiddler OTel SDK](/integrations/agentic-ai/fiddler-otel-sdk) — `@trace` decorator and `set_attribute()` usage * [Agentic AI Overview](/integrations/agentic-ai-and-llm-frameworks/agentic-ai) — compare all integration options # Claude Code Integration Source: https://docs.fiddler.ai/integrations/agentic-ai/claude-code-integration Integrate Claude Code with Fiddler for coding agent observability — track LLM calls, tool usage, user prompts, and session behavior via OpenTelemetry traces. ## Overview [Claude Code](https://docs.anthropic.com/en/docs/claude-code/overview) is Anthropic's CLI coding agent. It emits OpenTelemetry traces that Fiddler natively ingests and maps to the Fiddler schema, giving you observability over coding agent sessions — including user prompts, LLM calls, tool invocations, token usage, and permission decisions. No Fiddler SDK is required. Claude Code's built-in OTel instrumentation sends traces directly to Fiddler's OTLP ingestion endpoint. **Beta telemetry.** Claude Code's OpenTelemetry tracing requires the `CLAUDE_CODE_ENHANCED_TELEMETRY_BETA` flag and is subject to change between versions. Several content attributes (LLM responses, tool input/output) are **not available** in trace spans. See [Known Limitations](#known-claude-code-upstream-limitations) for full details. | Capability | Support | | ---------------------------- | ------------------------------------------- | | User prompt capture | ✅ Requires `OTEL_LOG_USER_PROMPTS=1` | | LLM response capture | ❌ Not available in traces | | Tool name tracking | ✅ Always available | | Tool input/output | ❌ Not emitted in trace spans | | Token counts | ✅ Input, output, cache read, cache creation | | Session correlation | ✅ Via `session.id` | | Permission decision tracking | ✅ Accept/deny on tool invocations | | Cost tracking | ❌ Not emitted by Claude Code | | Enrichment (Prompt Safety) | ✅ Via Fiddler evaluator rules | *** ## Prerequisites * **Claude Code** v2.1.138 or later * A **Fiddler application** with a valid `application.id` *** ## Quick Start ### Step 1 — Enable Claude Code telemetry Set the following environment variables before launching Claude Code: ```bash theme={null} # Required — enable OTel tracing (beta) export CLAUDE_CODE_ENABLE_TELEMETRY=1 export CLAUDE_CODE_ENHANCED_TELEMETRY_BETA=1 export OTEL_TRACES_EXPORTER=otlp # Required — point at Fiddler's OTLP ingestion endpoint export OTEL_EXPORTER_OTLP_ENDPOINT="https://" export OTEL_EXPORTER_OTLP_HEADERS="fiddler-application-id=,Authorization=Bearer " export OTEL_EXPORTER_OTLP_PROTOCOL="http/protobuf" # Required — tag traces with your Fiddler application export OTEL_RESOURCE_ATTRIBUTES="application.id=" # Recommended — enable content capture export OTEL_LOG_USER_PROMPTS=1 export OTEL_LOG_TOOL_DETAILS=1 export OTEL_LOG_TOOL_CONTENT=1 ``` ### Step 2 — Launch Claude Code ```bash theme={null} claude ``` Use Claude Code normally. Every interaction generates OTel traces that flow to Fiddler. ### Step 3 — Verify traces in Fiddler Navigate to your application in the Fiddler UI. You should see traces appearing within 30 seconds, with: * **Agent spans** for each user interaction (prompt → reasoning → tool calls → response) * **LLM spans** for each model call (Sonnet, Haiku) with token counts and latency * **Tool spans** for each tool invocation (Bash, Read, Write, MCP tools, WebSearch) *** ## Managed Deployment via Settings File For enterprise or managed deployments, you can configure telemetry via Claude Code's settings file instead of environment variables. This ensures consistent telemetry across all developers without requiring them to set env vars manually. Create or update `.claude/settings.json` (project-level) or `~/.claude/settings.json` (user-level): ```json theme={null} { "env": { "CLAUDE_CODE_ENABLE_TELEMETRY": "1", "CLAUDE_CODE_ENHANCED_TELEMETRY_BETA": "1", "OTEL_TRACES_EXPORTER": "otlp", "OTEL_EXPORTER_OTLP_ENDPOINT": "https://", "OTEL_EXPORTER_OTLP_HEADERS": "fiddler-application-id=,Authorization=Bearer ", "OTEL_EXPORTER_OTLP_PROTOCOL": "http/protobuf", "OTEL_RESOURCE_ATTRIBUTES": "application.id=", "OTEL_LOG_USER_PROMPTS": "1", "OTEL_LOG_TOOL_DETAILS": "1", "OTEL_LOG_TOOL_CONTENT": "1" } } ``` **Do not commit API keys to version control.** The `OTEL_EXPORTER_OTLP_HEADERS` value contains your Fiddler API key. If using project-level `.claude/settings.json`, add it to `.gitignore` to prevent accidental exposure. For CI/CD or shared environments, prefer setting credentials via environment variables instead of the settings file. Settings in `.claude/settings.json` (project-level) take precedence over environment variables. Settings in the user-level `~/.claude/settings.json` apply to all projects unless overridden. *** ## What Gets Captured ### Span Hierarchy Each user interaction produces a trace with the following span structure: ``` claude_code.interaction (agent — root span, one per user prompt) ├── claude_code.llm_request (llm — LLM API call, e.g., Sonnet or Haiku) ├── claude_code.llm_request (llm — parallel model call, e.g., Haiku for routing) ├── claude_code.tool (tool — tool invocation wrapper) │ ├── claude_code.tool.blocked_on_user (chain — permission prompt wait) │ └── claude_code.tool.execution (chain — actual tool execution) ├── claude_code.tool (tool — second tool invocation) │ └── claude_code.tool.execution (chain) └── claude_code.llm_request (llm — follow-up LLM call with tool results) ``` ### Span Type Mapping | Claude Code Span | Fiddler Span Type | Description | | ---------------------------------- | ----------------- | --------------------------------------------------------------------------------------------------------- | | `claude_code.interaction` | `agent` | Root span for a user interaction. Contains the user prompt and interaction-level metadata. | | `claude_code.llm_request` | `llm` | Individual LLM API call. Contains model name, token counts, latency, and success/error status. | | `claude_code.tool` | `tool` | Tool invocation wrapper. Contains the tool name and total duration (including permission wait). | | `claude_code.tool.blocked_on_user` | `chain` | Time spent waiting for the user to accept or deny a tool permission prompt. Contains the user's decision. | | `claude_code.tool.execution` | `chain` | Actual tool execution after permission is granted. Contains success status and execution duration. | ### Captured Attributes by Span Type #### Agent Spans (`claude_code.interaction`) | Attribute | Fiddler Mapping | Requires Env Var | Description | | ------------------------- | ------------------------------------------- | ------------------------- | ------------------------------------------------------------------------------------- | | `user_prompt` | `fiddler.contents.gen_ai.llm.input.user` | `OTEL_LOG_USER_PROMPTS=1` | The user's prompt text. Shows `` when env var is not set. | | `user_prompt_length` | `fiddler.span.user.user_prompt_length` | No | Character count of the user prompt (always available, even when content is redacted). | | `interaction.sequence` | `fiddler.span.user.interaction.sequence` | No | Sequence number within the session (1 for first interaction, 2 for second, etc.). | | `interaction.duration_ms` | `fiddler.span.user.interaction.duration_ms` | No | Total duration of the interaction in milliseconds. | | `session.id` | `fiddler.metadata.gen_ai.conversation.id` | No | Claude Code session UUID. Used for session correlation. | #### LLM Spans (`claude_code.llm_request`) | Attribute | Fiddler Mapping | Description | | ----------------------- | ------------------------------------------------ | -------------------------------------------------------------------------- | | `input_tokens` | `fiddler.span.system.gen_ai.usage.input_tokens` | Number of input tokens (excluding cache). | | `output_tokens` | `fiddler.span.system.gen_ai.usage.output_tokens` | Number of output tokens. | | `cache_read_tokens` | `fiddler.span.user.cache_read_tokens` | Tokens read from Anthropic's prompt cache. | | `cache_creation_tokens` | `fiddler.span.user.cache_creation_tokens` | Tokens written to Anthropic's prompt cache. | | `model` | Passthrough | Model identifier (e.g., `claude-sonnet-4-5@20250929`). | | `gen_ai.request.model` | Passthrough | Same as `model`, following OTel GenAI semantic conventions. | | `gen_ai.system` | Passthrough | LLM provider (always `anthropic` for Claude Code). | | `ttft_ms` | `fiddler.span.user.ttft_ms` | Time to first token in milliseconds. | | `stop_reason` | `fiddler.span.user.stop_reason` | Why the LLM stopped: `end_turn`, `tool_use`, `max_tokens`. | | `success` | `fiddler.span.user.success` | Whether the LLM call succeeded (`true`/`false`). | | `error` | `fiddler.span.user.error` | Error message when `success` is `false`. | | `attempt` | `fiddler.span.user.attempt` | Retry attempt number (1 for first try). | | `llm_request.context` | `fiddler.span.user.llm_request.context` | Call context: `interaction` (top-level) or `tool` (nested in a tool span). | **LLM response content is not available in traces.** Claude Code emits LLM output via OTel log records, not trace span attributes. This mapper processes trace spans only. See [Known Limitations](#known-claude-code-upstream-limitations). #### Tool Spans (`claude_code.tool`) | Attribute | Fiddler Mapping | Description | | ------------- | -------------------------------------- | ------------------------------------------------------------------------------------------ | | `tool_name` | `fiddler.span.system.gen_ai.tool.name` | Tool identifier (e.g., `Bash`, `Read`, `Write`, `Edit`, `WebSearch`, `mcp__server__tool`). | | `duration_ms` | `fiddler.span.user.duration_ms` | Total tool duration including permission wait. | **Tool input/output content is not available in traces.** Despite the `OTEL_LOG_TOOL_CONTENT=1` env var, Claude Code does not currently emit `tool.output` span events on tool spans. See [Known Limitations](#known-claude-code-upstream-limitations). #### Permission Decision Spans (`claude_code.tool.blocked_on_user`) | Attribute | Fiddler Mapping | Description | | ------------- | ------------------------------- | -------------------------------------------------------------------------- | | `decision` | `fiddler.span.user.decision` | User's permission decision: `accept` or `deny`. | | `source` | `fiddler.span.user.source` | How the decision was made: `user_temporary`, `user_permanent`, `settings`. | | `duration_ms` | `fiddler.span.user.duration_ms` | Time spent waiting for the user to respond. | *** ## Session Grouping Claude Code assigns a `session.id` to each coding session. Fiddler maps this to `gen_ai.conversation.id`, enabling session-level grouping in the UI. All spans within a session share the same `session.id`, allowing you to: * View the full timeline of a coding session * Correlate LLM calls with tool invocations * Track interaction sequences within a session When `session.id` is absent (rare), Fiddler falls back to using the OTel `trace_id` as the conversation ID. *** ## Enrichment Setup Fiddler can automatically score Claude Code user prompts using Prompt Safety (powered by the Centor Model for Safety) or other evaluators. To configure: 1. Navigate to your application in the Fiddler UI. 2. Create an evaluator rule with: * **Span type:** `agent` * **Text field:** `user_prompt` * **Evaluator:** Prompt Safety (or any custom evaluator) 3. New `claude_code.interaction` spans will be scored automatically as they arrive. Enrichment requires the `user_prompt` attribute to be populated. Set `OTEL_LOG_USER_PROMPTS=1` to enable content capture. When disabled, `user_prompt` contains `` and enrichment will score the redaction placeholder instead of the actual prompt. *** ## Configuration Reference ### Environment Variables #### Required | Variable | Description | | ------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | | `CLAUDE_CODE_ENABLE_TELEMETRY` | Set to `1` to enable telemetry. | | `CLAUDE_CODE_ENHANCED_TELEMETRY_BETA` | Set to `1` to enable OTel trace export (beta). | | `OTEL_TRACES_EXPORTER` | Set to `otlp` to enable OTLP trace export. | | `OTEL_EXPORTER_OTLP_ENDPOINT` | Fiddler's OTLP ingestion endpoint base URL (e.g., `https://your-fiddler-instance.com`). The OTel SDK appends `/v1/traces` automatically. | | `OTEL_EXPORTER_OTLP_HEADERS` | Must include `fiddler-application-id=` and `Authorization=Bearer `. | | `OTEL_EXPORTER_OTLP_PROTOCOL` | Set to `http/protobuf`. | | `OTEL_RESOURCE_ATTRIBUTES` | Must include `application.id=` matching the header above. | #### Content Logging | Variable | Default | Description | | ----------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `OTEL_LOG_USER_PROMPTS` | `0` | Set to `1` to include user prompt text in traces. When disabled, `user_prompt` shows ``. | | `OTEL_LOG_TOOL_DETAILS` | `0` | Set to `1` to include additional tool metadata (`file_path` for Read/Edit/Write, `full_command` for Bash). | | `OTEL_LOG_TOOL_CONTENT` | `0` | Set to `1` to include tool input/output content. Currently not functioning as documented — see [Known Limitations](#known-claude-code-upstream-limitations). | #### Optional | Variable | Default | Description | | ------------------- | ------------- | -------------------------------------------------------------------------------------------------------- | | `OTEL_SERVICE_NAME` | `claude-code` | Override the service name. Must remain `claude-code` for Fiddler to detect and map the traces correctly. | *** ## Troubleshooting ### Traces not appearing in Fiddler 1. Verify telemetry is enabled: ```bash theme={null} echo $CLAUDE_CODE_ENABLE_TELEMETRY # should be 1 echo $CLAUDE_CODE_ENHANCED_TELEMETRY_BETA # should be 1 echo $OTEL_TRACES_EXPORTER # should be otlp ``` 2. Verify the OTLP endpoint, protocol, and headers are set: ```bash theme={null} echo $OTEL_EXPORTER_OTLP_ENDPOINT # should be the base URL (no /v1/traces) echo $OTEL_EXPORTER_OTLP_PROTOCOL # should be http/protobuf echo $OTEL_EXPORTER_OTLP_HEADERS # should contain fiddler-application-id echo $OTEL_RESOURCE_ATTRIBUTES # should contain application.id ``` 3. Verify `application.id` in `OTEL_RESOURCE_ATTRIBUTES` is a valid UUID for an existing Fiddler application. Spans with an invalid or missing `application.id` are dropped during ingestion. 4. Verify the endpoint URL is the base URL (the SDK appends `/v1/traces` automatically) and `OTEL_EXPORTER_OTLP_PROTOCOL` is set to `http/protobuf`. ### User prompts showing as `` Set `OTEL_LOG_USER_PROMPTS=1` in the environment before launching Claude Code. This is disabled by default for privacy. ### Tool details missing from spans Tool spans only include `tool_name` and `duration_ms` by default. Setting `OTEL_LOG_TOOL_DETAILS=1` adds `file_path` (for Read/Edit/Write tools) and `full_command` (for Bash tools). However, tool input/output content is not currently available in trace spans — see [Known Limitations](#known-claude-code-upstream-limitations). ### Enrichment worker skipping spans If you see warnings like `Missing fiddler.span.system.gen_ai.agent.name in span.attributes`, the Fiddler mapper automatically sets this to `"claude-code"` on all spans. Ensure you are running the latest version of the external OTel consumer that includes the Claude Code mapper. ### Spans classified as `chain` instead of expected types Only three span types have specific classifications: `claude_code.interaction` (agent), `claude_code.llm_request` (llm), and `claude_code.tool` (tool). All other spans — including `tool.blocked_on_user` and `tool.execution` — are classified as `chain`. This is expected behavior. *** ## Known Claude Code Upstream Limitations Claude Code's OpenTelemetry tracing is currently in **beta** and has several limitations that affect what data is available in Fiddler. These are not Fiddler issues — they are limitations of Claude Code's OTel instrumentation. Fiddler captures and maps every attribute that Claude Code emits. ### LLM response content not available in traces Claude Code does not emit LLM response text as a trace span attribute. Response content is only available via OTel **log records** (controlled by `OTEL_LOGS_EXPORTER` and `OTEL_LOG_RAW_API_BODIES`), not trace spans. Additionally, OTel log records are currently emitted without `trace_id` or `span_id`, making log-to-trace correlation impossible. **Impact:** Session views in Fiddler show user prompts (input) but not Claude's responses (output). Evaluators that require both input and output (e.g., response faithfulness) cannot run on Claude Code traces. ### Tool input/output not emitted in trace spans Claude Code's documentation states that `OTEL_LOG_TOOL_CONTENT=1` records a `tool.output` span event with tool input and output bodies. In practice, tool spans have empty event arrays — the `tool.output` event is not emitted. Tool spans only carry `tool_name` and `duration_ms`. **Impact:** Cannot see what arguments were passed to tools or what they returned. This limits visibility into MCP tool interactions and debugging tool failures. ### Tracing is beta and requires opt-in Claude Code's OTel tracing requires the `CLAUDE_CODE_ENHANCED_TELEMETRY_BETA` flag. The trace schema (span names, attribute names, hierarchy) may change between Claude Code versions without notice. **Impact:** Fiddler's mapper may need updates when Claude Code's trace schema changes. Pin Claude Code versions in managed deployments to avoid unexpected schema changes. ### No distributed tracing to LLM providers Claude Code does not send W3C `traceparent` headers when making LLM API calls. If Claude Code is routed through a proxy (e.g., LiteLLM), the proxy creates a new trace root rather than continuing Claude Code's trace. Claude Code traces and proxy traces are separate trace trees. Claude Code does propagate `TRACEPARENT` to Bash subprocesses (e.g., when running shell commands), enabling trace correlation for subprocess-initiated LLM calls in non-interactive mode. **Impact:** End-to-end distributed traces (user → coding agent → LLM proxy → LLM provider) require joining on `session.id` or `x-claude-code-session-id` at query time rather than native trace propagation. ### Content redaction is all-or-nothing per category Content capture is controlled by three separate env vars (`OTEL_LOG_USER_PROMPTS`, `OTEL_LOG_TOOL_DETAILS`, `OTEL_LOG_TOOL_CONTENT`). Each controls an entire category — there is no per-attribute or per-tool-type granularity. You cannot, for example, capture user prompts while keeping tool content redacted within a single category. ### Thinking and reasoning content not available There is no env var to export Claude's extended thinking or reasoning steps in OTel telemetry. Only metadata (token counts, model, latency) is available for the reasoning process, not the content. ### ScopeName and ScopeVersion empty in collected traces Despite using instrumentation scope `com.anthropic.claude_code.tracing 1.0.0`, traces may show empty `ScopeName` and `ScopeVersion` fields. This does not affect span routing or processing — `service.name` and span name prefixes are used for detection. ### Summary | Limitation | Severity | Description | | ------------------------------- | -------- | ----------------------------------------------------------------------------------- | | No LLM response in traces | High | Output content available only via OTel log records (with broken trace correlation). | | No tool input/output | High | `OTEL_LOG_TOOL_CONTENT=1` does not emit `tool.output` span events as documented. | | Beta tracing | Medium | Schema may change between versions. Requires `CLAUDE_CODE_ENHANCED_TELEMETRY_BETA`. | | No traceparent to LLM providers | Medium | Separate trace trees for agent and proxy. Join on session ID. | | All-or-nothing redaction | Low | Cannot selectively control content capture per attribute. | | No thinking content | Medium | Reasoning steps not available in any telemetry signal. | | Empty ScopeName/ScopeVersion | Low | Does not affect functionality. | *** ## Related Documentation * [OpenTelemetry Integration](/integrations/agentic-ai/opentelemetry-integration) — Manual OTel instrumentation for custom frameworks * [LiteLLM Integration](/integrations/agentic-ai/litellm-integration) — Unified LLM gateway with Fiddler observability * [Strands Agents SDK](/integrations/agentic-ai/strands-sdk) — Native monitoring for Strands agent applications * [AgentGateway Integration](/integrations/agentic-ai/agentgateway-integration) — Cisco AgentGateway observability * [Fiddler OTel SDK](/integrations/agentic-ai/fiddler-otel-sdk) — Foundation package for custom OTel instrumentation # Fiddler Evals SDK Source: https://docs.fiddler.ai/integrations/agentic-ai/evals-sdk LLM experiments framework with pre-built evaluators and custom metrics ✓ **GA** | 🏆 **Native SDK** Evaluate LLM application quality with Fiddler's evaluation framework. Run batch experiments with 13 pre-built evaluators or create custom metrics for domain-specific quality assessment. ## What You'll Need * Fiddler account * Python 3.10 or higher * Fiddler API key and access token * Dataset for experiments ## Quick Start ```bash theme={null} # Step 1: Install pip install fiddler-evals ``` ```python theme={null} # Step 2: Initialize connection from fiddler_evals import init init( url='https://your-org.fiddler.ai', token='your-access-token' ) # Step 3: Create project and application from fiddler_evals import Project, Application, Dataset project = Project.get_or_create(name='my_eval_project') application = Application.get_or_create( name='my_llm_app', project_id=project.id ) # Step 4: Create dataset and add test cases from fiddler_evals.pydantic_models.dataset import NewDatasetItem dataset = Dataset.create( name='experiment_dataset', application_id=application.id, description='Test cases for LLM experiments' ) test_cases = [ NewDatasetItem( inputs={"question": "What is the capital of France?"}, expected_outputs={"answer": "Paris is the capital of France"}, metadata={"type": "Factual", "category": "Geography"} ), ] dataset.insert(test_cases) # Step 5: Run evaluation from fiddler_evals import evaluate from fiddler_evals.evaluators import AnswerRelevance, Conciseness, Coherence MODEL = "openai/gpt-4o" CREDENTIAL = "your-credential-name" def my_llm_task(inputs, extras, metadata): """Your LLM application logic""" question = inputs.get("question", "") # Call your LLM here answer = f"Mock response to: {question}" return {"answer": answer} results = evaluate( dataset=dataset, task=my_llm_task, evaluators=[ AnswerRelevance(model=MODEL, credential=CREDENTIAL), Conciseness(model=MODEL, credential=CREDENTIAL), Coherence(model=MODEL, credential=CREDENTIAL) ], name_prefix="my_experiment", score_fn_kwargs_mapping={ "user_query": lambda x: x["inputs"]["question"], "rag_response": "answer", "response": "answer", } ) # Step 6: Analyze results in Fiddler UI print(f"✅ Evaluated {len(results.results)} test cases") ``` ## Pre-Built Evaluators ### Safety & Trust * **FTLPromptSafety** - Detect prompt injection, jailbreaks, and unsafe prompts (runs on Fiddler Centor Models) ### Quality & Accuracy * **AnswerRelevance** - Assess how well responses address user queries (High / Medium / Low) * **ContextRelevance** - Evaluate whether retrieved documents are relevant to the query (High / Medium / Low). Available in Agentic Monitoring and Experiments only * **RAGFaithfulness** - Check if responses are grounded in retrieved documents (Yes / No) * **FTLResponseFaithfulness** - Powered by the Centor Model for Faithfulness for low-latency guardrails * **Coherence** - Measure logical flow and consistency * **Conciseness** - Evaluate response brevity and efficiency ### Content Analysis * **Sentiment** - Analyze emotional tone * **TopicClassification** - Categorize content by topic * **RegexSearch** / **RegexMatch** - Custom pattern-based evaluation * **EvalFn** - Wrap any Python function as an evaluator ## Example Usage ### Batch Experiment with Multiple Evaluators ```python theme={null} from fiddler_evals import init, evaluate, Dataset from fiddler_evals.evaluators import ( AnswerRelevance, Conciseness, FTLResponseFaithfulness ) MODEL = "openai/gpt-4o" CREDENTIAL = "your-credential-name" # Initialize connection init(url='https://your-org.fiddler.ai', token='your-access-token') # Get existing dataset dataset = Dataset.get_by_name( name='llm_outputs', application_id=application.id ) # Define your LLM task def evaluate_llm(inputs, extras, metadata): question = inputs['question'] context = extras.get('context', '') # Your LLM call here response = my_llm_model.generate(question, context) return { "answer": response, "question": question, "context": context } # Run evaluation with multiple evaluators results = evaluate( dataset=dataset, task=evaluate_llm, evaluators=[ AnswerRelevance(model=MODEL, credential=CREDENTIAL), Conciseness(model=MODEL, credential=CREDENTIAL), FTLResponseFaithfulness() # Centor Models don't require model= parameter ], name_prefix="llm-eval", description="Comprehensive LLM experiment", metadata={"model_version": "v2.1", "environment": "production"}, score_fn_kwargs_mapping={ "user_query": lambda x: x["inputs"]["question"], "rag_response": "answer", "response": "answer", "context": lambda x: x["extras"].get("context", "") }, max_workers=4 # Parallel processing ) # Access results programmatically for result in results.results: item = result.experiment_item print(f"\nTest Case: {item.dataset_item_id}") print(f"Status: {item.status}") print(f"Duration: {item.duration_ms}ms") for score in result.scores: print(f" {score.name}: {score.value}") ``` ### Custom Evaluators ```python theme={null} from fiddler_evals.evaluators.base import Evaluator from fiddler_evals.pydantic_models.score import Score class LengthEvaluator(Evaluator): """Custom evaluator for response length""" def __init__(self, min_length=10, max_length=200): super().__init__() self.min_length = min_length self.max_length = max_length def score(self, output: str) -> Score: length = len(output.strip()) if length < self.min_length: score_value = 0.0 reasoning = f"Too short ({length} chars, min {self.min_length})" elif length > self.max_length: score_value = 0.5 reasoning = f"Too long ({length} chars, max {self.max_length})" else: score_value = 1.0 reasoning = f"Appropriate length ({length} chars)" return Score( name="length_check", evaluator_name=self.name, value=score_value, reasoning=reasoning ) # Use custom evaluator alongside built-in ones results = evaluate( dataset=dataset, task=my_llm_task, evaluators=[ AnswerRelevance(model="openai/gpt-4o", credential="your-credential-name"), Conciseness(model="openai/gpt-4o", credential="your-credential-name"), LengthEvaluator(min_length=15, max_length=100) ], score_fn_kwargs_mapping={ "user_query": lambda x: x["inputs"]["question"], "rag_response": "answer", "response": "answer", "output": "answer", } ) ``` ### Importing Test Cases from Files ```python theme={null} # From CSV file dataset.insert_from_csv_file( file_path='test_cases.csv', input_columns=['question'], expected_output_columns=['answer'], metadata_columns=['category', 'difficulty'] ) # From JSONL file dataset.insert_from_jsonl_file( file_path='test_cases.jsonl', input_keys=['question'], expected_output_keys=['answer'], metadata_keys=['category'] ) # From pandas DataFrame import pandas as pd df = pd.DataFrame({ 'question': ['What is AI?', 'Explain ML'], 'expected_answer': ['AI is...', 'ML is...'], 'category': ['definition', 'definition'] }) dataset.insert_from_pandas( df=df, input_columns=['question'], expected_output_columns=['expected_answer'], metadata_columns=['category'] ) ``` ## Viewing Results Results are automatically tracked in the Fiddler UI. Navigate to your application to: * View experiment results with detailed scores * Compare experiments side-by-side * Filter and analyze by metadata * Export results for further analysis ### Programmatic Analysis ```python theme={null} from fiddler_evals import ScoreStatus, ExperimentItemStatus # Analyze individual results for i, result in enumerate(results.results): item = result.experiment_item scores = result.scores print(f"\n📝 Test Case {i + 1}:") print(f" Status: {item.status}") print(f" Duration: {item.duration_ms}ms") if item.status == ExperimentItemStatus.SUCCESS: for score in scores: status_emoji = "✅" if score.status == ScoreStatus.SUCCESS else "❌" print(f" {status_emoji} {score.name}: {score.value}") if score.reasoning: print(f" {score.reasoning}") # Calculate summary statistics from collections import defaultdict evaluator_scores = defaultdict(list) for result in results.results: for score in result.scores: if score.value is not None: evaluator_scores[score.name].append(score.value) print("\n🎯 Summary by Evaluator:") for evaluator_name, values in evaluator_scores.items(): avg_score = sum(values) / len(values) if values else 0 print(f" {evaluator_name}: {avg_score:.3f} (avg)") ``` ## Advanced Configuration ### Parallel Processing ```python theme={null} # Process multiple test cases concurrently results = evaluate( dataset=large_dataset, task=my_llm_task, evaluators=[ AnswerRelevance(model="openai/gpt-4o", credential="your-credential-name"), Conciseness(model="openai/gpt-4o", credential="your-credential-name"), ], max_workers=8, # Use 8 parallel workers name_prefix="parallel-eval" ) ``` ### Experiment Metadata and Organization ```python theme={null} # Track experiments with custom metadata results = evaluate( dataset=dataset, task=my_llm_task, evaluators=[AnswerRelevance(model="openai/gpt-4o", credential="your-credential-name")], name_prefix="model-comparison", description="Comparing GPT-4 vs GPT-3.5", metadata={ "model_name": "gpt-4", "temperature": 0.7, "max_tokens": 1000, "evaluation_date": "2024-01-15", "environment": "production", "version": "v2.1" } ) ``` ### Custom Parameter Mapping ```python theme={null} # Map evaluator parameters to your task output structure results = evaluate( dataset=dataset, task=my_llm_task, evaluators=[ AnswerRelevance(model="openai/gpt-4o", credential="your-credential-name"), # Needs: user_query, rag_response Conciseness(model="openai/gpt-4o", credential="your-credential-name"), # Needs: response ], score_fn_kwargs_mapping={ # Map evaluator parameters to task output keys "user_query": lambda x: x["inputs"]["question"], # Lambda for nested values "rag_response": "answer", # Simple key mapping "response": "answer", # Multiple evaluators can use same output "context": lambda x: x["extras"].get("context", "") # With defaults } ) ``` ## Troubleshooting ### Connection Issues **Problem**: Cannot connect to Fiddler instance **Solution**: 1. Verify your URL is correct (e.g., `https://your-org.fiddler.ai`) 2. Ensure your access token is valid and not expired 3. Check network connectivity: `curl -I https://your-org.fiddler.ai` 4. Regenerate token from Fiddler UI: **Settings** > **Credentials** ### Import Errors **Problem**: `ModuleNotFoundError: No module named 'fiddler_evals'` **Solution**: ```bash theme={null} # Verify installation pip list | grep fiddler-evals # Reinstall if needed pip uninstall fiddler-evals pip install fiddler-evals # Check Python version (requires 3.10+) python --version ``` ### Experiment Failures **Problem**: Evaluators failing with parameter errors **Solution**: 1. Check `score_fn_kwargs_mapping` matches evaluator requirements 2. Verify task output format matches expected structure 3. Test evaluators individually: ```python theme={null} from fiddler_evals.evaluators import AnswerRelevance evaluator = AnswerRelevance(model="openai/gpt-4o", credential="your-credential-name") score = evaluator.score( user_query="What is AI?", rag_response="AI is artificial intelligence" ) print(f"Score: {score.value}, Reasoning: {score.reasoning}") ``` ### Performance Issues **Problem**: Experiment running slowly **Solution**: ```python theme={null} # Use parallel processing results = evaluate( dataset=dataset, task=my_llm_task, evaluators=[ AnswerRelevance(model="openai/gpt-4o", credential="your-credential-name"), Conciseness(model="openai/gpt-4o", credential="your-credential-name"), ], max_workers=4 # Adjust based on your system ) # Or process in smaller batches for i in range(0, len(all_test_cases), 100): batch = all_test_cases[i:i+100] batch_dataset = Dataset.create(name=f"batch_{i}") batch_dataset.insert(batch) results = evaluate(dataset=batch_dataset, task=my_llm_task, evaluators=[...]) ``` ## Related Integrations * [**Evals SDK Quick Start**](/evaluate-and-test/evals-sdk-quick-start) - Detailed setup guide with code examples * [**Evals SDK Reference**](/sdk-api/evals/evaluate) - Complete SDK API documentation * [**LangGraph SDK**](/integrations/agentic-ai/langgraph-sdk) - Runtime monitoring for LangGraph agents * [**Strands Agents SDK**](/integrations/agentic-ai/strands-sdk) - Monitor Strands Agents * [**Python Client SDK**](/sdk-api/python-client/connection) - Full platform API access ## Next Steps 1. [**Quick Start Guide**](/evaluate-and-test/evals-sdk-quick-start) - Complete tutorial with working examples 2. [**Getting Started with Experiments**](/getting-started/experiments) - Understand experiment concepts and best practices 3. [**SDK API Reference**](/sdk-api/evals/evaluate) - Explore all available classes and methods # Fiddler OTel SDK Source: https://docs.fiddler.ai/integrations/agentic-ai/fiddler-otel-sdk Instrument any Python AI agent or LLM application with Fiddler's core OpenTelemetry SDK # Fiddler OTel SDK [![PyPI](https://img.shields.io/pypi/v/fiddler-otel)](https://pypi.org/project/fiddler-otel/) Instrument any Python AI agent or LLM application with OpenTelemetry-based tracing for comprehensive agentic observability. The Fiddler OTel SDK is the foundation package used by all Fiddler framework integrations (`fiddler-langgraph`, `fiddler-langchain`). Use it directly when you have no LangGraph or LangChain dependency, or when you want lightweight decorator-based instrumentation for custom Python agents. **Migrating from `fiddler-langgraph`?** The core instrumentation functionality (`FiddlerClient`, `@trace`, span wrappers, etc.) has been extracted from `fiddler-langgraph` into this standalone `fiddler-otel` package. If you previously imported these symbols from `fiddler_langgraph`, update your imports to use `fiddler_otel` — the classes and behaviour are identical. See the [deprecation notice](/changelog/langgraph-sdk) in the LangGraph SDK changelog for details. ## What you'll need * Fiddler account (cloud or on-premises) * Python 3.10, 3.11, 3.12, or 3.13 * Fiddler API key and application ID ## Quick start Get monitoring in 3 steps: ```bash theme={null} # Step 1: Install pip install fiddler-otel ``` ```python theme={null} # Step 2: Initialize the Fiddler client from fiddler_otel import FiddlerClient, trace client = FiddlerClient( application_id='your-app-id', # Must be valid UUID4 api_key='your-api-key', url='https://your-instance.fiddler.ai' ) # Step 3: Decorate your functions @trace(as_type='generation') def call_llm(prompt: str) -> str: # Your LLM call here ... ``` That's it! Your agent traces are now flowing to Fiddler. This Quick Start uses the `@trace` decorator. For context manager and manual instrumentation approaches, see [Instrumentation Methods](#instrumentation-methods) below. ## What gets monitored The Fiddler OTel SDK captures: ### Trace hierarchy Spans are automatically nested into parent-child relationships based on the call stack: ``` [Span] supervisor_agent (agent - TYPE=agent) └── [Span] call_llm (LLM - TYPE=llm) └── [Span] search_hotels (Tool - TYPE=tool) └── [Span] call_llm (LLM - TYPE=llm) ``` ### Captured data * Function inputs and return values (auto-serialized to JSON) * LLM prompts, completions, and token usage * Tool names, inputs, and outputs * Agent name, agent ID, and conversation ID * Execution times and error traces ## Application setup Before instrumenting your application, you must create an application in Fiddler and obtain your Application ID. Log in to your Fiddler instance and navigate to **GenAI Applications**, then click **Add Application** and follow the onboarding wizard to create your application. After creating your application, copy the **Application ID** from the GenAI Applications page. This must be a valid UUID4 format (for example, `550e8400-e29b-41d4-a716-446655440000`). You'll need this for initialization. Go to **Settings** > **Credentials** and copy your API key. You'll need this for initialization. ## Detailed setup ### Installation ```bash theme={null} pip install fiddler-otel ``` **Requirements:** * **Python:** 3.10, 3.11, 3.12, or 3.13 * **OpenTelemetry:** API, SDK, and OTLP exporter `>= 1.27.0` (installed automatically) * **pydantic:** `>= 2.0` (installed automatically) ### Configuration #### Direct initialization (Recommended) ```python theme={null} from fiddler_otel import FiddlerClient client = FiddlerClient( application_id='your-app-id', # Required (UUID4 format) api_key='your-api-key', # Required when otlp_enabled=True (default) url='https://your-instance.fiddler.ai' # Required when otlp_enabled=True (default) ) ``` #### Using environment variables ```python theme={null} import os from fiddler_otel import FiddlerClient client = FiddlerClient( application_id=os.getenv('FIDDLER_APPLICATION_ID'), api_key=os.getenv('FIDDLER_API_KEY'), url=os.getenv('FIDDLER_URL') ) ``` **Environment Variables Reference:** | Variable | Description | Example | | ------------------------ | ------------------------- | -------------------------------------- | | `FIDDLER_API_KEY` | Your Fiddler API key | `fid_...` | | `FIDDLER_APPLICATION_ID` | Your application UUID4 | `550e8400-e29b-41d4-a716-446655440000` | | `FIDDLER_URL` | Your Fiddler instance URL | `https://your-instance.fiddler.ai` | ## Instrumentation methods The Fiddler OTel SDK provides two instrumentation approaches. Choose the one that fits your application: | Approach | Best For | Key API | | --------------------------------------------------- | -------------------------------------------- | ----------------------------------------- | | [Decorator-Based](#decorator-based-instrumentation) | Custom Python functions, minimal boilerplate | `@trace()`, `get_current_span()` | | [Manual](#manual-instrumentation) | Fine-grained span lifecycle control | `start_as_current_span()`, `start_span()` | You can combine both approaches in the same application. For example, use the decorator for most functions and manual spans where you need fine-grained lifecycle control. ### Decorator-based instrumentation Use the `@trace()` decorator to instrument individual Python functions. Works with both synchronous and asynchronous functions. ```python theme={null} from openai import OpenAI from fiddler_otel import FiddlerClient, trace, get_current_span, set_conversation_id import uuid client = FiddlerClient( application_id='your-app-id', api_key='your-api-key', url='https://your-instance.fiddler.ai' ) openai_client = OpenAI() @trace( as_type='generation', capture_input=False, # Disable auto-capture to set attributes manually capture_output=False, model='gpt-4o-mini', # Sets gen_ai.request.model on the span system='openai', # Sets gen_ai.system on the span ) def call_llm(prompt: str) -> str: span = get_current_span(as_type='generation') if span: span.set_user_prompt(prompt) response = openai_client.chat.completions.create( model='gpt-4o-mini', messages=[{'role': 'user', 'content': prompt}] ) result = response.choices[0].message.content if span: span.set_completion(result) span.set_usage( input_tokens=response.usage.prompt_tokens, output_tokens=response.usage.completion_tokens, ) return result @trace(as_type='tool') def search_hotels(query: str) -> str: span = get_current_span(as_type='tool') if span: span.set_tool_name('search_hotels') span.set_tool_input({'query': query}) result = f'Found: Grand Hotel for query "{query}"' if span: span.set_tool_output(result) return result @trace(as_type='chain') def run_agent(user_message: str) -> str: span = get_current_span(as_type='chain') if span: span.set_agent_name('travel_agent') span.set_input(user_message) response = call_llm(user_message) hotels = search_hotels(user_message) result = f'{response}\n\n{hotels}' if span: span.set_output(result) return result # Set conversation ID to link multiple turns set_conversation_id(str(uuid.uuid4())) run_agent('Find me a hotel in Tokyo') ``` **`@trace` decorator parameters:** | Parameter | Type | Default | Description | | ---------------- | --------------------------------------------- | ------------- | --------------------------------------------------------- | | `as_type` | `'span'`, `'generation'`, `'chain'`, `'tool'` | `'span'` | Span type for Fiddler categorization | | `name` | `str \| None` | function name | Custom span name | | `capture_input` | `bool` | `True` | Auto-serialize function arguments as span input | | `capture_output` | `bool` | `True` | Auto-serialize return value as span output | | `model` | `str \| None` | `None` | Sets `gen_ai.request.model` | | `system` | `str \| None` | `None` | Sets `gen_ai.system` (LLM provider) | | `user_id` | `str \| None` | `None` | Sets `user.id` | | `version` | `str \| None` | `None` | Sets `service.version` | | `client` | `FiddlerClient \| None` | `None` | Override the client to use (defaults to global singleton) | **Using `get_current_span()` inside a decorated function:** Call `get_current_span()` inside any `@trace`-decorated function to access the active span and set additional attributes. Pass `as_type` matching the decorator to get a typed wrapper with semantic helpers: ```python theme={null} @trace(as_type='generation') def my_llm_call(prompt: str) -> str: span = get_current_span(as_type='generation') if span: span.set_model('gpt-4o-mini') span.set_user_prompt(prompt) span.set_system_prompt('You are a helpful assistant.') ... ``` **When to use `capture_input=False`:** Set `capture_input=False` when you want to control exactly what gets recorded on the span (for example, to set `set_user_prompt()` instead of the default raw argument dict). This avoids double-recording the same data. ### Manual instrumentation Use context managers for explicit span lifecycle control. This gives you full control over when spans start and end. ```python theme={null} from openai import OpenAI from fiddler_otel import FiddlerClient client = FiddlerClient( application_id='your-app-id', api_key='your-api-key', url='https://your-instance.fiddler.ai' ) openai_client = OpenAI() user_message = 'Find me a hotel in Tokyo' # Context manager (automatic lifecycle) with client.start_as_current_span('travel_agent', as_type='chain') as chain: chain.set_agent_name('travel_agent') chain.set_input(user_message) with client.start_as_current_span('gpt-4o-mini', as_type='generation') as gen: gen.set_model('gpt-4o-mini') gen.set_system('openai') gen.set_user_prompt(user_message) response = openai_client.chat.completions.create( model='gpt-4o-mini', messages=[{'role': 'user', 'content': user_message}] ) result = response.choices[0].message.content gen.set_completion(result) gen.set_usage( input_tokens=response.usage.prompt_tokens, output_tokens=response.usage.completion_tokens, ) with client.start_as_current_span('search_hotels', as_type='tool') as tool: tool.set_tool_name('search_hotels') tool.set_tool_input({'query': user_message}) tool_result = search_hotels(user_message) tool.set_tool_output(tool_result) chain.set_output(result) ``` **Manual lifecycle (explicit `end()`):** Use `start_span()` when you need to manage the span lifecycle manually, for example across asynchronous callbacks: ```python theme={null} prompt = 'Find me a hotel in Tokyo' span = client.start_span('my_operation', as_type='generation') try: span.set_user_prompt(prompt) result = call_llm(prompt) # your LLM call span.set_completion(result) except Exception as exc: span.record_exception(exc) raise finally: span.end() ``` ## Span types and wrappers The SDK provides four span types, each with semantic convention helpers: ### `FiddlerSpan` — base (any `as_type='span'`) | Method | OTel Attribute | Description | | --------------------------- | ------------------------ | ---------------------------------------------------------- | | `set_input(data)` | `gen_ai.llm.input.user` | Auto-serializes dicts/lists to JSON | | `set_output(data)` | `gen_ai.llm.output` | Auto-serializes dicts/lists to JSON | | `set_attribute(key, value)` | custom | Set any custom attribute | | `update(**kwargs)` | — | Bulk-set `input`, `output`, and any attributes in one call | | `set_agent_name(name)` | `gen_ai.agent.name` | Agent label in Fiddler UI | | `set_agent_id(id)` | `gen_ai.agent.id` | Agent identifier | | `set_conversation_id(id)` | `gen_ai.conversation.id` | Links spans to a conversation | | `record_exception(exc)` | — | Records exception and marks span ERROR | | `end()` | — | End span (for manual lifecycle only) | ### `FiddlerGeneration` — LLM spans (`as_type='generation'`) Extends `FiddlerSpan` with: | Method | OTel Attribute | Description | | ----------------------------------------------------------- | ------------------------- | ------------------------------------- | | `set_model(name)` | `gen_ai.request.model` | LLM model name | | `set_system(provider)` | `gen_ai.system` | LLM provider (e.g. `'openai'`) | | `set_system_prompt(text)` | `gen_ai.llm.input.system` | System prompt text | | `set_user_prompt(text)` | `gen_ai.llm.input.user` | User prompt (last human message) | | `set_completion(text)` | `gen_ai.llm.output` | LLM completion text | | `set_usage(input_tokens, output_tokens, total_tokens=None)` | `gen_ai.usage.*` | Token counts | | `set_context(text)` | `gen_ai.llm.context` | Additional context | | `set_messages(messages)` | `gen_ai.input.messages` | Full chat history (JSON) | | `set_output_messages(messages)` | `gen_ai.output.messages` | Output messages (JSON) | | `set_tool_definitions(defs)` | `gen_ai.tool.definitions` | Available tools (JSON, OpenAI format) | `set_messages()` and `set_output_messages()` accept simple OpenAI format and auto-convert to OTel parts format: ```python theme={null} gen.set_messages([ {'role': 'system', 'content': 'You are a travel agent.'}, {'role': 'user', 'content': 'Book a flight to Tokyo.'} ]) ``` ### `FiddlerTool` — tool spans (`as_type='tool'`) Extends `FiddlerSpan` with: | Method | OTel Attribute | Description | | ---------------------------- | ------------------------- | ------------------------------------- | | `set_tool_name(name)` | `gen_ai.tool.name` | Tool/function name | | `set_tool_input(data)` | `gen_ai.tool.input` | Tool input (auto-serialized to JSON) | | `set_tool_output(data)` | `gen_ai.tool.output` | Tool result (auto-serialized to JSON) | | `set_tool_definitions(defs)` | `gen_ai.tool.definitions` | Available tools | ### `FiddlerChain` — pipeline spans (`as_type='chain'`) Extends `FiddlerSpan` with no additional methods. Use for high-level orchestration spans that group multiple LLM calls and tool calls together. ## Advanced usage ### Multi-turn conversation tracking Use `set_conversation_id()` to link multiple agent invocations into a single conversation in the Fiddler UI. Set a new UUID at the start of each conversation; all spans created in the current thread or async coroutine after this call will carry the same conversation ID. ```python theme={null} from fiddler_otel import set_conversation_id import uuid # Call once per conversation — persists for the current thread/async task set_conversation_id(str(uuid.uuid4())) result1 = run_agent('What flights go to Tokyo?') result2 = run_agent('Book the cheapest one.') # Same conversation_id ``` ### Async agents The `@trace` decorator automatically detects async functions and wraps them correctly. Use the same patterns as sync functions: ```python theme={null} import asyncio from openai import AsyncOpenAI from fiddler_otel import FiddlerClient, trace, get_current_span client = FiddlerClient(application_id='...', api_key='...', url='...') async_openai_client = AsyncOpenAI() @trace(as_type='generation', model='gpt-4o-mini') async def call_llm_async(prompt: str) -> str: span = get_current_span(as_type='generation') if span: span.set_user_prompt(prompt) response = await async_openai_client.chat.completions.create( model='gpt-4o-mini', messages=[{'role': 'user', 'content': prompt}] ) result = response.choices[0].message.content if span: span.set_completion(result) span.set_usage( input_tokens=response.usage.prompt_tokens, output_tokens=response.usage.completion_tokens, ) return result @trace(as_type='chain') async def run_agent_async(message: str) -> str: result = await call_llm_async(message) return result asyncio.run(run_agent_async('Hello')) ``` ### Context isolation `fiddler-otel` uses its own isolated OpenTelemetry context that does not interfere with any existing global tracer in your application. If you already use OpenTelemetry for infrastructure tracing, Fiddler spans will not appear in your infrastructure traces and vice versa. This means you can safely add `fiddler-otel` to an application that already has OpenTelemetry instrumentation without any conflict. ### Global client singleton The first `FiddlerClient` created in a process becomes the global singleton, accessible via `get_client()`. The `@trace` decorator uses this singleton automatically when `client=` is not passed: ```python theme={null} from fiddler_otel import FiddlerClient, get_client, trace # Created once at startup client = FiddlerClient(application_id='...', api_key='...', url='...') # Anywhere in your code — no need to pass client= @trace(as_type='generation') def call_llm(prompt: str) -> str: ... # Or retrieve the singleton explicitly fdl = get_client() ``` ### Session attributes Use `add_session_attributes()` to attach key-value metadata that is automatically applied to **all spans** created in the current thread or async coroutine. Use this for user-level or environment-level metadata that applies across an entire session — such as `user_id`, `environment`, or feature flags. Attributes are emitted as `fiddler.session.user.{key}` on every span and propagated from parent to child spans automatically. ```python theme={null} from fiddler_otel import FiddlerClient, trace, add_session_attributes client = FiddlerClient(application_id='...', api_key='...', url='...') # Set once per session — applies to all spans that follow in this context add_session_attributes(key='user_id', value='user_12345') add_session_attributes(key='environment', value='production') add_session_attributes(key='tier', value='premium') add_session_attributes(key='request_count', value=42) # int (since 1.1.1) add_session_attributes(key='confidence_score', value=0.87) # float (since 1.1.1) @trace(as_type='chain') def run_agent(message: str) -> str: # All spans inside this call carry user_id, environment, tier ... ``` Unlike `set_conversation_id()` (which links invocations into a conversation), `add_session_attributes` is for descriptive metadata. Both can be used together. ### Custom span attributes Set any custom attribute on an individual span to add business context for that specific operation: ```python theme={null} @trace(as_type='tool') def search_hotels(query: str) -> str: span = get_current_span(as_type='tool') if span: span.set_attribute('fiddler.span.user.department', 'travel') span.set_attribute('fiddler.span.user.region', 'apac') span.set_attribute('fiddler.span.user.reward_points', 5.0) ... ``` ### Production configuration **Sampling (reduce volume):** ```python theme={null} from opentelemetry.sdk.trace import sampling client = FiddlerClient( application_id='...', api_key='...', url='...', sampler=sampling.TraceIdRatioBased(0.1), # Sample 10% of traces ) ``` **Span limits (large prompts):** ```python theme={null} from opentelemetry.sdk.trace import SpanLimits client = FiddlerClient( application_id='...', api_key='...', url='...', span_limits=SpanLimits( max_span_attribute_length=8192, # Allow up to 8 KB per attribute ), ) ``` **Resource attributes (environment metadata):** ```python theme={null} client = FiddlerClient(application_id='...', api_key='...', url='...') client.update_resource({'service.version': '2.1.0', 'deployment.environment': 'production'}) # Must be called before get_tracer() is invoked (before the first @trace call) ``` ### Flush and shutdown `FiddlerClient` registers an `atexit` handler to flush and shut down automatically. For short scripts or critical workloads, call `force_flush()` explicitly to ensure all buffered spans are exported before the process exits: ```python theme={null} # Sync client.force_flush() client.shutdown() # Async await client.aflush() await client.ashutdown() # Context manager (calls shutdown() on exit) with FiddlerClient(application_id='...', api_key='...', url='...') as client: run_agent('Hello') ``` ### Local debugging **Console output (print spans to stdout in addition to Fiddler export):** `console_tracer=True` is **additive** — span data is printed to stdout **and** continues to be exported to Fiddler via OTLP. Setting this to `True` does **not** suppress or disable the OTLP export to Fiddler. Use it to visually confirm spans are being created during development. ```python theme={null} client = FiddlerClient( application_id='...', api_key='...', url='...', console_tracer=True, # Prints spans to stdout; OTLP export to Fiddler still active ) ``` **JSONL file capture (save a local copy of spans in addition to Fiddler export):** `jsonl_capture_enabled=True` is **additive** — spans are saved to a local JSONL file **and** continue to be exported to Fiddler via OTLP. Setting this to `True` does **not** suppress or disable the OTLP export to Fiddler. The JSONL format written here is a custom Fiddler format and is **not** compatible with the Fiddler S3 connector. To write S3-compatible files, use `otlp_json_capture_enabled=True` instead (see [Offline and S3 Routing Mode](#offline-and-s3-routing-mode) below). ```python theme={null} client = FiddlerClient( application_id='...', api_key='...', url='...', jsonl_capture_enabled=True, # Saves spans to local file; OTLP export still active jsonl_file_path='trace_data.jsonl', ) ``` Override the output file path via environment variable: ```bash theme={null} FIDDLER_JSONL_FILE=trace_data.jsonl python my_agent.py ``` ### Offline and S3 Routing Mode Use this mode when traces must be routed through an intermediate store (such as Amazon S3) before reaching Fiddler, rather than being sent directly. This is the correct approach when your security or network policies require all data to pass through a controlled intermediary. * **`otlp_enabled=False`** — disables all direct OTLP export to Fiddler. `api_key` and `url` are not required in this mode. * **`otlp_json_capture_enabled=True`** — writes traces to local `.json` files in standard OTLP JSON format (`ExportTraceServiceRequest` envelope). These files are directly consumable by the Fiddler S3 connector. * **`application_id` is still required** — even though no data is sent to Fiddler directly, the S3 connector uses the `application_id` embedded in the trace files to route ingested traces to the correct application in Fiddler. ```python theme={null} from fiddler_otel import FiddlerClient # No api_key or url needed — traces go to local files only client = FiddlerClient( application_id='YOUR_APPLICATION_ID', # UUID4 — required for S3 connector routing otlp_enabled=False, # Disables direct export to Fiddler otlp_json_capture_enabled=True, # Writes OTLP JSON files locally otlp_json_output_dir='./fiddler_traces', # Directory for output files (default: 'fiddler_traces') ) ``` After running your application, upload the generated `.json` files from `otlp_json_output_dir` to your S3 bucket. The Fiddler S3 connector reads them directly. Each batch of spans is written to a separate timestamped `.json` file in the output directory. The directory is created automatically if it does not exist. ### Running in AWS SageMaker Run the Fiddler OTel SDK inside an [Amazon SageMaker Partner AI App](/integrations/cloud-platforms-and-deployment/aws-sagemaker) to export agent traces with AWS Signature Version 4 (SigV4) signing. Authentication is **entirely environment-variable driven — no code changes are required.** Because the `fiddler-langchain` and `fiddler-langgraph` integrations export through `FiddlerClient`, SageMaker signing flows through them automatically as well. Install the `sagemaker` extra (pre-installed in SageMaker-managed runtimes): ```bash theme={null} pip install "fiddler-otel[sagemaker]" ``` Set the following environment variables. When SageMaker authentication is enabled, `FiddlerClient` attaches a SigV4-signing session to the OTLP exporter, so every trace export is signed and routed through the SageMaker partner-app proxy: | Variable | Description | | ---------------------- | ------------------------------------------------------------------------------------------------------ | | `AWS_PARTNER_APP_AUTH` | Set to `true` to enable SageMaker Partner App authentication. | | `AWS_PARTNER_APP_ARN` | The ARN of your Fiddler SageMaker Partner AI App. | | `AWS_PARTNER_APP_URL` | The base URL of the partner-app endpoint. This is the same value you pass to `FiddlerClient` as `url`. | AWS credentials are resolved through the standard boto3 credential chain (IAM role inside a SageMaker runtime, `~/.aws/credentials`, instance profile, or environment variables) — no additional AWS credential variables are needed when running inside the partner-app sandbox. Your instrumentation code is unchanged from any other environment — `FiddlerClient` reads the SageMaker variables itself: ```python theme={null} import os from fiddler_otel import FiddlerClient, trace # In a SageMaker Partner App, the Fiddler URL is the partner-app endpoint # (the same value as AWS_PARTNER_APP_URL), not a *.fiddler.ai URL. client = FiddlerClient( application_id=os.environ['FIDDLER_APPLICATION_ID'], # UUID4 api_key=os.environ['FIDDLER_API_KEY'], url=os.environ['AWS_PARTNER_APP_URL'], ) @trace(as_type='generation') def call_llm(prompt: str) -> str: ... ``` SageMaker authentication is resolved eagerly when you construct `FiddlerClient`. A misconfigured environment — a missing ARN or URL, missing AWS credentials, or the `sagemaker` extra not installed — raises an error at construction time rather than failing silently on the first trace export. Set [`FIDDLER_OTLP_DEBUG=true`](#local-debugging) to log each signed export while you validate the setup. **Traces are not yet visible in the Fiddler UI on AWS.** In the current SageMaker environment, traces are signed and exported correctly but are not yet surfaced in the Fiddler UI. This is an environment limitation, not an SDK defect. ## Relationship to other Fiddler SDKs `fiddler-otel` is the foundation package that all Fiddler SDK integrations build on: | Package | Framework | Instrumentation Approach | | ------------------- | ---------------------------------- | ------------------------------------------------------------ | | `fiddler-otel` | Any Python application | `@trace` decorator, context managers | | `fiddler-langchain` | LangChain V1 (`create_agent`) | `FiddlerLangChainInstrumentor` (auto-patches `create_agent`) | | `fiddler-langgraph` | LangGraph (`StateGraph.compile()`) | `LangGraphInstrumentor` (callback handler) | Both `fiddler-langchain` and `fiddler-langgraph` depend on `fiddler-otel` and re-export its core symbols (`FiddlerClient`, `trace`, `get_current_span`, `set_conversation_id`). If your application uses LangChain V1 (`create_agent` API) or LangGraph, install the framework-specific package — it includes `fiddler-otel` automatically. ## API reference The `fiddler-otel` SDK provides the same core classes as `fiddler-langgraph` — the codebase is shared, and `fiddler-langgraph` re-exports all `fiddler-otel` symbols unchanged. Until a dedicated `fiddler-otel` API reference is autogenerated, the detailed reference pages are co-located in the shared SDK API reference. The classes, parameters, and behaviour are identical regardless of which package you import from — use `fiddler_otel` as the import source when using the core SDK standalone. | Class / Function | Import | Description | | --------------------------------------------------------------------- | ------------------------------------------------- | ------------------------------------------------------------------------ | | [FiddlerClient](/sdk-api/langgraph/fiddler-client) | `from fiddler_otel import FiddlerClient` | Configure the OTel tracer and manage the connection to Fiddler | | [get\_client](/sdk-api/langgraph/get-client) | `from fiddler_otel import get_client` | Retrieve the active `FiddlerClient` instance | | [trace](/sdk-api/langgraph/trace) | `from fiddler_otel import trace` | Decorator for automatic function instrumentation | | [get\_current\_span](/sdk-api/langgraph/get-current-span) | `from fiddler_otel import get_current_span` | Access the active Fiddler span within a traced function | | [FiddlerSpan](/sdk-api/langgraph/fiddler-span) | `from fiddler_otel import FiddlerSpan` | Base span wrapper | | [FiddlerGeneration](/sdk-api/langgraph/fiddler-generation) | `from fiddler_otel import FiddlerGeneration` | Span wrapper for LLM calls | | [FiddlerChain](/sdk-api/langgraph/fiddler-chain) | `from fiddler_otel import FiddlerChain` | Span wrapper for agent/chain workflows | | [FiddlerTool](/sdk-api/langgraph/fiddler-tool) | `from fiddler_otel import FiddlerTool` | Span wrapper for tool calls | | [add\_session\_attributes](/sdk-api/langgraph/add-session-attributes) | `from fiddler_otel import add_session_attributes` | Add session-level attributes applied to all spans in the current context | | [set\_conversation\_id](/sdk-api/langgraph/set-conversation-id) | `from fiddler_otel import set_conversation_id` | Link spans into a single conversation | ## Troubleshooting ### No spans appearing in Fiddler 1. **Check your credentials** — verify `api_key`, `application_id` (must be a valid UUID4), and `url` are correct. These are only required when `otlp_enabled=True` (the default). 2. **Force flush before exit** — for short scripts, the `BatchSpanProcessor` may not flush before the process exits. Call `client.force_flush()` or use the context manager (`with FiddlerClient(...) as client:`). 3. **Enable console tracing** — set `console_tracer=True` to also print spans to stdout and confirm they are being created. This is additive; OTLP export to Fiddler continues alongside console output: ```python theme={null} client = FiddlerClient( application_id='...', api_key='...', url='...', console_tracer=True, # Adds console output; does NOT disable OTLP export ) ``` 4. **Check the application ID** — the `application_id` must match an existing application in your Fiddler instance and must be a valid UUID4. `FiddlerClient` raises `ValueError` on initialization if the format is invalid. ### `RuntimeError: No FiddlerClient initialized` `get_current_span()` or `get_client()` was called before a `FiddlerClient` was created. Create the client before decorating or calling any instrumented functions: ```python theme={null} from fiddler_otel import FiddlerClient, trace client = FiddlerClient(application_id='...', api_key='...', url='...') @trace(as_type='generation') def call_llm(prompt: str) -> str: ... ``` ### `ValueError: application_id must be a valid UUID4` The `application_id` passed to `FiddlerClient` is not a valid UUID version 4. Copy the Application ID directly from the **GenAI Applications** page in the Fiddler UI — it should look like `550e8400-e29b-41d4-a716-446655440000`. ### Spans missing from async code Context variables propagate correctly across `await` in the same async task. If you are spawning new tasks with `asyncio.create_task()`, call `set_conversation_id()` and `add_session_attributes()` inside the task so the context is re-established. Use `client.ashutdown()` instead of `client.shutdown()` to avoid blocking the event loop during teardown. ### Spans interfering with another OpenTelemetry tracer `FiddlerClient` uses an isolated `Context` that is separate from the global OTel context. Spans created via `@trace` or `start_as_current_span()` will not appear in any other tracer, and spans from other tracers will not appear in Fiddler. This isolation is intentional and requires no configuration. ### Local JSONL file is empty Ensure `jsonl_capture_enabled=True` is set on `FiddlerClient` and that the process has executed instrumented code. The JSONL file is written synchronously, so spans appear immediately after each span ends. Check the path: the default is `fiddler_trace_data.jsonl` in the current working directory; override with `jsonl_file_path` or the `FIDDLER_JSONL_FILE` environment variable. **Note:** `jsonl_capture_enabled=True` is additive — it saves a local copy of spans while OTLP export to Fiddler continues. If your goal is to write files for S3 upload and stop sending directly to Fiddler, use `otlp_enabled=False` combined with `otlp_json_capture_enabled=True` instead. See [Offline and S3 Routing Mode](#offline-and-s3-routing-mode). *** ## What's next? * [**LangChain SDK**](/integrations/agentic-ai/langchain-sdk) — If your application uses LangChain V1 `create_agent` * [**LangGraph SDK**](/integrations/agentic-ai/langgraph-sdk) — If your application uses LangGraph * [**Agentic Observability Concepts**](/getting-started/agentic-monitoring) — Understand the agent lifecycle and monitoring approach # Fiddler Google ADK SDK Source: https://docs.fiddler.ai/integrations/agentic-ai/google-adk-sdk Native monitoring for Google ADK agents with Fiddler's purpose-built SDK [![PyPI](https://img.shields.io/pypi/v/fiddler-adk)](https://pypi.org/project/fiddler-adk/) Monitor Google ADK (Agent Development Kit) applications with Fiddler's purpose-built SDK. Get deep visibility into agent reasoning, LLM interactions, and tool execution for ADK-based agent applications. **Platform Compatibility:** Works with ADK agents using either Google Gemini API keys or Vertex AI authentication. ## What You'll Need * Fiddler account (cloud or on-premises) * Google ADK agent application * Python 3.10 or higher * Fiddler API key * Google Gemini API key or Vertex AI credentials ## Quick Start ```bash theme={null} # Step 1: Install (uv recommended) uv add fiddler-adk # or: pip install fiddler-adk ``` ```python theme={null} # Step 2: Set up instrumentation from fiddler_otel import FiddlerClient from fiddler_adk import GoogleADKInstrumentor client = FiddlerClient( api_key="YOUR_FIDDLER_API_KEY", application_id="YOUR_APPLICATION_UUID", url="https://your-fiddler-instance.com", ) GoogleADKInstrumentor(client).instrument() # Step 3: Create your ADK agent as usual from google.adk.agents.llm_agent import Agent agent = Agent( model="gemini-2.5-flash", name="my_agent", description="A helpful assistant", instruction="You are a helpful assistant. Be concise.", ) # Step 4: Agent calls are automatically traced # (use Runner to execute the agent — see Quick Start Guide for full example) ``` ## What Gets Monitored ### ADK Agent Operations * **Agent Invocations** (`invoke_agent`) - Full agent execution with timing and session tracking * **LLM Calls** (`call_llm`) - LLM request/response capture with input, output, system instructions, and tool definitions * **Tool Execution** (`execute_tool`) - Tool call arguments and return values * **Model Inference** (`generate_content`) - Token usage, model name, and finish reasons ### Captured Attributes * **LLM Input/Output** - User prompt text, model response text, system instructions * **Tool I/O** - Tool call arguments (JSON) and tool response payloads * **Token Usage** - Input tokens, output tokens, reasoning tokens * **Agent Identity** - Agent name, agent ID, session/conversation ID * **Finish Reasons** - LLM stop reason per generation ## Configuration Options ### Programmatic Configuration ```python theme={null} from fiddler_otel import FiddlerClient from fiddler_adk import GoogleADKInstrumentor client = FiddlerClient( api_key="YOUR_FIDDLER_API_KEY", application_id="YOUR_APPLICATION_UUID", # UUID4 from Fiddler GenAI Applications url="https://your-fiddler-instance.com", ) GoogleADKInstrumentor(client).instrument() # All agents created after this point are automatically instrumented ``` ### Google Authentication ADK supports two authentication methods for accessing Gemini models: ```bash theme={null} # Option A: Gemini API key export GOOGLE_API_KEY="your-gemini-api-key" # Option B: Vertex AI (uses gcloud Application Default Credentials) export GOOGLE_GENAI_USE_VERTEXAI=1 export GOOGLE_CLOUD_PROJECT="your-gcp-project-id" export GOOGLE_CLOUD_LOCATION="us-central1" ``` ### Content Capture ADK includes full LLM request/response payloads in span attributes by default. To disable payload capture (e.g., for PII protection): ```bash theme={null} export ADK_CAPTURE_MESSAGE_CONTENT_IN_SPANS=false ``` ## Example Applications ### Document Processing Agent with Tools ```python theme={null} import asyncio from fiddler_otel import FiddlerClient from fiddler_adk import GoogleADKInstrumentor from google.adk.agents.llm_agent import Agent from google.adk.runners import Runner from google.adk.sessions import InMemorySessionService from google.genai import types # Set up Fiddler instrumentation client = FiddlerClient( api_key="YOUR_FIDDLER_API_KEY", application_id="YOUR_APPLICATION_UUID", url="https://your-fiddler-instance.com", ) GoogleADKInstrumentor(client).instrument() # Define tools def classify_document(doc_type: str, content: str) -> dict: """Classify a document into a known category.""" return {"category": "Credit Memo", "confidence": 0.95} def extract_fields(document_id: str) -> dict: """Extract structured fields from a document.""" return {"supplier": "McKesson", "total": "$12,450.00"} # Create agent with tools agent = Agent( model="gemini-2.5-flash", name="doc_processor", description="Document processing assistant", instruction="You classify and extract fields from medical documents.", tools=[classify_document, extract_fields], ) async def main(): session_service = InMemorySessionService() runner = Runner(agent=agent, app_name="demo", session_service=session_service) session = await session_service.create_session(app_name="demo", user_id="user1") message = types.Content( role="user", parts=[types.Part(text="Classify this credit memo: supplier McKesson, amount $5000")], ) async for event in runner.run_async( user_id="user1", session_id=session.id, new_message=message ): if hasattr(event, "content") and event.content: parts = getattr(event.content, "parts", []) or [] text = "".join(p.text for p in parts if getattr(p, "text", None)) if text: print(f"Agent: {text}") # Flush traces to Fiddler before exit client.force_flush(timeout_millis=5000) asyncio.run(main()) ``` [**View complete example -->**](https://github.com/fiddler-labs/fiddler-examples/blob/main/quickstart/latest/Fiddler_Quickstart_Google_ADK_Integration.ipynb) ## Viewing Your Data Navigate to Fiddler UI to analyze Google ADK agent performance: 1. **Explorer** - View full span trees: agent > LLM > tool hierarchy 2. **Session Analysis** - Multi-turn conversation flows grouped by session 3. **LLM Performance** - Input/output content, token usage, latency 4. **Tool Metrics** - Tool call arguments, responses, and execution time 5. **Cost Tracking** - Token usage per agent session ### Span Types | ADK Operation | Fiddler Span Type | Content | | ------------------ | ----------------- | --------------------------------------------------------------- | | `call_llm` | LLM | User input, model output, system instructions, tool definitions | | `invoke_agent` | Agent | Agent name, session ID | | `execute_tool` | Tool | Tool arguments, tool response | | `generate_content` | Span | Token counts, model name, finish reason | | `invocation` | Span | Root span per turn | ## How It Works Google ADK emits OpenTelemetry spans natively through a tracer named `gcp.vertex.agent`. The `fiddler-adk` SDK: 1. **Sets up an isolated tracing pipeline** via `FiddlerClient` (provider, processor, OTLP exporter) and promotes it to the global tracer provider so ADK's tracer resolves to it. 2. **Propagates session identity** by backfilling `gen_ai.conversation.id` from child spans onto the root `invocation` span, ensuring all spans in a turn share the same session ID. 3. **Delegates content extraction to the Fiddler backend**, which parses ADK's JSON span attributes (`gcp.vertex.agent.llm_request`, etc.) into human-readable fields. The SDK operates in standalone mode -- it does not interact with customer-configured tracers or providers. ## Troubleshooting ### Traces Not Appearing in Fiddler **Verify credentials:** ```python theme={null} from fiddler_otel import FiddlerClient client = FiddlerClient( api_key="YOUR_KEY", application_id="YOUR_APP_UUID", url="https://your-instance.com", ) # If credentials are wrong, you'll see 401 errors in logs ``` **Check instrumentation is active:** ```python theme={null} import logging logging.basicConfig(level=logging.INFO) # Look for: "Google ADK instrumentation enabled" ``` **Ensure traces are flushed before exit:** ```python theme={null} # ADK agents run async — ensure flush before process exits client.force_flush(timeout_millis=10000) ``` ### Missing Content on Spans Content extraction (LLM input/output, tool I/O) is handled by the Fiddler backend. If you see raw JSON instead of extracted text, ensure your Fiddler instance has the Google ADK backend mapper deployed. ### Orphan Root Spans If `invocation` root spans appear disconnected from their children, update to the latest `fiddler-adk` version. The `ADKSpanProcessor` backfills `gen_ai.conversation.id` to root spans automatically. ## Related Documentation * [**Google ADK Quick Start**](/developers/quick-starts/google-adk-quick-start) - Detailed setup guide * [**Fiddler Evals SDK**](/integrations/agentic-ai/evals-sdk) - Evaluate agent quality * [**Google ADK SDK Reference**](/sdk-api/adk/google-adk-instrumentor) - Complete class and method documentation # Kong AI Gateway Integration Source: https://docs.fiddler.ai/integrations/agentic-ai/kong-integration Integrate Kong AI Gateway with Fiddler for zero-instrumentation LLM observability — no application code changes required. ## Overview [Kong AI Gateway](https://konghq.com/products/kong-ai-gateway) (v3.13+) is an API gateway with built-in AI proxy and OpenTelemetry support. Fiddler integrates with Kong at the gateway layer via Kong's `opentelemetry` plugin, giving you full LLM observability — prompts, responses, token usage, latency — without adding any SDK to your application code. | Capability | Notes | | -------------------------- | ------------------------------------------------------------------------------------------ | | **Zero instrumentation** | Point your app at Kong instead of `api.openai.com` — no code changes needed | | **LLM span tracing** | Token counts, model name, latency, and content (with `log_payloads: true`) | | **Multi-provider support** | OpenAI, Anthropic, Cohere, Azure OpenAI, Google Gemini, and more via the `ai-proxy` plugin | | **Direct OTLP export** | Kong exports traces directly to Fiddler over HTTPS with auth headers | ## Architecture ```mermaid theme={null} flowchart TD A["Your app
(any language, standard OpenAI client)"] -->|points base_url at Kong :8000| B["Kong AI Gateway
(port 8000)"] B -->|proxies to OpenAI / Anthropic / …| C["LLM Provider"] B -->|OTLP/HTTPS with auth headers| D["Fiddler
(enrichment, monitoring, dashboards)"] ``` Kong exposes an OpenAI-compatible endpoint at `/openai`. Your application requires no SDK — it just calls Kong instead of the provider directly. ## Prerequisites * Fiddler account with a GenAI application already created * A running [Kong Gateway](https://konghq.com/install) **v3.13 or later** instance (Gen AI OTel attributes require 3.13) * A valid LLM provider API key (e.g. `OPENAI_API_KEY`) * Your Fiddler API key (found under organizational settings) and application UUID (found under application settings) ## Quick Start ### Step 1: Create the Kong configuration file Save the following as `kong_fiddler_config.yaml`. The `${...}` values are placeholders — you'll replace them with your actual values in Step 2. Kong does not read environment variables from its config file, so the real values must be written into the file. ```yaml theme={null} _format_version: "3.0" services: - name: openai-service host: api.openai.com port: 443 protocol: https routes: - name: openai-chat-route paths: - /openai strip_path: true plugins: - name: ai-proxy service: openai-service config: route_type: llm/v1/chat auth: header_name: Authorization header_value: "Bearer ${OPENAI_API_KEY}" model: provider: openai name: gpt-4o-mini options: max_tokens: 512 temperature: 0.7 # Set log_payloads: true to include prompt and completion text in OTel spans. # WARNING: payloads may contain PII. Disable in production unless needed. logging: log_statistics: true log_payloads: true # Session grouping: read the X-Fiddler-Conversation-Id request header and stamp # it as gen_ai.conversation.id on the request's OTel spans, so multi-turn calls # sharing one conversation id group into a single Fiddler Session. # See the "Session Grouping" section below for how this works. - name: pre-function config: access: - | local conv_id = kong.request.get_header("X-Fiddler-Conversation-Id") if conv_id and conv_id ~= "" then ngx.ctx.fiddler_conversation_id = conv_id end header_filter: - | local conv_id = ngx.ctx.fiddler_conversation_id if conv_id then local spans = ngx.ctx.KONG_SPANS if spans then for _, span in ipairs(spans) do span:set_attribute("gen_ai.conversation.id", conv_id) end end end - name: opentelemetry config: traces_endpoint: "${FIDDLER_URL}/v1/traces" headers: Authorization: "Bearer ${FIDDLER_API_KEY}" fiddler-application-id: "${FIDDLER_APP_ID}" resource_attributes: service.name: kong application.id: "${FIDDLER_APP_ID}" propagation: default_format: w3c ``` `service.name: kong` in `resource_attributes` is required — Fiddler uses this value to recognize and correctly process Kong spans. `application.id` is also required; spans without it are silently dropped. ### Step 2: Replace the placeholders with your values Kong does **not** read environment variables from its declarative config, so open `kong_fiddler_config.yaml` and replace each `${...}` placeholder with your actual value: | Placeholder | Replace with | | -------------------- | ------------------------------------------------------------------- | | `${OPENAI_API_KEY}` | Your OpenAI API key | | `${FIDDLER_URL}` | Your Fiddler instance URL (e.g. `https://your-instance.fiddler.ai`) | | `${FIDDLER_API_KEY}` | Your Fiddler API key | | `${FIDDLER_APP_ID}` | Your Fiddler application UUID | The file now contains secrets — do not commit it. Apply it to your Kong instance the way you already manage Kong configuration — a DB-less declarative file, [decK](https://docs.konghq.com/deck/), the Admin API, or your Helm chart's config. If you already have a Kong declarative config, you do not need to replace your existing file. Copy just the three plugin entries (`ai-proxy`, `pre-function`, `opentelemetry`) and add them under your existing `plugins:` block. The `services:` and `routes:` blocks in the example above are only needed if you do not already have an OpenAI route configured. If any `${...}` placeholder is left unreplaced, Kong fails to start with errors like `'traces_endpoint': missing host in url` — Kong's declarative loader does not interpolate environment variables. ### Step 3: Enable tracing on Kong The `opentelemetry` plugin only emits spans if Kong's tracing is enabled at the process level. These three settings **cannot** be set in the declarative config — set them wherever your Kong reads its configuration (`kong.conf`, `KONG_*` environment variables, or your Helm chart's `env:` values): | Setting (`kong.conf`) | Environment variable | Value | | -------------------------- | ------------------------------- | ----- | | `tracing_instrumentations` | `KONG_TRACING_INSTRUMENTATIONS` | `all` | | `tracing_sampling_rate` | `KONG_TRACING_SAMPLING_RATE` | `1.0` | | `untrusted_lua` | `KONG_UNTRUSTED_LUA` | `on` | `tracing_instrumentations` and `tracing_sampling_rate` are what make Kong produce OTel spans at all — without them no spans are emitted regardless of the `opentelemetry` plugin config. `untrusted_lua = on` is required for the `pre-function` session-grouping plugin to run its inline Lua. ### Step 4: Point your application at Kong ```python theme={null} import os import uuid from openai import OpenAI KONG_URL = os.getenv("KONG_URL", "http://localhost:8000") # api_key is not forwarded to OpenAI — Kong handles auth via ai-proxy. client = OpenAI(base_url=f"{KONG_URL}/openai", api_key="kong-managed") # Generate one conversation UUID per session and send it on every LLM call # so Fiddler groups them into a single Session. session_id = str(uuid.uuid4()) response = client.chat.completions.create( model="gpt-4o-mini", messages=[{"role": "user", "content": "What is the capital of France?"}], extra_headers={"X-Fiddler-Conversation-Id": session_id}, ) print(response.choices[0].message.content) ``` Traces appear in Fiddler automatically — no SDK import, no callback registration, no changes to your application logic. To override the default Kong URL, set `KONG_URL` (defaults to `http://localhost:8000`): ```bash theme={null} export KONG_URL="http://my-kong-host:8000" ``` ### Step 5: Verify traces are arriving Open the Fiddler UI and navigate to your application's **Explorer**. You should see the trace within a few seconds of making your first completion call. ## Span Type Mapping Fiddler classifies Kong spans based on the span name and `gen_ai.operation.name`. Kong 3.13 names LLM spans `"{operation} {model}"` (e.g. `"chat gpt-4o-mini"`). All infrastructure spans start with `"kong"`. | Kong span | Fiddler treatment | | --------------------------------------------------------------------------- | ------------------------ | | `"chat {model}"`, `"text_completion {model}"`, `"generate_content {model}"` | `llm` (forwarded) | | `kong` (root HTTP span) | dropped (infrastructure) | | `kong.router` | dropped (infrastructure) | | `kong.access.plugin.ai-proxy` | dropped (infrastructure) | | `kong.dns`, `kong.balancer` | dropped (infrastructure) | | Any other span starting with `"kong"` | dropped (infrastructure) | Kong emits a span hierarchy per request: a root HTTP span (`kong`), routing and plugin spans (all starting with `kong.`), and the LLM Gen AI span (named `"{operation} {model}"`). Only the **LLM span** is forwarded to Fiddler; Kong's infrastructure spans are dropped (matching AgentGateway's LLM-only behaviour). The forwarded LLM span is re-parented to the trace root so it is not flagged as an orphan, and it carries `gen_ai.conversation.id`, so multi-turn calls sharing one conversation id group under a single Session. ## Attribute Mapping Kong follows the OTel Gen AI semantic conventions. Fiddler's mapper normalises these automatically: | Kong attribute | Fiddler treatment | | ----------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `gen_ai.provider.name` | Passed through unchanged (e.g. `"openai"`, `"anthropic"`) | | `gen_ai.request.model`, `gen_ai.response.model` | Passed through unchanged | | `gen_ai.usage.input_tokens` | Mapped to `fiddler.span.system.gen_ai.usage.input_tokens` | | `gen_ai.usage.output_tokens` | Mapped to `fiddler.span.system.gen_ai.usage.output_tokens` | | `gen_ai.usage.total_tokens` | Computed as `input + output` when absent | | `gen_ai.agent.name` | Defaulted to `` when absent | | `gen_ai.conversation.id` | Defaulted to `trace_id.hex()` when absent | | `gen_ai.input.messages` | Parsed into `gen_ai.llm.input.system` (first system message) and `gen_ai.llm.input.user` (last user message); the latter surfaces as the **Input** column (requires `log_payloads: true` on ai-proxy) | | `gen_ai.output.messages` | Parsed into `gen_ai.llm.output` (assistant message); surfaces as the **Output** column (requires `log_payloads: true` on ai-proxy) | ## Session Grouping Each Kong request is its own trace, so without a shared `gen_ai.conversation.id` Fiddler falls back to `trace_id.hex()` and every LLM call shows up as a separate Session. To group a multi-turn conversation into one Session, the **same** `gen_ai.conversation.id` must be set on each call's LLM span. Kong 3.13 has **no native conversation-id field** — it only supports W3C `traceparent` for distributed tracing. The Quick Start config above solves this with the built-in **`pre-function`** plugin (this is the approach Kong Support recommends for adding a custom attribute from a request header): * In the **`access`** phase it reads the `X-Fiddler-Conversation-Id` request header and stashes it in the per-request `ngx.ctx`. * In the **`header_filter`** phase it stamps that value as `gen_ai.conversation.id` on the request's OTel spans, *before* the `opentelemetry` plugin exports them in the `log` phase. Because only the LLM span is forwarded to Fiddler (Kong's infrastructure spans are dropped), stamping in `header_filter` is sufficient: the LLM span already exists at that point, so it always receives the conversation id. There are no later-created infrastructure spans to worry about — they are discarded by Fiddler's Kong mapper before reaching the UI. Your application just sends the same header value on every call in a conversation: ```python theme={null} import uuid conversation_id = str(uuid.uuid4()) # one per conversation client.chat.completions.create( model="gpt-4o-mini", messages=[{"role": "user", "content": "..."}], extra_headers={"X-Fiddler-Conversation-Id": conversation_id}, ) ``` **Why iterate `ngx.ctx.KONG_SPANS` instead of `kong.tracing.active_span()`?** The documented `kong.tracing.active_span()` returns the **root (`kong`) span**, which Fiddler drops as infrastructure. Fiddler keeps only Kong's Gen AI/LLM span, so the attribute must land on that span — iterating every span guarantees it does, regardless of which span is the LLM one. This approach is **verified working on Kong Gateway 3.13** (the version pinned above). `ngx.ctx.KONG_SPANS` is an internal Kong field rather than a stable public API, so re-verify session grouping after upgrading Kong. The `pre-function` plugin also requires `KONG_UNTRUSTED_LUA=on` and a sampling rate of `1.0` (so spans always exist when the plugin runs). **Alternative — application-side root span (no Kong plugin).** If you already instrument your app with the OpenTelemetry SDK, open a parent span per conversation, tag it, and let Kong nest its spans under your trace via the propagated `traceparent`. This is the pattern in Kong's [Voice AI observability cookbook](https://developer.konghq.com/cookbooks/voice-ai-observability/). It avoids the `pre-function` plugin but requires OTel SDK code in your application. ## Troubleshooting **Kong fails to start (`missing host in url` or similar)** This means the config still contains `${...}` placeholders. Kong does not read environment variables — open `kong_fiddler_config.yaml` and replace every `${...}` with your actual value (see [Step 2](#step-2-replace-the-placeholders-with-your-values)). **Traces not appearing in Fiddler** Verify `kong_fiddler_config.yaml` has no `${...}` placeholders left (every value filled in): ```bash theme={null} grep '\${' kong_fiddler_config.yaml # prints nothing when fully filled in ``` Also confirm Kong is emitting spans at all — check your Kong logs for OpenTelemetry export activity (for example, `grep -i otel` over your Kong proxy/error logs). Both `application.id` (OTel resource attribute) and `fiddler-application-id` (HTTP header on the export request) are required. If either is missing or does not match a valid Fiddler application UUID, spans are silently dropped. **Prompt and response content not showing** `log_payloads: true` is required in the `ai-proxy` plugin `logging` config. Without it, `gen_ai.input.messages` and `gen_ai.output.messages` are not captured by Kong, so Fiddler will show token counts and model info but no text content. **Spans not being emitted by Kong** Confirm tracing is enabled at the Kong process level (see [Step 3](#step-3-enable-tracing-on-kong)): `tracing_instrumentations=all` and `tracing_sampling_rate=1.0`, set as `kong.conf` settings or `KONG_*` environment variables. These cannot be configured via the declarative config file. **Span type showing as Unknown** Fiddler routes spans to the Kong mapper when `service.name == "kong"` on the OTel resource. Verify the `resource_attributes` block in the `opentelemetry` plugin config has `service.name: kong` (exact string match, case-sensitive). ## Known Limitations | Limitation | Details | | ------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Content requires payload logging** | Prompt and completion text are only captured when `log_payloads: true` is set on the `ai-proxy` plugin. This may expose PII — disable in production if needed. | | **Session grouping relies on a `pre-function` plugin** | Kong has no native conversation-id field, so the Quick Start config uses a `pre-function` plugin to map the `X-Fiddler-Conversation-Id` header onto spans (requires `KONG_UNTRUSTED_LUA=on`). It reads spans from the internal `ngx.ctx.KONG_SPANS` — verified working on Kong 3.13, but re-verify after Kong upgrades since this is not a stable public API. See [Session Grouping](#session-grouping). | | **Kong Gateway 3.13+ required** | Gen AI semantic convention attributes (`gen_ai.*`) are only emitted by Kong 3.13+. Earlier versions emit only HTTP-level spans. | ## Related Documentation * [AgentGateway Integration](/integrations/agentic-ai/agentgateway-integration) — Fiddler observability via the AgentGateway proxy * [LiteLLM Integration](/integrations/agentic-ai/litellm-integration) — Fiddler observability via the LiteLLM proxy gateway * [OpenTelemetry Integration](/integrations/agentic-ai/opentelemetry-integration) — Manual OTel instrumentation for custom frameworks * [OTel Trace Export](/integrations/agentic-ai/otel-trace-export) — Direct OTLP export to Fiddler without a proxy * [Kong AI Gateway documentation](https://docs.konghq.com/gateway/latest/ai-gateway/) — Official Kong AI Gateway docs # Fiddler LangChain SDK Source: https://docs.fiddler.ai/integrations/agentic-ai/langchain-sdk Instrument LangChain V1 agents with Fiddler observability # Fiddler LangChain SDK [![PyPI](https://img.shields.io/pypi/v/fiddler-langchain)](https://pypi.org/project/fiddler-langchain/) Instrument your LangChain V1 agents built with `langchain.agents.create_agent` for comprehensive agentic observability. The Fiddler LangChain SDK produces a clean, flat trace hierarchy — agent → LLM calls → tool calls — with no noisy Chain wrappers. One call to `FiddlerLangChainInstrumentor.instrument()` auto-traces every agent in your application. **Using LangChain prior to v1?** The `fiddler-langchain` SDK requires LangChain v1 (`langchain.agents.create_agent` API). For applications using earlier LangChain versions or LangGraph workflows, use the [Fiddler LangGraph SDK](/integrations/agentic-ai/langgraph-sdk) instead — it covers both LangGraph and earlier LangChain-based agents. ## What you'll need * Fiddler account (cloud or on-premises) * Python 3.10-3.14 * LangChain V1 application using `langchain.agents.create_agent` * Fiddler API key and application ID ## Quick start Get monitoring in 4 steps: ```bash theme={null} # Step 1: Install pip install fiddler-langchain ``` ```python theme={null} # Step 2: Initialize the Fiddler client import langchain.agents from langchain_openai import ChatOpenAI from fiddler_otel import FiddlerClient from fiddler_langchain import FiddlerLangChainInstrumentor client = FiddlerClient( application_id='your-app-id', # Must be valid UUID4 api_key='your-api-key', url='https://your-instance.fiddler.ai' ) # Step 3: Instrument (patches create_agent globally) FiddlerLangChainInstrumentor(client=client).instrument() # Step 4: Create your agent — Fiddler middleware is injected automatically agent = langchain.agents.create_agent( model=ChatOpenAI(model='gpt-4o-mini'), tools=[...], name='my_agent', # Optional — label this agent in traces ) result = agent.invoke({'messages': [{'role': 'user', 'content': 'Hello!'}]}) ``` That's it! Your agent traces are now flowing to Fiddler. **Important:** Use `langchain.agents.create_agent` (the module attribute), not `from langchain.agents import create_agent`. Call `instrument()` before importing `create_agent` if you use the `from ... import` style so the local name is bound to the patched version. ## What gets monitored ### Trace hierarchy Each agent invocation produces a clean, flat trace with no noisy Chain wrappers: ``` [Span] my_agent (Agent root - TYPE=agent) └── [Span] gpt-4o-mini (LLM call - TYPE=llm) └── [Span] search_docs (Tool call - TYPE=tool) └── [Span] gpt-4o-mini (LLM call - TYPE=llm) ``` ### Captured data **Agent root span:** * Agent name and agent ID * Conversation ID (if set via `set_conversation_id()`) **LLM spans (per model invocation):** * Model name and provider * System prompt and user prompt (last human message) * Full input message history (`gen_ai.input.messages`) * LLM completion and output messages (`gen_ai.output.messages`) * Token usage (input, output, total) * LLM context (if set via `set_llm_context()`) * Available tool definitions **Tool spans (per tool call):** * Tool name, input arguments, and output ## Application setup Before instrumenting your application, you must create an application in Fiddler and obtain your Application ID. ### 1. Create your application in Fiddler Log in to your Fiddler instance and navigate to **GenAI Applications**, then click **Add Application** and follow the onboarding wizard to create your application. ### 2. Copy your Application ID After creating your application, copy the **Application ID** from the GenAI Applications page. This must be a valid UUID4 format (for example, `550e8400-e29b-41d4-a716-446655440000`). You'll need this for initialization. ### 3. Get your API key Go to **Settings** > **Credentials** and copy your API key. You'll need this for initialization. ## Detailed setup ### Installation ```bash theme={null} pip install fiddler-langchain ``` **Framework Compatibility:** * **LangChain V1:** `>= 1.0.0` — agents built with `langchain.agents.create_agent` * **Python:** 3.10-3.14 * **fiddler-otel:** `>= 1.0.0` (installed automatically) * **OpenTelemetry:** API and SDK `>= 1.27.0` (installed automatically) ### Configuration #### Direct initialization (Recommended) ```python theme={null} import langchain.agents from fiddler_otel import FiddlerClient from fiddler_langchain import FiddlerLangChainInstrumentor client = FiddlerClient( application_id='your-app-id', # Required (UUID4 format) api_key='your-api-key', # Required when otlp_enabled=True (default) url='https://your-instance.fiddler.ai' # Required when otlp_enabled=True (default) ) instrumentor = FiddlerLangChainInstrumentor(client=client) instrumentor.instrument() ``` #### Using environment variables ```python theme={null} import os import langchain.agents from fiddler_otel import FiddlerClient from fiddler_langchain import FiddlerLangChainInstrumentor client = FiddlerClient( application_id=os.getenv('FIDDLER_APPLICATION_ID'), api_key=os.getenv('FIDDLER_API_KEY'), url=os.getenv('FIDDLER_URL') ) FiddlerLangChainInstrumentor(client=client).instrument() ``` **Environment Variables Reference:** | Variable | Description | Example | | ------------------------ | ------------------------- | -------------------------------------- | | `FIDDLER_API_KEY` | Your Fiddler API key | `fid_...` | | `FIDDLER_APPLICATION_ID` | Your application UUID4 | `550e8400-e29b-41d4-a716-446655440000` | | `FIDDLER_URL` | Your Fiddler instance URL | `https://your-instance.fiddler.ai` | ## Instrumentation methods The Fiddler LangChain SDK provides two instrumentation approaches: | Approach | Best For | Key API | | --------------------------------------------- | ---------------------------- | ------------------------------ | | [Auto-Instrumentation](#auto-instrumentation) | All agents in an application | `FiddlerLangChainInstrumentor` | | [Manual Middleware](#manual-middleware) | Per-agent control | `FiddlerAgentMiddleware` | ### Auto-instrumentation `FiddlerLangChainInstrumentor.instrument()` monkey-patches `langchain.agents.create_agent` once. Every subsequent call to `create_agent()` automatically receives a `FiddlerAgentMiddleware`. No changes to individual agent creation calls are needed. ```python theme={null} import langchain.agents from langchain_openai import ChatOpenAI from fiddler_otel import FiddlerClient from fiddler_langchain import FiddlerLangChainInstrumentor client = FiddlerClient(application_id='...', api_key='...', url='...') # Instrument once at startup instrumentor = FiddlerLangChainInstrumentor(client=client) instrumentor.instrument() # All agents created after this point are automatically traced agent1 = langchain.agents.create_agent( model=ChatOpenAI(model='gpt-4o-mini'), tools=[search_tool], name='search_agent', ) agent2 = langchain.agents.create_agent( model=ChatOpenAI(model='gpt-4o-mini'), tools=[booking_tool], name='booking_agent', ) ``` **Key behaviors:** * **Idempotent:** Calling `instrument()` multiple times is safe — it will not create duplicate middleware. * **Agent naming:** If `name='...'` is passed to `create_agent()`, that name is used for the agent in traces. If omitted, no agent name is set and the agent appears without a label in the UI. * **Existing middleware preserved:** If you pass a `FiddlerAgentMiddleware` instance manually in `middleware=[...]`, the instrumentor skips injection for that call so your manual configuration is preserved. **Uninstrumenting:** ```python theme={null} # Restore original create_agent (agents already created keep their middleware) instrumentor.uninstrument() ``` ### Manual middleware For per-agent control, pass `FiddlerAgentMiddleware` directly to `create_agent()` without using the instrumentor: ```python theme={null} import langchain.agents from langchain_openai import ChatOpenAI from fiddler_otel import FiddlerClient from fiddler_langchain import FiddlerAgentMiddleware client = FiddlerClient(application_id='...', api_key='...', url='...') agent = langchain.agents.create_agent( model=ChatOpenAI(model='gpt-4o-mini'), tools=[search_tool], name='my_agent', middleware=[FiddlerAgentMiddleware(client=client, agent_name='my_agent')], ) ``` Use manual middleware when you want to trace only specific agents, or when you need different configurations per agent. ## Advanced usage ### Multi-turn conversations Use `set_conversation_id()` to link multiple agent invocations into a single conversation in the Fiddler UI. All agents in the application that share the same `conversation_id` appear together in conversation-level views. ```python theme={null} from fiddler_langchain import set_conversation_id import uuid # Call once per conversation set_conversation_id(str(uuid.uuid4())) # All agent invocations after this carry the same conversation_id result1 = agent.invoke({'messages': [{'role': 'user', 'content': 'Find hotels in Tokyo.'}]}) result2 = agent.invoke({'messages': [{'role': 'user', 'content': 'Book the cheapest one.'}]}) ``` ### LLM context Attach contextual metadata to LLM spans by calling `set_llm_context()` before the agent runs. The instrumentation reads this value from the model's metadata at invocation time and records it as `gen_ai.llm.context` on every LLM span for that model. ```python theme={null} import langchain.agents from langchain_openai import ChatOpenAI from fiddler_otel import FiddlerClient from fiddler_langchain import FiddlerLangChainInstrumentor, set_llm_context client = FiddlerClient(application_id='...', api_key='...', url='...') FiddlerLangChainInstrumentor(client=client).instrument() model = ChatOpenAI(model='gpt-4o-mini') set_llm_context(model, 'User profile: enterprise customer, prefers concise answers') agent = langchain.agents.create_agent(model=model, tools=[...], name='my_agent') ``` `set_llm_context()` accepts both plain model instances (`BaseLanguageModel`) and `RunnableBinding` instances (for example, models wrapped with `.with_config()` or `.bind_tools()`). #### Clearing LLM context for non-RAG steps In multi-step agent workflows, context set after a RAG retrieval step leaks into subsequent non-RAG LLM calls (tool planning, routing, etc.), causing unintended faithfulness evaluation. Use `clear_llm_context()` to explicitly remove context before non-RAG steps: ```python theme={null} from fiddler_langchain import set_llm_context, clear_llm_context # After RAG retrieval — attach context for faithfulness evaluation set_llm_context(model, retrieved_documents) response = agent.invoke(rag_prompt) # faithfulness evaluated # Before non-RAG steps — clear context to skip faithfulness evaluation clear_llm_context(model) plan = agent.invoke(planning_prompt) # no faithfulness evaluation ``` `clear_llm_context(model)` is equivalent to `set_llm_context(model, None)`. ### Span-level attributes Use `add_span_attributes()` to attach custom metadata to a specific LangChain component (model, tool, or retriever). The middleware reads these attributes when creating the span for that component and records them as `fiddler.span.user.{key}`. ```python theme={null} import langchain.agents from langchain_openai import ChatOpenAI from langchain_core.tools import tool from fiddler_otel import FiddlerClient from fiddler_langchain import FiddlerLangChainInstrumentor, add_span_attributes client = FiddlerClient(application_id='...', api_key='...', url='...') FiddlerLangChainInstrumentor(client=client).instrument() # Add attributes to a specific model — appear only on that model's LLM spans model = ChatOpenAI(model='gpt-4o-mini') add_span_attributes(model, model_version='v2', cost_center='cc-123') # Add attributes to a specific tool — appear only on that tool's spans @tool def search_hotels(query: str) -> str: """Search for hotels.""" return f'Hotels for: {query}' add_span_attributes(search_hotels, category='travel', region='apac') agent = langchain.agents.create_agent(model=model, tools=[search_hotels], name='my_agent') ``` Unlike `add_session_attributes` (which applies to every span in the context), `add_span_attributes` is scoped to a single component. ### Session attributes Use `add_session_attributes()` to attach metadata that appears on **every span** created in the current thread or async coroutine. Use this for user-level or environment-level metadata that applies to the whole session. ```python theme={null} import langchain.agents from fiddler_otel import FiddlerClient from fiddler_langchain import FiddlerLangChainInstrumentor, add_session_attributes client = FiddlerClient(application_id='...', api_key='...', url='...') FiddlerLangChainInstrumentor(client=client).instrument() # Set once — applies to all spans in this context (emitted as fiddler.session.user.{key}) add_session_attributes('user_id', 'user_12345') add_session_attributes('environment', 'production') add_session_attributes('tier', 'premium') agent = langchain.agents.create_agent(model=ChatOpenAI(model='gpt-4o-mini'), tools=[...], name='my_agent') agent.invoke({'messages': [{'role': 'user', 'content': 'Hello!'}]}) ``` ### Retriever instrumentation The LangChain V1 middleware does not expose a dedicated retriever hook. Following the same convention used in `fiddler-langgraph`, **retrievers are treated as tools**. Wrap your retriever with `@tool` (or use `create_retriever_tool`) and pass it to `create_agent`. The middleware's tool hook captures the retriever call automatically as a `TYPE=tool` span — with the query as `tool_input` and the retrieved documents as `tool_output`. ```python theme={null} import langchain.agents from langchain_core.tools import tool from fiddler_otel import FiddlerClient from fiddler_langchain import FiddlerLangChainInstrumentor client = FiddlerClient(application_id='...', api_key='...', url='...') FiddlerLangChainInstrumentor(client=client).instrument() retriever = vector_store.as_retriever() @tool def search_docs(query: str) -> str: """Search company documents for relevant information.""" return str(retriever.invoke(query)) agent = langchain.agents.create_agent( model=ChatOpenAI(model='gpt-4o-mini'), tools=[search_docs], name='rag_agent', ) ``` The resulting trace: ``` [Span] rag_agent (Agent root - TYPE=agent) └── [Span] gpt-4o-mini (LLM call - TYPE=llm) └── [Span] search_docs (Retriever as Tool - TYPE=tool) └── [Span] gpt-4o-mini (LLM call - TYPE=llm) ``` ### Multi-agent setup With the instrumentor, a single `instrument()` call patches `create_agent` so every agent is traced. Pass `name='...'` to each `create_agent()` to label agents in traces. When a sub-agent is invoked from within a delegation tool, its root Agent span is automatically created as a **child of the tool span** — the entire multi-agent flow appears in a **single trace**. No manual linking is needed: `wrap_tool_call` attaches the active tool span into the OTel context before invoking the handler, and `before_agent` detects that active span and nests under it. ```python theme={null} import langchain.agents from langchain_openai import ChatOpenAI from langchain_core.tools import tool from fiddler_otel import FiddlerClient from fiddler_langchain import FiddlerLangChainInstrumentor client = FiddlerClient(application_id='...', api_key='...', url='...') FiddlerLangChainInstrumentor(client=client).instrument() # Sub-agents flight_agent = langchain.agents.create_agent( model=ChatOpenAI(model='gpt-4o-mini'), tools=[book_flight], name='flight_assistant', ) hotel_agent = langchain.agents.create_agent( model=ChatOpenAI(model='gpt-4o-mini'), tools=[search_hotel, book_hotel], name='hotel_assistant', ) # Delegation tools — the tool span becomes the parent of the sub-agent span automatically @tool def delegate_to_flight_assistant(task: str) -> str: """Delegate a flight booking task to the flight assistant.""" result = flight_agent.invoke({'messages': [{'role': 'user', 'content': task}]}) return result['messages'][-1].content @tool def delegate_to_hotel_assistant(task: str) -> str: """Delegate a hotel search and booking task to the hotel assistant.""" result = hotel_agent.invoke({'messages': [{'role': 'user', 'content': task}]}) return result['messages'][-1].content # Supervisor — invoking this produces one trace containing all agents supervisor = langchain.agents.create_agent( model=ChatOpenAI(model='gpt-4o-mini'), tools=[delegate_to_flight_assistant, delegate_to_hotel_assistant], name='supervisor', ) supervisor.invoke({'messages': [{'role': 'user', 'content': 'Book a flight and a hotel in Tokyo.'}]}) ``` Trace output (all agents appear in a **single trace**): ``` [Span] supervisor (root - TYPE=agent) └── [Span] gpt-4o-mini (LLM - TYPE=llm) └── [Span] delegate_to_flight_assistant (Tool - TYPE=tool) └── [Span] flight_assistant (Agent - TYPE=agent) └── [Span] gpt-4o-mini (LLM - TYPE=llm) └── [Span] book_flight (Tool - TYPE=tool) └── [Span] delegate_to_hotel_assistant (Tool - TYPE=tool) └── [Span] hotel_assistant (Agent - TYPE=agent) └── [Span] gpt-4o-mini (LLM - TYPE=llm) └── [Span] search_hotel (Tool - TYPE=tool) └── [Span] book_hotel (Tool - TYPE=tool) ``` `set_conversation_id()` is useful for linking **multiple top-level invocations** (e.g., multi-turn conversations) — not for joining sub-agents within a single invocation, since they already share the same trace automatically. ### Async agents The instrumentation fully supports async agents via the `awrap_model_call` and `awrap_tool_call` hooks. Use `agent.ainvoke()` — no additional configuration needed: ```python theme={null} import asyncio import langchain.agents from langchain_openai import ChatOpenAI from fiddler_otel import FiddlerClient from fiddler_langchain import FiddlerLangChainInstrumentor client = FiddlerClient(application_id='...', api_key='...', url='...') FiddlerLangChainInstrumentor(client=client).instrument() agent = langchain.agents.create_agent( model=ChatOpenAI(model='gpt-4o-mini'), tools=[...], name='my_agent', ) async def main(): result = await agent.ainvoke({'messages': [{'role': 'user', 'content': 'Hello!'}]}) print(result['messages'][-1].content) asyncio.run(main()) ``` The instrumentation automatically uses the async lifecycle hooks when the agent is invoked asynchronously, producing the same span hierarchy as the sync path. ### Error handling If an LLM call or tool call raises an exception, the instrumentation: 1. Catches the exception and marks the failing span with `StatusCode.ERROR` 2. Re-raises the exception so normal error handling in your application is unaffected 3. Cleanly closes the root agent span — no dangling open spans ```python theme={null} try: result = agent.invoke({'messages': [{'role': 'user', 'content': 'Hello!'}]}) except Exception as e: # The failing LLM or tool span is already marked ERROR in Fiddler # The root agent span is closed — all spans are recorded raise ``` This means partial traces are never lost — all spans up to the point of failure are recorded and visible in Fiddler. ### Running in AWS SageMaker Because `fiddler-langchain` exports traces through `FiddlerClient`, it inherits the Fiddler OTel SDK's [AWS SageMaker Partner App authentication](/integrations/agentic-ai/fiddler-otel-sdk#running-in-aws-sagemaker). Install the `sagemaker` extra (`pip install "fiddler-otel[sagemaker]"`) and set the `AWS_PARTNER_APP_AUTH`, `AWS_PARTNER_APP_ARN`, and `AWS_PARTNER_APP_URL` environment variables — your instrumentation code is unchanged. ### Flush and shutdown ```python theme={null} # Sync client.force_flush() client.shutdown() # Async await client.aflush() await client.ashutdown() # Context manager (calls shutdown() on exit) with FiddlerClient(application_id='...', api_key='...', url='...') as client: FiddlerLangChainInstrumentor(client=client).instrument() result = agent.invoke({'messages': [...]}) ``` ### Local debugging **JSONL file capture (save a local copy of spans in addition to Fiddler export):** `jsonl_capture_enabled=True` is **additive** — spans are saved to a local JSONL file **and** continue to be exported to Fiddler via OTLP. Setting this to `True` does **not** suppress or disable the OTLP export to Fiddler. ```python theme={null} client = FiddlerClient( application_id='...', api_key='...', url='...', jsonl_capture_enabled=True, # Saves spans locally; OTLP export to Fiddler still active jsonl_file_path='trace_data.jsonl', ) ``` Override the output file path via environment variable: ```bash theme={null} FIDDLER_JSONL_FILE=trace_data.jsonl python my_agent.py ``` Each line in the output file is a JSON object. Fields: | Field | Description | | ------------------------ | ----------------------------------- | | `trace_id` | Trace identifier | | `span_id` | Span identifier | | `parent_span_id` | Parent span identifier | | `span_type` | Span type (`agent`, `llm`, `tool`) | | `agent_name` | Name of the agent | | `conversation_id` | Conversation identifier | | `model_name` | LLM model name | | `model_provider` | LLM provider | | `llm_input_system` | System prompt | | `llm_input_user` | User prompt | | `llm_output` | LLM completion text | | `llm_context` | Context set via `set_llm_context()` | | `llm_token_count_input` | Input token count | | `llm_token_count_output` | Output token count | | `llm_token_count_total` | Total token count | | `gen_ai_input_messages` | Full input message history (JSON) | | `gen_ai_output_messages` | Output messages (JSON) | | `tool_name` | Tool/function name | | `tool_input` | Tool input arguments | | `tool_output` | Tool result | | `tool_definitions` | Available tool schemas (JSON) | ## Relationship to fiddler-langgraph | Package | Framework | Instrumentation Approach | | ------------------- | ---------------------------------- | --------------------------------------------------------------------------- | | `fiddler-langchain` | LangChain V1 (`create_agent`) | `FiddlerLangChainInstrumentor` auto-patches `langchain.agents.create_agent` | | `fiddler-langgraph` | LangGraph (`StateGraph.compile()`) | `LangGraphInstrumentor` callback handler | Both packages depend on `fiddler-otel` for the core `FiddlerClient` and span wrappers. ## What's next? * [**Fiddler OTel SDK**](/integrations/agentic-ai/fiddler-otel-sdk) — For decorator-based instrumentation of custom Python functions * [**LangGraph SDK**](/integrations/agentic-ai/langgraph-sdk) — If your application uses LangGraph * [**Agentic Observability Concepts**](/getting-started/agentic-monitoring) — Understand the agent lifecycle and monitoring approach # Fiddler LangGraph SDK Source: https://docs.fiddler.ai/integrations/agentic-ai/langgraph-sdk Instrument LangGraph agents and custom AI applications with Fiddler's native SDK [![PyPI](https://img.shields.io/pypi/v/fiddler-langgraph)](https://pypi.org/project/fiddler-langgraph/) Instrument your LangGraph agent applications and custom AI workflows with OpenTelemetry-based tracing for comprehensive agentic observability. The Fiddler LangGraph SDK provides three instrumentation approaches — auto-instrumentation for LangGraph workflows, decorator-based tracing for custom functions, and manual span creation for fine-grained control — capturing every step from thought to action to execution. ## What you'll need * Fiddler account (cloud or on-premises) * Python 3.10-3.14 * LangGraph or LangChain application * Fiddler API key and application ID ## Quick start Get monitoring in 3 steps: ```bash theme={null} # Step 1: Install pip install fiddler-langgraph ``` ```python theme={null} # Step 2: Initialize the Fiddler client from fiddler_langgraph import FiddlerClient, LangGraphInstrumentor fdl_client = FiddlerClient( application_id='your-app-id', # Must be valid UUID4 api_key='your-api-key', url='https://your-instance.fiddler.ai' ) # Step 3: Instrument your application instrumentor = LangGraphInstrumentor(fdl_client) instrumentor.instrument() # Your existing LangGraph code runs normally # Traces will automatically be sent to Fiddler ``` That's it! Your agent traces are now flowing to Fiddler. This Quick Start uses auto-instrumentation for LangGraph applications. For custom functions or fine-grained control, see [Instrumentation Methods](#instrumentation-methods) below. ## What gets monitored The LangGraph SDK automatically captures: ### Hierarchical tracing * **Application Level** - Overall system performance and health * **Session Level** - User interaction and conversation flows * **Agent Level** - Individual agent behavior and decisions * **Span Level** - Tool calls, LLM requests, state transitions ### Agent lifecycle stages Every agent operation is tracked through five observable stages: 1. **Thought** - Data ingestion, context retrieval, information interpretation 2. **Action** - Planning processes, tool selection, decision-making 3. **Execution** - Task performance, API calls, external integrations 4. **Reflection** - Self-evaluation, learning signals, adaptation 5. **Alignment** - Trust validation, safety checks, policy enforcement ### Captured data * Agent state transitions and decision points * Tool invocations with inputs and outputs * LLM API calls with prompts and responses * Execution times and latency metrics * Error traces and exception handling * Custom metadata and tags ## Application setup Before instrumenting your application, you must create an application in Fiddler and obtain your Application ID: ### 1. Create your application in Fiddler Log in to your Fiddler instance and navigate to **GenAI Applications**, then click **Add Application** and follow the onboarding wizard to create your application. GenAI Applications page with Add Application button ### 2. Copy your Application ID After creating your application, copy the **Application ID** from the GenAI Applications page using the copy icon next to the ID. This must be a valid UUID4 format (for example, `550e8400-e29b-41d4-a716-446655440000`). You'll need this for initialization. GenAI Applications page showing Application ID column with copy icons ### 3. Get your access token Go to **Settings** > **Credentials** and copy your access token. You'll need this for initialization. Fiddler Settings- Credentials tab showing admin's access token ## Detailed setup ### Installation ```bash theme={null} pip install fiddler-langgraph ``` **Framework Compatibility:** * **LangGraph:** >= 0.3.28 and \<= 1.1.0 OR **LangChain:** >= 0.3.28 and \<= 1.1.0 * **Python:** 3.10, 3.11, 3.12, or 3.13 * **OpenTelemetry:** API and SDK >= 1.28.0 and \<= 1.39.1 (installed automatically) ### Configuration #### Direct initialization (Recommended) ```python theme={null} from fiddler_langgraph import FiddlerClient, LangGraphInstrumentor fdl_client = FiddlerClient( application_id='your-app-id', # Required (UUID4 format) api_key='your-api-key', # Required url='https://your-instance.fiddler.ai' # Required ) instrumentor = LangGraphInstrumentor(fdl_client) instrumentor.instrument() ``` #### Using environment variables You can use environment variables instead of hardcoding credentials: ```python theme={null} import os from fiddler_langgraph import FiddlerClient, LangGraphInstrumentor fdl_client = FiddlerClient( application_id=os.getenv("FIDDLER_APPLICATION_ID"), api_key=os.getenv("FIDDLER_API_KEY"), url=os.getenv("FIDDLER_URL") ) instrumentor = LangGraphInstrumentor(fdl_client) instrumentor.instrument() ``` **Environment Variables Reference:** | Variable | Description | Example | | ------------------------ | ------------------------- | -------------------------------------- | | `FIDDLER_API_KEY` | Your Fiddler API key | `fid_...` | | `FIDDLER_APPLICATION_ID` | Your application UUID4 | `550e8400-e29b-41d4-a716-446655440000` | | `FIDDLER_URL` | Your Fiddler instance URL | `https://your-instance.fiddler.ai` | ## Instrumentation methods The Fiddler LangGraph SDK provides three instrumentation approaches. Choose the one that fits your application: | Approach | Best For | Key API | | --------------------------------------------------- | ---------------------------------------- | ----------------------------------------- | | [Auto-Instrumentation](#auto-instrumentation) | LangGraph and LangChain applications | `LangGraphInstrumentor` | | [Decorator-Based](#decorator-based-instrumentation) | Custom Python functions, mixed workflows | `@trace()`, `get_current_span()` | | [Manual](#manual-instrumentation) | Fine-grained span lifecycle control | `start_as_current_span()`, `start_span()` | You can combine all three approaches in the same application. For example, use auto-instrumentation for your LangGraph graph and decorators for custom helper functions that the graph calls. ### Auto-Instrumentation Auto-instrumentation captures LangGraph and LangChain workflows automatically. Initialize the instrumentor once, and all graph invocations produce traces with no additional code changes. ```python theme={null} from fiddler_langgraph import FiddlerClient, LangGraphInstrumentor client = FiddlerClient( application_id="your-app-id", api_key="your-api-key", url="https://your-instance.fiddler.ai" ) instrumentor = LangGraphInstrumentor(client) instrumentor.instrument() # Your LangGraph/LangChain code runs normally — traces are captured automatically ``` **When to use:** Your application uses LangGraph `StateGraph` or LangChain runnables and you want comprehensive tracing with zero instrumentation code. See the [Quick Start](#quick-start) section above for a complete walkthrough, or the [Advanced Usage](#advanced-usage) section for context enrichment and production configuration. ### Decorator-based instrumentation Use the `@trace()` decorator to instrument individual Python functions. This is the recommended approach for custom functions that are not part of a LangGraph graph, such as standalone LLM calls, tool implementations, or orchestration logic. ```python theme={null} from openai import OpenAI from fiddler_langgraph import FiddlerClient, trace, get_current_span client = FiddlerClient( application_id="your-app-id", api_key="your-api-key", url="https://your-instance.fiddler.ai" ) openai_client = OpenAI() # Assumes OPENAI_API_KEY is set in environment # vector_store: a pre-configured vector database client (e.g., Pinecone, Chroma, Weaviate) @trace(as_type="generation", model="gpt-4o", system="openai") def call_llm(prompt: str) -> str: span = get_current_span(as_type="generation") if span: span.set_user_prompt(prompt) response = openai_client.chat.completions.create( model="gpt-4o", messages=[{"role": "user", "content": prompt}] ) result = response.choices[0].message.content if span: span.set_completion(result) return result @trace(as_type="tool", name="search_knowledge_base") def search_kb(query: str) -> list[str]: span = get_current_span(as_type="tool") if span: span.set_tool_input({"query": query}) results = vector_store.search(query) if span: span.set_tool_output(results) return results @trace(name="handle_request") def handle_request(user_input: str) -> str: context = search_kb(user_input) # Child span (tool) response = call_llm(user_input) # Child span (generation) return response # Parent span auto-closes ``` **When to use:** You have custom Python functions — LLM wrappers, tool implementations, or orchestration logic — that you want to trace with full control over span metadata. #### `@trace()` Arguments | Argument | Type | Default | Description | | ---------------- | --------------- | ------------- | ------------------------------------------------------------------------------------- | | `name` | `str` | Function name | Custom span name | | `as_type` | `str` | `"span"` | Span type: `"span"`, `"generation"`, `"chain"`, or `"tool"` | | `capture_input` | `bool` | `True` | Automatically capture function arguments as span input | | `capture_output` | `bool` | `True` | Automatically capture return value as span output | | `model` | `str` | `None` | LLM model name (sets `gen_ai.request.model`) | | `system` | `str` | `None` | LLM provider such as `"openai"` or `"anthropic"` (sets `gen_ai.system`) | | `user_id` | `str` | `None` | User identifier | | `version` | `str` | `None` | Service version string | | `client` | `FiddlerClient` | `None` | Explicit client instance (defaults to the [global singleton](#global-client-pattern)) | #### Accessing the current span Inside a decorated function, call `get_current_span()` to access the active span and add metadata: ```python theme={null} from fiddler_langgraph import get_current_span @trace(as_type="generation") def my_llm_call(prompt: str) -> str: span = get_current_span(as_type="generation") if span: span.set_user_prompt(prompt) span.set_model("gpt-4o") span.set_system("openai") # ... make your LLM call ... if span: span.set_completion(result) span.set_usage(input_tokens=50, output_tokens=120) return result ``` Pass `as_type` to get a type-specific wrapper with semantic helper methods. See [Span Types and Helper Methods](#span-types-and-helper-methods) for the full list. Always check `if span:` before calling helper methods. `get_current_span()` returns `None` if no Fiddler span is active — for example, during unit tests or when the client is not initialized. #### Async support The `@trace()` decorator works with both sync and async functions. No additional configuration is needed: ```python theme={null} @trace(as_type="generation", model="gpt-4o", system="openai") async def async_llm_call(prompt: str) -> str: span = get_current_span(as_type="generation") if span: span.set_user_prompt(prompt) response = await openai_client.chat.completions.create( model="gpt-4o", messages=[{"role": "user", "content": prompt}] ) result = response.choices[0].message.content if span: span.set_completion(result) return result ``` #### Automatic parent-child relationships Nested decorated functions create proper span hierarchies automatically. The outer function becomes the parent span, and inner calls become child spans: ```python theme={null} @trace(name="agent_workflow", as_type="chain") def run_agent(query: str) -> str: context = retrieve_docs(query) # Child span answer = generate_answer(context) # Child span return answer # Parent span @trace(as_type="tool") def retrieve_docs(query: str) -> list[str]: # Automatically a child of "agent_workflow" return vector_db.search(query) @trace(as_type="generation", model="gpt-4o") def generate_answer(context: list[str]) -> str: # Also a child of "agent_workflow" return llm.generate(context) ``` ### Manual instrumentation Create spans manually using context managers or explicit start/end calls. This gives you full control over span lifecycle — useful for dynamic span creation, conditional instrumentation, or code where decorator syntax does not apply. #### Context manager (automatic lifecycle) Use `start_as_current_span()` to create a span that ends automatically when the block exits: ```python theme={null} from openai import OpenAI from fiddler_langgraph import FiddlerClient openai_client = OpenAI() # Assumes OPENAI_API_KEY is set in environment client = FiddlerClient( application_id="your-app-id", api_key="your-api-key", url="https://your-instance.fiddler.ai" ) with client.start_as_current_span("llm_call", as_type="generation") as span: span.set_model("gpt-4o") span.set_system("openai") span.set_user_prompt("What is the capital of France?") response = openai_client.chat.completions.create( model="gpt-4o", messages=[{"role": "user", "content": "What is the capital of France?"}] ) span.set_completion(response.choices[0].message.content) span.set_usage( input_tokens=response.usage.prompt_tokens, output_tokens=response.usage.completion_tokens ) # Span ends automatically here ``` #### Explicit span control Use `start_span()` when you need to manage span lifecycle manually — for example, in callback-driven or event-based code: ```python theme={null} span = client.start_span("background_task", as_type="tool") try: span.set_tool_name("data_processor") span.set_tool_input({"file": "data.csv"}) result = process_file("data.csv") span.set_tool_output(result) finally: span.end() # Must call end() explicitly ``` Always call `span.end()` when using `start_span()`. Forgetting to end a span causes a resource leak. Prefer `start_as_current_span()` unless you need explicit lifecycle control. **When to use:** You need explicit control over when spans start and end — for example, in callback-driven code, conditional spans, or complex control flow where decorators do not fit. ### Span types and helper methods Both decorator and manual instrumentation support four span types. Set the `as_type` parameter to select a type, which determines which semantic helper methods are available on the span wrapper. | Type | Wrapper Class | Use For | | -------------- | ------------------- | --------------------------------------------- | | `"span"` | `FiddlerSpan` | Generic operations, orchestration | | `"generation"` | `FiddlerGeneration` | LLM calls (prompts, completions, token usage) | | `"chain"` | `FiddlerChain` | Multi-step workflows, processing chains | | `"tool"` | `FiddlerTool` | Tool or function calls (name, input, output) | #### Common methods (all types) | Method | Description | | ----------------------------- | --------------------------------------------------------- | | `set_input(data)` | Set input data (auto-serializes dicts and lists to JSON) | | `set_output(data)` | Set output data (auto-serializes dicts and lists to JSON) | | `set_attribute(key, value)` | Set a custom span attribute | | `set_agent_name(name)` | Set the agent name (`gen_ai.agent.name`) | | `set_agent_id(id)` | Set the agent ID (`gen_ai.agent.id`) | | `set_conversation_id(id)` | Set the conversation ID (`gen_ai.conversation.id`) | | `record_exception(exception)` | Record an error on the span | #### Generation methods (`FiddlerGeneration`) | Method | Sets Attribute | | ------------------------------------------------------ | ------------------------- | | `set_model(name)` | `gen_ai.request.model` | | `set_system(provider)` | `gen_ai.system` | | `set_system_prompt(text)` | `gen_ai.llm.input.system` | | `set_user_prompt(text)` | `gen_ai.llm.input.user` | | `set_completion(text)` | `gen_ai.llm.output` | | `set_usage(input_tokens, output_tokens, total_tokens)` | `gen_ai.usage.*` | | `set_context(text)` | `gen_ai.llm.context` | | `set_messages(messages)` | `gen_ai.input.messages` | | `set_output_messages(messages)` | `gen_ai.output.messages` | | `set_tool_definitions(definitions)` | `gen_ai.tool.definitions` | #### Tool methods (`FiddlerTool`) | Method | Sets Attribute | | ----------------------------------- | ------------------------- | | `set_tool_name(name)` | `gen_ai.tool.name` | | `set_tool_input(data)` | `gen_ai.tool.input` | | `set_tool_output(data)` | `gen_ai.tool.output` | | `set_tool_definitions(definitions)` | `gen_ai.tool.definitions` | For complete API documentation, see the LangGraph SDK API Reference. ## Context isolation The Fiddler LangGraph SDK maintains its own isolated OpenTelemetry context. Fiddler traces do not interfere with other OpenTelemetry tracers that may be active in your application, and vice versa. Each `FiddlerClient` creates a private `Context` instance. All span creation, parent-child linking, and context propagation happen within this isolated context. When you use `@trace()`, `start_as_current_span()`, or `start_span()`, the SDK manages context attachment and detachment automatically. You can verify whether a span belongs to Fiddler using `is_fiddler_span()`: ```python theme={null} from fiddler_otel.utils import is_fiddler_span from opentelemetry import trace otel_span = trace.get_current_span() if is_fiddler_span(otel_span): print("This span belongs to Fiddler") ``` This isolation matters if your application uses other OpenTelemetry-based observability tools (such as Datadog, Honeycomb, or custom OTel exporters). Fiddler traces remain completely separate, so you can run multiple tracing systems side by side without conflicts. ## Global client pattern The Fiddler SDK uses a singleton pattern for `FiddlerClient`. The first client created in your process is automatically registered as the global default. Retrieve it anywhere using `get_client()`: ```python theme={null} from fiddler_langgraph import FiddlerClient, get_client # Initialize once (automatically registered as global singleton) client = FiddlerClient( application_id="your-app-id", api_key="your-api-key", url="https://your-instance.fiddler.ai" ) # Retrieve anywhere in your application def some_utility_function(): fdl_client = get_client() # Returns the same client instance with fdl_client.start_as_current_span("utility_op") as span: span.set_attribute("source", "utility") # ... your logic ... ``` The `@trace()` decorator uses `get_client()` internally, so you do not need to pass a client to each decorated function. As long as a `FiddlerClient` has been created somewhere in your application, all `@trace()` decorators and `get_current_span()` calls work automatically. There is no `set_current_client()` function. The singleton is set automatically during `FiddlerClient` initialization. If you create multiple clients, only the first one becomes the global default. Pass an explicit `client` argument to `@trace()` to use a different client. ## Advanced usage ### Adding context and metadata Enrich traces with custom context and conversation tracking: ```python theme={null} from fiddler_langgraph import set_llm_context, clear_llm_context, set_conversation_id import uuid # Set descriptive context for LLM processing set_llm_context(model, 'Customer support conversation') # Set conversation ID for tracking multi-turn conversations conversation_id = str(uuid.uuid4()) set_conversation_id(conversation_id) ``` #### Clearing LLM context for non-RAG steps In multi-step agent workflows, context set after a RAG retrieval step leaks into subsequent non-RAG LLM calls (tool planning, routing, etc.), causing unintended faithfulness evaluation. Use `clear_llm_context()` to explicitly remove context before non-RAG steps: ```python theme={null} from fiddler_langgraph import set_llm_context, clear_llm_context # After RAG retrieval — attach context for faithfulness evaluation set_llm_context(llm, retrieved_documents) response = llm.invoke(rag_prompt) # faithfulness evaluated # Before non-RAG steps — clear context to skip faithfulness evaluation clear_llm_context(llm) plan = llm.invoke(planning_prompt) # no faithfulness evaluation ``` `clear_llm_context(llm)` is equivalent to `set_llm_context(llm, None)`. ### Custom span and session attributes Add custom attributes to individual spans or entire sessions: ```python theme={null} from fiddler_langgraph import add_span_attributes, add_session_attributes # Add attributes to specific spans add_span_attributes({ "user_id": "user_123", "request_type": "billing_inquiry" }) # Add attributes that persist across all spans in a session add_session_attributes({ "session_type": "premium", "feature_flags": ["new_ui", "advanced_mode"] }) ``` ### Sampling configuration Control trace sampling for high-volume applications: ```python theme={null} from opentelemetry.sdk.trace import sampling from fiddler_langgraph import FiddlerClient, LangGraphInstrumentor # Sample 10% of traces sampler = sampling.TraceIdRatioBased(0.1) fdl_client = FiddlerClient( application_id="your-app-id", api_key="your-api-key", url="https://your-instance.fiddler.ai", sampler=sampler ) instrumentor = LangGraphInstrumentor(fdl_client) instrumentor.instrument() ``` For production deployments, consider these sampling strategies: * **High-volume applications:** Sample 5-10% (`TraceIdRatioBased(0.05)`) * **Development/testing:** Sample 100% (default - no sampler specified) * **Cost optimization:** Sample 1-5% (`TraceIdRatioBased(0.01)`) ### Production configuration For high-volume production applications, configure span limits and batch processing: ```python theme={null} import os from opentelemetry.sdk.trace import SpanLimits, sampling from opentelemetry.exporter.otlp.proto.http.trace_exporter import Compression from fiddler_langgraph import FiddlerClient, LangGraphInstrumentor # Configure batch processing BEFORE initializing FiddlerClient os.environ['OTEL_BSP_MAX_QUEUE_SIZE'] = '500' # Increased from default 100 os.environ['OTEL_BSP_SCHEDULE_DELAY_MILLIS'] = '500' # Faster export than default 1000ms os.environ['OTEL_BSP_MAX_EXPORT_BATCH_SIZE'] = '50' # Larger batches than default 10 # Increase span limits to capture more data production_limits = SpanLimits( max_events=128, # Default: 32 max_span_attributes=128, # Default: 32 max_span_attribute_length=8192, # Default: 2048 ) # Sample 5-10% of traces production_sampler = sampling.TraceIdRatioBased(0.05) fdl_client = FiddlerClient( application_id=os.getenv("FIDDLER_APPLICATION_ID"), api_key=os.getenv("FIDDLER_API_KEY"), url=os.getenv("FIDDLER_URL"), span_limits=production_limits, sampler=production_sampler, compression=Compression.Gzip, ) instrumentor = LangGraphInstrumentor(fdl_client) instrumentor.instrument() ``` ### Offline and S3 Routing Mode Use this mode when traces must be routed through an intermediate store (such as Amazon S3) before reaching Fiddler, rather than being sent directly. This is the correct approach when your security or network policies require all data to pass through a controlled intermediary. * **`otlp_enabled=False`** — disables all direct OTLP export to Fiddler. `api_key` and `url` are not required in this mode. * **`otlp_json_capture_enabled=True`** — writes traces to local `.json` files in standard OTLP JSON format (`ExportTraceServiceRequest` envelope). These files are directly consumable by the Fiddler S3 connector with no reformatting. * **`application_id` is still required** — even though no data is sent to Fiddler directly, the S3 connector uses the `application_id` embedded in the trace files to route ingested traces to the correct application in Fiddler. ```python theme={null} from fiddler_langgraph import FiddlerClient, LangGraphInstrumentor # No api_key or url needed — traces go to local files only fdl_client = FiddlerClient( application_id="YOUR_APPLICATION_ID", # UUID4 — required for S3 connector routing otlp_enabled=False, # Disables direct export to Fiddler otlp_json_capture_enabled=True, # Writes OTLP JSON files locally otlp_json_output_dir="./fiddler_traces", # Directory for output files (default: 'fiddler_traces') ) instrumentor = LangGraphInstrumentor(fdl_client) instrumentor.instrument() # Your LangGraph code runs normally — traces are written to ./fiddler_traces/*.json ``` Upload the generated `.json` files from `otlp_json_output_dir` to your S3 bucket. The Fiddler S3 connector reads them directly. Each batch of spans is written to a separate timestamped `.json` file in the output directory. The directory is created automatically if it does not exist. **Do not confuse `console_tracer` or `jsonl_capture_enabled` with this mode.** Both of those flags are **additive** — they add a local output on top of the existing OTLP export to Fiddler but do not disable it. Only `otlp_enabled=False` fully stops direct export to Fiddler. ### Running in AWS SageMaker Because `fiddler-langgraph` exports traces through `FiddlerClient`, it inherits the Fiddler OTel SDK's [AWS SageMaker Partner App authentication](/integrations/agentic-ai/fiddler-otel-sdk#running-in-aws-sagemaker). Install the `sagemaker` extra (`pip install "fiddler-otel[sagemaker]"`) and set the `AWS_PARTNER_APP_AUTH`, `AWS_PARTNER_APP_ARN`, and `AWS_PARTNER_APP_URL` environment variables — your instrumentation code is unchanged. ### Flush and shutdown handling The SDK uses OpenTelemetry's batch span processor, which buffers spans in memory and exports them on a schedule. To avoid losing buffered spans when your process exits, use explicit flush and shutdown: * **Process exit:** The SDK registers an `atexit` handler that flushes and shuts down the tracer when the process exits. For short scripts or environments where `atexit` may not run (e.g. SIGKILL, forked processes), call `force_flush()` and `shutdown()` explicitly—for example in a `try`/`finally` or signal handler. * **Long-running servers (e.g. FastAPI, uvicorn):** On graceful shutdown (SIGTERM), call the Fiddler client's shutdown so pending spans are exported before the process exits. From async code use `ashutdown()` (or `aflush()` then `ashutdown()`) so the event loop is not blocked; the sync `force_flush()` and `shutdown()` can block for up to the flush timeout (default 30 seconds). **Sync (scripts or signal handler):** ```python theme={null} # Ensure spans are sent before exit (e.g. in finally or SIGTERM handler) fdl_client.shutdown() ``` **Async (e.g. FastAPI/uvicorn lifespan):** ```python theme={null} # In your app's shutdown/lifespan handler (e.g. on SIGTERM) await fdl_client.ashutdown() ``` **Context manager (scripts):** Use `with FiddlerClient(...) as client:` so `shutdown()` is called automatically when the block exits. ## Example applications ### Multi-agent travel planner ```python theme={null} from langgraph.graph import StateGraph, END from langchain_openai import ChatOpenAI from typing import TypedDict from fiddler_langgraph import FiddlerClient, LangGraphInstrumentor # Initialize Fiddler monitoring fdl_client = FiddlerClient( application_id="your-app-id", api_key="your-api-key", url="https://your-instance.fiddler.ai" ) instrumentor = LangGraphInstrumentor(fdl_client) instrumentor.instrument() # Define your agent graph class TravelState(TypedDict): destination: str budget: float itinerary: list # Research agent def research_agent(state: TravelState): # Agent logic - automatically traced return {"research_complete": True} # Booking agent def booking_agent(state: TravelState): # Agent logic - automatically traced return {"bookings": [...]} # Build graph graph = StateGraph(TravelState) graph.add_node("research", research_agent) graph.add_node("booking", booking_agent) graph.add_edge("research", "booking") graph.add_edge("booking", END) # Run - traces automatically sent to Fiddler app = graph.compile() result = app.invoke({"destination": "Paris", "budget": 5000}) ``` [**View the Advanced Observability Notebook →**](https://github.com/fiddler-labs/fiddler-examples/blob/main/quickstart/latest/Fiddler_Quickstart_LangGraph_Advanced_Observability.ipynb) | [**Custom Instrumentation Notebook →**](https://github.com/fiddler-labs/fiddler-examples/blob/main/quickstart/latest/Fiddler_Quickstart_LangGraph_Custom_Instrumentation.ipynb) ### Customer support agent with tools ```python theme={null} from langchain.tools import Tool from langchain_openai import ChatOpenAI from langgraph.prebuilt import create_react_agent from fiddler_langgraph import FiddlerClient, LangGraphInstrumentor # Initialize Fiddler monitoring fdl_client = FiddlerClient( application_id="your-app-id", api_key="your-api-key", url="https://your-instance.fiddler.ai" ) instrumentor = LangGraphInstrumentor(fdl_client) instrumentor.instrument() # Define tools - calls automatically traced tools = [ Tool(name="search_kb", func=search_knowledge_base), Tool(name="create_ticket", func=create_support_ticket), Tool(name="escalate", func=escalate_to_human) ] # Create agent - instrumentation is automatic model = ChatOpenAI(model="gpt-4o") agent = create_react_agent(model, tools) # Run agent - full trace in Fiddler response = agent.invoke({ "messages": [{"role": "user", "content": "My order is delayed"}] }) ``` ## Viewing your data After running your instrumented application: 1. **Navigate to Fiddler UI** - `https://your-instance.fiddler.ai` 2. **Select "GenAI Applications"** - View your application 3. **Inspect traces** - Drill down from application → session → agent → span 4. **Analyze patterns** - Use analytics to identify bottlenecks and errors ### Key metrics tracked * **Latency**: P50, P95, P99 response times across agents * **Error Rate**: Percentage of failed agent executions * **Token Usage**: LLM token consumption per agent/session * **Tool Calls**: Frequency and success rate of tool invocations * **State Transitions**: Agent decision path analysis ## Troubleshooting ### Application not showing as "Active" **Check your configuration:** * Ensure your application executes instrumented code * Verify your Fiddler access token and application ID are correct * Check network connectivity to your Fiddler instance **Enable console tracer for debugging:** ```python theme={null} fdl_client = FiddlerClient( application_id="your-app-id", api_key="your-api-key", url="https://your-instance.fiddler.ai", console_tracer=True # Also prints spans to console; OTLP export to Fiddler continues ) ``` `console_tracer=True` is **additive** — span data is printed to stdout **and** continues to be exported to Fiddler via OTLP. Setting this to `True` does **not** disable or suppress the OTLP export to Fiddler. Use it to visually confirm spans are being created during local development. ### Network connectivity issues **Verify connectivity to your Fiddler instance:** ```bash theme={null} curl -I https://your-instance.fiddler.ai ``` **Check firewall settings:** * Ensure HTTPS traffic on port 443 is allowed * Verify your Fiddler instance URL is correct ### Import errors **Problem:** `ModuleNotFoundError: No module named 'fiddler_langgraph'` **Solution:** Ensure you've installed the correct package: ```bash theme={null} pip install fiddler-langgraph ``` **Problem:** `ImportError: cannot import name 'LangGraphInstrumentor'` **Solution:** Ensure you have the correct import path: ```python theme={null} from fiddler_langgraph import LangGraphInstrumentor ``` ### Version compatibility issues **Verify your versions match requirements:** ```bash theme={null} python --version # Should be 3.10, 3.11, 3.12, or 3.13 pip show langgraph # Should be >= 0.3.28 and <= 1.1.0 ``` **If you have version conflicts:** ```bash theme={null} pip install langgraph>=0.3.28,<=1.1.0 ``` ### Invalid application ID **Problem:** `ValueError: application_id must be a valid UUID4` **Solution:** Ensure your Application ID is in proper UUID4 format: ```python theme={null} # ❌ This will fail fdl_client = FiddlerClient( application_id="invalid-id", # Not a valid UUID4 api_key="your-access-token", url="https://instance.fiddler.ai" ) # ✅ Correct format fdl_client = FiddlerClient( application_id="550e8400-e29b-41d4-a716-446655440000", # Valid UUID4 api_key="your-access-token", url="https://instance.fiddler.ai" ) ``` Copy the Application ID directly from the Fiddler dashboard to avoid formatting issues. ### Agent shows as "UNKNOWN\_AGENT" **For LangChain applications**, ensure you're setting the agent name in the config parameter: ```python theme={null} from langchain_core.output_parsers import StrOutputParser # Define your LangChain runnable chat_app_chain = prompt | llm | StrOutputParser() # Run with agent name configuration response = chat_app_chain.invoke({ "input": user_input, "history": messages, }, config={"configurable": {"agent_name": "service_chatbot"}}) ``` **Note:** LangGraph applications automatically extract agent names. This manual configuration is only needed for LangChain applications. ## OpenTelemetry compatibility The LangGraph SDK is built on OpenTelemetry Protocol (OTLP). The SDK uses standard OpenTelemetry components, allowing you to: * Integrate with existing observability infrastructure * Export traces to multiple backends (with custom configuration) * Use custom OTEL collectors and processors All telemetry data follows OpenTelemetry semantic conventions for AI/ML workloads. ## Related integrations * [**Fiddler Evals SDK**](/integrations/agentic-ai/evals-sdk) - Evaluate LangGraph agent quality offline * [**Python Client SDK**](/sdk-api/python-client/connection) - Additional monitoring capabilities ## Migration guides ### From LangSmith ```python theme={null} # Before (LangSmith) import os os.environ["LANGCHAIN_TRACING_V2"] = "true" os.environ["LANGCHAIN_API_KEY"] = "ls_..." # After (Fiddler - both can run simultaneously) from fiddler_langgraph import FiddlerClient, LangGraphInstrumentor fdl_client = FiddlerClient( application_id="your-app-id", api_key="your-api-key", url="https://your-instance.fiddler.ai" ) instrumentor = LangGraphInstrumentor(fdl_client) instrumentor.instrument() # Your LangGraph code remains unchanged ``` ### From manual tracing If you've built custom tracing, migration is straightforward: ```python theme={null} # Before (manual timing/logging) import time start = time.time() result = my_agent.run() duration = time.time() - start log_to_system(duration, result) # After (Fiddler SDK - automatic instrumentation) # Initialize Fiddler client and instrumentor (once) fdl_client = FiddlerClient( application_id="your-app-id", api_key="your-api-key", url="https://your-instance.fiddler.ai" ) instrumentor = LangGraphInstrumentor(fdl_client) instrumentor.instrument() # Remove all manual timing/logging code result = my_agent.run() # Automatic instrumentation ``` ## API reference Full SDK documentation: * [**LangGraph SDK Reference**](/sdk-api/langgraph/fiddler-client) - Complete class and method documentation ## Next steps Now that your application is instrumented: 1. **Explore the data:** Check your Fiddler dashboard for traces, metrics, and performance insights 2. **Learn advanced features:** See our [Advanced Usage Guide](/developers/tutorials/llm-monitoring/langgraph-sdk-advanced) for complex multi-agent scenarios 3. **Review the SDK reference:** Check the [Fiddler LangGraph SDK Reference](/sdk-api/langgraph/fiddler-client) for complete documentation 4. **Optimize for production:** Review configuration options for high-volume applications # LiteLLM Integration Source: https://docs.fiddler.ai/integrations/agentic-ai/litellm-integration Integrate LiteLLM with Fiddler for unified LLM cost tracking, latency monitoring, and LLM call observability — via the LiteLLM SDK or the LiteLLM proxy gateway. # LiteLLM Integration ## Overview [LiteLLM](https://docs.litellm.ai/) provides a unified interface for calling 100+ LLM providers. Fiddler supports two integration modes: | Mode | Best for | Extra packages required | | ----------------- | ------------------------------------------------------------------------------- | ----------------------- | | **LiteLLM SDK** | Applications calling LLM providers directly via `litellm.completion()` | None | | **LiteLLM Proxy** | Teams routing all LLM traffic through a centrally managed LiteLLM proxy gateway | None | Both modes work by routing OpenTelemetry traces to Fiddler's OTLP ingestion endpoint using standard environment variables. *** ## LiteLLM SDK Integration ### Overview LiteLLM includes a built-in OpenTelemetry integration. When you enable it and point the OTLP exporter at Fiddler, every LLM call is automatically traced — with no Fiddler-specific package required. Fiddler natively ingests LiteLLM SDK-generated OTel traces and maps them to the Fiddler schema, giving you full observability over prompts, responses, and token usage across all LLM providers. The following SDK functions are supported: | SDK Function | `gen_ai.operation.name` | Fiddler Span Type | | ------------------------------------------------------------- | ---------------------------------------- | ----------------- | | `litellm.completion()` / `litellm.acompletion()` | `chat` / `completion` / `acompletion` | `llm` | | `litellm.text_completion()` / `litellm.atext_completion()` | `text_completion` / `atext_completion` | `llm` | | `litellm.responses()` / `litellm.aresponses()` | `responses` / `aresponses` | `llm` | | `litellm.anthropic_interface.messages.create()` / `acreate()` | `anthropic_messages` | `llm` | | `litellm.generate_content()` / `litellm.agenerate_content()` | `generate_content` / `agenerate_content` | `llm` | | `litellm.embedding()` / `litellm.aembedding()` | `embedding` / `aembedding` | `chain` | | `litellm.image_generation()` / `litellm.aimage_generation()` | `image_generation` / `aimage_generation` | `chain` | | `litellm.image_edit()` / `litellm.aimage_edit()` | `image_edit` / `aimage_edit` | `chain` | | `litellm.moderation()` / `litellm.amoderation()` | `moderation` / `amoderation` | `chain` | | `litellm.transcription()` / `litellm.atranscription()` | `transcription` / `atranscription` | `chain` | | `litellm.speech()` / `litellm.aspeech()` | `speech` / `aspeech` | `chain` | | `litellm.rerank()` / `litellm.arerank()` | `rerank` / `arerank` | `chain` | | `litellm.ocr()` / `litellm.aocr()` | `ocr` / `aocr` | `chain` | **Notes on the table above:** * **`completion` operation name:** LiteLLM versions before `1.82.1` (released January 2026) emit `gen_ai.operation.name = "completion"` literally for `litellm.completion()` calls. Newer versions rewrite it to `"chat"`. Both are classified identically as `llm`. * **Non-text APIs classified as `chain`:** Fiddler's LLM observability currently focuses on text-based generative completions. Image, audio, embedding, moderation, ranking, and OCR operations are classified as `chain` so they remain visible in traces without being treated as LLM completions. **Conversation tracking is not currently supported** for the LiteLLM integration. Session-level grouping of multi-turn conversations will be addressed in a future release as part of broader session attribute support. ### Architecture ```mermaid theme={null} graph TB App["Your Application
litellm.callbacks = ["otel"]"] -->|OTLP/HTTP| Fiddler subgraph "Fiddler Platform" Fiddler["OTLP Ingestion Endpoint"] Fiddler --> Mapper["LiteLLM Span Mapper
Classify llm / chain
Extract messages & tokens
Map to Fiddler schema"] Mapper --> Analytics["Analytics & Visualization
Explorer
Latency Monitoring"] end style App fill:#e1f5ff style Mapper fill:#fff4e6 style Analytics fill:#e6ffe6 ``` ### Prerequisites * Fiddler account with a GenAI application already created * `pip install litellm` (or `uv add litellm`) * A valid LLM provider API key (e.g. `OPENAI_API_KEY` for OpenAI models) ### Quick Start #### Step 1: Set environment variables Set these before starting your application: ```bash theme={null} # Fiddler OTel ingestion export OTEL_EXPORTER_OTLP_ENDPOINT="https://your-fiddler-instance.com" export OTEL_EXPORTER_OTLP_HEADERS="authorization=Bearer ,fiddler-application-id=" export OTEL_RESOURCE_ATTRIBUTES="application.id=" # LLM provider key (name varies by provider) export OPENAI_API_KEY="your-openai-key" ``` To find your application UUID: navigate to your application in the Fiddler UI and copy the UUID from the URL or application settings. #### Step 2: Enable the built-in OTel callback Add one line to your application startup: ```python theme={null} import litellm litellm.callbacks = ["otel"] ``` #### Step 3: Make completions as normal No other code changes are required: ```python theme={null} response = litellm.completion( model="gpt-4o-mini", messages=[ {"role": "system", "content": "You are a helpful assistant."}, {"role": "user", "content": "What is the capital of France?"}, ], ) print(response.choices[0].message.content) ``` Every call is now automatically traced and exported to Fiddler. #### Step 4: Verify traces are arriving Open the Fiddler UI and navigate to your application's **Explorer**. You should see the trace within a few seconds of making your first completion call. ### What Gets Captured **Message Content** | Fiddler Field | Description | | ---------------- | ----------------------------------------- | | System prompt | The system instructions sent to the model | | User input | The most recent user turn | | Assistant output | The model's response | **Token Usage** | Attribute | Description | | ---------------------------- | --------------------------- | | `gen_ai.usage.input_tokens` | Prompt tokens consumed | | `gen_ai.usage.output_tokens` | Completion tokens generated | | `gen_ai.usage.total_tokens` | Total tokens | **Model Information** `gen_ai.system` and `gen_ai.request.model` are SDK first-class LLM attributes. They are stored at their unprefixed keys and resolved at query time by the Fiddler backend's field registry, making them queryable via `SpanAttribute::gen_ai.system` and `SpanAttribute::gen_ai.request.model`. | Attribute | Description | | ----------------------- | ------------------------------------- | | `gen_ai.request.model` | Model requested (e.g. `gpt-4o-mini`) | | `gen_ai.response.model` | Model actually used | | `gen_ai.system` | Provider (e.g. `openai`, `anthropic`) | ### Supported Features | Feature | Support | Notes | | --------------------------------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Chat/text completion tracing | ✅ Full | Prompts, responses, token usage via `completion()`, `text_completion()` | | Responses API tracing | ⚠️ Partial | Token usage captured; output text and `instructions` system prompt not populated by LiteLLM — see [Known LiteLLM Upstream Caveats](#known-litellm-upstream-caveats) | | Anthropic Messages API tracing | ⚠️ Partial | `system` prompt not populated by LiteLLM — see [Known LiteLLM Upstream Caveats](#known-litellm-upstream-caveats) | | Google GenAI native tracing | ⚠️ Partial | `systemInstruction` not populated by LiteLLM (chat-completion path is fine) — see [Known LiteLLM Upstream Caveats](#known-litellm-upstream-caveats) | | Embeddings, images, audio, rerank | ⚠️ As `chain` | Spans captured with token/cost metadata but not classified as `llm` | | Token usage | ✅ Full | Input, output, and total tokens | | Model information | ✅ Full | Requested and actual model, provider | | Cost tracking | ❌ Not supported | LiteLLM SDK does not emit `gen_ai.cost.*` attributes | | Tool spans | ❌ Not supported | LiteLLM SDK does not emit tool spans | | Conversation tracking | ❌ Not supported | Session-level grouping of multi-turn conversations is not available | ### Troubleshooting **Traces not appearing in Fiddler** Check that all three environment variables are set correctly: ```bash theme={null} echo $OTEL_EXPORTER_OTLP_ENDPOINT echo $OTEL_EXPORTER_OTLP_HEADERS echo $OTEL_RESOURCE_ATTRIBUTES ``` Check that `litellm.callbacks = ["otel"]` is set before your first `litellm.completion()` call. **Check the `fiddler-application-id` header and `application.id` resource attribute are both set** Both are required. `fiddler-application-id` must be a valid UUID for an existing Fiddler application, otherwise spans will be dropped during ingestion. *** ## LiteLLM Proxy Integration ### Overview [LiteLLM](https://docs.litellm.ai/) is an OpenAI-compatible proxy gateway that lets you call 100+ LLM providers through a single API. When LiteLLM proxy is configured to emit OpenTelemetry traces, Fiddler automatically detects and ingests them — no additional SDK or code changes required. Fiddler includes a purpose-built mapper for LiteLLM proxy traces that handles the proxy's specific span format, attribute layout, and operation naming conventions. This gives you full observability over every LLM call routed through your proxy: prompts, responses, token usage, cost metadata, and latency — across all models and providers in one place. ### Architecture ```mermaid theme={null} graph TB App["Your Application
(any language, any framework)"] App -->|"OpenAI-compatible API
/chat/completions, /v1/responses,
/completions, /embeddings, ..."| Proxy Proxy["LiteLLM Proxy Gateway
service.name = "litellm""] Proxy -->|OTLP/gRPC or OTLP/HTTP| Fiddler subgraph "Fiddler Platform" Fiddler["OTLP Ingestion Endpoint"] Fiddler --> Mapper["LiteLLM Span Mapper
Classify llm / chain
Extract messages & tokens
Map costs to fiddler.span.user.*"] Mapper --> Analytics["Analytics & Visualization
Explorer
Cost Dashboards
Latency Monitoring"] end style App fill:#e1f5ff style Proxy fill:#fff4e6 style Mapper fill:#f0e6ff style Analytics fill:#e6ffe6 ``` ### When to Use This Integration Use the LiteLLM proxy integration when: * You are already running LiteLLM proxy as your LLM gateway * You want to monitor all LLM traffic centrally regardless of underlying provider (OpenAI, Anthropic, Bedrock, etc.) * You want cost attribution and latency tracking without instrumenting individual applications ### Quick Start #### Step 1: Configure LiteLLM proxy to emit OpenTelemetry Set the following environment variables before starting the proxy: ```bash theme={null} export OTEL_EXPORTER_OTLP_ENDPOINT="https://your-fiddler-instance.com" export OTEL_EXPORTER_OTLP_HEADERS="authorization=Bearer ,fiddler-application-id=" export OTEL_RESOURCE_ATTRIBUTES="application.id=" litellm --config config.yaml ``` Or set them inside your LiteLLM proxy `config.yaml`: ```yaml theme={null} general_settings: otel: true environment_variables: OTEL_EXPORTER_OTLP_ENDPOINT: "https://your-fiddler-instance.com" OTEL_EXPORTER_OTLP_HEADERS: "authorization=Bearer ,fiddler-application-id=" OTEL_RESOURCE_ATTRIBUTES: "application.id=" ``` #### Step 2: Set your Fiddler application ID Two environment variables carry your application ID and both are required: * **`OTEL_RESOURCE_ATTRIBUTES`** — sets `application.id` on every OTel resource, which Fiddler uses to route traces to the correct application * **`OTEL_EXPORTER_OTLP_HEADERS`** — includes `fiddler-application-id` as an HTTP header for authentication and routing at the ingestion endpoint To find your application UUID: navigate to your application in the Fiddler UI and copy the UUID from the URL or application settings. #### Step 3: Verify traces are arriving Make a test request through your proxy: ```bash theme={null} curl -X POST https://your-litellm-proxy/chat/completions \ -H "Content-Type: application/json" \ -d '{ "model": "gpt-4o-mini", "messages": [{"role": "user", "content": "Hello"}] }' ``` Then open the Fiddler UI and navigate to your application's **Explorer**. You should see the trace within a few seconds. ### Using with OpenAI Codex CLI [OpenAI Codex CLI](https://github.com/openai/codex) does not need its own Fiddler integration. Codex's native OpenTelemetry **traces** carry only token counts — no prompt, response, or tool content. (That content exists only in Codex's OpenTelemetry **logs**, which Fiddler does not ingest.) So the recommended way to observe Codex in Fiddler is to point it at your LiteLLM proxy. The proxy then emits full `llm` spans (prompt + response + token usage) that Fiddler ingests through the integration described above, with no Fiddler-side code. #### Step 1: Use LiteLLM 1.88+ with a Codex-compatible model Codex uses the OpenAI Responses API, and its streamed output is only captured by LiteLLM **1.88.0 or later**. Ensure the proxy is on a supported version with the OTel exporter SDK installed: ```bash theme={null} pip install "litellm[proxy]>=1.88.0" opentelemetry-sdk opentelemetry-exporter-otlp-proto-http ``` In your proxy `config.yaml`, map an alias (the name Codex will request) to a Codex-capable model. Use a current Codex-family model from your OpenAI account for the upstream `model` — for example `gpt-5.2-codex`. General chat models such as `gpt-4o-mini` will **not** work, because they reject Codex's tool calls. ```yaml theme={null} model_list: - model_name: codex-model # alias Codex requests (any name; reused in Step 2) litellm_params: model: openai/ # e.g. gpt-5.2-codex — must accept Codex's tool calls api_key: os.environ/OPENAI_API_KEY litellm_settings: callbacks: ["otel"] drop_params: true ``` #### Step 2: Point Codex at the proxy Add a custom model provider to `~/.codex/config.toml` so Codex sends requests to your LiteLLM proxy instead of OpenAI directly: ```toml theme={null} model = "codex-model" # must match the model_name alias from Step 1 model_provider = "fiddler-gw" [model_providers.fiddler-gw] name = "Fiddler GW" base_url = "http://localhost:4000/v1" # your LiteLLM proxy URL wire_api = "responses" # Codex only supports the Responses API env_key = "GW_KEY" # any non-empty value; LiteLLM holds the real provider key ``` ```bash theme={null} export GW_KEY=any-non-empty-value ``` #### Step 3: Use Codex normally ```bash theme={null} codex exec "Plan a 4-day trip to Japan" ``` Each turn appears in your application's **Explorer** as an `llm` span with the full user prompt, assistant response, and token usage. Codex uses the OpenAI Responses API. On the proxy path with **LiteLLM ≥ 1.88.0**, LiteLLM captures both the input and output messages for Responses-API calls, so prompts and responses appear in full. The `/v1/responses` content gap noted in [Known LiteLLM Upstream Caveats](#known-litellm-upstream-caveats) applies only to earlier LiteLLM versions and does not affect this setup. **Requirements and limitations** * **API-key mode only.** Routing through a proxy uses your OpenAI API key; it does not work with ChatGPT-subscription login. * **The upstream model must accept Codex's tool calls.** Use a current Codex-family model from your OpenAI account (for example `gpt-5.2-codex`); general chat models such as `gpt-4o-mini` reject Codex's tool format. ### What Gets Captured #### Span Types LiteLLM proxy emits several span types per request. Fiddler classifies them based on the `gen_ai.operation.name` attribute: **LLM endpoints** — classified as `llm` (generative text completions): | Gateway Endpoint | `gen_ai.operation.name` | Description | | ------------------------------------------------------------------- | ------------------------------------------------------ | ------------------------------------ | | `/chat/completions` | `chat` / `acompletion` / `completion` | Chat completion (most common) | | `/completions` | `text_completion` / `atext_completion` | Legacy text completion | | `/v1/responses` | `responses` / `aresponses` | OpenAI Responses API | | `/v1/messages`, `/anthropic/v1/messages` | `anthropic_messages` | Anthropic Messages API | | `/generate_content`, `/models/{model}:generateContent` | `generate_content` / `agenerate_content` | Google Gemini native (non-streaming) | | `/generate_content_stream`, `/models/{model}:streamGenerateContent` | `generate_content_stream` / `agenerate_content_stream` | Google Gemini native (streaming) | **Non-LLM endpoints** — classified as `chain` (not generative text completions): | Gateway Endpoint | `gen_ai.operation.name` | Description | | ----------------------- | ---------------------------------------- | ----------------------------- | | `/embeddings` | `embedding` / `aembedding` | Text-to-vector conversion | | `/moderations` | `moderation` / `amoderation` | Content safety scoring | | `/images/generations` | `image_generation` / `aimage_generation` | Image generation | | `/images/edits` | `image_edit` / `aimage_edit` | Image editing | | `/audio/speech` | `speech` / `aspeech` | Text-to-speech | | `/audio/transcriptions` | `transcription` / `atranscription` | Speech-to-text | | `/rerank` | `rerank` / `arerank` | Document relevance scoring | | `/ocr` | `ocr` / `aocr` | Optical character recognition | **Infrastructure spans** — classified as `chain`: | LiteLLM Span Name | Description | | ----------------- | -------------------------------------- | | `self` | Internal LiteLLM API call timing | | `router` | Model routing and deployment selection | | `proxy_pre_call` | Pre-processing before LLM call | Each proxy request typically produces up to 3 spans: | LiteLLM Span Name | Description | | ------------------------------- | --------------------------------------------------- | | `Received Proxy Server Request` | Top-level server span (parent) | | `litellm_request` | Primary span carrying all attributes | | `raw_gen_ai_request` | Child span with raw provider-level request/response | #### Captured Attributes **Message Content** LiteLLM writes full conversation history as JSON on the span (not as span events). Fiddler extracts: | Fiddler Field | Source | Description | | ---------------- | ----------------------------------------------------------- | ----------------------------------------- | | System prompt | First `role: system` message in `gen_ai.input.messages` | The system instructions sent to the model | | User input | Last `role: user` message in `gen_ai.input.messages` | The most recent user turn | | Assistant output | First `role: assistant` message in `gen_ai.output.messages` | The model's response | If you have disabled message logging in LiteLLM (`turn_off_message_logging: true`), the message content fields will be absent from traces. Token counts and cost metadata are still captured. **Token Usage** | Attribute | Description | | ---------------------------- | --------------------------- | | `gen_ai.usage.input_tokens` | Prompt tokens consumed | | `gen_ai.usage.output_tokens` | Completion tokens generated | | `gen_ai.usage.total_tokens` | Total tokens | **Model Information** `gen_ai.system` and `gen_ai.request.model` are SDK first-class LLM attributes. They are stored at their unprefixed keys and resolved at query time by the Fiddler backend's field registry, making them queryable via `SpanAttribute::gen_ai.system` and `SpanAttribute::gen_ai.request.model`. | Attribute | Description | | ----------------------- | ----------------------------------------------- | | `gen_ai.request.model` | Model requested (e.g. `gpt-4o-mini`) | | `gen_ai.response.model` | Model actually used (may differ from requested) | | `gen_ai.system` | Provider (e.g. `openai`, `anthropic`) | **Cost Metadata** (stored as `fiddler.span.user.*`) LiteLLM emits cost fields under `gen_ai.cost.*`. These are preserved in Fiddler as user-visible span attributes: | Attribute | Description | | ----------------------------- | ------------------------------------ | | `gen_ai.cost.total_cost` | Total cost of the request | | `gen_ai.cost.prompt_cost` | Cost attributed to prompt tokens | | `gen_ai.cost.completion_cost` | Cost attributed to completion tokens | **Proxy Metadata** (stored as `fiddler.span.user.*`) LiteLLM proxy emits `metadata.*` attributes containing API key, team, user, and routing information. These are preserved as user-visible span attributes for auditing and cost attribution. ### Supported Features #### Endpoint Coverage | Endpoint | Span Type | Messages | Tokens | Cost | Notes | | -------------------------------------- | --------- | -------------------------- | ------ | ---- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `/chat/completions` | `llm` | ✅ | ✅ | ✅ | Full support — prompts, responses, all metadata | | `/completions` | `llm` | ✅ | ✅ | ✅ | Legacy text completion, full content extraction | | `/v1/responses`, `/responses` | `llm` | ❌ | ✅ | ✅ | Both `gen_ai.input.messages` and `gen_ai.output.messages` are absent — LiteLLM's OTel callback reads `kwargs["messages"]` / `response["choices"]`, but the Responses API uses `input` / `output`. `instructions` system prompt and provider attribution also missing — see [Known LiteLLM Upstream Caveats](#known-litellm-upstream-caveats) | | `/v1/messages` (Anthropic) | `llm` | partial (no system prompt) | ✅ | ✅ | `system` prompt **not populated** by LiteLLM's OTel integration; provider attribution missing — see [Known LiteLLM Upstream Caveats](#known-litellm-upstream-caveats) | | `/v1beta/...:generateContent` (Gemini) | `llm` | partial (no system prompt) | ✅ | ✅ | `systemInstruction` **not populated** by LiteLLM's OTel integration; provider attribution missing — see [Known LiteLLM Upstream Caveats](#known-litellm-upstream-caveats) | | `/embeddings` | `chain` | ❌ | ✅ | ✅ | Not a generative completion — no messages to extract | | `/moderations` | `chain` | ❌ | ❌ | ❌ | Content safety scoring; no generative output | | `/images/generations` | `chain` | ❌ | ❌ | ✅ | Image generation; no text output | | `/images/edits` | `chain` | ❌ | ❌ | ✅ | Image editing; no text output | | `/audio/speech` | `chain` | ❌ | ❌ | ✅ | Text-to-speech; no text output | | `/audio/transcriptions` | `chain` | ❌ | ✅ | ✅ | Speech-to-text; transcription not extracted | | `/rerank` | `chain` | ❌ | ✅ | ✅ | Document relevance scoring | | `/ocr` | `chain` | ❌ | ❌ | ❌ | Optical character recognition | #### Platform Features | Feature | Support | Notes | | --------------------- | --------------- | -------------------------------------------------------------------------------- | | Cost tracking | ✅ Full | Via `gen_ai.cost.*` attributes | | Provider attribution | ✅ Full | Via `gen_ai.system` | | Proxy metadata | ✅ Full | API key, team, user, routing info | | Tool spans | ❌ Not supported | LiteLLM does not emit tool spans natively | | Infrastructure spans | ⚠️ As `chain` | `self`, `router`, `proxy_pre_call` are captured but classified as generic chains | | Conversation tracking | ❌ Not supported | Session-level grouping of multi-turn conversations is not available | ### Troubleshooting **Traces not appearing in Fiddler** Check that OTel is enabled in LiteLLM: ```bash theme={null} echo $OTEL_EXPORTER_OTLP_ENDPOINT echo $OTEL_EXPORTER_OTLP_HEADERS echo $OTEL_RESOURCE_ATTRIBUTES ``` Check the `fiddler-application-id` header and `application.id` resource attribute are both set: Both are required. `fiddler-application-id` must be a valid UUID for an existing Fiddler application, otherwise spans will be dropped during ingestion. **Check `service.name` is `"litellm"`** Fiddler detects LiteLLM proxy spans by `service.name`. LiteLLM proxy sets this to `"litellm"` by default. If you have overridden `OTEL_SERVICE_NAME`, ensure it is set to `"litellm"` or `"litellm-proxy"`: ```bash theme={null} export OTEL_SERVICE_NAME="litellm" ``` **Message content missing from traces** LiteLLM's message logging may be disabled. Check your config for: ```yaml theme={null} litellm_settings: turn_off_message_logging: true # This suppresses gen_ai.input/output.messages ``` Remove or set to `false` to re-enable message capture. **Spans classified as `chain` instead of `llm`** This happens for internal LiteLLM infrastructure spans (`self`, `router`, `proxy_pre_call`) and for non-completion operations (embeddings, image generation, speech, etc.). This is expected behavior — only completion-generating endpoints (`/chat/completions`, `/completions`, `/v1/responses`) are classified as `llm` spans. **`/v1/responses` spans are missing message content** See the [Known LiteLLM Upstream Caveats](#known-litellm-upstream-caveats) section below for details. Token counts, costs, and span-type classification are unaffected. *** ## Known LiteLLM Upstream Caveats While integrating with LiteLLM, several gaps were identified in LiteLLM's own OpenTelemetry callback (`litellm/integrations/opentelemetry.py`). These are **not** Fiddler issues — they affect every downstream OTel consumer (Datadog, Honeycomb, Phoenix, etc.). Fiddler classifies the spans correctly and surfaces every attribute that LiteLLM does emit, but the gaps below mean some content is simply absent from the trace at the source. ### `/v1/responses` and `/responses` — input and output messages both missing LiteLLM's OTel callback reads input messages from `kwargs["messages"]` and output messages from `response["choices"]` — both shapes specific to `/chat/completions`. The Responses API uses `kwargs["input"]` and `response["output"]` instead, so neither extraction block runs. | What you see | What's missing | | ------------------------------- | ---------------------------------- | | `gen_ai.usage.*` ✅ | `gen_ai.input.messages` ❌ | | `gen_ai.cost.*` ✅ | `gen_ai.output.messages` ❌ | | Span correctly typed as `llm` ✅ | `gen_ai.response.finish_reasons` ❌ | | | tool call attributes (if any) ❌ | **Where the data does exist:** the `raw_gen_ai_request` child span (a sibling of the parent `litellm_request` span) carries both the request and response under `llm..input` / `llm..output`. It is currently surfaced as a `chain` span without content extraction. **Tracking:** [BerriAI/litellm#25840](https://github.com/BerriAI/litellm/issues/25840) ### `/v1/responses`, `/responses`, `/v1/messages`, `/v1beta/...:generateContent` — system prompt missing LiteLLM's OTel callback writes `gen_ai.system_instructions` only when the kwarg name is exactly `system_instructions`. Other endpoints use different field names for the same concept: | Endpoint | Kwarg name LiteLLM uses internally | OTel callback reads it? | | ---------------------------------------------------------- | ---------------------------------- | ----------------------- | | Vertex AI Gemini chat-completion path | `system_instructions` | ✅ | | OpenAI Responses API (`/v1/responses`, `/responses`) | `instructions` | ❌ | | Anthropic Messages API (`/v1/messages`) | `system` | ❌ | | Gemini direct pass-through (`/v1beta/...:generateContent`) | `systemInstruction` (nested) | ❌ | The system prompt does reach LiteLLM and is included in the actual LLM request — it just never lands on `gen_ai.system_instructions` in the OTel trace. As with the output-text gap, the data is visible on the `raw_gen_ai_request` child span (`llm..instructions` / `llm..system` / `llm..systemInstruction`). **Tracking:** [BerriAI/litellm#25840 (follow-up comment)](https://github.com/BerriAI/litellm/issues/25840#issuecomment-4278874801) ### Non-chat-completion endpoints — `gen_ai.system` empty and `llm.None.*` attribute prefix For every endpoint family except `/chat/completions`, LiteLLM's `custom_llm_provider` is not propagated into the OTel callback's view of `litellm_params`. This causes two visible symptoms: * `gen_ai.system` is set to an empty string instead of the provider (e.g. `"openai"`, `"vertex_ai"`, `"anthropic"`). * Raw provider attributes on the `raw_gen_ai_request` child span use a `llm.None.*` prefix (e.g. `llm.None.output`, `llm.None.model`) instead of `llm.openai.*` or `llm.vertex_ai.*`. **Tracking:** [BerriAI/litellm#25240](https://github.com/BerriAI/litellm/issues/25240); fix in flight via [PR #25309](https://github.com/BerriAI/litellm/pull/25309) (scoped to the Responses API; `/v1/messages` and Gemini may need follow-up after merge). ### Gemini streaming variant — `gen_ai.response.model` not set `/v1beta/models/{model}:streamGenerateContent` does not emit `gen_ai.response.model` on the parent span, even though the non-streaming `:generateContent` variant does. Likely lives in LiteLLM's Gemini streaming aggregation path. Low impact; not yet filed upstream. ### Summary — what works and what doesn't, by endpoint | Endpoint | Span type | Tokens | Cost | Input messages | Output messages | System prompt | Provider | | ----------------------------------------------------------------- | --------- | ------ | ---- | ------------------ | ------------------------ | ----------------- | -------------------------------------- | | `/chat/completions` | `llm` | ✅ | ✅ | ✅ | ✅ | ✅ (in `messages`) | ✅ | | `/completions` (text) | `llm` | ✅ | ✅ | ✅ | ✅ | n/a | ✅ | | `/v1/responses`, `/responses` | `llm` | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | | `/v1/messages` (Anthropic) | `llm` | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | | `/v1beta/...:generateContent` | `llm` | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | | `/v1beta/...:streamGenerateContent` | `llm` | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ (also missing `response.model`) | | `/embeddings`, `/moderations`, `/images/*`, `/audio/*`, `/rerank` | `chain` | ✅ | ✅ | ✅ where applicable | n/a (no text completion) | n/a | ✅ for `/chat/completions`, ❌ elsewhere | | Internal infra (`self`, `router`, `proxy_pre_call`) | `chain` | n/a | n/a | n/a | n/a | n/a | n/a | These caveats will resolve as the upstream LiteLLM PRs land. Fiddler will pick up the improvements automatically — no Fiddler-side changes will be needed when LiteLLM fixes ship. *** ## Guardrails Fiddler implements the LiteLLM Generic Guardrail API spec, letting you plug Fiddler's real-time guardrails directly into the LiteLLM proxy gateway. Once configured, every request routed through the proxy is checked for secrets, PII, and unsafe content before it reaches the model. See [LiteLLM Guardrails](/protection/litellm-guardrails) for setup instructions, check behavior, and the full API reference. *** ## Related Documentation * [OpenTelemetry Integration](/integrations/agentic-ai/opentelemetry-integration) — Manual OTel instrumentation for custom frameworks * [Strands Agents SDK](/integrations/agentic-ai/strands-sdk) — Native monitoring for Strands agent applications * [LangGraph SDK](/integrations/agentic-ai/langgraph-sdk) — Auto-instrumentation for LangGraph applications * [LiteLLM OTel documentation](https://docs.litellm.ai/docs/proxy/logging#opentelemetry) — LiteLLM's official OpenTelemetry setup guide # OpenTelemetry Integration Source: https://docs.fiddler.ai/integrations/agentic-ai/opentelemetry-integration Connect custom AI agents and multi-framework agentic applications to Fiddler using OpenTelemetry's OTLP protocol for comprehensive observability. ## Overview Fiddler supports native OpenTelemetry integration through the OTLP (OpenTelemetry Protocol) standard, enabling you to monitor custom AI agents and multi-framework environments with full observability. This integration provides a vendor-neutral approach to collecting telemetry data from your agentic applications, allowing you to instrument agents built with any framework or custom implementation. The OpenTelemetry integration maps your agent's span attributes to Fiddler's semantic conventions, capturing LLM calls, tool executions, agent chains, and custom business metrics. This approach is ideal for teams running multiple agentic frameworks or building custom agent architectures that require unified monitoring across diverse technologies. With OpenTelemetry, you maintain complete control over your instrumentation while benefiting from Fiddler's advanced analytics, trace visualization, cost tracking, and performance monitoring capabilities. ## When to Use OpenTelemetry Integration Use OpenTelemetry integration when: * **Multi-framework environments**: You're using multiple agent frameworks and need unified observability * **Custom agent architectures**: Your agent framework doesn't have a dedicated Fiddler SDK * **Advanced instrumentation control**: You need fine-grained control over trace attributes and sampling * **Standards-based approach**: You want a vendor-neutral telemetry solution using industry standards * **Existing OpenTelemetry setup**: You're already using OpenTelemetry and want to route traces to Fiddler **When to Use Fiddler SDKs Instead** For specific frameworks with dedicated SDKs, we recommend using the framework-specific integration for easier setup and automatic instrumentation: * **LangGraph and LangChain** → [Use Fiddler LangGraph SDK](/sdk-api/langgraph/fiddler-client) * **Strands Agents** → Use [Strands Agents SDK](/sdk-api/strands/strands-agent-instrumentor) These SDKs provide auto-instrumentation and require significantly less code to set up. ## Quick Links ### Getting Started * [**OpenTelemetry Quick Start Guide**](/developers/quick-starts/opentelemetry-quick-start) - Step-by-step guide to integrate OpenTelemetry with Fiddler (\~10-15 minutes) * [**Advanced OpenTelemetry Notebook**](https://github.com/fiddler-labs/fiddler-examples/blob/main/quickstart/latest/Fiddler_Quickstart_OpenTelemetry_Advanced.ipynb) - Comprehensive working examples with production patterns ([Open in Colab](https://colab.research.google.com/github/fiddler-labs/fiddler-examples/blob/main/quickstart/latest/Fiddler_Quickstart_OpenTelemetry_Advanced.ipynb)) ### Related Documentation * [Getting Started: Agentic Observability](/getting-started/agentic-monitoring) - Overview of agentic observability concepts * [Agentic AI Integrations](/integrations/agentic-ai-and-llm-frameworks/agentic-ai) - Compare integration options for different frameworks * [Fiddler LangGraph SDK](/integrations/agentic-ai/langgraph-sdk) - Alternative for LangGraph/LangChain users * [Strands Agents SDK](/integrations/agentic-ai/strands-sdk) - Alternative for Strands agent users ## Supported Features OpenTelemetry integration with Fiddler supports: | Feature | Support | Description | | ------------------------- | ------- | -------------------------------------------------------- | | **LLM Tracing** | ✅ Full | Track LLM calls with prompts, responses, and token usage | | **Tool Execution** | ✅ Full | Monitor tool calls with inputs and outputs | | **Agent Chains** | ✅ Full | Visualize complex agent workflows and decision flows | | **Custom Attributes** | ✅ Full | Add business context with user-defined attributes | | **Conversation Tracking** | ✅ Full | Track multi-turn conversations across sessions | | **Token Cost Analysis** | ✅ Full | Monitor LLM API costs through token tracking | | **Performance Metrics** | ✅ Full | Latency, throughput, and error rate tracking | | **Sampling** | ✅ Full | Configure trace sampling for high-volume applications | | **Batch Processing** | ✅ Full | Optimize network usage with batched exports | | **Compression** | ✅ Full | Reduce data transmission with gzip compression | ## Integration Overview ### Architecture ```mermaid theme={null} graph TB subgraph app["Your AI Agent Application"] sdk["OpenTelemetry SDK
TracerProvider, span creation, attribute mapping"] exporter["OTLP Exporter
batch processing, compression"] sdk --> exporter end exporter -->|"HTTPS (OTLP/HTTP)"| ingest subgraph fiddler["Fiddler Platform"] ingest["OTLP Ingestion Endpoint"] processing["Trace Processing
semantic validation, attribute extraction"] analytics["Analytics and Visualization
dashboards, alerts, cost tracking"] ingest --> processing --> analytics end style sdk fill:#e1f5ff style exporter fill:#e1f5ff style ingest fill:#e6ffe6 style processing fill:#e6ffe6 style analytics fill:#e6ffe6 ``` ### Required Setup 1. **Environment Configuration** * Set `OTEL_EXPORTER_OTLP_ENDPOINT` to your Fiddler instance URL * Configure `OTEL_EXPORTER_OTLP_HEADERS` with authentication and application ID * Set `OTEL_RESOURCE_ATTRIBUTES` with your application UUID 2. **OpenTelemetry Initialization** * Install OpenTelemetry packages * Initialize `TracerProvider` with proper configuration * Configure `OTLPSpanExporter` for Fiddler endpoint * Add `BatchSpanProcessor` for efficient transmission 3. **Span Instrumentation** * Create spans for agent operations (chains, LLM calls, tools) * Map attributes to Fiddler semantic conventions * Add custom business context as needed ## Attribute Mapping Fiddler requires specific attributes to properly process and visualize your traces: ### Required Attributes **Resource Level:** * `application.id` - Your Fiddler application UUID (UUID4 format) **Span Level:** * `fiddler.span.type` - Type of operation: `chain`, `llm`, `tool`, or `agent` ### Optional Attributes * **Agent**: `gen_ai.agent.name` - Name of your AI agent. If provided, set on **every span in the trace** so all spans are attributed to the correct agent. * **Agent**: `gen_ai.agent.id` - Unique identifier for the agent. If provided, set on **every span in the trace** alongside `gen_ai.agent.name`. * **LLM Spans**: Model, system prompt, user input, output, token usage * **Tool Spans**: Tool name, input JSON, output JSON * **Conversation**: `gen_ai.conversation.id` for session tracking * **Custom**: `fiddler.session.user.*` and `fiddler.span.user.*` for business context ## Getting Started Ready to integrate OpenTelemetry with Fiddler? 1. [**Follow the Quick Start Guide**](/developers/quick-starts/opentelemetry-quick-start) - Complete setup in 10-15 minutes 2. [**Explore the Advanced Notebook**](https://github.com/fiddler-labs/fiddler-examples/blob/main/quickstart/latest/Fiddler_Quickstart_OpenTelemetry_Advanced.ipynb) - Learn production patterns 3. **Review the attribute reference** - Understand required and optional attributes 4. **Test your integration** - Verify traces appear in Fiddler dashboard ## Example: Instrumenting a Custom Agent While OpenTelemetry integration works with any framework, here's a basic example: `tracer.start_as_current_span()` can be used as a function decorator (recommended when a span wraps an entire function) or as a context manager (when you need a span narrower than a function). Both are pure OpenTelemetry — no Fiddler SDK required. ```python theme={null} from opentelemetry import trace tracer = trace.get_tracer(__name__) # Recommended: decorate the function to span its full execution @tracer.start_as_current_span("custom_agent") def run_agent(user_request: str): span = trace.get_current_span() span.set_attribute("fiddler.span.type", "chain") span.set_attribute("gen_ai.agent.name", "my_agent") # optional span.set_attribute("gen_ai.agent.id", "my_agent_v1") # optional # Alternative: use a context manager for a span narrower than the # function — wrapping just one section instead of the whole call. with tracer.start_as_current_span("db_lookup") as section_span: section_span.set_attribute("fiddler.span.type", "tool") # ... a specific section of code # ... rest of your agent code ``` # Exporting OTel Traces to Fiddler Source: https://docs.fiddler.ai/integrations/agentic-ai/otel-trace-export Map pre-existing OpenTelemetry span attributes to Fiddler's schema and export them to the v1/traces protobuf endpoint from your own storage or pipeline. # Exporting OTel Traces to Fiddler ## Overview This guide covers the **client-side export** scenario: your application has already generated OpenTelemetry traces, you manage their storage and processing, and you need to ship them to Fiddler. You are responsible for: 1. **Attribute mapping** — translating your OTel span attributes to Fiddler's schema 2. **Protobuf serialization** — building `ResourceSpans → ScopeSpans → Span` structures 3. **Export** — POSTing the compressed payload to Fiddler's `v1/traces` endpoint This differs from [live instrumentation](/integrations/agentic-ai/opentelemetry-integration), where the OTel SDK exports spans automatically as your agent runs. **When to use this approach** Use client-side export when you have: * Traces stored in a data warehouse, JSONL files, or a logging pipeline that you want to replay into Fiddler * A custom export pipeline that processes spans before sending (e.g., filtering, enrichment, or ID regeneration) * Batch backfill of historical trace data For real-time agent instrumentation, use the [OpenTelemetry Integration](/integrations/agentic-ai/opentelemetry-integration) or a framework SDK instead. *** ## Prerequisites * A Fiddler account with a GenAI application created — you will need its **Application UUID** * A valid **Fiddler API token** (from **Settings** > **Credentials**) * Python packages: ```bash theme={null} pip install opentelemetry-proto httpx ``` *** ## The v1/traces Endpoint Send traces as a gzip-compressed protobuf `ExportTraceServiceRequest` payload: | Property | Value | | -------------------------- | ------------------------------------------- | | **URL** | `https:///v1/traces` | | **Method** | `POST` | | **Content-Type** | `application/x-protobuf` | | **Content-Encoding** | `gzip` | | **Authorization** | `Bearer ` | | **fiddler-application-id** | `` | ```python theme={null} import gzip import httpx from opentelemetry.proto.collector.trace.v1.trace_service_pb2 import ExportTraceServiceRequest payload = ExportTraceServiceRequest(resource_spans=[...]).SerializeToString() httpx.post( "https://your-instance.fiddler.ai/v1/traces", content=gzip.compress(payload), headers={ "Authorization": "Bearer ", "fiddler-application-id": "", "Content-Type": "application/x-protobuf", "Content-Encoding": "gzip", }, ) ``` *** ## Protobuf Structure Fiddler expects the standard OTLP hierarchy: ``` ExportTraceServiceRequest └── ResourceSpans[] ├── Resource │ └── attributes: [application.id, service.name, ...] └── ScopeSpans[] └── Span[] ├── trace_id, span_id, parent_span_id ├── name, kind, status ├── start_time_unix_nano, end_time_unix_nano └── attributes: [gen_ai.agent.name, fiddler.span.type, ...] ``` **`application.id`** must be set at the **Resource** level (not on individual spans): ```python theme={null} from opentelemetry.proto.resource.v1.resource_pb2 import Resource from opentelemetry.proto.common.v1.common_pb2 import AnyValue, KeyValue resource = Resource(attributes=[ KeyValue(key="application.id", value=AnyValue(string_value="")), KeyValue(key="service.name", value=AnyValue(string_value="my-agent-service")), ]) ``` *** ## AnyValue Typing Each `KeyValue` in the protobuf structure carries its value in an `AnyValue` message. `AnyValue` is a **oneof** — exactly one typed field must be set. Using the correct field ensures Fiddler classifies the data with the right type (e.g., numeric fields enable aggregation, charting, and alerting). | Python type | `AnyValue` field | Fiddler storage type | Example | | ----------- | ---------------- | ------------------------- | --------------------------------- | | `str` | `string_value` | String | `AnyValue(string_value="gpt-4o")` | | `int` | `int_value` | Numeric (stored as float) | `AnyValue(int_value=150)` | | `float` | `double_value` | Numeric (stored as float) | `AnyValue(double_value=0.95)` | | `bool` | `bool_value` | String | `AnyValue(bool_value=True)` | **Use `int_value` / `double_value` for numeric attributes.** If you wrap a number in `string_value` (e.g., `AnyValue(string_value="150")`), Fiddler will treat it as a string column. This means you lose the ability to compute numerical aggregations (sum, average, percentiles) and set alerts on that attribute. ```python theme={null} from opentelemetry.proto.common.v1.common_pb2 import AnyValue def to_any_value(value: str | int | float | bool) -> AnyValue: """ Convert a Python value to a correctly typed AnyValue. :param value: The value to convert. :returns: An AnyValue with the appropriate typed field set. :raises TypeError: If *value* is not a supported type (including ``None`` and ``bytes``). Filter ``None`` values upstream — OTel attributes have no null concept, so omit the attribute instead. For ``bytes``, decode to ``str`` first — Fiddler stores bytes as strings internally. Example:: to_any_value(150) # AnyValue(int_value=150) to_any_value("us-west") # AnyValue(string_value="us-west") """ # bool must be checked before int (bool is a subclass of int in Python) if isinstance(value, bool): return AnyValue(bool_value=value) if isinstance(value, int): return AnyValue(int_value=value) if isinstance(value, float): return AnyValue(double_value=value) if isinstance(value, str): return AnyValue(string_value=value) # For bytes, consider decoding to str to unblock: AnyValue(string_value=value.decode("utf-8")) # For None, consider Filtering upstream, omitting the attribute instead. raise TypeError(f"Unsupported type {type(value).__name__} for AnyValue") ``` For the full attribute quick overview (all attributes, types, and `AnyValue` fields), see [Span and Resource Attributes — Quick Overview](/integrations/agentic-ai/attributes#attribute-quick-overview). *** ## Attribute Mapping Reference ### Span Structure Fields The following fields control the span's structural properties and are **not** sent as span attributes. Map them to the corresponding protobuf `Span` fields instead: | Your field | Protobuf `Span` field | | -------------------- | ------------------------------------------ | | `trace_id` | `trace_id` (bytes, 16 bytes / 32-char hex) | | `span_id` | `span_id` (bytes, 8 bytes / 16-char hex) | | `parent_span_id` | `parent_span_id` (bytes, same format) | | `span_name` / `name` | `name` | | `span_kind` | `kind` (SpanKind enum) | | `status_code` | `status.code` (StatusCode enum) | | `start_time` | `start_time_unix_nano` | | `end_time` | `end_time_unix_nano` | ### Required Span Attributes Every span sent to Fiddler must include this attribute: | Attribute | Description | | ------------------- | --------------------------------------------- | | `fiddler.span.type` | Span type: `llm`, `tool`, `chain`, or `agent` | `application.id` is required at the **Resource** level (see above). ### Span Type: Deriving from gen\_ai.operation.name If your spans follow the GenAI semantic conventions and carry `gen_ai.operation.name`, map it to `fiddler.span.type` as follows: | `gen_ai.operation.name` | `fiddler.span.type` | | ----------------------------- | ------------------- | | `chat` | `llm` | | `execute_tool` | `tool` | | `invoke_agent` | `chain` | | *(any other value or absent)* | `chain` *(default)* | ### LLM Semantic Convention Mappings | Your OTel attribute | Fiddler attribute | Notes | | ---------------------------- | ---------------------------------------------- | ----------------------------------------------------------- | | `gen_ai.input.messages` | `gen_ai.llm.input.user` + `gen_ai.llm.context` | See [message parsing](#parsing-gen_ai-input-messages) below | | `gen_ai.output.messages` | `gen_ai.llm.output` | | | `gen_ai.system_instructions` | `gen_ai.llm.input.system` | | | `gen_ai.response.model` | `gen_ai.request.model` | Fiddler normalises to the request-side attribute | | `gen_ai.usage.input_tokens` | `gen_ai.usage.input_tokens` | Pass through unchanged | | `gen_ai.usage.output_tokens` | `gen_ai.usage.output_tokens` | Pass through unchanged | | `gen_ai.usage.total_tokens` | `gen_ai.usage.total_tokens` | Pass through unchanged | | `gen_ai.system` | `gen_ai.system` | LLM provider identifier (e.g. `openai`) | | `gen_ai.request.model` | `gen_ai.request.model` | Pass through unchanged | ### Tool Semantic Convention Mappings | Your OTel attribute | Fiddler attribute | | ---------------------------- | -------------------- | | `gen_ai.tool.call.arguments` | `gen_ai.tool.input` | | `gen_ai.tool.call.result` | `gen_ai.tool.output` | | `gen_ai.tool.name` | `gen_ai.tool.name` | ### Agent and Conversation Attributes | Your OTel attribute | Fiddler attribute | Notes | | ------------------------ | ------------------------ | ---------------------------------------------------- | | `gen_ai.agent.name` | `gen_ai.agent.name` | Optional | | `gen_ai.agent.id` | `gen_ai.agent.id` | Optional | | `gen_ai.conversation.id` | `gen_ai.conversation.id` | Optional — used for multi-turn conversation grouping | **Set agent attributes on every span.** If `gen_ai.agent.name` or `gen_ai.agent.id` are provided, set both on **every span within the trace**. Fiddler uses these attributes to attribute spans to the correct agent — spans missing these fields will be unattributed even if other spans in the same trace carry them. ### Legacy / Underscore Field Names If your traces use older underscore-style field names, map them to the Fiddler dotted equivalents before serialization: | Legacy field | Fiddler attribute | | ------------------ | ------------------------- | | `model_name` | `gen_ai.request.model` | | `model_provider` | `gen_ai.system` | | `tool_name` | `gen_ai.tool.name` | | `tool_input` | `gen_ai.tool.input` | | `tool_output` | `gen_ai.tool.output` | | `llm_input_system` | `gen_ai.llm.input.system` | | `llm_input_user` | `gen_ai.llm.input.user` | | `llm_output` | `gen_ai.llm.output` | | `llm_context` | `gen_ai.llm.context` | ### Custom User Attributes To attach business-level metadata to spans, prefix your keys with `fiddler.span.user.`: ```python theme={null} # Source field: custom_attributes = {"session_type": "onboarding", "region": "us-west"} # Maps to: span.attributes["fiddler.span.user.session_type"] = "onboarding" span.attributes["fiddler.span.user.region"] = "us-west" ``` These attributes are indexed and queryable in Fiddler's [Explorer](/observability/agentic/trace-explorer). *** ## Parsing gen\_ai.input.messages The `gen_ai.input.messages` attribute is a JSON array of chat-style message objects. Fiddler expects it split into two separate attributes: | Output attribute | Content | | ----------------------- | ------------------------------------------------------------------------- | | `gen_ai.llm.input.user` | Text content of the **last message with `role: user`** | | `gen_ai.llm.context` | All other messages (conversation history), formatted as `[role]: content` | **Example input:** ```json theme={null} [ {"role": "system", "content": "You are a helpful assistant."}, {"role": "user", "content": "What is the capital of France?"}, {"role": "assistant", "content": "Paris."}, {"role": "user", "content": "And Germany?"} ] ``` **Resulting mapping:** | Attribute | Value | | ----------------------- | ----------------------------------------------------------------------------------------------------------- | | `gen_ai.llm.input.user` | `"And Germany?"` | | `gen_ai.llm.context` | `"[system]: You are a helpful assistant.\n\n[user]: What is the capital of France?\n\n[assistant]: Paris."` | If no `user` message is found, all messages are placed in `gen_ai.llm.context` and `gen_ai.llm.input.user` is omitted.
Python implementation ```python theme={null} import json def parse_input_messages(value: str | list) -> dict[str, str]: """ Parse gen_ai.input.messages and split into Fiddler attributes. Extracts the last user message as ``gen_ai.llm.input.user`` and formats all other messages as ``gen_ai.llm.context``. :param value: JSON string or already-parsed list of message dicts. Each message must have a ``role`` key and either a ``content`` string or a ``parts`` list of text objects. :returns: Dict with zero, one, or both of: - ``gen_ai.llm.input.user`` – last user message text - ``gen_ai.llm.context`` – prior conversation history """ # Parse JSON string if needed if isinstance(value, str): try: messages = json.loads(value) except (json.JSONDecodeError, ValueError): return {"gen_ai.llm.input.user": value} else: messages = value if not isinstance(messages, list) or not messages: return {} def extract_content(message: dict) -> str: """Extract plain text from a message object.""" parts = message.get("parts", []) if isinstance(parts, list): text_parts = [ part.get("content", "") if isinstance(part, dict) and part.get("type") == "text" else part for part in parts if isinstance(part, str) or (isinstance(part, dict) and part.get("type") == "text") ] if text_parts: return "\n".join(text_parts) elif isinstance(parts, str): return parts content = message.get("content", "") return content if isinstance(content, str) else str(content) # Find the index of the last user message last_user_idx = next( (i for i in range(len(messages) - 1, -1, -1) if isinstance(messages[i], dict) and messages[i].get("role") == "user"), None, ) result: dict[str, str] = {} if last_user_idx is None: # No user message — put everything in context context_parts = [ f"[{m.get('role', 'unknown')}]: {extract_content(m)}" for m in messages if isinstance(m, dict) ] if context_parts: result["gen_ai.llm.context"] = "\n\n".join(context_parts) return result # Last user message → input.user user_text = extract_content(messages[last_user_idx]) if user_text: result["gen_ai.llm.input.user"] = user_text # All other messages → context context_messages = messages[:last_user_idx] + messages[last_user_idx + 1:] context_parts = [ f"[{m.get('role', 'unknown')}]: {extract_content(m)}" for m in context_messages if isinstance(m, dict) and extract_content(m) ] if context_parts: result["gen_ai.llm.context"] = "\n\n".join(context_parts) return result # Usage attributes = parse_input_messages(span_row["gen_ai.input.messages"]) # e.g. { # "gen_ai.llm.input.user": "And Germany?", # "gen_ai.llm.context": "[system]: You are a helpful assistant.\n\n[user]: What is the capital of France?\n\n[assistant]: Paris." # } ```
*** ## Span Kind and Status Mappings **Span kind** (`SpanKind` enum): | String value | Protobuf value | | ------------ | ------------------------------- | | `INTERNAL` | `SpanKind.INTERNAL` *(default)* | | `SERVER` | `SpanKind.SERVER` | | `CLIENT` | `SpanKind.CLIENT` | | `PRODUCER` | `SpanKind.PRODUCER` | | `CONSUMER` | `SpanKind.CONSUMER` | **Status code** (`StatusCode` enum): | String value | Protobuf value | | ------------ | --------------------------- | | `OK` | `StatusCode.OK` *(default)* | | `ERROR` | `StatusCode.ERROR` | | `UNSET` | `StatusCode.UNSET` | *** ## Minimal End-to-End Example ```python theme={null} import gzip import httpx from opentelemetry.proto.collector.trace.v1.trace_service_pb2 import ExportTraceServiceRequest from opentelemetry.proto.common.v1.common_pb2 import AnyValue, InstrumentationScope, KeyValue from opentelemetry.proto.resource.v1.resource_pb2 import Resource from opentelemetry.proto.trace.v1.trace_pb2 import ResourceSpans, ScopeSpans, Span, Status from opentelemetry.trace import SpanKind from opentelemetry.trace.status import StatusCode FIDDLER_URL = "https://your-instance.fiddler.ai" APP_UUID = "550e8400-e29b-41d4-a716-446655440000" FIDDLER_TOKEN = "your-api-token" # Build a single LLM span span = Span( trace_id=bytes.fromhex("4bf92f3577b34da6a3ce929d0e0e4736"), span_id=bytes.fromhex("00f067aa0ba902b7"), name="chat", kind=SpanKind.INTERNAL.value, start_time_unix_nano=1_700_000_000_000_000_000, end_time_unix_nano=1_700_000_001_000_000_000, status=Status(code=StatusCode.OK.value), attributes=[ KeyValue(key="gen_ai.agent.name", value=AnyValue(string_value="my-agent")), KeyValue(key="fiddler.span.type", value=AnyValue(string_value="llm")), KeyValue(key="gen_ai.request.model", value=AnyValue(string_value="gpt-4o")), KeyValue(key="gen_ai.llm.input.user", value=AnyValue(string_value="What is the capital of France?")), KeyValue(key="gen_ai.llm.output", value=AnyValue(string_value="Paris.")), # Numeric attributes — use int_value so Fiddler registers them as numeric columns KeyValue(key="gen_ai.usage.input_tokens", value=AnyValue(int_value=12)), KeyValue(key="gen_ai.usage.output_tokens",value=AnyValue(int_value=3)), KeyValue(key="gen_ai.usage.total_tokens", value=AnyValue(int_value=15)), # Custom user attributes — use the AnyValue field matching each value's type KeyValue(key="fiddler.span.user.confidence", value=AnyValue(double_value=0.97)), KeyValue(key="fiddler.span.user.region", value=AnyValue(string_value="us-west")), KeyValue(key="fiddler.span.user.is_internal", value=AnyValue(bool_value=False)), ], ) # Wrap in ResourceSpans resource_spans = ResourceSpans( resource=Resource(attributes=[ KeyValue(key="application.id", value=AnyValue(string_value=APP_UUID)), KeyValue(key="service.name", value=AnyValue(string_value="my-agent-service")), ]), scope_spans=[ScopeSpans( scope=InstrumentationScope(name="my-tracer", version="1.0.0"), spans=[span], )], ) # Serialize and compress payload = ExportTraceServiceRequest(resource_spans=[resource_spans]).SerializeToString() # Send response = httpx.post( f"{FIDDLER_URL}/v1/traces", content=gzip.compress(payload), headers={ "Authorization": f"Bearer {FIDDLER_TOKEN}", "fiddler-application-id": APP_UUID, "Content-Type": "application/x-protobuf", "Content-Encoding": "gzip", }, timeout=30.0, ) response.raise_for_status() ``` *** ## Related Documentation * [OpenTelemetry Integration](/integrations/agentic-ai/opentelemetry-integration) — live agent instrumentation via the OTel SDK * [OpenTelemetry Quick Start](/developers/quick-starts/opentelemetry-quick-start) — step-by-step setup guide * [Agentic AI Overview](/integrations/agentic-ai-and-llm-frameworks/agentic-ai) — compare all integration options * [Span and Resource Attributes](/integrations/agentic-ai/attributes) — attribute typing, custom attributes, and how they flow into metrics and alerts # S3 Trace Ingestion Source: https://docs.fiddler.ai/integrations/agentic-ai/s3-trace-ingestion Ingest pre-generated OTLP trace files from Amazon S3 into Fiddler without modifying your application code. Ideal for ECS Fargate, air-gapped environments, or any architecture where direct SDK integration is not possible. # S3 Trace Ingestion ## Overview The Fiddler S3 Connector allows you to ingest OpenTelemetry (OTLP) trace data from Amazon S3 into Fiddler without requiring any live SDK integration. Your application writes OTLP trace files to an S3 bucket (or a compatible object store), and Fiddler's ingestion service automatically discovers, parses, and forwards those traces into the observability platform. This is the recommended approach for: * **Air-gapped or high-security deployments** where direct outbound connections from the application to Fiddler are not permitted * **Batch ingestion pipelines** that transform logs or events into OTLP format and stage them in S3 * **Custom log transformers** that convert raw LangGraph or other framework logs into the Fiddler OTLP format **When to use the SDK instead** If your application can make direct outbound HTTPS requests, the [Fiddler LangGraph SDK](/integrations/agentic-ai/langgraph-sdk) or [Fiddler OTel SDK](/integrations/agentic-ai/fiddler-otel-sdk) provide zero-config auto-instrumentation with no file staging required. Use S3 ingestion only when direct SDK integration is not possible. *** ## Architecture ```mermaid theme={null} graph TB App["Your Application"] App -->|"writes OTLP trace files"| S3 S3["Object Store (S3, GCS, Azure)
(your bucket, your prefix)"] S3 -->|"scans every N seconds"| Manager subgraph "Fiddler Platform" Manager["object-store-ingestion-manager
discovers new files, enqueues them"] Manager --> Worker Worker["object-store-ingestion-worker
downloads, parses, sends to collector"] Worker -->|"OTLP protobuf (HTTP/4318)"| Collector Collector["Fiddler OTEL Collector
authenticates, routes to Kafka → ClickHouse"] Collector --> UI["Fiddler UI
traces visible under your GenAI Application"] end style App fill:#e1f5ff style S3 fill:#fff4e6 style Manager fill:#f0e6ff style Worker fill:#f0e6ff style Collector fill:#e6ffe6 style UI fill:#e6ffe6 ``` *** ## Prerequisites * A Fiddler account with a GenAI **Application** created — you will need its **Application UUID** * A valid **Fiddler API key** (from **Settings → Credentials**) — this is used to authenticate the worker with the OTEL Collector * An **Amazon S3 bucket** (or S3-compatible store) that Fiddler's worker can read from * IAM permissions on the bucket — see [IAM Setup](#iam-setup) below *** ## OTLP File Format Files placed in S3 must be valid OTLP data in one of the supported formats below. All formats use the standard `ExportTraceServiceRequest` schema. ### Supported file extensions | Format | Extensions | Description | | ------------- | --------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- | | OTLP JSON | `.json`, `.json.gz`, `.json.zst` | One `ExportTraceServiceRequest` JSON envelope per file. | | OTLP JSONL | `.jsonl`, `.jsonl.gz`, `.jsonl.zst`, `.ndjson`, `.ndjson.gz`, `.ndjson.zst` | One `ExportTraceServiceRequest` JSON envelope per line, each with a single `resourceSpans` entry. | | OTLP Protobuf | `.binpb`, `.binpb.gz`, `.binpb.zst` | Binary serialized `ExportTraceServiceRequest` protobuf. | Compression is transparent — files with `.gz` (gzip) or `.zst` (zstd) suffixes are decompressed automatically before parsing. Configure `file_extensions` on the ingestion source to match the format your pipeline produces. ### Required JSON structure ```json theme={null} { "resourceSpans": [ { "resource": { "attributes": [ { "key": "application.id", "value": { "stringValue": "" } }, { "key": "service.name", "value": { "stringValue": "your-service-name" } } ] }, "scopeSpans": [ { "scope": { "name": "your-tracer-name", "version": "1.0.0" }, "spans": [ { "traceId": "", "spanId": "", "parentSpanId": "", "name": "agent_invocation", "kind": 1, "startTimeUnixNano": "1744200000000000000", "endTimeUnixNano": "1744200005500000000", "status": { "code": 1 }, "attributes": [ { "key": "fiddler.span.type", "value": { "stringValue": "llm" } } ] } ] } ] } ] } ``` ### Critical fields | Field | Description | Notes | | --------------------------------------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | | `resource.attributes["application.id"]` | **Fiddler Application UUID** | **Must match** the application UUID in your Fiddler instance. This routes spans to the correct application in the UI. | | `startTimeUnixNano` / `endTimeUnixNano` | Span timestamps as nanoseconds since Unix epoch | Must reflect the **actual time** of each event. Wrong timestamps cause spans to appear in the wrong time range in the UI. | | `traceId` | 16-byte trace identifier | Accepted as **base64** (`S/kvNXezTaajzpKdDg5HNg==`) or **hex** (`4bf92f3577b34da6a3ce929d0e0e4736`). Fiddler auto-normalizes hex to base64. | | `spanId` | 8-byte span identifier | Same encoding rules as `traceId`. | | `parentSpanId` | Parent span ID | Set to `""` (empty string) for root spans. | | `fiddler.span.type` | Span type for Fiddler's UI | Recommended values: `llm`, `tool`. See [Supported span types](#supported-span-types-and-attributes) below. | **`application.id` must be in the file** The `application.id` resource attribute inside the OTLP file is the source of truth for routing spans to the correct Fiddler application. The `application_ids` field on the ingestion source (see below) is used for access control only — it does **not** override the `application.id` in the span data. If these do not match, spans will be ingested but will not appear under your application in the UI. ### Supported span types and attributes | `fiddler.span.type` | Key attributes | | ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `llm` | `gen_ai.system`, `gen_ai.request.model`, `gen_ai.llm.input.user`, `gen_ai.llm.input.system`, `gen_ai.llm.output`, `gen_ai.usage.input_tokens`, `gen_ai.usage.output_tokens` | | `tool` | `gen_ai.tool.name`, `gen_ai.tool.input`, `gen_ai.tool.output` | | `agent` | `gen_ai.agent.name`, `gen_ai.agent.id` | | `chain` *(legacy — LangChain)* | `gen_ai.agent.name`, `gen_ai.agent.id`, `gen_ai.conversation.id` | For the full attribute reference including all supported keys and their types, see [Span and Resource Attributes](/integrations/agentic-ai/attributes). Custom span attributes can be added using the `fiddler.span.user.*` namespace: ```json theme={null} { "key": "fiddler.span.user.risk_rating", "value": { "stringValue": "Moderate-High" } } ``` *** **Platform enablement required** The S3 connector must be enabled for your Fiddler environment before use. Contact your **Fiddler account team or platform admin** to request enablement. Once confirmed, proceed with the steps below to set up your ingestion source. ## Setting Up the Ingestion Source Create an ingestion source via the Fiddler REST API to tell the connector where to look in S3. ### API endpoint ``` POST /v3/ingestion-sources ``` ### Request body ```json theme={null} { "name": "my-agent-traces", "description": "Production LangGraph agent traces from ECS Fargate", "provider": "s3", "region": "us-west-2", "bucket": "my-company-traces", "prefix": "fiddler/prod/", "scan_interval_seconds": 60, "file_extensions": [".json"], "credential_type": "iam_role", "role_arn": "arn:aws:iam::123456789012:role/my-ingestion-role", "application_ids": [""] } ``` ### Request fields | Field | Required | Description | | ----------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `name` | ✅ | Unique name for this ingestion source (1–255 characters) | | `bucket` | ✅ | S3 bucket name (without `s3://` prefix) | | `application_ids` | ✅ | List containing exactly one Fiddler application UUID (v1 enforces 1:1) | | `provider` | ❌ | Object store provider. Default: `"s3"`. One of: `s3`, `gcs`, `azure` | | `region` | ❌ | AWS region of the bucket (e.g. `"us-west-2"`). Optional | | `prefix` | ❌ | S3 key prefix to scan (e.g. `"traces/prod/"`). Default: `""` (scan entire bucket) | | `file_extensions` | ❌ | List of file extensions to process. Default: `[".json"]`. Supported values: `.json`, `.json.gz`, `.json.zst`, `.jsonl`, `.jsonl.gz`, `.jsonl.zst`, `.ndjson`, `.ndjson.gz`, `.ndjson.zst`, `.binpb`, `.binpb.gz`, `.binpb.zst` | | `credential_type` | ❌ | `"iam_role"` (default) to use an IAM role, or `"access_key"` for static access key/secret | | `access_key_id` | ❌ | Required when `credential_type` is `"access_key"`. Write-only, never returned in responses | | `secret_access_key` | ❌ | Required when `credential_type` is `"access_key"`. Write-only, never returned in responses | | `role_arn` | ❌ | IAM role ARN to assume via STS (cross-account). Omit to use the worker's node IAM role | | `external_id` | ❌ | STS external ID for cross-account role assumption. Write-only, never returned in responses | | `endpoint_url` | ❌ | Custom endpoint URL for S3-compatible stores (e.g. MinIO). Default: `null` | | `scan_interval_seconds` | ❌ | How often the manager scans for new files. Default: `60`. Minimum: `10` | | `description` | ❌ | Optional description (max 1000 characters) | ### Example using Python ```python theme={null} import requests FIDDLER_URL = "https://your-instance.fiddler.ai" API_KEY = "your-api-key" APPLICATION_ID = "your-application-uuid" response = requests.post( f"{FIDDLER_URL}/v3/ingestion-sources", headers={ "Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json", }, json={ "name": "my-agent-traces", "description": "Agent traces from S3", "provider": "s3", "region": "us-west-2", "bucket": "my-traces-bucket", "prefix": "traces/", "scan_interval_seconds": 60, "file_extensions": [".json"], "credential_type": "iam_role", "application_ids": [APPLICATION_ID], }, ) print(response.json()) ``` *** ## IAM Setup The Fiddler worker needs read access to your S3 bucket. The recommended approach is an IAM role. ### Minimum required IAM policy ```json theme={null} { "Version": "2012-10-17", "Statement": [ { "Sid": "FiddlerS3ReadAccess", "Effect": "Allow", "Action": [ "s3:GetObject", "s3:ListBucket" ], "Resource": [ "arn:aws:s3:::my-traces-bucket", "arn:aws:s3:::my-traces-bucket/traces/*" ] } ] } ``` ### Encrypted buckets (SSE-KMS) If your bucket is encrypted with a **customer-managed KMS key (CMK)**, the worker needs decrypt permission on that key in addition to the S3 actions above. Without it, `s3:GetObject` succeeds at the S3 authorization step but the request fails at the decryption step, and the file is marked `failed` with an error like: ``` AccessDenied ... not authorized to perform: kms:Decrypt on resource: arn:aws:kms:...:key/... because no identity-based policy allows the kms:Decrypt action ``` Add the following statement to the role's IAM policy, alongside the `FiddlerS3ReadAccess` statement: ```json theme={null} { "Sid": "FiddlerKmsDecrypt", "Effect": "Allow", "Action": [ "kms:Decrypt", "kms:DescribeKey" ], "Resource": "arn:aws:kms:us-west-2:123456789012:key/" } ``` `kms:Decrypt` is the only permission strictly required for the read path; `kms:DescribeKey` is optional but commonly included for diagnostics. KMS access is gated by **two policies evaluated together** — the role's IAM policy **and** the KMS key policy. If the key policy keeps the default `arn:aws:iam::123456789012:root` / `kms:*` delegation, granting `kms:Decrypt` in the IAM policy above is sufficient. If that delegation was removed or restricted, you must also add the worker role as an allowed principal in the **KMS key policy** with `kms:Decrypt` and `kms:DescribeKey`. Buckets encrypted with **SSE-S3 (AES-256)** or the **AWS-managed `aws/s3` key** do not require any extra KMS permissions. ### Options | Option | How to configure | When to use | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------ | | **EKS Node IAM Role** | Grant the Fiddler worker node's IAM role access to your bucket. Omit `role_arn` in the API request. | Same AWS account, simple setup | | **Cross-account IAM Role** | Create a role in your account with a trust policy allowing Fiddler's worker role to assume it. Set `role_arn` in the API request. | Cross-account or tighter security boundary | *** ## Monitoring File Processing Status ### Aggregate stats Get a summary count of files by status and total spans ingested: ``` GET /v3/ingestion-sources/{source_id}/stats ``` ```bash theme={null} curl -H "Authorization: Bearer " \ "https://your-instance.fiddler.ai/v3/ingestion-sources//stats" ``` Example response: ```json theme={null} { "data": { "source_id": "", "total_files": 10, "pending": 2, "processing": 1, "completed": 6, "failed": 1, "total_spans_ingested": 342, "last_file_completed_at": "2026-04-10T09:38:22Z", "last_file_failed_at": null } } ``` ### Per-file list List individual files with their status: ``` GET /v3/ingestion-sources/{source_id}/files ``` ```bash theme={null} curl -H "Authorization: Bearer " \ "https://your-instance.fiddler.ai/v3/ingestion-sources//files" ``` ### File statuses | Status | Meaning | | ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `pending` | Discovered by the manager, queued for processing. Also the status a file returns to after a transient error when retries remain (`retries` counter increments each time). | | `processing` | Worker is currently downloading and parsing the file | | `completed` | Successfully ingested. `spans_count` shows how many spans were sent | | `failed` | Permanently failed. Either a non-retryable error (e.g. malformed OTLP data, auth error) or all retries exhausted. Check `error_message` for details. Use the retry API to re-queue. | ### Example response ```json theme={null} { "data": { "items": [ { "id": 1, "s3_key": "traces/sample_trace.json", "file_size_bytes": 10097, "status": "completed", "error_message": null, "spans_count": 4, "retries": 0, "max_retries": 3, "processed_at": "2026-04-10T09:38:22Z", "created_at": "2026-04-10T09:38:18Z" } ] } } ``` ### Retry a failed file Retry a single failed file: ``` POST /v3/ingestion-sources/{source_id}/files/{file_id}/retry ``` Bulk retry all failed files for a source at once: ``` POST /v3/ingestion-sources/{source_id}/retry-failed ``` *** ## Testing the Connection Before uploading production traces, verify that the ingestion source can reach your bucket: ``` POST /v3/ingestion-sources/{source_id}/test ``` ```bash theme={null} curl -X POST \ -H "Authorization: Bearer " \ "https://your-instance.fiddler.ai/v3/ingestion-sources//test" ``` A successful response returns `{ "status": "success", "files_found": N }` where `files_found` is the number of files discovered under the configured prefix. A failure returns `{ "status": "error", "message": "" }` (e.g. `AccessDenied`, `NoSuchBucket`). *** ## Generating OTLP Files with the Fiddler SDK If your application can write files locally (but cannot send traces directly to Fiddler), you can use the Fiddler LangGraph SDK's built-in OTLP file capture and upload the files to S3 separately. ```python theme={null} from fiddler_langgraph import FiddlerClient client = FiddlerClient( application_id="your-application-uuid", otlp_enabled=False, # Do not send traces directly to Fiddler otlp_json_capture_enabled=True, otlp_json_output_dir="./traces", # Directory to write OTLP JSON files ) ``` Each LangGraph invocation writes one OTLP JSON file to `./traces/`. Upload these files to your S3 bucket using the AWS CLI or any S3 client: ```bash theme={null} aws s3 sync ./traces/ s3://my-traces-bucket/traces/ ``` For environments where local file writes are also not possible (e.g. ECS Fargate with read-only filesystems), generate the OTLP JSON in memory and stream it directly to S3 using `boto3.client('s3').put_object()` without writing to disk. *** ## Troubleshooting ### Spans not appearing in the UI | Symptom | Likely cause | Fix | | ---------------------------------------------------------- | ----------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | File `status: completed` but no spans visible | Time range filter in UI doesn't cover the span timestamps | Change the UI date range to match `startTimeUnixNano` in your files | | File `status: completed` but spans under wrong application | `application.id` in the file doesn't match the Fiddler application UUID | Update your transformer to embed the correct `application.id` as a resource attribute | | File `status: failed` with `invalid TraceID length` | `traceId` / `spanId` encoded incorrectly | Use 32-char hex or standard base64. Fiddler auto-normalizes hex; avoid other encodings | | File `status: failed` with `AccessDenied` | Worker IAM role lacks `s3:GetObject` on your bucket | Update the IAM policy — see [IAM Setup](#iam-setup) | | File `status: failed` with `kms:Decrypt` `AccessDenied` | Bucket uses SSE-KMS and the worker role lacks `kms:Decrypt` on the CMK | Add `kms:Decrypt` + `kms:DescribeKey` to the role's IAM policy, and ensure the KMS key policy allows the role — see [Encrypted buckets (SSE-KMS)](#encrypted-buckets-sse-kms) | | File `status: failed` with `CredentialError` | `OTEL_COLLECTOR_AUTH_TOKEN` not configured on the worker | Contact your Fiddler admin to configure the collector auth token | | Files never appear (stuck in `pending`) | Manager cannot list the bucket | Check `s3:ListBucket` permission and that `prefix` is correct | ### Verifying file format locally Use the following Python snippets to validate your OTLP files before uploading: **JSON (`.json`):** ```python theme={null} import json from google.protobuf.json_format import ParseDict from opentelemetry.proto.trace.v1.trace_pb2 import ResourceSpans with open("my_trace.json") as f: data = json.load(f) for rs_dict in data["resourceSpans"]: try: rs = ParseDict(rs_dict, ResourceSpans()) print(f"OK: {sum(len(ss.spans) for ss in rs.scope_spans)} spans") except Exception as e: print(f"ERROR: {e}") ``` **JSONL (`.jsonl`):** ```python theme={null} import json from google.protobuf.json_format import ParseDict from opentelemetry.proto.collector.trace.v1.trace_service_pb2 import ExportTraceServiceRequest with open("my_trace.jsonl") as f: for i, line in enumerate(f, 1): line = line.strip() if not line: continue try: data = json.loads(line) req = ParseDict(data, ExportTraceServiceRequest()) spans = sum(len(ss.spans) for rs in req.resource_spans for ss in rs.scope_spans) print(f"Line {i} OK: {spans} spans") except Exception as e: print(f"Line {i} ERROR: {e}") ``` **Protobuf (`.binpb`):** ```python theme={null} from opentelemetry.proto.collector.trace.v1.trace_service_pb2 import ExportTraceServiceRequest with open("my_trace.binpb", "rb") as f: data = f.read() try: req = ExportTraceServiceRequest() req.ParseFromString(data) spans = sum(len(ss.spans) for rs in req.resource_spans for ss in rs.scope_spans) print(f"OK: {spans} spans across {len(req.resource_spans)} resourceSpans") except Exception as e: print(f"ERROR: {e}") ``` *** ## File Naming and Organization The S3 connector processes every file under the configured `prefix` that matches the configured `file_extensions`. Supported extensions include `.json`, `.jsonl`, `.binpb`, and their compressed variants (`.gz`, `.zst`). Once a file is processed (whether `completed` or `failed`), it is not reprocessed unless you call the retry API. **Recommended S3 key structure:** ``` traces/ 2026/04/10/ agent-run-abc123.json agent-run-def456.json 2026/04/11/ agent-run-ghi789.json ``` This date-partitioned layout makes it easy to manage retention policies and audit ingestion history. *** ## Related Documentation * [Exporting OTel Traces to Fiddler](/integrations/agentic-ai/otel-trace-export) — client-side protobuf export for custom pipelines * [Fiddler LangGraph SDK](/integrations/agentic-ai/langgraph-sdk) — direct SDK integration for LangGraph applications * [OpenTelemetry Integration](/integrations/agentic-ai/opentelemetry-integration) — live OTLP export for custom agent frameworks * [Fiddler OTel SDK](/integrations/agentic-ai/fiddler-otel-sdk) — decorator-based tracing for custom Python agents # Fiddler Strands SDK Source: https://docs.fiddler.ai/integrations/agentic-ai/strands-sdk Native monitoring for Strands Agents with Strands Agents SDK [![PyPI](https://img.shields.io/pypi/v/fiddler-strands)](https://pypi.org/project/fiddler-strands/) Monitor Strands Agent applications with Fiddler's purpose-built SDK. The Strands Agents SDK provides deep visibility into agent reasoning, tool execution, and multi-agent coordination for Strands-based agent applications. **Platform Compatibility:** Works with Strands agents deployed on any platform, including AWS Bedrock, custom infrastructure, or other cloud providers. ## What You'll Need * Fiddler account (cloud or on-premises) * Strands agent application * Python 3.10 or higher * Fiddler API key ## Quick Start ```bash theme={null} # Step 1: Install (uv recommended) uv add fiddler-strands # or: pip install fiddler-strands ``` ```python theme={null} # Step 2: Set up telemetry and instrumentation import os from strands.telemetry import StrandsTelemetry from fiddler_strandsagents import StrandsAgentInstrumentor strands_telemetry = StrandsTelemetry() strands_telemetry.setup_otlp_exporter() # Sends to Fiddler StrandsAgentInstrumentor(strands_telemetry).instrument() # Step 3: Create your Strands agent as usual from strands import Agent from strands.models.openai import OpenAIModel model = OpenAIModel(api_key=os.getenv("OPENAI_API_KEY")) agent = Agent(model=model, system_prompt="You are a helpful assistant") # Step 4: Agent calls are automatically traced response = agent("Hello, how are you?") ``` **Prerequisites:** Configure OpenTelemetry environment variables for Fiddler integration: ```bash theme={null} export OTEL_EXPORTER_OTLP_ENDPOINT="https://your-fiddler-instance.com" export OTEL_EXPORTER_OTLP_HEADERS="authorization=Bearer ,fiddler-application-id=" ``` ## What Gets Monitored ### Strands Agent Operations * **Agent Invocations** - Full request/response capture with timing * **Tool Execution** - Tool and API call tracking * **Knowledge Base Queries** - RAG retrieval and context usage * **Prompt Orchestration** - Prompt templates and LLM interactions * **Session Management** - Multi-turn conversation tracking ### Strands-Specific Metrics * **Reasoning Traces** - Agent thought process and decision-making * **Tool Execution** - Success rates, latency, error patterns * **Knowledge Retrieval** - Relevance scores, source attribution * **Multi-Agent Coordination** - Cross-agent communication patterns * **Infrastructure Metrics** - Platform-specific infrastructure calls ## Configuration Options ### Environment Variables (OpenTelemetry Standard) The SDK uses standard OpenTelemetry environment variables for configuration: ```bash theme={null} # Required - Fiddler OTLP endpoint export OTEL_EXPORTER_OTLP_ENDPOINT="https://your-fiddler-instance.com" # Required - Fiddler authentication and application ID export OTEL_EXPORTER_OTLP_HEADERS="authorization=Bearer ,fiddler-application-id=" # Optional - Application metadata export OTEL_RESOURCE_ATTRIBUTES="application.id=,service.name=my-agent,deployment.environment=production" # Required - OpenAI API key (for running agents) export OPENAI_API_KEY="sk-..." ``` See the [Quick Start Guide](/developers/quick-starts/strands-agent-quick-start) for detailed configuration steps. ### Programmatic Configuration ```python theme={null} from strands.telemetry import StrandsTelemetry from fiddler_strandsagents import StrandsAgentInstrumentor # Basic setup strands_telemetry = StrandsTelemetry() strands_telemetry.setup_console_exporter() # Optional: for debugging strands_telemetry.setup_otlp_exporter() # Sends to Fiddler StrandsAgentInstrumentor(strands_telemetry).instrument() # All agents created after this point are automatically instrumented ``` ## Example Applications ### Customer Service Agent with Tools ```python theme={null} import os from strands import Agent, tool from strands.models.openai import OpenAIModel from strands.telemetry import StrandsTelemetry from fiddler_strandsagents import StrandsAgentInstrumentor, set_conversation_id # Set up instrumentation strands_telemetry = StrandsTelemetry() strands_telemetry.setup_otlp_exporter() StrandsAgentInstrumentor(strands_telemetry).instrument() # Define tools @tool def lookup_order(order_id: str) -> str: """Look up customer order details.""" return f"Order {order_id}: Shipped, arriving Tuesday" @tool def check_inventory(product: str) -> str: """Check product inventory.""" return f"{product}: 42 units in stock" # Create agent with tools model = OpenAIModel(api_key=os.getenv("OPENAI_API_KEY")) agent = Agent( model=model, system_prompt="You are a helpful customer service agent.", tools=[lookup_order, check_inventory] ) # Track conversation set_conversation_id(agent, "customer-12345") # Use agent - all interactions automatically traced to Fiddler: # - Agent reasoning steps # - Tool calls (lookup_order, check_inventory) # - Response generation response = agent("What's the status of order #789?") ``` ### Multi-Agent System ```python theme={null} from strands import Agent from strands.models.openai import OpenAIModel # All agents are automatically instrumented after setup model = OpenAIModel(api_key=os.getenv("OPENAI_API_KEY")) # Create specialized agents with unique IDs verification_agent = Agent( model=model, system_prompt="You verify user identity", agent_id="verification-agent" ) account_agent = Agent( model=model, system_prompt="You create user accounts", agent_id="account-agent" ) # Each agent appears separately in Fiddler with full trace visibility ``` [**View complete example →**](https://github.com/fiddler-labs/fiddler-examples/blob/main/quickstart/latest/Fiddler_Quickstart_Strands_Agent_Integration.ipynb) ## Viewing Your Data Navigate to Fiddler UI to analyze Strands Agent performance: 1. **Agent Overview** - Overall agent performance metrics 2. **Session Analysis** - Multi-turn conversation flows 3. **Action Group Metrics** - Tool usage patterns and success rates 4. **Knowledge Base Performance** - Retrieval quality and relevance 5. **Cost Tracking** - Token usage and AWS costs per agent ### Key Metrics * **Agent Latency**: P50/P95/P99 response times * **Tool Success Rate**: Percentage of successful action group executions * **Retrieval Quality**: Knowledge base query relevance scores * **Token Usage**: LLM tokens consumed per session * **Error Rates**: Failed invocations by error type ## Advanced Features ### Custom Metadata with Helper Functions The SDK provides helper functions to enrich your traces with custom business context: #### Conversation Tracking ```python theme={null} from fiddler_strandsagents import set_conversation_id, get_conversation_id # Set conversation ID for multi-turn tracking set_conversation_id(agent, 'session_1234567890') # Retrieve it later conversation_id = get_conversation_id(agent) ``` #### Session-Level Attributes ```python theme={null} from fiddler_strandsagents import set_session_attributes, get_session_attributes # Add business context to all spans in this session set_session_attributes(agent, customer_tier="premium", region="us-west", campaign="summer-2024", cost_center="support_team" ) # Retrieve session attributes attributes = get_session_attributes(agent) ``` #### Span-Level Attributes ```python theme={null} from fiddler_strandsagents import set_span_attributes, get_span_attributes # Add attributes to specific components set_span_attributes(model, model_version="gpt-4o-mini", temperature=0.7, max_tokens=1000 ) set_span_attributes(search_tool, department="search", version="2.0", environment="production" ) # Retrieve span attributes model_attrs = get_span_attributes(model) ``` #### LLM Context ```python theme={null} from fiddler_strandsagents import set_llm_context, get_llm_context # Set additional context for LLM interactions # This context will be added to telemetry spans as 'gen_ai.llm.context' set_llm_context(model, 'Available hotels: Hilton, Marriott, Hyatt...') # Retrieve LLM context context = get_llm_context(model) ``` ## Troubleshooting ### Traces Not Appearing in Fiddler **Verify environment variables:** ```bash theme={null} echo $OTEL_EXPORTER_OTLP_ENDPOINT echo $OTEL_EXPORTER_OTLP_HEADERS ``` **Check instrumentation is enabled:** ```python theme={null} from fiddler_strandsagents import StrandsAgentInstrumentor instrumentor = StrandsAgentInstrumentor(strands_telemetry) print(f"Instrumented: {instrumentor.is_instrumented_by_opentelemetry}") ``` **Test with console exporter:** ```python theme={null} # Add console exporter to see traces locally strands_telemetry.setup_console_exporter() ``` ### Missing Agent Attributes on Child Spans **Verify SDK instrumentation:** ```python theme={null} # Ensure StrandsAgentInstrumentor is called StrandsAgentInstrumentor(strands_telemetry).instrument() ``` **Add custom attributes:** ```python theme={null} from fiddler_strandsagents import set_span_attributes set_span_attributes(agent, custom_attr="value") set_span_attributes(model, environment="production") ``` ### Performance Optimization The SDK uses batch span processing by default for minimal overhead. For additional optimization: **Disable console exporter in production:** ```python theme={null} # Only use OTLP exporter in production strands_telemetry.setup_otlp_exporter() # Don't call setup_console_exporter() ``` **Adjust batch processor settings:** ```python theme={null} from opentelemetry.sdk.trace.export import BatchSpanProcessor # Custom batch settings for high-throughput scenarios # (See Advanced Configuration in Quick Start Guide) ``` ## Related Documentation * [**Strands Agents SDK Quick Start** ](/developers/quick-starts/strands-agent-quick-start)- Detailed setup guide * [**Fiddler Evals SDK**](/integrations/agentic-ai/evals-sdk) - Evaluate Strands Agent quality * [**Strands Agents SDK Reference** ](/sdk-api/strands/strands-agent-instrumentor)- Complete class and method documentation # Admin Guide Source: https://docs.fiddler.ai/integrations/aws-sagemaker/partner-ai-app-admin-guide Admin guide to deploy the Fiddler Partner AI App on AWS SageMaker. Configure IAM roles, permissions, and subscriptions for secure AI systems observability. ### Introduction This Admin Guide supplements the official [Amazon SageMaker Partner AI Apps documentation](https://docs.aws.amazon.com/sagemaker/latest/dg/partner-apps.html) with Fiddler-specific guidance and practical examples. While Amazon's documentation provides the foundation for Partner AI Apps, specific implementation details can benefit from additional vendor-specific context. Based on our direct experience deploying the Fiddler Partner AI App in SageMaker environments, this guide offers proven configuration patterns, troubleshooting tips, and concrete examples to help you integrate Fiddler's ML monitoring capabilities into your SageMaker infrastructure. ### SageMaker Partner AI Apps Subscription Prerequisites and Permissions Before proceeding with procurement, the AWS Admin must have some things in place to enable subscription to and deployment of Amazon SageMaker Partner AI Apps as noted in the [Set up Partner AI Apps](https://docs.aws.amazon.com/sagemaker/latest/dg/partner-app-onboard.html) section. #### Prerequisites While Amazon lists both items as optional, having both will help facilitate the deployment and validation processes in the SageMaker console. * A SageMaker AI domain * AWS CLI (latest version) #### Administrative Permissions Configuring the appropriate permissions is an important step. Every organization will have its own security policies and configuration, so the setup will not be identical across organizations. Some of these grants may already be available to admins in a more permissive environment. The key steps are: * Grant permissions to your admin role to complete AWS Marketplace subscriptions * Grant permissions for SageMaker AI to run other AWS operations on the admin's behalf * Set up an execution role for the Partner AI App (note this role will be needed when deploying the Fiddler Partner AI App) * Create an AWS License Manager service-linked role or confirm one exists * Grant permissions for the Fiddler Partner AI App to access AWS License Manager * Grant Amazon S3 permissions to the execution role Attach the `AWSMarketplaceManageSubscriptions` managed policy to the IAM role you'll use to access the SageMaker AI console and subscribe to Fiddler: ```bash theme={null} aws iam attach-role-policy --role-name YourAdminRole --policy-arn arn:aws:iam::aws:policy:AWSMarketplaceManageSubscriptions ``` Or add the policy through the AWS IAM console. Create and attach the following policy to your administrator role: ```json theme={null} { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "sagemaker:CreatePartnerApp", "sagemaker:DeletePartnerApp", "sagemaker:UpdatePartnerApp", "sagemaker:DescribePartnerApp", "sagemaker:ListPartnerApps", "sagemaker:CreatePartnerAppPresignedUrl", "sagemaker:AddTags", "sagemaker:ListTags", "sagemaker:DeleteTags" ], "Resource": "*" }, { "Effect": "Allow", "Action": [ "iam:PassRole" ], "Resource": "arn:aws:iam::*:role/*", "Condition": { "StringEquals": { "iam:PassedToService": "sagemaker.amazonaws.com" } } } ] } ``` This role allows Fiddler to access the necessary AWS resources: ```bash theme={null} aws iam create-role --role-name PartnerAiAppExecutionRole --assume-role-policy-document '{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": [ "sagemaker.amazonaws.com" ] }, "Action": "sts:AssumeRole" } ] }' ``` ```sh theme={null} # License Manager service-linked roles are typically created automatically # when you first use License Manager features. You can verify if it exists: aws iam get-role --role-name AWSServiceRoleForAWSLicenseManagerRole 2>/dev/null || echo "License Manager service-linked role will be created automatically when first used" # If you need to create it manually (rarely required), use: # aws iam create-service-linked-role --aws-service-name license-manager.amazonaws ``` Comments ```bash theme={null} aws iam put-role-policy --role-name PartnerAiAppExecutionRole --policy-name LicenseManagerPolicy --policy-document '{ "Version": "2012-10-17", "Statement": { "Effect": "Allow", "Action": [ "license-manager:CheckoutLicense", "license-manager:CheckInLicense", "license-manager:ExtendLicenseConsumption", "license-manager:GetLicense", "license-manager:GetLicenseUsage" ], "Resource": "*" } }' ``` To allow access to the required S3 bucket, add the appropriate S3 permissions to the execution role. ``` { "Version": "2012-10-17", "Statement": [ { "Action": [ "s3:ListBucket" ], "Effect": "Allow", "Resource": [ "arn:aws:s3:::SageMaker" ] }, { "Action": [ "s3:GetObject", "s3:PutObject", "s3:DeleteObject" ], "Effect": "Allow", "Resource": [ "arn:aws:s3:::SageMaker/*" ] } ] } ``` #### User Permissions Non-admin users require the following permissions to use the Fiddler Partner AI App: * Grant permissions for SageMaker AI to run other AWS operations on the user's behalf * Add the *sts:TagSession* trust policy to the role used to launch Studio and/or Fiddler * Grant API permission to the IAM role used with the notebook or code editor to enable access to the Fiddler Python client SDK Create and attach this policy to the execution role of the user profile: ```json theme={null} { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "sagemaker:DescribePartnerApp", "sagemaker:ListPartnerApps", "sagemaker:CreatePartnerAppPresignedUrl" ], "Resource": "arn:aws:sagemaker:*:*:partner-app/app-*" } ] } ``` Add the `sts:TagSession` trust policy to the role used to launch Studio or the Fiddler Partner AI App directly: ```json theme={null} { "Effect": "Allow", "Principal": { "Service": "sagemaker.amazonaws.com" }, "Action": [ "sts:AssumeRole", "sts:TagSession" ] } ``` Enable user access to Fiddler's SDK functionality by adding this permission to the Studio execution role or the IAM role used with notebooks outside Studio: ```json theme={null} { "Version": "2012-10-17", "Statement": [ { "Sid": "Statement1", "Effect": "Allow", "Action": [ "sagemaker:CallPartnerAppApi" ], "Resource": [ "arn:aws:sagemaker:region:account:partner-app/app-*" ] } ] } ``` ### Authorization and Authentication Fiddler and Partner AI Apps require user identity propagation to function correctly. For detailed configuration requirements, refer to the [Manage user authorization and authentication](https://docs.aws.amazon.com/sagemaker/latest/dg/partner-app-onboard.html#partner-app-onboard-auth) section in the AWS documentation. **Critical Configuration Points**: * The username format in your identity source must **exactly match** the admin usernames you'll enter during Fiddler deployment * For IAM Identity Center: usernames are typically email addresses * For IAM: usernames match the IAM user or role name * Enable STS identity propagation during Fiddler configuration (this is mandatory) ### Fiddler Partner AI App SageMaker Subscription Process Amazon SageMaker Partner AI Apps are only available through the Amazon Marketplace. Currently, Fiddler is available on a subscription basis or as a 30-day free trial. Partner AI App subscriptions are for software license costs only. The infrastructure necessary to run Partner AI Apps is an additional cost billed to the subscriber under their existing agreement with Amazon. #### Fiddler 30-day Free Trial The 30-day free trial is a fully functional Fiddler Partner AI App deployment with no functional limitations. The number of models allowed for monitoring is capped at five. As the Partner AI App free trials are not intended for production use cases, AWS provides no migration path for upgrading trial deployments to fully subscribed deployments. The 30-day free trial does not include infrastructure costs, which are billed like a full subscription directly to your AWS account per your existing agreement with Amazon. You MUST delete your Fiddler Partner AI App deployment at the end of the 30 days or whenever you wish to stop incurring AWS infrastructure costs. ### Deploying the Fiddler Partner AI App #### Admin Management For the Fiddler Partner AI App, you must enter at least one and up to five root admin users. The usernames entered here must match the identity principal forwarded to the Fiddler UI when launched. * The root users will not be editable once the Fiddler AI App has been deployed * This list of root users will persist in SageMaker AI even if the Fiddler app is deleted and then later redeployed * Admin users created within the Fiddler UI will not persist after the Fiddler Partner AI App deployment is deleted #### Infrastructure Options Amazon SageMaker offers Partner AI Apps in small, medium, and large tier sizes. The subscription tier selection screen will have the most current t-shirt-size use cases and estimated AWS costs to help guide your selection. ### Monitor and Manage Your Fiddler Partner AI App Deployment #### **View Deployment Status** Navigate to the "My Apps" tab in the Partner AI Apps section to view the status of your Fiddler deployment: * **Deployed**: Application is ready for use * **Error**: Issue with deployment; troubleshoot and reconfigure * **Not deployed**: Subscribed but not yet deployed #### **Access Fiddler** Users can access Fiddler in two ways: * From SageMaker Studio: Navigate to Partner AI Apps and select Fiddler * Via pre-signed URL: Generate using the `CreatePartnerAppPresignedUrl` with the [Amazon SageMaker API](https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_CreatePartnerAppPresignedUrl.html) or the [AWS CLI](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/sagemaker/create-partner-app-presigned-url.html) #### **Update Configuration** To update configuration settings: * Navigate to "My Apps" in Partner AI Apps * Select the Fiddler application * Choose "Update" to modify configuration parameters #### **Delete Deployment** To delete the Fiddler deployment: * Navigate to "My Apps" in Partner AI Apps * Select the Fiddler application * Choose "Delete" * Note: This does not cancel your subscription, but it does delete the associated AWS infrastructure ### Troubleshooting #### **Deployment Failure** If deployment fails: * Check IAM roles and permissions * Verify that the execution role has all required permissions * Check CloudWatch logs for detailed error information * Open a support ticket with your AWS support team #### **Access Issues** If users cannot access Fiddler: * Verify that the user IAM permissions include the necessary Partner AI App access * Confirm identity propagation is correctly configured * Check that usernames match between your identity source and Fiddler #### **Python Client Connection Issues** If users cannot connect using the Fiddler Python client: * Verify the `sagemaker:CallPartnerAppApi` permission is configured * Confirm environment variables are correctly set: ```python theme={null} os.environ['AWS_PARTNER_APP_AUTH'] = 'true' os.environ['AWS_PARTNER_APP_ARN'] = '' os.environ['AWS_PARTNER_APP_URL'] = '' ``` The same three environment variables also authenticate trace export from the [Fiddler OTel SDK](/integrations/agentic-ai/fiddler-otel-sdk#running-in-aws-sagemaker) (`fiddler-otel` 1.3.0+) when users instrument GenAI or agentic applications. For OTel tracing, users additionally install the `sagemaker` extra with `pip install "fiddler-otel[sagemaker]"`. ### Additional Resources * [Amazon SageMaker AI Domain Overview](https://docs.aws.amazon.com/sagemaker/latest/dg/gs-studio-onboard.html) * [Partner AI Apps Documentation](https://docs.aws.amazon.com/sagemaker/latest/dg/partner-apps.html) * [AWS Identity and Access Management (IAM) Documentation](https://docs.aws.amazon.com/IAM/latest/UserGuide/introduction.html) # Quick Setup Script Source: https://docs.fiddler.ai/integrations/aws-sagemaker/partner-ai-app-quick-setup-script Quickly set up Fiddler's Partner AI App on SageMaker with our script. Automates IAM roles, permissions, and configuration for fast deployment. ### Introduction This quick setup script automates the complex IAM configuration required to deploy and use the Fiddler Partner AI App on Amazon SageMaker. Setting up Partner AI Apps involves creating multiple IAM roles, configuring over 20 individual permissions across different AWS services, and establishing proper identity propagation—a process that can take hours to complete manually. This script reduces the setup time to minutes, ensuring all general security best practices are followed. #### What This Script Does The script automates the complete setup process, including: * Configuring your existing AWS admin role with Partner AI App permissions * Creating all required IAM roles (execution, user access, and domain roles) * Setting up a SageMaker domain with shared collaboration spaces (if needed) * Generating helper scripts for user access and SDK configuration * Validating each step to ensure successful completion #### Prerequisites Before running this script, ensure you have: * AWS CLI installed and configured with appropriate credentials * An AWS account with permissions to create IAM roles and SageMaker domains * Your AWS account ID and preferred region * An existing VPC and subnet IDs if using VPC mode #### Important Security Considerations * The script creates roles with specific permissions following AWS's principle of least privilege * All credentials are handled securely and cleaned up after use * External IDs are used for role assumption to prevent confused deputy attacks * Review all created IAM policies to ensure they meet your organization's security requirements #### Time Estimate * **With an existing SageMaker domain**: \~5 minutes * **Creating new SageMaker domain**: \~15-20 minutes (includes domain provisioning time) #### Post-Script Steps After the script completes successfully, you'll still need to: 1. Subscribe to Fiddler in the AWS Marketplace 2. Deploy the Fiddler Partner AI App through the SageMaker console 3. Configure admin users during the deployment process The script will provide detailed instructions for these remaining manual steps upon completion. ```bash theme={null} #!/bin/bash # ============================================================================= # COMPLETE FIDDLER PARTNER AI APP & SAGEMAKER SETUP FROM SCRATCH # ============================================================================= # This script follows AWS documentation to: # 1. Set up admin permissions for Fiddler Partner AI App # 2. Create Partner AI App execution role # 3. Create SageMaker Domain with shared space support # 4. Configure shared space for collaboration # 5. Create shared user profile for all AWS users # 6. Set up non-admin user access to Fiddler Partner AI App and SDK # # References: # - https://docs.aws.amazon.com/sagemaker/latest/dg/partner-app-onboard.html # - https://docs.aws.amazon.com/sagemaker/latest/dg/partner-apps-sdk.html # ============================================================================= # CONFIGURATION - UPDATE THESE VALUES BEFORE RUNNING export AWS_ACCOUNT_ID="" export AWS_REGION="" # SageMaker Domain Configuration: Choose your own naming convention export DOMAIN_NAME="fiddler-paa-domain" export SHARED_SPACE_NAME="fiddler-collaboration-space" export SHARED_USER_PROFILE_NAME="fiddler-shared-profile" export VPC_ID="vpc-xxxxxxxxxxxxxxxxxx" # UPDATE: Your VPC ID and Subnet IDs export SUBNET_IDS=( "subnet-xxxxxxxxxxxxxxxxx" "subnet-xxxxxxxxxxxxxxxxx" "subnet-xxxxxxxxxxxxxxxxx" ) export EXISTING_ADMIN_ROLE_NAME="" # Existing AWS admin role export PARTNER_APP_EXECUTION_ROLE_NAME="FiddlerPartnerAppExecutionRole" # Choose your own naming convention export USER_EXECUTION_ROLE_NAME="FiddlerUserExecutionRole" # Choose your own naming convention export USER_ACCESS_ROLE_NAME="FiddlerUserAccessRole" # Choose your own naming convention echo "=== Fiddler Partner AI App & SageMaker Complete Setup ===" echo "" echo "This script will create:" echo " • Partner AI Apps permissions for existing admin role: $EXISTING_ADMIN_ROLE_NAME" echo " • Fiddler Partner AI App execution role" echo " • SageMaker Domain (optionally): $DOMAIN_NAME" echo " • Shared Space: $SHARED_SPACE_NAME" echo " • Shared User Profile: $SHARED_USER_PROFILE_NAME" echo " • User access roles and permissions" echo "" read -p "Continue with setup? (y/n): " CONFIRM if [[ "$CONFIRM" != "y" && "$CONFIRM" != "Y" ]]; then echo "Setup cancelled." exit 0 fi # ============================================================================= # STEP 1: ADD PARTNER AI APPS PERMISSIONS TO EXISTING ADMIN ROLE # ============================================================================= echo "" echo "=== STEP 1: Adding Partner AI Apps Permissions to Existing Admin Role ===" # Verify existing admin role exists echo "Checking existing admin role: $EXISTING_ADMIN_ROLE_NAME" aws iam get-role --role-name "$EXISTING_ADMIN_ROLE_NAME" --query 'Role.RoleName' --output text >/dev/null 2>&1 if [[ $? -ne 0 ]]; then echo "❌ Admin role not found: $EXISTING_ADMIN_ROLE_NAME" echo "" echo "Please update EXISTING_ADMIN_ROLE_NAME variable with your actual admin role name." echo "To list your roles, run:" echo "aws iam list-roles --query 'Roles[*].RoleName' --output table" exit 1 fi echo "✅ Found existing admin role: $EXISTING_ADMIN_ROLE_NAME" # Check if AWS Marketplace permissions are already attached echo "Checking AWS Marketplace permissions..." MARKETPLACE_ATTACHED=$(aws iam list-attached-role-policies --role-name "$EXISTING_ADMIN_ROLE_NAME" --query 'AttachedPolicies[?PolicyArn==`arn:aws:iam::aws:policy/AWSMarketplaceManageSubscriptions`].PolicyName' --output text 2>/dev/null) if [[ -n "$MARKETPLACE_ATTACHED" ]]; then echo "✅ AWS Marketplace permissions already attached" else echo "Adding AWS Marketplace permissions..." aws iam attach-role-policy --role-name "$EXISTING_ADMIN_ROLE_NAME" --policy-arn "arn:aws:iam::aws:policy/AWSMarketplaceManageSubscriptions" echo "✅ AWS Marketplace permissions attached" fi Create Partner AI Apps admin permissions policy echo "Adding Partner AI Apps admin permissions..." cat > partner-ai-admin-policy.json << EOF { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "sagemaker:CreatePartnerApp", "sagemaker:DeletePartnerApp", "sagemaker:UpdatePartnerApp", "sagemaker:DescribePartnerApp", "sagemaker:ListPartnerApps", "sagemaker:CreatePartnerAppPresignedUrl", "sagemaker:AddTags", "sagemaker:ListTags", "sagemaker:DeleteTags" ], "Resource": "*" }, { "Effect": "Allow", "Action": [ "iam:PassRole" ], "Resource": "arn:aws:iam::*:role/*", "Condition": { "StringEquals": { "iam:PassedToService": "sagemaker.amazonaws.com" } } } ] } EOF # Check if Partner AI Apps policy already exists EXISTING_POLICY=$(aws iam get-role-policy --role-name "$EXISTING_ADMIN_ROLE_NAME" --policy-name "PartnerAIAppsAdminPolicy" --query 'PolicyName' --output text 2>/dev/null) if [[ "$EXISTING_POLICY" == "PartnerAIAppsAdminPolicy" ]]; then echo "Partner AI Apps policy already exists, updating..." aws iam put-role-policy --role-name "$EXISTING_ADMIN_ROLE_NAME" --policy-name "PartnerAIAppsAdminPolicy" --policy-document file://partner-ai-admin-policy.json echo "✅ Partner AI Apps policy updated" else echo "Adding new Partner AI Apps policy..." aws iam put-role-policy --role-name "$EXISTING_ADMIN_ROLE_NAME" --policy-name "PartnerAIAppsAdminPolicy" --policy-document file://partner-ai-admin-policy.json echo "✅ Partner AI Apps policy added" fi echo "✅ Existing admin role configured with Partner AI Apps permissions" # ============================================================================= # STEP 2: CREATE FIDDLER PARTNER AI APP EXECUTION ROLE # ============================================================================= echo "" echo "=== STEP 2: Creating Fiddler Partner AI App Execution Role ===" # Create Partner AI App execution role trust policy cat > partner-app-execution-trust-policy.json << EOF { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "sagemaker.amazonaws.com" }, "Action": [ "sts:AssumeRole", "sts:TagSession" ] } ] } EOF # Create Partner AI App execution role echo "Creating Partner AI App execution role..." aws iam create-role --role-name "$PARTNER_APP_EXECUTION_ROLE_NAME" --assume-role-policy-document file://partner-app-execution-trust-policy.json --description "Execution role for Fiddler Partner AI App" # Create AWS License Manager permissions policy (required for Fiddler) echo "Adding AWS License Manager permissions..." cat > license-manager-policy.json << EOF { "Version": "2012-10-17", "Statement": { "Effect": "Allow", "Action": [ "license-manager:CheckoutLicense", "license-manager:CheckInLicense", "license-manager:ExtendLicenseConsumption", "license-manager:GetLicense", "license-manager:GetLicenseUsage" ], "Resource": "*" } } EOF aws iam put-role-policy --role-name "$PARTNER_APP_EXECUTION_ROLE_NAME" --policy-name "LicenseManagerPolicy" --policy-document file://license-manager-policy.json # Add S3 permissions for Fiddler data access echo "Adding S3 permissions for Fiddler..." cat > fiddler-s3-policy.json << EOF { "Version": "2012-10-17", "Statement": [ { "Sid": "FiddlerS3Access", "Effect": "Allow", "Action": [ "s3:GetObject", "s3:PutObject", "s3:DeleteObject", "s3:ListBucket", "s3:GetBucketLocation" ], "Resource": [ "arn:aws:s3:::sagemaker-*", "arn:aws:s3:::sagemaker-*/*" ] }, { "Sid": "FiddlerCloudWatchLogs", "Effect": "Allow", "Action": [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents", "logs:DescribeLogGroups", "logs:DescribeLogStreams" ], "Resource": "arn:aws:logs:*:*:log-group:/aws/sagemaker/*" } ] } EOF aws iam put-role-policy --role-name "$PARTNER_APP_EXECUTION_ROLE_NAME" --policy-name "FiddlerS3Policy" --policy-document file://fiddler-s3-policy.json # Attach SageMaker execution policy echo "Attaching SageMaker execution permissions..." aws iam attach-role-policy --role-name "$PARTNER_APP_EXECUTION_ROLE_NAME" --policy-arn "arn:aws:iam::aws:policy/AmazonSageMakerFullAccess" echo "✅ Fiddler Partner AI App execution role created with all required permissions" # ============================================================================= # STEP 3: CREATE USER EXECUTION ROLE # ============================================================================= echo "" echo "=== STEP 3: Creating User Execution Role ===" # Create user execution role trust policy cat > user-execution-trust-policy.json << EOF { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "sagemaker.amazonaws.com" }, "Action": [ "sts:AssumeRole", "sts:TagSession" ] } ] } EOF # Create user execution role echo "Creating user execution role..." aws iam create-role --role-name "$USER_EXECUTION_ROLE_NAME" --assume-role-policy-document file://user-execution-trust-policy.json --description "Execution role for SageMaker domain users" # Create user permissions policy cat > user-execution-policy.json << EOF { "Version": "2012-10-17", "Statement": [ { "Sid": "PartnerAIAppsUserAccess", "Effect": "Allow", "Action": [ "sagemaker:DescribePartnerApp", "sagemaker:ListPartnerApps", "sagemaker:CreatePartnerAppPresignedUrl", "sagemaker:CallPartnerAppApi" ], "Resource": "*" }, { "Sid": "SageMakerStudioAccess", "Effect": "Allow", "Action": [ "sagemaker:CreateApp", "sagemaker:DeleteApp", "sagemaker:DescribeApp", "sagemaker:ListApps", "sagemaker:CreateSpace", "sagemaker:DeleteSpace", "sagemaker:DescribeSpace", "sagemaker:ListSpaces", "sagemaker:UpdateSpace", "sagemaker:DescribeDomain", "sagemaker:DescribeUserProfile", "sagemaker:CreatePresignedDomainUrl" ], "Resource": "*" }, { "Sid": "S3AccessForML", "Effect": "Allow", "Action": [ "s3:GetObject", "s3:PutObject", "s3:DeleteObject", "s3:ListBucket" ], "Resource": [ "arn:aws:s3:::sagemaker-*", "arn:aws:s3:::sagemaker-*/*" ] } ] } EOF aws iam put-role-policy --role-name "$USER_EXECUTION_ROLE_NAME" --policy-name "UserExecutionPolicy" --policy-document file://user-execution-policy.json # Attach basic SageMaker policy aws iam attach-role-policy --role-name "$USER_EXECUTION_ROLE_NAME" --policy-arn "arn:aws:iam::aws:policy/AmazonSageMakerFullAccess" echo "✅ User execution role created" # ============================================================================= # STEP 4: CREATE USER ACCESS ROLE # ============================================================================= echo "" echo "=== STEP 4: Creating User Access Role ===" # Create user access role trust policy cat > user-access-trust-policy.json << EOF { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::${AWS_ACCOUNT_ID}:root" }, "Action": [ "sts:AssumeRole", "sts:TagSession" ], "Condition": { "StringEquals": { "sts:ExternalId": "fiddler-user-access" } } } ] } EOF # Create user access role echo "Creating user access role..." aws iam create-role --role-name "$USER_ACCESS_ROLE_NAME" --assume-role-policy-document file://user-access-trust-policy.json --description "Access role for users to assume for SageMaker and Fiddler access" # Create user access permissions policy cat > user-access-policy.json << EOF { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "sagemaker:CreatePresignedDomainUrl", "sagemaker:DescribeDomain", "sagemaker:DescribeUserProfile", "sagemaker:DescribeSpace", "sagemaker:ListSpaces", "sagemaker:CreatePartnerAppPresignedUrl", "sagemaker:DescribePartnerApp", "sagemaker:ListPartnerApps" ], "Resource": "*" } ] } EOF aws iam put-role-policy --role-name "$USER_ACCESS_ROLE_NAME" --policy-name "UserAccessPolicy" --policy-document file://user-access-policy.json echo "✅ User access role created" # ============================================================================= # STEP 5: CREATE SAGEMAKER DOMAIN (Optional) # ============================================================================= echo "" echo "=== STEP 5: Creating SageMaker Domain ===" # Determine network configuration NETWORK_CONFIG="PublicInternetOnly" # or "VpcOnly" VPC_CONFIG="--vpc-id $VPC_ID --subnet-ids ${SUBNET_IDS[@]}" echo "Using network configuration: $NETWORK_CONFIG with VPC $VPC_ID" # Create the domain echo "Creating SageMaker domain..." DOMAIN_ARN=$(aws sagemaker create-domain --domain-name "$DOMAIN_NAME" --auth-mode "IAM" --default-user-settings '{ "ExecutionRole": "arn:aws:iam::'$AWS_ACCOUNT_ID':role/'$USER_EXECUTION_ROLE_NAME'", "SharingSettings": { "NotebookOutputOption": "Allowed" }, "JupyterServerAppSettings": { "DefaultResourceSpec": { "InstanceType": "system" } }, "JupyterLabAppSettings": { "DefaultResourceSpec": { "InstanceType": "ml.t3.medium" } }, "DefaultLandingUri": "studio::", "StudioWebPortal": "ENABLED" }' --default-space-settings '{ "ExecutionRole": "arn:aws:iam::'$AWS_ACCOUNT_ID':role/'$USER_EXECUTION_ROLE_NAME'", "JupyterServerAppSettings": { "DefaultResourceSpec": { "InstanceType": "system" } }, "JupyterLabAppSettings": { "DefaultResourceSpec": { "InstanceType": "ml.t3.medium" } }, "SpaceStorageSettings": { "DefaultEbsStorageSettings": { "DefaultEbsVolumeSizeInGb": 20, "MaximumEbsVolumeSizeInGb": 100 } } }' --domain-settings '{ "ExecutionRoleIdentityConfig": "USER_PROFILE_NAME" }' --app-network-access-type "$NETWORK_CONFIG" $VPC_CONFIG --region "$AWS_REGION" --query 'DomainArn' --output text) # Extract the Domain ID from the full ARN. This is more portable than sed. DOMAIN_ID=${DOMAIN_ARN##*/} if [[ -z "$DOMAIN_ID" ]]; then echo "❌ Failed to create domain" exit 1 fi echo "Domain created with ID: $DOMAIN_ID" # Wait for domain to be in service echo "Waiting for domain to be ready..." while true; do DOMAIN_STATUS=$(aws sagemaker describe-domain --domain-id "$DOMAIN_ID" --region "$AWS_REGION" --query 'Status' --output text) if [[ "$DOMAIN_STATUS" == "InService" ]]; then echo "✅ Domain is ready" break elif [[ "$DOMAIN_STATUS" == "Failed" ]]; then echo "❌ Domain creation failed" exit 1 else echo "Domain status: $DOMAIN_STATUS, waiting..." sleep 30 fi done # Check if domain has DefaultSpaceSettings echo "Verifying domain has shared space settings..." DOMAIN_SPACE_SETTINGS=$(aws sagemaker describe-domain --domain-id "$DOMAIN_ID" --region "$AWS_REGION" --query 'DefaultSpaceSettings' --output text 2>/dev/null) if [[ "$DOMAIN_SPACE_SETTINGS" == "None" || -z "$DOMAIN_SPACE_SETTINGS" ]]; then echo "Domain missing shared space settings, updating domain..." aws sagemaker update-domain --domain-id "$DOMAIN_ID" --default-space-settings '{ "ExecutionRole": "arn:aws:iam::'$AWS_ACCOUNT_ID':role/'$USER_EXECUTION_ROLE_NAME'", "JupyterServerAppSettings": { "DefaultResourceSpec": { "InstanceType": "system" } }, "JupyterLabAppSettings": { "DefaultResourceSpec": { "InstanceType": "ml.t3.medium" } }, "SpaceStorageSettings": { "DefaultEbsStorageSettings": { "DefaultEbsVolumeSizeInGb": 20, "MaximumEbsVolumeSizeInGb": 100 } } }' --region "$AWS_REGION" echo "Waiting for domain update to complete..." while true; do DOMAIN_STATUS=$(aws sagemaker describe-domain --domain-id "$DOMAIN_ID" --region "$AWS_REGION" --query 'Status' --output text) if [[ "$DOMAIN_STATUS" == "InService" ]]; then echo "✅ Domain updated with shared space settings" break elif [[ "$DOMAIN_STATUS" == "Failed" ]]; then echo "❌ Domain update failed" exit 1 else echo "Domain update status: $DOMAIN_STATUS, waiting..." sleep 15 fi done else echo "✅ Domain already has shared space settings configured" fi # ============================================================================= # STEP 6: CREATE SHARED USER PROFILE # ============================================================================= echo "" echo "=== STEP 6: Creating Shared User Profile ===" echo "Creating shared user profile..." aws sagemaker create-user-profile --domain-id "$DOMAIN_ID" --user-profile-name "$SHARED_USER_PROFILE_NAME" --user-settings '{ "ExecutionRole": "arn:aws:iam::'$AWS_ACCOUNT_ID':role/'$USER_EXECUTION_ROLE_NAME'", "SharingSettings": { "NotebookOutputOption": "Allowed" }, "JupyterServerAppSettings": { "DefaultResourceSpec": { "InstanceType": "system" } }, "JupyterLabAppSettings": { "DefaultResourceSpec": { "InstanceType": "ml.t3.medium" } } }' --region "$AWS_REGION" # Wait for user profile to be ready echo "Waiting for user profile to be ready..." while true; do PROFILE_STATUS=$(aws sagemaker describe-user-profile --domain-id "$DOMAIN_ID" --user-profile-name "$SHARED_USER_PROFILE_NAME" --region "$AWS_REGION" --query 'Status' --output text) if [[ "$PROFILE_STATUS" == "InService" ]]; then echo "✅ User profile is ready" break elif [[ "$PROFILE_STATUS" == "Failed" ]]; then echo "❌ User profile creation failed" exit 1 else echo "Profile status: $PROFILE_STATUS, waiting..." sleep 15 fi done # ============================================================================= # STEP 7: CREATE SHARED SPACE # ============================================================================= echo "" echo "=== STEP 7: Creating Shared Space ===" echo "Creating shared space for collaboration..." aws sagemaker create-space --domain-id "$DOMAIN_ID" --space-name "$SHARED_SPACE_NAME" --region "$AWS_REGION" # Wait for shared space to be ready echo "Waiting for shared space to be ready..." while true; do SPACE_STATUS=$(aws sagemaker describe-space --domain-id "$DOMAIN_ID" --space-name "$SHARED_SPACE_NAME" --region "$AWS_REGION" --query 'Status' --output text) if [[ "$SPACE_STATUS" == "InService" ]]; then echo "✅ Shared space is ready" break elif [[ "$SPACE_STATUS" == "Failed" ]]; then echo "❌ Shared space creation failed" exit 1 else echo "Space status: $SPACE_STATUS, waiting..." sleep 15 fi done # ============================================================================= # STEP 8: CREATE USER ACCESS SCRIPTS # ============================================================================= echo "" echo "=== STEP 8: Creating User Access Scripts ===" # Create user access script cat > fiddler-user-access.sh << 'EOF' #!/bin/bash # ============================================================================= # FIDDLER USER ACCESS SCRIPT # ============================================================================= # Configuration - UPDATE THESE VALUES export AWS_ACCOUNT_ID="" export AWS_REGION="" export DOMAIN_ID="PLACEHOLDER_DOMAIN_ID" export USER_PROFILE_NAME="fiddler-shared-profile" export USER_ACCESS_ROLE_NAME="FiddlerUserAccessRole" # Get username for identity propagation CALLER_ARN=$(aws sts get-caller-identity --query 'Arn' --output text) USERNAME=${CALLER_ARN##*/} echo "=== Fiddler Partner AI App & SageMaker Access ===" echo "Setting up access for user: $USERNAME" # Assume role with session tags for identity propagation echo "1. Assuming user access role with identity tags..." TEMP_CREDENTIALS=$(aws sts assume-role --role-arn "arn:aws:iam::${AWS_ACCOUNT_ID}:role/${USER_ACCESS_ROLE_NAME}" --role-session-name "${USERNAME}-fiddler-session" --external-id "fiddler-user-access" --tags Key=SageMakerPartnerAppUser,Value="$USERNAME" --query 'Credentials.[AccessKeyId,SecretAccessKey,SessionToken]' --output text) if [[ $? -ne 0 ]]; then echo "❌ Failed to assume role. Please check your permissions." exit 1 fi # Extract credentials export AWS_ACCESS_KEY_ID=$(echo $TEMP_CREDENTIALS | cut -d' ' -f1) export AWS_SECRET_ACCESS_KEY=$(echo $TEMP_CREDENTIALS | cut -d' ' -f2) export AWS_SESSION_TOKEN=$(echo $TEMP_CREDENTIALS | cut -d' ' -f3) echo "✅ Successfully assumed role with user identity: $USERNAME" # Generate Studio access URL echo "2. Generating SageMaker Studio access URL..." STUDIO_URL=$(aws sagemaker create-presigned-domain-url --domain-id "$DOMAIN_ID" --user-profile-name "$USER_PROFILE_NAME" --session-expiration-duration-in-seconds 3600 --region "$AWS_REGION" --query 'AuthorizedUrl' --output text) if [[ $? -ne 0 ]]; then echo "❌ Failed to generate Studio URL" exit 1 fi echo "" echo "=== ACCESS INFORMATION ===" echo "🔗 SageMaker Studio URL (valid for 1 hour):" echo "$STUDIO_URL" echo "" echo "👤 User Identity: $USERNAME" echo "🏠 Domain: $DOMAIN_ID" echo "👥 Shared Profile: $USER_PROFILE_NAME" echo "" echo "=== WHAT YOU CAN ACCESS ===" echo "✅ SageMaker Studio - Full development environment" echo "✅ Shared Space - 'fiddler-collaboration-space' for team collaboration" echo "✅ Fiddler Partner AI Apps - AI observability platform" echo "✅ Jupyter notebooks with Fiddler SDK support" echo "" echo "=== INSTRUCTIONS ===" echo "1. Copy and paste the Studio URL above into your browser" echo "2. In Studio, access:" echo " • Partner AI Apps from the Studio interface" echo " • Shared space: 'fiddler-collaboration-space'" echo " • Personal spaces for individual work" echo "3. Your identity ($USERNAME) is properly configured for all services" # Clean up credentials unset AWS_ACCESS_KEY_ID unset AWS_SECRET_ACCESS_KEY unset AWS_SESSION_TOKEN echo "" echo "✅ Session credentials cleaned up for security" EOF # Update the user access script with the actual domain ID, using OS-specific sed syntax if [[ "$(uname -s)" == "Darwin" ]]; then # macOS (BSD) sed requires an empty string argument for in-place editing sed -i '' "s/PLACEHOLDER_DOMAIN_ID/$DOMAIN_ID/g" fiddler-user-access.sh else # Linux (GNU) sed does not require an argument for in-place editing sed -i "s/PLACEHOLDER_DOMAIN_ID/$DOMAIN_ID/g" fiddler-user-access.sh fi chmod +x fiddler-user-access.sh # Create Fiddler SDK setup script cat > setup-fiddler-sdk.sh << 'EOF' #!/bin/bash # ============================================================================= # FIDDLER SDK SETUP SCRIPT # ============================================================================= echo "=== Setting up Fiddler SDK Environment ===" # Check if running in SageMaker Studio if [[ -n "$SAGEMAKER_APP_TYPE" ]]; then echo "✅ Running in SageMaker Studio environment" else echo "⚠️ Not running in SageMaker Studio - some features may not work" fi # Install compatible SageMaker Python SDK echo "1. Installing compatible SageMaker Python SDK..." pip install "sagemaker>=2.237.0" --upgrade # Install Fiddler Python Client echo "2. Installing Fiddler Python Client..." pip install fiddler-client --upgrade # Set up environment variables for Fiddler SDK echo "3. Setting up Fiddler environment variables..." # Create environment setup cat > setup_fiddler_env.py << 'PYTHON_EOF' import os import boto3 def setup_fiddler_environment(): """Set up environment variables for Fiddler SDK integration with SageMaker Partner AI Apps""" # Get SageMaker session information try: # These environment variables are automatically set in SageMaker Studio domain_id = os.environ.get('SAGEMAKER_DOMAIN_ID') region = os.environ.get('AWS_DEFAULT_REGION', 'us-east-1') print(f"SageMaker Domain ID: {domain_id}") print(f"AWS Region: {region}") # Set up Fiddler-specific environment variables # These will be used by the Fiddler Python Client to connect to the Partner AI App # Note: The actual Fiddler API endpoint will be provided by the Partner AI App # when it's deployed. Users will need to get this from the Fiddler UI. print("\n✅ Environment setup complete!") print("\n📝 Next steps:") print("1. Deploy Fiddler Partner AI App from SageMaker Studio") print("2. Get API key from Fiddler Partner AI App UI") print("3. Set FIDDLER_API_KEY environment variable:") print(" os.environ['FIDDLER_API_KEY'] = 'your-api-key'") print("4. Get Fiddler URL from Partner AI App and set:") print(" os.environ['FIDDLER_URL'] = 'your-fiddler-app-url'") return True except Exception as e: print(f"❌ Error setting up environment: {e}") return False if __name__ == "__main__": setup_fiddler_environment() PYTHON_EOF # Run the environment setup python setup_fiddler_env.py echo "" echo "✅ Fiddler SDK setup complete!" echo "" echo "📋 SDK Usage Instructions:" echo "1. Run this script in a SageMaker Studio Jupyter notebook" echo "2. Deploy Fiddler Partner AI App from Studio interface" echo "3. Get API credentials from Fiddler Partner AI App" echo "4. Use Fiddler Python Client to connect to your models" echo "" echo "📖 For detailed Fiddler SDK documentation, visit:" echo " https://docs.fiddler.ai/" EOF chmod +x setup-fiddler-sdk.sh echo "✅ User access scripts created" # ============================================================================= # STEP 9: CLEAN UP TEMPORARY FILES # ============================================================================= echo "" echo "=== STEP 9: Cleaning up temporary files ===" rm -f partner-ai-admin-policy.json rm -f partner-app-execution-trust-policy.json rm -f license-manager-policy.json rm -f fiddler-s3-policy.json rm -f user-execution-trust-policy.json rm -f user-execution-policy.json rm -f user-access-trust-policy.json rm -f user-access-policy.json echo "✅ Temporary files cleaned up" # ============================================================================= # SETUP COMPLETE - SUMMARY # ============================================================================= echo "" echo "🎉 FIDDLER PARTNER AI APP & SAGEMAKER SETUP COMPLETE!" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "" echo "📋 CREATED RESOURCES:" echo "✅ Existing Admin Role Enhanced: $EXISTING_ADMIN_ROLE_NAME" echo "✅ Partner AI App Execution Role: $PARTNER_APP_EXECUTION_ROLE_NAME" echo "✅ User Execution Role: $USER_EXECUTION_ROLE_NAME" echo "✅ User Access Role: $USER_ACCESS_ROLE_NAME" echo "✅ SageMaker Domain: $DOMAIN_NAME (ID: $DOMAIN_ID)" echo "✅ Shared User Profile: $SHARED_USER_PROFILE_NAME" echo "✅ Shared Space: $SHARED_SPACE_NAME" echo "✅ User Access Script: fiddler-user-access.sh" echo "✅ Fiddler SDK Setup Script: setup-fiddler-sdk.sh" echo "" echo "🚀 NEXT STEPS:" echo "" echo "1. SUBSCRIBE TO FIDDLER IN AWS MARKETPLACE:" echo " • Use your existing admin role: $EXISTING_ADMIN_ROLE_NAME" echo " • Go to AWS Marketplace and subscribe to Fiddler AI Observability" echo " • Follow the subscription process" echo "" echo "2. DEPLOY FIDDLER PARTNER AI APP:" echo " • Use SageMaker Console or AWS CLI to create Partner AI App" echo " • Specify root admin IAM username for: $EXISTING_ADMIN_ROLE_NAME" echo " • Use execution role: $PARTNER_APP_EXECUTION_ROLE_NAME" echo "" echo "📖 DOCUMENTATION REFERENCES:" echo "• Partner AI Apps: https://docs.aws.amazon.com/sagemaker/latest/dg/partner-app-onboard.html" echo "• Fiddler SDK: https://docs.aws.amazon.com/sagemaker/latest/dg/partner-apps-sdk.html" echo "• SageMaker Domains: https://docs.aws.amazon.com/sagemaker/latest/dg/gs-studio-onboard.html" echo "" echo "✨ Your team can now collaborate using Fiddler for AI observability in SageMaker!" ``` # User Guide Source: https://docs.fiddler.ai/integrations/aws-sagemaker/partner-ai-app-user-guide User guide for Fiddler on AWS SageMaker. Learn to use the Fiddler UI and Python SDK to monitor, explain, and analyze your models and GenAI apps. ### Introduction The Fiddler Partner AI App for Amazon SageMaker brings enterprise-grade AI observability directly into your SageMaker environment. As a fully integrated Partner AI App, Fiddler enables data scientists and ML engineers to monitor, explain, and analyze their AI applications without leaving the SageMaker ecosystem. This seamless integration allows you to leverage Fiddler's powerful monitoring capabilities—including drift detection, performance tracking, and explainability features—while maintaining your existing SageMaker workflows and security boundaries. ### Prerequisites Before using the Fiddler Partner AI App, ensure you have: * Access to an AWS account with the Fiddler Partner AI App deployed by your administrator * A SageMaker Studio user profile with appropriate permissions configured by your administrator, OR a similar role to assume when creating direct links to the Fiddler UI * Basic familiarity with SageMaker Studio navigation and notebooks ### Using Fiddler in SageMaker Studio #### Accessing the Fiddler Partner AI App The Fiddler Partner AI App integrates seamlessly with SageMaker Studio, providing multiple access points for your model monitoring workflows. **From SageMaker Studio** 1. Open SageMaker Studio and navigate to the **Applications** section in the left navigation panel 2. Under **Partner AI apps**, locate and select **Fiddler** 3. Click **Open app** to launch the Fiddler interface in a new tab 4. The application will automatically authenticate using your SageMaker credentials **Direct Link Using the AWS CLI** * AWS provides a CLI function to generate the Fiddler UI URL: `create-partner-app-presigned-url` * Along with the appropriate role and permissions, you also need: * The Fiddler Partner AI App ARN * The AWS Region ```bash theme={null} AWS_REGION="us-west-2" # Use this command to get the partner app ARN: aws sagemaker list-partner-apps --region "$AWS_REGION" --output table # Create the URL aws sagemaker create-partner-app-presigned-url --arn "$FIDDLER_PAA_ARN" --expires-in-seconds 300 --session-expiration-duration-in-seconds 1800 --region "$AWS_REGION" --query 'Url' --output text ``` #### Navigating the Fiddler Interface For users new to the Fiddler AI platform, our [Getting Started with ML Model Observability](/getting-started/ml-observability) guide provides a thorough introduction to the model or application onboarding process, event publishing, and Fiddler features. ### Using the Fiddler Python Client SDK The Fiddler Python client enables programmatic access to Fiddler's capabilities directly from your SageMaker notebooks and code editors. * Getting started with the [Fiddler Python Client SDK](/sdk-api/python-client/connection) #### Prerequisites * The AWS SageMaker Partner App ARN. This is the unique identifier of your SageMaker Fiddler Partner AI App * The AWS SageMaker Partner App URL. This is the fully qualified domain of the Fiddler UI launched from Studio * The Fiddler user authentication token, which you can find on the [Credentials](/reference/administration/settings#credentials) tab in the Fiddler UI If you are using SageMaker Studio to access Fiddler, the SageMaker Partner App ARN and URL can be found by launching Studio and clicking on the Fiddler icon in the Applications list as shown below: #### Setting Up the SDK Connection To connect to Fiddler from a SageMaker notebook, code editor, or similar: 1. **Install the latest version of the Fiddler client** (if not pre-installed) and at least 2.237.0 of the SageMaker Python SDK: ```sh theme={null} pip install fiddler-client "sagemaker>=2.237.0" ``` 2. **Configure the connection using SageMaker's built-in authentication**: ```python theme={null} import os import fiddler as fdl # Edit the values in this section! APP_URL = '' # the SageMaker App URL APP_ARN = '' # the SageMaker App ARN TOKEN = '' # the Fiddler User API Key # Enable Partner AI App authentication os.environ['AWS_PARTNER_APP_AUTH'] = 'true' os.environ['AWS_PARTNER_APP_ARN'] = APP_ARN os.environ['AWS_PARTNER_APP_URL'] = APP_URL ``` 3. **Initialize the Fiddler client**: ```python theme={null} # Initialize the Fiddler client fdl.init(url=APP_URL, token=TOKEN) ``` #### Common SDK Operations The [Python Client Guides](/developers/python-client-guides/installation-and-setup) section of Fiddler's documentation contains many examples of everyday use cases and tasks. ### Tracing GenAI Agents from SageMaker To trace LLM and agentic applications running in your SageMaker Partner AI App, use the [Fiddler OTel SDK](/integrations/agentic-ai/fiddler-otel-sdk). Starting in `fiddler-otel` 1.3.0, the SDK signs trace exports with the same Partner App authentication used by the Python client — set `AWS_PARTNER_APP_AUTH`, `AWS_PARTNER_APP_ARN`, and `AWS_PARTNER_APP_URL`, install the `sagemaker` extra (`pip install "fiddler-otel[sagemaker]"`), and your instrumentation runs unchanged. See [Running in AWS SageMaker](/integrations/agentic-ai/fiddler-otel-sdk#running-in-aws-sagemaker) for the full walkthrough. In the current SageMaker environment, agent traces are signed and exported correctly but are not yet visible in the Fiddler UI. This is an environment limitation, not an SDK defect. #### Best Practices for SDK Usage * **Notebook Organization**: Keep your Fiddler monitoring code in dedicated sections or separate notebooks for clarity * **Environment Variables**: Store the Partner App environment variables at the beginning of your notebooks for consistent access * **Batch Operations**: Use batch methods when publishing large volumes of data to optimize performance #### Troubleshooting SDK Connections If you encounter connection issues: 1. **Verify that environment variables** are correctly set 2. **Check your IAM permissions** include `sagemaker:CallPartnerAppApi` 3. **Ensure the Fiddler app is deployed** and in "Deployed" status # AWS SageMaker Partner AI App Source: https://docs.fiddler.ai/integrations/cloud-platforms-and-deployment/aws-sagemaker Run Fiddler AI Observability platform within Amazon SageMaker as a Partner AI App. Procure, provision, and securely operate Fiddler seamlessly all within your existing AWS account. ## Introduction This guide helps AWS administrators configure, deploy, and manage [Fiddler AI ](https://fiddler.ai/)as an Amazon SageMaker Partner AI App. Fiddler AI is an enterprise-grade AI Observability platform that helps monitor, explain, and analyze ML models, LLM applications, GenAI systems, and AI agents directly within your AWS environment. ## What is a Partner AI App? Amazon SageMaker Partner AI Apps are fully managed AI/ML applications from AWS partners that run natively within your SageMaker environment. Think of them as pre-built, enterprise-ready applications that integrate seamlessly with your existing AWS infrastructure—no complex deployments or external accounts required. **Key Benefits**: * **Secure by Design**: Applications run entirely within your AWS account, maintaining your existing security boundaries and compliance requirements * **Unified Experience**: Access partner tools directly from SageMaker Studio alongside your notebooks, models, and datasets * **Simplified Procurement**: Subscribe through AWS Marketplace with consolidated billing on your AWS invoice * **Managed Infrastructure**: AWS handles the underlying infrastructure while you focus on using the application ## How the Fiddler Partner AI App Works The Fiddler Partner AI App is a fully integrated component within your SageMaker environment. The following sections will explain how this integration works. ### Architecture Overview 1. **Deployment Model**: Fiddler runs as a fully managed, containerized application within your AWS account, requiring no operational support from your team. AWS handles all infrastructure management, updates, and maintenance while isolating your environment and securing access to your data and models. 2. **Data Flow**: * Your data never leaves your AWS environment * Fiddler processes model predictions and monitoring data within your existing security boundaries, typically avoiding the need for additional security reviews * All computations and storage remain under your AWS account's control 3. **Integration Points**: * **SageMaker Studio UI**: Launch Fiddler's web interface directly from Studio or via pre-signed URLs * **Python SDK**: Connect to Fiddler from notebooks using authenticated API calls * **Model Monitoring**: Monitor any model, including those deployed on SageMaker endpoints * **S3 Storage**: Fiddler uses designated S3 buckets within your account for data persistence 4. **Authentication & Authorization**: * Leverages SageMaker's identity propagation to maintain user context * Requires specific IAM permissions configured by your administrator * No separate Fiddler-specific credentials needed for Studio access * API access uses Fiddler tokens combined with AWS authentication ## Prerequisites for Subscribing to the Fiddler Partner AI App Before deploying Fiddler AI, ensure you have: * An active AWS account with administrator privileges * An existing SageMaker AI domain if launching Fiddler from Studio is required * Appropriate IAM permissions to manage AWS Marketplace subscriptions * Basic understanding of AWS IAM roles and policies ## Configure Required Permissions The official [Amazon SageMaker Partner AI Apps documentation](https://docs.aws.amazon.com/sagemaker/latest/dg/partner-apps.html) is the primary reference for preparing, subscribing to, and deploying the Fiddler Partner AI App. This guide assumes you have completed the documentation's Set up Partner AI Apps section, which covers permissions, authentication, and authorization requirements. ### Important Considerations Before proceeding, be aware of these standard requirements and potential friction points: **Identity Configuration**: * Partner AI Apps require identity propagation to be correctly configured * Your SageMaker domain must use either IAM or IAM Identity Center authentication * The username format must match between your identity provider and the Fiddler admin configuration **Permission Requirements**: * Multiple IAM roles are required (admin role, execution role, and user roles) * AWS License Manager permissions are mandatory for Fiddler * The setup involves numerous individual IAM permissions across different services **Time and Complexity**: * Initial permission setup typically takes 30-60 minutes * Consider using our Quick Setup Script to automate this process * Some organizations may need security team approval for the required IAM policies **Common Gotchas**: * The execution role name cannot be changed after Fiddler deployment * Admin usernames entered during deployment cannot be modified later * Free trial deployments cannot be upgraded to paid subscriptions (requires redeployment) ## Fiddler Subscription Options ### Pricing Structure Fiddler Partner AI App pricing consists of two components: 1. **Software License Costs**: Billed through AWS Marketplace * **30-Day Free Trial**: Full functionality for up to 5 models with no software costs (infrastructure charges still apply) * **Monthly Subscription**: Pay-as-you-go monthly pricing * **Annual Subscription**: Discounted pricing with a 12-month commitment 2. **Infrastructure Costs**: Billed separately by AWS based on usage * Compute instances (EC2) * Storage (EBS volumes) * Data transfer * Managed services (RDS, AMQ, etc.) * These costs vary based on the tier size you select (Small, Medium, or Large) and your contract discounts ### Subscription Tiers
TierRecommended Use CaseEstimated Monthly Infrastructure\* Cost
SmallDevelopment, POCs, teams \<10 users$500 - $1,000
MediumProduction workloads, teams 10-50 users$1,500 - $3,000
LargeEnterprise deployments, teams 50+ users$3,000 - $6,000
\*Infrastructure costs are estimates and vary based on actual usage and AWS region ### Trial vs. Paid Subscription **30-Day Free Trial**: * Full Fiddler functionality with no functionality restrictions on up to five models * No software license charges * Infrastructure costs still apply * Cannot be upgraded to paid (requires redeployment) * Ideal for evaluation and testing **Paid Subscription**: * Continuous access with no time limits * Includes AWS support for Partner AI Apps * Can be upgraded/downgraded between tiers * Suitable for production use cases ## Subscribe to the Fiddler Partner AI App Below is a brief example of using the Amazon SageMaker console to subscribe to the Fiddler Partner AI App. 1. With the admin account configured per the prerequisites, open your Amazon SageMaker AI Console and click the new *Partner AI Apps* link in the left-hand navigation to view the Partner AI Apps. Partner AI Apps listing page in SageMaker 2. Click the View details link to review the Fiddler details on contract pricing and estimated infrastructure costs. Fiddler Partner AI App detail page 3. Click the *Go to Marketplace to subscribe* link to purchase or select the free trial. Then click on the *View purchase options* or *Try for free* links to open the subscription page. Fiddler Partner AI App page in AWS Marketplace 4. This page lets you select your desired contract length, license options, and costs. When you are ready to confirm your subscription, click the Subscribe button. Fiddler Partner AI App subscription options and purchase page ## Provision and Deploy the Fiddler Partner AI App The documentation's [Partner AI App Provisioning](https://docs.aws.amazon.com/sagemaker/latest/dg/partner-apps-provision.html) section lists the general instructions for provisioning Partner AI Apps. The guide below is an example walkthrough of provisioning the Fiddler Partner AI App. 1. The configuration and deployment process has six steps. Begin by choosing a name for your Fiddler SageMaker Partner AI App and selecting your desired maintenance time window. Step 1 of Fiddler Partner AI App provision and deploy wizard: app name 2. Add at least one and up to five users with Org Admin privileges within Fiddler. The username entered here must match the IAM username passed to Fiddler on launch. Step 2 of Fiddler Partner AI App provision and deploy wizard: add admin users 3. Select the execution role used by the Fiddler Partner AI App to run AWS resources and authenticate subscription licenses. This role is created following the [Set up Partner AI Apps](https://docs.aws.amazon.com/sagemaker/latest/dg/partner-app-onboard.html) section of the AWS documentation. Step 3 of Fiddler Partner AI App provision and deploy wizard: select execution role 4. Ensure that the STS identity propagation section has *Enable STS* selected. Step 4 of Fiddler Partner AI App provision and deploy wizard: STS identity option 5. Choose the tier size appropriate for your use cases, click *Next* to review, and then click the ***Deploy*** button to deploy the application. Allow time for this process to complete. It should be ready in under an hour. Step 5 of Fiddler Partner AI App provision and deploy wizard: choose infrastructure tier size 6. Please return to the Partner AI Apps > My Apps tab in the SageMaker console to check the status. The application can take 1-2 hours to complete the deployment process, at which point the status will be *Deployed*. My Apps tab of SageMaker console's Partner AI Apps page ## Next Steps Once your Fiddler Partner AI App is deployed: * **For Administrators**: * Leverage the [Fiddler Partner AI App Quick Setup Script](/integrations/aws-sagemaker/partner-ai-app-quick-setup-script) to get started with all the required roles and policies for running Fiddler in Studio * Get detailed information on IAM requirements, deployment tips, and troubleshooting with the [Admin Guide](/integrations/aws-sagemaker/partner-ai-app-admin-guide) * **For Users**: Learn how to access and use Fiddler with the [User Guide](/integrations/aws-sagemaker/partner-ai-app-user-guide) * **For GenAI and agentic applications**: Trace LLM and agent workloads from SageMaker with the [Fiddler OTel SDK](/integrations/agentic-ai/fiddler-otel-sdk#running-in-aws-sagemaker), which signs trace exports using the same Partner App authentication # Cloud Platforms Overview Source: https://docs.fiddler.ai/integrations/cloud-platforms-and-deployment/cloud-platforms Deploy and operate Fiddler natively on leading cloud platforms Run Fiddler AI Observability in your preferred cloud environment with native platform integrations. Deploy as a fully managed Partner AI App on AWS SageMaker, run in your Kubernetes clusters, or leverage cloud-native services for ML model monitoring at scale. ## Why Cloud Platform Integrations Matter Modern AI systems are built on cloud infrastructure. Fiddler's cloud platform integrations ensure you can: * **Maintain Data Sovereignty** - Keep all your data and models within your existing cloud security boundaries * **Simplify Procurement** - Subscribe through cloud marketplaces with consolidated billing * **Leverage Existing Infrastructure** - Use your current IAM, networking, and security configurations * **Scale Seamlessly** - Cloud-native deployment automatically scales with your ML workloads * **Reduce Operational Overhead** - Managed platform integrations eliminate manual infrastructure management ## AWS Deployments ### AWS SageMaker Partner AI App Run Fiddler as a fully managed Partner AI App within Amazon SageMaker. **Best for:** Enterprise AWS customers wanting seamless SageMaker integration with zero external infrastructure **Key Features:** * Fully managed infrastructure within your AWS account * Native SageMaker Studio integration * No external accounts or data transfer required * Automatic updates and maintenance handled by AWS * Consolidated AWS billing through Marketplace **Deployment Options:** * **30-Day Free Trial** - Full functionality for up to 5 models (infrastructure costs apply) * **Tiered Subscriptions** - Small, Medium, and Large configurations for different team sizes * **AWS Marketplace** - Monthly or annual subscriptions with flexible pricing **Status:** ✓ **GA** - Production-ready [**Get Started with AWS SageMaker Partner AI App →**](/integrations/cloud-platforms-and-deployment/aws-sagemaker) **Related AWS Integrations:** * [Amazon S3](/integrations/data-platforms/integration-with-s3) - Connect Fiddler to S3 data sources * [SageMaker Pipelines](/integrations/data-platforms/sagemaker-integration) - Monitor SageMaker ML pipelines * [Strands SDK](/integrations/agentic-ai/strands-sdk) - Monitor Strands Agents ## Multi-Cloud & Kubernetes While AWS SageMaker Partner AI App is our featured cloud platform integration, Fiddler supports deployment across multiple cloud providers: ### Supported Deployment Patterns **Cloud Platforms:** * **AWS** - Native SageMaker Partner AI App (recommended), EC2, EKS * **Azure** - Azure ML integration (contact sales), AKS deployment * **Google Cloud** - GKE deployment, Vertex AI connectivity * **Private Cloud** - On-premises Kubernetes with cloud connectivity **Kubernetes Deployments:** * **Helm Charts** - Production-grade Kubernetes deployment templates * **Operator Pattern** - Automated lifecycle management for Fiddler clusters * **Multi-Cluster Support** - Monitor ML models across distributed Kubernetes environments * **Cloud-Agnostic** - Run on EKS, AKS, GKE, or on-premises Kubernetes **Container Orchestration:** * **Docker Compose** - Development and testing environments * **Docker Swarm** - Small-scale production deployments * **Kubernetes** - Enterprise production deployments ## Deployment Architecture Patterns ### Pattern 1: Fully Managed (Recommended for AWS) **Use AWS SageMaker Partner AI App** for zero-infrastructure management: ``` AWS Account (Your VPC) ├── SageMaker Studio (UI Access) ├── Fiddler Partner AI App (Managed) │ ├── Compute (Managed by AWS) │ ├── Storage (Your S3 buckets) │ └── Database (Managed RDS) └── Your ML Models (SageMaker Endpoints) ``` **Advantages:** * No operational overhead * Automatic scaling and updates * AWS handles infrastructure security * Seamless Studio integration ### Pattern 2: Self-Managed Kubernetes **Use Helm Charts** for full control over infrastructure: ``` Cloud Provider (Your Kubernetes Cluster) ├── Fiddler Namespace │ ├── API Server Pods │ ├── Worker Pods │ ├── Database (StatefulSet) │ └── Storage (PersistentVolumes) └── Ingress/Load Balancer ``` **Advantages:** * Full infrastructure control * Cloud-agnostic deployment * Custom security configurations * On-premises compatibility ### Pattern 3: Hybrid Multi-Cloud **Deploy Fiddler in one cloud, monitor models across all:** ``` Primary Cloud (Fiddler Installation) ├── Fiddler Platform └── Centralized Monitoring Dashboard Connected Clouds ├── AWS (SageMaker models) ├── Azure (Azure ML models) ├── GCP (Vertex AI models) └── On-Premises (Legacy models) ``` **Advantages:** * Unified observability across clouds * Centralized governance and compliance * Flexible hybrid architecture ## Getting Started ### For AWS Customers **Quick Start Path:** 1. **Subscribe** - Get Fiddler from AWS Marketplace 2. **Deploy** - Use SageMaker Partner AI Apps one-click deployment 3. **Configure** - Run the [Quick Setup Script](/integrations/aws-sagemaker/partner-ai-app-quick-setup-script) for IAM roles 4. **Monitor** - Connect your SageMaker models and LLM applications [**Full AWS Deployment Guide →**](/integrations/cloud-platforms-and-deployment/aws-sagemaker) **Need Help?** * [Quick Setup Script](/integrations/aws-sagemaker/partner-ai-app-quick-setup-script) - Automated IAM configuration * [Admin Guide](/integrations/aws-sagemaker/partner-ai-app-admin-guide) - Detailed deployment and management * [User Guide](/integrations/aws-sagemaker/partner-ai-app-user-guide) - Accessing and using Fiddler ### For Kubernetes Deployments **Prerequisites:** * Kubernetes 1.21+ cluster * Helm 3.8+ installed * Storage provisioner (for persistent volumes) * Ingress controller (for external access) **Installation:** ```bash theme={null} # Add Fiddler Helm repository helm repo add fiddler https://helm.fiddler.ai helm repo update # Install Fiddler helm install fiddler fiddler/fiddler \ --namespace fiddler \ --create-namespace \ --set license.key= \ --set ingress.enabled=true \ --set ingress.hostname=fiddler.your-domain.com ``` [**Contact Sales for Kubernetes Deployment →**](mailto:sales@fiddler.ai) ### For Other Cloud Providers **Azure Customers:** * Azure ML integration available * AKS deployment supported * [Contact us for deployment assistance →](mailto:support@fiddler.ai) **Google Cloud Customers:** * GKE deployment supported * Vertex AI connectivity available * [Contact us for deployment assistance →](mailto:support@fiddler.ai) ## Migration & Upgrade Paths ### From Other Monitoring Platforms **Migrating from Competitor Platform:** 1. **Parallel Deployment** - Run Fiddler alongside existing monitoring 2. **Data Migration** - Import historical metrics and model metadata 3. **Gradual Cutover** - Model-by-model transition with zero downtime 4. **Training & Onboarding** - Dedicated support during migration **Common Migration Sources:** * **Arize** - Direct migration tools available * **Weights & Biases** - Model metadata import supported * **DataRobot** - Custom migration scripts available * **Custom Solutions** - API-based migration assistance ### Upgrading Within Fiddler **AWS SageMaker Partner AI App Upgrades:** * **Tier Upgrades** - Scale from Small → Medium → Large as needed * **Version Updates** - Automatic updates during maintenance windows * **Trial to Production** - Requires redeployment (preserve data with migration scripts) **Self-Managed Upgrades:** * **Helm Upgrades** - Standard `helm upgrade` process * **Rolling Updates** - Zero-downtime deployments * **Backup & Restore** - Automated backup before each upgrade ## Security & Compliance ### Data Residency **AWS SageMaker Partner AI App:** * All data stays within your AWS account and region * No external data transfer to Fiddler's infrastructure * Choose your preferred AWS region during deployment **Self-Managed Deployments:** * Full control over data location * Support for air-gapped environments * On-premises deployment options ### Compliance Certifications * **SOC 2 Type II** - Fiddler platform certified * **GDPR** - Data processing agreements available * **HIPAA** - Compliant deployment options for healthcare * **FedRAMP** - In progress (contact for timeline) ### Security Features * **Encryption at Rest** - All stored data encrypted (AWS KMS, customer-managed keys) * **Encryption in Transit** - TLS 1.3 for all network communication * **SSO Integration** - SAML 2.0, OIDC support (Azure AD, Okta, AWS SSO) * **RBAC** - Role-based access control with fine-grained permissions * **Audit Logging** - Complete audit trail of all platform activities ## Cost Optimization ### AWS SageMaker Partner AI App Pricing **Total Cost of Ownership (TCO):** * **Software License** - Billed through AWS Marketplace * **Infrastructure** - AWS resource costs (EC2, RDS, S3, etc.) * **Data Transfer** - Minimal costs (data stays in your VPC) **Tier Selection Guidelines:** | Team Size | Models Monitored | Recommended Tier | Est. Monthly Cost\* | | ----------- | ---------------- | ---------------- | ------------------- | | \< 10 users | \< 20 models | Small | $500 - $1,000 | | 10-50 users | 20-100 models | Medium | $1,500 - $3,000 | | 50+ users | 100+ models | Large | $3,000 - $6,000 | \*Infrastructure costs only (software license additional) **Cost Optimization Tips:** * Start with **Small tier** for POCs and development * Use **Reserved Instances** for production workloads (20-40% savings) * **Right-size tier** based on actual usage metrics * **Scheduled scaling** for non-production environments ### Self-Managed Cost Optimization * **Spot Instances** - Use for worker nodes (50-70% savings) * **Auto-Scaling** - Scale compute based on monitoring load * **Storage Tiering** - Move historical data to cheaper storage classes * **Multi-Tenancy** - Share Fiddler instance across multiple teams ## Monitoring Infrastructure Health ### Platform Metrics **AWS SageMaker Partner AI App:** * View infrastructure health in SageMaker Console * CloudWatch metrics for Fiddler components * Automatic alerting for platform issues * AWS Support for troubleshooting **Self-Managed:** * Prometheus metrics exported by default * Grafana dashboards for infrastructure monitoring * Health check endpoints for uptime monitoring * Integration with existing observability stack ## Support & Resources ### AWS SageMaker Partner AI App * **AWS Support** - Leverage your existing AWS support plan * **Fiddler Support** - Direct support channel for platform issues * **Documentation** - [Complete SageMaker deployment guides →](/integrations/cloud-platforms-and-deployment/aws-sagemaker) * **AWS Marketplace** - [Subscribe and get started →](https://aws.amazon.com/marketplace/pp/prodview-caia5ckldtyhs) ### Self-Managed Deployments * **Enterprise Support** - 24/7 support with SLA guarantees * **Deployment Assistance** - Professional services for setup * **Training** - Platform administrator training programs * **Community** - [Join our Slack community](/integrations/cloud-platforms-and-deployment/cloud-platforms) ## Related Integrations * [**Data Platforms**](/integrations/data-platforms-and-pipelines/data-platforms) - Connect Fiddler to S3, Snowflake, BigQuery * [**ML Platforms**](/integrations/ml-platforms-and-tools/ml-platforms) - Integrate with Databricks, MLflow * [**Agentic AI**](/integrations/agentic-ai-and-llm-frameworks/agentic-ai) - Monitor LangGraph and Strands Agents * [**Monitoring & Alerting**](/integrations/monitoring-and-alerting/monitoring-alerting) - Send alerts to Datadog, PagerDuty ## Need Help Choosing? Not sure which deployment option is right for you? We're here to help: * **AWS SageMaker Customers** - [Get started with Partner AI App →](/integrations/cloud-platforms-and-deployment/aws-sagemaker) * **Multi-Cloud Requirements** - [Contact sales for architecture consultation →](mailto:sales@fiddler.ai) * **On-Premises Deployment** - [Discuss private cloud options →](mailto:sales@fiddler.ai) * **Migration Assistance** - [Talk to our solutions team →](mailto:solutions@fiddler.ai) *** **Featured Integration:** The AWS SageMaker Partner AI App is our recommended deployment for AWS customers, offering the fastest time-to-value with zero operational overhead. [Learn more →](/integrations/cloud-platforms-and-deployment/aws-sagemaker) # Data Platforms Overview Source: https://docs.fiddler.ai/integrations/data-platforms-and-pipelines/data-platforms Connect Fiddler to data warehouses, streaming platforms, and ML pipelines Integrate Fiddler with your existing data infrastructure to seamlessly ingest training data, production events, and ground truth labels. From cloud data warehouses to real-time streaming platforms, Fiddler connects to the data sources you already use. ## Why Data Integration Matters AI observability requires continuous data flow from your ML pipelines and applications. Fiddler's data platform integrations enable: * **Automated Data Ingestion** - Pull training datasets and production events without manual uploads * **Real-Time Monitoring** - Stream prediction events for immediate drift and performance detection * **Unified Data Pipeline** - Single integration point for all your ML data sources * **Ground Truth Enrichment** - Automatically join production predictions with delayed labels * **Historical Analysis** - Query data warehouse for model performance over time ## Integration Categories ### 🏢 Data Warehouses Connect Fiddler to your cloud data warehouse for batch data ingestion and historical analysis. **Supported Platforms:** * [**Snowflake**](/integrations/data-platforms/snowflake-integration) - Cloud data warehouse with zero-copy data sharing ✓ **GA** * [**Google BigQuery**](/integrations/data-platforms/bigquery-integration) - Serverless data warehouse with SQL analytics ✓ **GA** **Common Use Cases:** * Import training datasets from data warehouse tables * Query historical model predictions for performance analysis * Join production events with delayed ground truth labels * Export Fiddler metrics back to warehouse for BI tools ### 📊 Data Streaming Stream real-time prediction events and feedback directly to Fiddler for immediate observability. **Supported Platforms:** * [**Apache Kafka**](/integrations/data-platforms/kafka-integration) - Distributed event streaming platform ✓ **GA** * [**Amazon S3**](/integrations/data-platforms/integration-with-s3) - Object storage with event notifications ✓ **GA** **Common Use Cases:** * Stream model predictions in real-time from production services * Monitor agentic AI interactions as they occur * Trigger alerts on data quality issues within seconds * Capture ground truth feedback from user interactions ### 🔄 Orchestration & Pipelines Integrate Fiddler into your ML workflow orchestration for automated monitoring at every pipeline stage. **Supported Platforms:** * [**Apache Airflow**](/integrations/data-platforms/airflow-integration) - Workflow orchestration platform ✓ **GA** * [**AWS SageMaker Pipelines**](/integrations/data-platforms/sagemaker-integration) - Managed ML pipeline service ✓ **GA** **Common Use Cases:** * Automatically upload datasets when training pipelines complete * Trigger model evaluation as part of CI/CD workflows * Schedule periodic drift checks and performance reports * Orchestrate ground truth label collection and enrichment ## Data Warehouse Integrations ### Snowflake **Why Snowflake + Fiddler:** * **Zero-Copy Data Sharing** - No data duplication, direct queries to Snowflake * **Secure Data Access** - OAuth 2.0 and key-pair authentication * **Scalable Analytics** - Leverage Snowflake's compute for large datasets * **Cost-Effective** - Pay only for queries executed, no data transfer fees **Quick Start:** ```sql theme={null} -- Create Fiddler integration user CREATE USER fiddler_user PASSWORD='...'; CREATE ROLE fiddler_role; GRANT ROLE fiddler_role TO USER fiddler_user; -- Grant permissions to your ML data GRANT USAGE ON DATABASE ml_data TO ROLE fiddler_role; GRANT USAGE ON SCHEMA ml_data.predictions TO ROLE fiddler_role; GRANT SELECT ON ALL TABLES IN SCHEMA ml_data.predictions TO ROLE fiddler_role; ``` [**Full Snowflake Setup Guide →**](/integrations/data-platforms/snowflake-integration) ### Google BigQuery **Why BigQuery + Fiddler:** * **Serverless Architecture** - No infrastructure management * **SQL-Based Queries** - Familiar interface for data teams * **Federated Queries** - Join Fiddler data with other GCP sources * **Machine Learning** - BigQuery ML model monitoring integration **Quick Start:** ```python theme={null} from fiddler import FiddlerClient # Connect Fiddler to BigQuery client = FiddlerClient(api_key="fid_...") client.add_bigquery_connection( project_id="your-gcp-project", dataset_id="ml_predictions", credentials_path="service-account-key.json" ) # Import dataset from BigQuery table client.upload_dataset_from_bigquery( project="your-project", dataset="ml_predictions", table="credit_risk_predictions" ) ``` [**Full BigQuery Setup Guide →**](/integrations/data-platforms/bigquery-integration) ## Streaming Integrations ### Apache Kafka **Why Kafka + Fiddler:** * **Real-Time Monitoring** - Sub-second latency from prediction to observability * **High Throughput** - Handle millions of events per second * **Event Replay** - Replay historical events for testing and validation * **Exactly-Once Semantics** - Guaranteed delivery for critical predictions **Architecture Pattern:** ``` Prediction Service ↓ (publish) Kafka Topic: model-predictions ↓ (consume) Fiddler Kafka Consumer ↓ (ingest) Fiddler Platform ``` **Quick Start:** ```python theme={null} from fiddler import FiddlerClient # Configure Kafka consumer for Fiddler client = FiddlerClient(api_key="fid_...") client.add_kafka_source( bootstrap_servers="kafka-broker:9092", topic="model-predictions", group_id="fiddler-consumer", # Message format value_deserializer="json", schema={ "prediction_id": "string", "model_id": "string", "prediction": "float", "features": "object" } ) ``` [**Full Kafka Setup Guide →**](/integrations/data-platforms/kafka-integration) ### Amazon S3 **Why S3 + Fiddler:** * **Batch Processing** - Ingest large datasets efficiently * **Event Notifications** - Automatic processing when new files arrive * **Data Lake Integration** - Monitor models trained on S3 data lakes * **Cost-Effective Storage** - Archive historical predictions in S3 **Integration Patterns:** **Pattern 1: Scheduled Batch Upload** ```python theme={null} from fiddler import FiddlerClient client = FiddlerClient(api_key="fid_...") # Upload dataset from S3 client.upload_dataset_from_s3( project="fraud-detection", dataset="production-predictions", s3_uri="s3://my-bucket/predictions/2024-11-10.parquet", format="parquet" ) ``` **Pattern 2: Event-Driven Upload** ```python theme={null} # AWS Lambda triggered by S3 event import json from fiddler import FiddlerClient def lambda_handler(event, context): # Extract S3 bucket and key from event bucket = event['Records'][0]['s3']['bucket']['name'] key = event['Records'][0]['s3']['object']['key'] # Upload to Fiddler client = FiddlerClient(api_key=os.environ['FIDDLER_API_KEY']) client.upload_dataset_from_s3( project="my-project", dataset="streaming-data", s3_uri=f"s3://{bucket}/{key}" ) ``` [**Full S3 Setup Guide →**](/integrations/data-platforms/integration-with-s3) ## Orchestration & Pipeline Integrations ### Apache Airflow **Why Airflow + Fiddler:** * **Automated Workflows** - Trigger Fiddler operations as DAG tasks * **Dependency Management** - Ensure data quality before model training * **Scheduling** - Periodic drift checks and model evaluations * **Observability** - Monitor ML pipelines and models in one platform **Example DAG:** ```python theme={null} from airflow import DAG from airflow.operators.python import PythonOperator from fiddler_airflow import FiddlerDatasetUploadOperator, FiddlerModelEvaluationOperator from datetime import datetime dag = DAG( 'ml_pipeline_with_monitoring', start_date=datetime(2024, 1, 1), schedule_interval='@daily' ) # Train model train_task = PythonOperator( task_id='train_model', python_callable=train_model_func, dag=dag ) # Upload training data to Fiddler upload_task = FiddlerDatasetUploadOperator( task_id='upload_to_fiddler', project='credit-risk', dataset='training_data', data_source='s3://my-bucket/training-data.csv', dag=dag ) # Evaluate model in Fiddler eval_task = FiddlerModelEvaluationOperator( task_id='evaluate_model', project='credit-risk', model='risk_model_v2', baseline_dataset='training_data', dag=dag ) train_task >> upload_task >> eval_task ``` [**Full Airflow Setup Guide →**](/integrations/data-platforms/airflow-integration) ### AWS SageMaker Pipelines **Why SageMaker Pipelines + Fiddler:** * **Native AWS Integration** - Seamless with SageMaker Partner AI App * **End-to-End ML Workflows** - From data prep to model monitoring * **Model Registry Integration** - Automatic monitoring setup for registered models * **Cost Optimization** - Leverage existing SageMaker infrastructure **Example Pipeline:** ```python theme={null} from sagemaker.workflow.pipeline import Pipeline from sagemaker.workflow.steps import ProcessingStep, TrainingStep from sagemaker.workflow.functions import Join from fiddler_sagemaker import FiddlerMonitoringStep # Define SageMaker pipeline steps processing_step = ProcessingStep(...) training_step = TrainingStep(...) # Add Fiddler monitoring step fiddler_step = FiddlerMonitoringStep( name="SetupFiddlerMonitoring", model_name=training_step.properties.ModelName, baseline_dataset_s3_uri=processing_step.properties.ProcessingOutputConfig.Outputs["baseline"].S3Output.S3Uri, fiddler_project="sagemaker-models", depends_on=[training_step] ) # Create pipeline pipeline = Pipeline( name="MLPipelineWithFiddler", steps=[processing_step, training_step, fiddler_step] ) ``` [**Full SageMaker Pipelines Guide →**](/integrations/data-platforms/sagemaker-integration) ## Integration Selector Not sure which data integration to use? Here's a quick decision guide: | Your Data Source | Recommended Integration | Why | | ---------------------------- | ----------------------- | -------------------------------------- | | Snowflake data warehouse | **Snowflake connector** | Zero-copy sharing, direct queries | | BigQuery tables | **BigQuery connector** | Serverless, SQL-based, GCP-native | | Real-time prediction streams | **Kafka integration** | Sub-second latency, high throughput | | S3 data lake | **S3 integration** | Batch processing, event-driven uploads | | Airflow ML pipelines | **Airflow operators** | Automated workflows, task dependencies | | SageMaker workflows | **SageMaker Pipelines** | Native AWS integration, model registry | ## Getting Started ### Prerequisites Before setting up data integrations, ensure you have: * **Fiddler Account** - Cloud or on-premises instance * **API Key** - Generate from Fiddler UI Settings * **Data Source Access** - Credentials with read permissions * **Network Connectivity** - Firewall rules allowing Fiddler → Data Source ### General Setup Pattern All data integrations follow this pattern: **1. Configure Connection** ```python theme={null} from fiddler import FiddlerClient client = FiddlerClient( api_key="fid_...", url="https://app.fiddler.ai" ) # Add data source client.add_data_source( name="my-data-warehouse", type="snowflake", # or bigquery, kafka, s3 connection_params={...} ) ``` **2. Test Connection** ```python theme={null} # Verify connectivity status = client.test_data_source("my-data-warehouse") print(f"Connection status: {status}") ``` **3. Ingest Data** ```python theme={null} # Upload dataset from data source client.upload_dataset_from_source( project="my-project", dataset="training-data", source="my-data-warehouse", query="SELECT * FROM predictions WHERE date > '2024-01-01'" ) ``` ## Advanced Patterns ### Pattern 1: Multi-Source Data Enrichment Combine data from multiple sources for comprehensive monitoring: ```python theme={null} # Production predictions from Kafka client.add_kafka_source( topic="production-predictions", # ... additional connection settings ) # Ground truth labels from Snowflake client.add_snowflake_source( database="ml_data", schema="labels", # ... additional connection settings ) # Join predictions with labels client.configure_ground_truth_enrichment( project="fraud-detection", prediction_source="production-predictions", label_source="ml_data.labels.fraud_labels", join_key="transaction_id", time_window_hours=24 ) ``` ### Pattern 2: Data Quality Validation Validate data quality before ingestion: ```python theme={null} from fiddler import DataValidator validator = DataValidator() validator.add_rule("age", min_value=18, max_value=100) validator.add_rule("income", not_null=True) validator.add_rule("credit_score", pattern=r'^\d{3}$') # Validate before upload is_valid = client.upload_dataset_from_source( ..., validator=validator, on_validation_failure="abort" # or "warn" or "ignore" ) ``` ### Pattern 3: Incremental Updates Efficiently update datasets with only new data: ```python theme={null} # Initial full load client.upload_dataset_from_source( project="my-project", dataset="user-events", source="my-bigquery", query="SELECT * FROM events" ) # Daily incremental updates (scheduled via Airflow) client.update_dataset_from_source( project="my-project", dataset="user-events", source="my-bigquery", query="SELECT * FROM events WHERE date = CURRENT_DATE()", mode="append" # or "upsert" ) ``` ## Data Format Requirements ### Baseline/Training Data Must include: * **Features** - All model input features * **Predictions** - Model outputs (for validation) * **Metadata** (optional) - Additional context fields **Example Schema:** ```json theme={null} { "transaction_id": "string", "amount": "float", "merchant_category": "string", "prediction": "float", "timestamp": "datetime" } ``` ### Production Event Data Must include: * **Event ID** - Unique identifier * **Timestamp** - Event time * **Features** - Model inputs * **Predictions** - Model outputs * **Model Version** (optional) - For multi-model monitoring **Example Kafka Message:** ```json theme={null} { "event_id": "evt_12345", "timestamp": "2024-11-10T14:32:01Z", "model": "fraud_detector_v3", "features": { "amount": 127.50, "merchant": "AMZN" }, "prediction": 0.23 } ``` ## Security & Compliance ### Authentication Methods **Snowflake:** * Username/Password * Key Pair Authentication (recommended for production) * OAuth 2.0 **BigQuery:** * Service Account JSON key * Application Default Credentials * Workload Identity (GKE) **Kafka:** * SASL/PLAIN * SASL/SCRAM * mTLS **S3:** * IAM Role (recommended for AWS deployments) * Access Key / Secret Key * Cross-account access via IAM role assumption ### Data Privacy * **Encryption in Transit** - TLS 1.3 for all data transfers * **Encryption at Rest** - Data encrypted in Fiddler storage * **PII Redaction** - Automatically detect and redact sensitive fields * **Data Retention** - Configurable retention policies per dataset ### Network Security **Firewall Rules:** ``` Source: Fiddler Platform IP ranges Destination: Your Data Source Ports: - Snowflake: 443 (HTTPS) - BigQuery: 443 (HTTPS) - Kafka: 9092/9093 (SASL/SSL) - S3: 443 (HTTPS) ``` **Private Connectivity:** * **AWS PrivateLink** - For SageMaker Partner AI App * **VPC Peering** - Direct connection to data sources * **VPN Tunnels** - Secure connectivity for on-premises sources ## Monitoring Data Pipeline Health ### Connection Health Checks ```python theme={null} # Check all data source connections sources = client.list_data_sources() for source in sources: status = client.test_data_source(source.name) print(f"{source.name}: {status.status} (latency: {status.latency_ms}ms)") ``` ### Data Ingestion Metrics Monitor data pipeline performance: * **Ingestion Latency** - Time from source to Fiddler * **Throughput** - Events per second processed * **Error Rate** - Failed ingestion attempts * **Data Freshness** - Time since last successful update ### Alerts on Pipeline Failures ```python theme={null} # Configure alert for data pipeline issues client.create_alert( name="Data Pipeline Failure", trigger="data_ingestion_failed", source="kafka-production-predictions", notification_channels=["email", "pagerduty"] ) ``` ## Troubleshooting ### Common Issues **Connection Timeouts:** * Check network connectivity and firewall rules * Verify credentials are current and have proper permissions * Ensure data source is reachable from Fiddler's network **Schema Mismatches:** * Validate data types match Fiddler's expected schema * Check for null values in required fields * Ensure timestamp fields use supported formats (ISO 8601) **High Latency:** * For Kafka: Check consumer lag and partition count * For Data Warehouses: Optimize queries, add indexes * For S3: Use Parquet or ORC instead of CSV **Data Quality Issues:** * Enable data validation rules before ingestion * Set up alerts for out-of-range values * Configure automatic PII redaction ## Related Integrations * [**Cloud Platforms**](/integrations/cloud-platforms-and-deployment/cloud-platforms) - Deploy Fiddler on AWS, Azure, GCP * [**ML Platforms**](/integrations/ml-platforms-and-tools/ml-platforms) - Integrate with Databricks, MLflow * [**Agentic AI**](/integrations/agentic-ai-and-llm-frameworks/agentic-ai) - Monitor LangGraph and Strands Agents * [**Monitoring & Alerting**](/integrations/monitoring-and-alerting/monitoring-alerting) - Send alerts to incident management tools *** # Apache Airflow Source: https://docs.fiddler.ai/integrations/data-platforms/airflow-integration Discover how to integrate Fiddler with an Airflow DAG for your ML pipeline, enabling you to train, manage, onboard models, and monitor performance seamlessly. Apache Airflow is an open source ETL platform to manage complex workflows. Companies are increasingly integrating their ML models pipeline into Airflow DAGs to manage and monitor all the components of their ML model system. By integrating Fiddler into an existing Airflow DAG, you will be able to train, manage, and onboard your models while actively monitoring performance, data quality, and troubleshooting degradations across your models. Fiddler can be easily integrated into your existing airflow DAG for ML model pipeline. A notebook which is used for publishing events can be orchestrated to run as a part of your airflow DAG using a ‘Papermill Operator’. ### Steps for the walkthrough 1. Setup airflow on your local or docker, these steps can be followed. [Link](https://airflow.apache.org/docs/apache-airflow/stable/start/index.html) 2. Add your jupyter notebook containing the code for publishing to your airflow home directory. In this example we will use the 2 different notebooks - a. [Notebook to onboard ML model to Fiddler platform](https://colab.research.google.com/github/fiddler-labs/fiddler-examples/blob/main/integration-examples/airflow/notebooks/Fiddler_Churn_Add_Model.ipynb) b. [Notebook to push production events to Fiddler platform](https://colab.research.google.com/github/fiddler-labs/fiddler-examples/blob/main/integration-examples/airflow/notebooks/Fiddler_Churn_Event_Publishing.ipynb) 3. Add an orchestration code to your airflow directory, airflow will pick up the orchestration code and construct a DAG as defined. The orchestration code contains the ‘papermill operator’ to orchestrate the jupyter notebooks which will be used to onboard models and publish events to Fiddler. Please refer to our [orchestration code](https://github.com/fiddler-labs/fiddler-examples/tree/main/integration-examples/airflow/DAGs). 4. The run interval can be set up in orchestration code as ‘schedule\_interval’ in the DAG class. This interval can be based on the frequency of training and inference of your ML model. 5. Once the DAGs are set up it can be monitored on the UI. Below we can see dummy DAGs have been set up with placeholder nodes for ‘data preparation ETL’ and ‘model training/inference’. We have two DAGs - a. To set up Fiddler model registration after preparing baseline data (training pipeline) b. To publish events to Fiddler after data preparation and ML model inference (inference pipeline) ### Label Update An important business use case is integrating Fiddler’s ‘Label Update’ as a part of your ML workflow using Airflow. Label update can be used to update the ground truth feature in your data. This can be done using the ‘​​publish\_event’ api, passing the event, event\_id parameters, and making the update\_event parameter as ‘True’. The code to update label can be found in the [notebook](https://colab.research.google.com/github/fiddler-labs/fiddler-examples/blob/main/integration-examples/airflow/notebooks/Fiddler_Churn_Label_Update.ipynb) This notebook can be integrated to run as a part of your airflow DAG using the [sample code](https://github.com/fiddler-labs/fiddler-examples/blob/main/integration-examples/airflow/DAGs/fiddler_event_update.py) ### Papermill Operator ``` operator_var = PapermillOperator( task_id="task_name", input_nb="input_jupyter_notebook", output_nb="output_jupyter_notebook", parameters={"variable_1": "{{ value }}"}, ) ``` ### Airflow DAG Below is an example of Model Registration Airflow DAG run history Model Registration Airflow DAG flow # BigQuery Source: https://docs.fiddler.ai/integrations/data-platforms/bigquery-integration Discover BigQuery integration with Fiddler. Learn how to load ML data from BigQuery tables and use it for tasks like publishing production data to Fiddler. ### Integrating Fiddler with BigQuery Learn how to connect Fiddler's ML monitoring platform with your BigQuery data to enable comprehensive model tracking and analysis. This guide covers: * Using BigQuery data to onboard models in Fiddler * Loading baseline datasets from BigQuery tables * Monitoring production data by connecting BigQuery to Fiddler #### Prerequisites: * A Google Cloud account with BigQuery access * Fiddler account [credentials](/reference/administration/settings#credentials) * [Python Client SDK](/sdk-api/python-client/connection) installed ### Configure BigQuery Access Before importing data, you'll need to set up BigQuery API access and authentication: 1. In the GCP platform, Go to the navigation menu -> click APIs & Services. Once you are there, click + Enable APIs and Services (Highlighted below). In the search bar, enter BigQuery API and click Enable. GCP APIs & Services dashboard with the Enable APIs and Services button highlights. BigQuery API landing page highlighting the Try This API button and showing the API as enabled. 2. In order to make a request to the API enabled in Step #1, you need to create a service account and get an authentication file for your Jupyter Notebook. To do so, navigate to the Credentials tab under APIs and Services console and click Create Credentials tab, and then Service account under dropdown. APIs & Services credentials landing page showing the Credentials left navigation link and the Create Credentials button highlighted. 3. Enter the Service account name and description and click Done. You can use the BigQuery Admin role under Grant this service account access to the project. You can now see the new service account under the Credentials screen. Click the pencil icon beside the new service account you have created and click Add Key to add auth key. Please choose JSON and click CREATE. It will download the JSON file with auth key info. (Download path will be used to authenticate) Showing Keys tab of the new service account and the create private key model for example account "fiddler" with JSON key type option selected. ### Connect to BigQuery Data Set up your Python environment and connect to BigQuery: 1. Install Required Packages ```bash theme={null} pip install google-cloud google-cloud-bigquery[pandas] google-cloud-storage ``` 2. Configure Authentication ```python theme={null} # Set environment variables for your notebook import os os.environ['GOOGLE_APPLICATION_CREDENTIALS'] = 'path/to/your/auth-key.json' ``` 3. Initialize BigQuery Client ```python theme={null} # Imports google cloud client library and initiates BQ service from google.cloud import bigquery bigquery_client = bigquery.Client() ``` 4. Query Your Data ```python theme={null} # Example query to fetch baseline data query = """ SELECT * FROM `fiddler-bq.fiddler_test.churn_prediction_baseline` """ # Execute query and load into pandas DataFrame baseline_df = bigquery_client.query(query).to_dataframe() ``` #### Next Steps Now that you've connected BigQuery to Fiddler, you can: 1. [Onboard a model](/developers/python-client-guides/model-onboarding/create-a-project-and-model) using the baseline dataset for the model schema inference sample. 2. [Upload a Baseline dataset](/developers/python-client-guides/publishing-production-data/creating-a-baseline-dataset), which is optional but recommended for monitoring comparisons. 3. [Publish production events](/developers/client-library-reference/publishing-production-data) for continuous monitoring. # Amazon S3 Source: https://docs.fiddler.ai/integrations/data-platforms/integration-with-s3 Effortlessly extract AWS S3 data for model onboarding and inference publishing to Fiddler for monitoring. This guide explains how to integrate AWS S3 with Fiddler to retrieve baseline or production data for model monitoring. You'll learn how to: * Extract data from S3 buckets using different authentication methods * Load data efficiently based on your needs * Connect the extracted data with Fiddler's monitoring capabilities ### How to Integrate Fiddler with AWS S3 #### Prerequisites Before getting started, ensure you have: * An AWS account with access to the required S3 bucket * Required Python packages installed: boto3, pandas, and fiddler-client * Appropriate AWS credentials or profile configuration * Basic familiarity with Python and AWS S3 concepts ### AWS Authentication Methods #### Method 1: Using AWS Access Keys If you're using AWS access keys for authentication, use this approach: ```python theme={null} import boto3 import pandas as pd # AWS Configuration S3_BUCKET = 'your_bucket_name' S3_FILENAME = 'path/to/your/file.csv' AWS_ACCESS_KEY_ID = 'your_access_key' AWS_SECRET_ACCESS_KEY = 'your_secret_key' AWS_REGION = 'your_region' # Create AWS session session = boto3.session.Session( aws_access_key_id=AWS_ACCESS_KEY_ID, aws_secret_access_key=AWS_SECRET_ACCESS_KEY, region_name=AWS_REGION, ) # Initialize S3 client s3 = session.client('s3') # Read data into pandas DataFrame s3_data = s3.get_object(Bucket=S3_BUCKET, Key=S3_FILENAME)['Body'] df = pd.read_csv(s3_data) ``` #### Method 2: Using AWS Profiles (Recommended) For enhanced security, we recommend using AWS profiles instead of hardcoding credentials: ```python theme={null} import boto3 import pandas as pd # Configuration S3_BUCKET = 'your_bucket_name' S3_FILENAME = 'path/to/your/file.csv' AWS_PROFILE = 'your_profile_name' # Create session using profile session = boto3.session.Session(profile_name=AWS_PROFILE) s3 = session.client('s3') # Read data s3_data = s3.get_object(Bucket=S3_BUCKET, Key=S3_FILENAME)['Body'] df = pd.read_csv(s3_data) ``` ### Data Loading Options #### Option 1: Direct Memory Loading For smaller datasets that fit in memory, load directly into a pandas DataFrame as shown in the examples above. #### Option 2: File System Loading For larger datasets or when memory constraints exist, save to disk first: ```python theme={null} import boto3 # AWS Configuration S3_BUCKET = 'your_bucket_name' S3_FILENAME = 'path/to/your/file.csv' OUTPUT_PATH = 'local/path/to/output.csv' # Initialize S3 client (using either authentication method) session = boto3.session.Session(profile_name='your_profile_name') s3 = session.client('s3') # Download file s3.download_file( Bucket=S3_BUCKET, Key=S3_FILENAME, Filename=OUTPUT_PATH ) ``` ### Using AWS S3 Data with Fiddler #### For Baseline Datasets After loading your data, you can use it to create a baseline dataset in Fiddler. See the [Creating a Baseline Dataset](/developers/python-client-guides/publishing-production-data/creating-a-baseline-dataset) guide for more details. ```python theme={null} import fiddler as fdl # Assumes an initialized Python client session and instantiated Model job = model.publish_batch( source=s3_data_df, environment=fdl.EnvType.PRE_PRODUCTION, dataset_name='your_baseline_name', ) print( f'Initiated pre-production dataset upload with Job ID = {job.id}' ) ``` #### For Production Traffic To publish production data for monitoring. Refer to the [batch publishing guide](/developers/python-client-guides/publishing-production-data/publishing-batches-of-events) for more details. For more publishing options, see the additional publishing guides located [here](/developers/client-library-reference/publishing-production-data). ```python theme={null} import fiddler as fdl # Assumes an initialized Python client session and instantiated Model job = model.publish_batch( source=s3_data_df, environment=fdl.EnvType.PRODUCTION, ) print( f'Initiated Production dataset upload with Job ID = {job.id}' ) ``` #### Best Practices * Always use AWS profiles instead of hardcoded credentials in production environments * Implement proper error handling around S3 operations * Consider data size when choosing between memory and file system loading * Use appropriate AWS IAM roles and permissions * Monitor memory usage when working with large datasets # Apache Kafka Source: https://docs.fiddler.ai/integrations/data-platforms/kafka-integration Dive into Fiddler’s Kafka connector services. Learn about prerequisites, installation, and limitations to manage production events and publish them to Fiddler. Fiddler Kafka connector is an optional Fiddler service that connects to a [Kafka topic](https://kafka.apache.org/documentation/#intro_concepts_and_terms) containing production events for a model, and publishes the events to Fiddler. ### Kafka Integration Pre-requisites We assume that the user has an account with Fiddler, has already created a project, and onboarded a model. #### Installation For Fiddler on-premises installations, the Kafka connector runs on Kubernetes in your environment. It is packaged as a Helm chart for quick installation: ```shell theme={null} helm repo add fiddler https://helm.fiddler.ai/stable/ helm repo update kubectl -n kafka create secret generic fiddler-credentials --from-literal=auth= helm install fiddler-kafka fiddler/fiddler-kafka --devel --namespace kafka --set fiddler.url=https:// --set fiddler.org= --set fiddler.project_id= --set fiddler.model_id= --set fiddler.ts_field=timestamp --set fiddler.ts_format=INFER --set kafka.host=kafka --set kafka.port=9092 --set kafka.topic= --set kafka.security_protocol=SSL --set kafka.ssl_cafile=cafile --set kafka.ssl_certfile=certfile --set kafka.ssl_keyfile=keyfile --set-string kafka.ssl_check_hostname=False ``` This creates a deployment that reads event data from the Kafka topic and publishes it to the configured Fiddler model. The deployment can be scaled as needed; however, note that if the Kafka topic is not partitioned, scaling will not result in any gains. #### Limitations 1. The connector assumes that there is a single dedicated topic containing production events for a given model. Multiple deployments can be created, one for each model, and scaled independently. 2. The connector assumes that events are published as JSON-serialized dictionaries of key-value pairs. Support for other formats can be added on request. As an example, a Kafka message should look like the following: ```json theme={null} { “feature_1”: 20.7, “feature_2”: 45000, “feature_3”: true, “output_column”: 0.79, “target_column”: 1, “ts”: 1637344470000, } ``` # SageMaker Pipelines Source: https://docs.fiddler.ai/integrations/data-platforms/sagemaker-integration Learn how integrating SageMaker with Fiddler simplifies model monitoring. Explore our guide on using AWS Lambda with the Fiddler Python client. ## Amazon SageMaker Integration ### Introduction Integrate Amazon SageMaker with Fiddler to monitor your deployed models effectively. This guide shows you how to create an AWS Lambda function that uses the Fiddler Python client to process SageMaker inference logs from Amazon S3 and send them to your Fiddler instance. This integration provides real-time monitoring capabilities and valuable insights into your model's performance and behavior. Fiddler AI Observability Platform is now available within Amazon SageMaker AI in SageMaker Unified Studio. This native integration lets SageMaker customers monitor ML models privately and securely without leaving the SageMaker environment. Learn more about the Amazon SageMaker AI with Fiddler native integration [here](https://www.fiddler.ai/blog/fiddler-delivers-native-enterprise-grade-ai-observability-to-amazon-sagemaker-ai-customers). ### Prerequisites Before you begin, ensure you have: 1. An active SageMaker model with: * Data capture enabled * Inference logs saved to S3 in JSONL format 2. Access to a Fiddler environment 3. Your SageMaker model is onboarded to Fiddler (See the [ML Monitoring Quick Start Guide](/developers/quick-starts/simple-ml-monitoring)) 4. Latest Fiddler Python client version ### Implementation Steps #### 1. Configure SageMaker Data Capture Ensure your SageMaker endpoint has data capture properly configured: 1. Open the SageMaker console 2. Navigate to your model endpoint 3. Verify data capture is enabled and configured to save to your S3 bucket 4. Confirm captured data is in JSONL format #### 2. Create an AWS Lambda Function 1. Open the AWS Lambda console 2. Click "Create function" 3. Configure the basic settings: * Name your function (for example, "fiddler-sagemaker-integration") * Select Python 3.10 or later as the runtime * Choose execution permissions that allow S3 access #### 3. Set Up Environment Variables Configure these environment variables in your Lambda function: | Variable | Description | Example | | -------------------- | ------------------------------------------ | ------------------------------------ | | `FIDDLER_URL` | Your Fiddler environment URL | `https://your_company.fiddler.ai` | | `FIDDLER_TOKEN` | Your Fiddler authorization token | *(secure token value)* | | `FIDDLER_MODEL_UUID` | Your model's unique identifier in Fiddler | 8a86cc43-71c1-49e7-a01b-d98ae91975bb | | `MODEL_COLUMNS` | Comma-separated list of input column names | `feature1,feature2,feature3` | | `MODEL_OUTPUT` | Name of the model output column | `prediction` | | `MODEL_TIMESTAMP` | Name of the timestamp column (optional) | `event_time` | If you provisioned Fiddler via the [SageMaker AI marketplace](https://docs.aws.amazon.com/sagemaker/latest/dg/partner-apps.html), add these additional variables: * `AWS_PARTNER_APP_AUTH`: Set to `True` * `AWS_PARTNER_APP_ARN`: The ARN of your SageMaker AI Fiddler instance * `AWS_PARTNER_APP_URL`: The URL of your SageMaker AI Fiddler instance AWS Lambda function console on the environment variables tab showing the example variables used in this guide. #### 4. Configure S3 Trigger Set up your Lambda to run automatically when new data arrives: 1. In the Lambda console, select your function 2. Choose the "Add trigger" option 3. Select "S3" as the trigger type 4. Configure these settings: * Bucket: Select your SageMaker inference logs bucket * Event type: "All object create events" * Prefix: (Optional) Specify a path prefix if needed * Suffix: `.jsonl` (to only process JSON Lines files) AWS Lambda function console on the triggers tab showing the details of the trigger used in this guide. #### 5. Add Lambda Function Code AWS Lambda function console on the main view showing the code tab and some of the code used in this guide. Copy this code into your Lambda function editor: ```python theme={null} import os import json import uuid import boto3 import logging from typing import Dict, List, Any import fiddler as fdl # Configure logging logger = logging.getLogger() logger.setLevel(logging.INFO) # Load environment variables, customize to model and use case url = os.getenv('FIDDLER_URL') token = os.getenv('FIDDLER_TOKEN') model_uuid = os.getenv('FIDDLER_MODEL_UUID') model_columns = os.getenv('MODEL_COLUMNS') model_output_column = os.getenv('MODEL_OUTPUT') timestamp_column = os.getenv('MODEL_TIMESTAMP') # Initialize AWS clients s3_client = boto3.client('s3') # Initialize Fiddler connection and Fiddler Model to receive events fdl.init(url=url, token=token) fiddler_model = fdl.Model.get(id_=model_uuid) def get_all_columns(): # The types of columns needed when publishing depend on use case. Typically, # you would expect to pass at least your model inputs and output(s) and often # metadata such as IDs, dates, data segments, etc. return model_columns.split(',') + [timestamp_column] + [model_output_column] def process_jsonl_content(event_data: str) -> Dict[str, Any]: input_data = event_data['captureData']['endpointInput']['data'] input_values = input_data.split(',') # Split the CSV string into a list # Extract the model prediction from 'captureData/endpointOutput/data' model_prediction = event_data['captureData']['endpointOutput']['data'] # Optionally, you can set your own timestamp value on the inference occurrence time, # or let Fiddler default it to the time of publish. timestamp_value = event_data['eventMetadata']['inferenceTime'] # Combine inputs and any metadata values with the output into a single row all_values = input_values + [timestamp_value] + [model_prediction] # Create dictionary using zip to pair column names with their values return dict(zip(get_all_columns(), all_values)) def parse_sagemaker_log(log_file_path: str) -> List[Dict[str, Any]]: try: # Collect all events in a List, 1 per JSON-line in the file event_rows = [] with open(log_file_path, 'r') as file: for line in file: event = json.loads(line.strip()) row = process_jsonl_content(event) event_rows.append(row) return { 'status': 'success', 'record_count': len(event_rows), 'data': event_rows } except json.JSONDecodeError as e: logger.error(f'Error parsing JSONL content: {str(e)}') raise def publish_to_fiddler(inferences: List[Dict[str, Any]], model: fdl.Model): # There are multiple options for publishing data to Fiddler, check # the online documentation for batch, streaming, and REST API options. # publish_stream() sends events synchronously; for large datasets # consider publish_batch() with a file path or DataFrame instead. event_ids = model.publish_stream( events=inferences, environment=fdl.EnvType.PRODUCTION ) return event_ids def lambda_handler(event: Dict[str, Any], context: Any) -> Dict[str, Any]: # Process each record in the event, streaming to Fiddler in batches for record in event['Records']: # Extract bucket and key information bucket = record['s3']['bucket']['name'] key = record['s3']['object']['key'] logger.info(f'Processing new file: {key} from bucket: {bucket}') # Persist log file to a temporary location tmp_key = key.replace('/', '') download_path = f'/tmp/{uuid.uuid4()}{tmp_key}' s3_client.download_file(bucket, key, download_path) # Retrieve the inference event(s) from the log file results = parse_sagemaker_log(download_path) # Check if the log file was processed successfully if results['status'] != 'success': logger.error(f'Error processing log file: {key}') return { 'statusCode': 500, 'body': {'message': 'Error processing log file', 'results': results}, } # Push the inference events to Fiddler event_ids = publish_to_fiddler(results["data"], fiddler_model) logger.info(f'Published events to Fiddler with ID(s): {event_ids}') return { 'statusCode': 200, 'body': {'message': 'Successfully processed events', 'results': results}, } ``` # Snowflake Source: https://docs.fiddler.ai/integrations/data-platforms/snowflake-integration Learn how to extract baseline or production data from Snowflake for model onboarding and publishing production data to Fiddler for ML and LLM monitoring. In this article, we will be looking at loading data from Snowflake tables and using the data for the following tasks: 1. Onboarding a model to Fiddler 2. Uploading baseline data to Fiddler 3. Publishing production data to Fiddler ## Import data from Snowflake In order to import data from Snowflake to a Jupyter notebook, we will use the snowflake library which can be installed using the following command in your Python environment. ```bash theme={null} pip install snowflake-connector-python ``` The following information is required in order to establish a connection to Snowflake: * Snowflake Warehouse * Snowflake Role * Snowflake Account * Snowflake User * Snowflake Password These values can be obtained from your Snowflake account under the ‘Admin’ option in the Menu as shown below or by running the queries below: * Warehouse - select CURRENT\_WAREHOUSE() * Role - select CURRENT\_ROLE() * Account - select CURRENT\_ACCOUNT() 'User' and 'Password' are the same that you use when logging in to your Snowflake account. Example Snowflake dashboard showing the Warehouse tab. Once you have this information, you can set up a Snowflake connector using the following code: ```python theme={null} # establish Snowflake connection connection = connector.connect( user=snowflake_username, password=snowflake_password, account=snowflake_account, role=snowflake_role, warehouse=snowflake_warehouse ) ``` You can then write a custom SQL query and import the data to a pandas dataframe. ```python theme={null} # sample SQL query sql_query = 'select * from FIDDLER.FIDDLER_SCHEMA.CHURN_BASELINE LIMIT 100' # create cursor object cursor = connection.cursor() # execute SQL query inside Snowflake cursor.execute(sql_query) baseline_df = cursor.fetch_pandas_all() ``` ## Publish Production Events Now that we have data imported from Snowflake to a dataframe, we can refer to the following pages to: 1. [Onboard a model](/developers/python-client-guides/model-onboarding/create-a-project-and-model) using the baseline dataset for the model schema inference sample. 2. [Upload a Baseline dataset](/developers/python-client-guides/publishing-production-data/creating-a-baseline-dataset), which is optional but recommended for monitoring comparisons. 3. [Publish production events](/developers/client-library-reference/publishing-production-data) for continuous monitoring. # Integrations Source: https://docs.fiddler.ai/integrations/index Connect Fiddler to your AI stack with native SDKs, cloud platform integrations, data pipeline connectors, and framework support. From agentic workflows to traditional ML models, Fiddler integrates with the tools you already use. ## Quick Start Choose your integration path based on what you're building: * [**Monitor LangGraph Agents →**](/integrations/agentic-ai-and-llm-frameworks/agentic-ai) Auto-instrument agentic applications with the LangGraph SDK * [**Deploy on AWS →**](/integrations/cloud-platforms-and-deployment/cloud-platforms) Run Fiddler as a Partner AI App in SageMaker * [**Connect Your Data →**](/integrations/data-platforms-and-pipelines/data-platforms) Integrate with Snowflake, BigQuery, S3, and more ## Integration Categories ### 🎯 Agentic AI & LLM Frameworks Native instrumentation for agentic workflows and LLM applications—Fiddler's competitive differentiator. **Native SDKs:** * [Fiddler LangGraph SDK](/integrations/agentic-ai/langgraph-sdk) - Auto-instrument LangGraph agents with OpenTelemetry * [Fiddler Strands SDK](/integrations/agentic-ai/strands-sdk) - Monitor Strands Agents * [Fiddler Evals SDK](/integrations/agentic-ai/evals-sdk) - LLM experiments framework with pre-built evaluators **Platform Access:** * Python Client SDK - Core SDK client for ML/LLM monitoring * [REST API](/sdk-api/rest-api/alert-rules) - Complete HTTP API for all platform features [**View all agentic AI integrations →**](/integrations/agentic-ai-and-llm-frameworks/agentic-ai) ### ☁️ Cloud Platforms & Deployment Deploy Fiddler on your preferred cloud infrastructure. **Featured:** * [AWS SageMaker Partner AI App](/integrations/cloud-platforms-and-deployment/aws-sagemaker) - Fully managed deployment in SageMaker **Data Storage:** * [Amazon S3](/integrations/data-platforms/integration-with-s3) - S3 bucket integration for data ingestion * [Google BigQuery](/integrations/data-platforms/bigquery-integration) - BigQuery connector for ML pipelines [**View all cloud integrations →**](/integrations/cloud-platforms-and-deployment/cloud-platforms) ### 🗄️ Data Platforms & Pipelines Connect Fiddler to your data infrastructure for seamless model monitoring. **Data Warehouses:** * [Snowflake](/integrations/data-platforms/snowflake-integration) - Snowflake connector for production data * [BigQuery](/integrations/data-platforms/bigquery-integration) - Google BigQuery integration **Data Streaming:** * [Apache Kafka](/integrations/data-platforms/kafka-integration) - Real-time streaming data integration **Orchestration:** * [Apache Airflow](/integrations/data-platforms/airflow-integration) - Workflow automation for model deployments [**View all data integrations →**](/integrations/data-platforms-and-pipelines/data-platforms) ### 🤖 ML Platforms & Tools Integrate with your existing ML infrastructure and experiment tracking tools. **MLOps Platforms:** * [Databricks](/integrations/ml-platforms/databricks-integration) - Databricks ML integration via MLflow and Spark * [MLflow](/integrations/ml-platforms/ml-flow-integration) - Model registry and experiment tracking [**View all ML platform integrations →**](/integrations/ml-platforms-and-tools/ml-platforms) ### 📡 Monitoring & Alerting Route alerts and metrics to your observability stack. **Observability Platforms:** * [Datadog](/integrations/monitoring-alerting/datadog-integration) - Export metrics to Datadog for centralized monitoring **Incident Management:** * [PagerDuty](/integrations/monitoring-alerting/pagerduty) - Alert routing and on-call management **Notifications:** * Webhooks - Generic webhook support for custom integrations * Email Alerts - Built-in email notification system [**View all monitoring integrations →**](/integrations/monitoring-and-alerting/monitoring-alerting) ### 🔐 Authentication & Access Enterprise SSO and authentication providers for secure access control. **Enterprise SSO:** * [Okta Integration](/reference/access-control/okta-integration) - Enterprise single sign-on * [Google Workspace](/reference/access-control/google-integration) - Google SSO integration **API Authentication:** * API Keys - Token-based API authentication * OAuth - OAuth 2.0 flow support [**View all authentication options →**](/reference/access-control) ## Integration Types * **🏆 Native SDK** - Built and maintained by Fiddler; included with platform * **🤝 Partner Integration** - Built in collaboration with technology partner * **🔌 Connector** - Pre-built component for data source integration * **📚 Framework Guide** - Code examples and patterns for specific frameworks ## What's Next? * **Getting Started:** Follow our [quick start guides](/developers) to set up your first integration * **SDK Documentation:** Dive into detailed [SDK API reference](/sdk-api) documentation *** **Ready to integrate?** Choose a category above to explore specific integrations and get started in minutes. # ML Platforms Overview Source: https://docs.fiddler.ai/integrations/ml-platforms-and-tools/ml-platforms Integrate Fiddler with MLOps platforms, experiment tracking tools, and ML frameworks Integrate Fiddler into your MLOps workflow to monitor models across the entire machine learning lifecycle. From experiment tracking to production deployment, Fiddler works with the ML platforms you already use. ## Why ML Platform Integrations Matter Modern ML teams use sophisticated platforms for experimentation, training, and deployment. Fiddler's integrations ensure you can: * **Unified Model Governance** - Track models from experiment to production in one platform * **Automated Monitoring Setup** - Auto-configure monitoring when models are registered * **Seamless Workflow Integration** - Add observability without changing existing processes * **Bi-Directional Sync** - Share metrics between Fiddler and your ML platform * **Experiment Comparison** - Compare production performance against training experiments ## MLOps Platform Integrations ### Databricks Integrate Fiddler with Databricks for unified ML development and monitoring. **Why Databricks + Fiddler:** * **Lakehouse Architecture** - Monitor models trained on Delta Lake data * **MLflow Integration** - Automatic sync of registered models to Fiddler * **Notebook Integration** - Use Fiddler SDK directly in Databricks notebooks * **Production Monitoring** - Monitor models served via Databricks Model Serving **Key Features:** * **Automatic Model Registration** - Models registered in Databricks MLflow automatically appear in Fiddler * **Feature Store Integration** - Monitor drift using Databricks Feature Store definitions * **Collaborative Debugging** - Share Fiddler insights in Databricks notebooks * **Unified Data Access** - Use Delta Lake as data source for baselines and production data [**Get Started with Databricks →**](/integrations/ml-platforms/databricks-integration) **Quick Start:** ```python theme={null} from databricks import mlflow as dbx_mlflow from fiddler import FiddlerClient # Register model in Databricks MLflow model_uri = "models:/credit_risk_model/Production" model_version = dbx_mlflow.register_model(model_uri, "credit_risk_model") # Automatically sync to Fiddler client = FiddlerClient(api_key="fid_...") client.sync_from_databricks( model_name="credit_risk_model", version=model_version, enable_monitoring=True ) ``` ### MLflow Connect Fiddler to MLflow for experiment tracking and model registry integration. **Why MLflow + Fiddler:** * **Open-Source Standard** - Works with any MLflow deployment (Databricks, AWS, GCP, self-hosted) * **Model Registry Sync** - Automatically monitor models when they transition to "Production" * **Experiment Tracking** - Compare production metrics with training experiment metrics * **Model Versioning** - Track performance across model versions **Key Features:** * **Automatic Model Onboarding** - Models in MLflow registry auto-configure in Fiddler * **Metric Synchronization** - Export Fiddler metrics back to MLflow for unified view * **Artifact Integration** - Link model artifacts between MLflow and Fiddler * **Stage-Based Monitoring** - Different monitoring configs for Staging vs Production [**Get Started with MLflow →**](/integrations/ml-platforms/ml-flow-integration) **Quick Start:** ```python theme={null} import mlflow from fiddler import FiddlerClient # Set MLflow tracking URI mlflow.set_tracking_uri("https://mlflow.example.com") # Configure Fiddler to sync with MLflow client = FiddlerClient(api_key="fid_...") client.add_mlflow_integration( tracking_uri="https://mlflow.example.com", auto_sync_on_stage_transition=True, stages=["Production", "Staging"] ) # Models transitioning to "Production" will automatically be monitored in Fiddler ``` ## Experiment Tracking & Model Registry ### Unified Model Lifecycle Track models from experimentation through production: ``` Experiment → Training → Registration → Staging → Production → Monitoring ↓ ↓ ↓ ↓ ↓ ↓ MLflow MLflow MLflow MLflow MLflow Fiddler Runs Runs Registry Registry Registry + MLflow ``` **Integration Benefits:** * **Single Source of Truth** - MLflow registry as canonical model inventory * **Automated Workflows** - Monitoring setup triggered by model registration * **Version Comparison** - Compare production metrics across model versions * **Rollback Readiness** - Quick rollback with historical performance data ### Experiment-to-Production Comparison Compare production model performance against training experiments: ```python theme={null} from fiddler import FiddlerClient client = FiddlerClient(api_key="fid_...") # Get production metrics prod_metrics = client.get_metrics( project="fraud-detection", model="fraud_model_v3", start_time="2024-11-01", end_time="2024-11-10" ) # Compare with training experiment (from MLflow) experiment_metrics = client.get_experiment_metrics( mlflow_experiment_id="exp_12345", mlflow_run_id="run_67890" ) # Generate comparison report report = client.compare_metrics( production=prod_metrics, experiment=experiment_metrics, metrics=["accuracy", "precision", "recall", "auc"] ) ``` ## ML Framework Support While Fiddler is framework-agnostic, we provide enhanced support for popular ML frameworks: ### Supported ML Frameworks **Classical ML:** * **Scikit-Learn** - Full support for all estimators * **XGBoost** - Native explainability for tree models * **LightGBM** - Fast SHAP explanations * **CatBoost** - Categorical feature support **Deep Learning:** * **TensorFlow/Keras** - Model analysis and monitoring * **PyTorch** - Dynamic graph model support * **JAX** - High-performance model monitoring * **ONNX** - Framework-agnostic model format **AutoML:** * **H2O.ai** - AutoML model monitoring * **AutoGluon** - Tabular model support * **TPOT** - Pipeline optimization monitoring ### Framework-Specific Features **Tree-Based Models (XGBoost, LightGBM, CatBoost):** * Fast SHAP explanations using native implementations * Feature importance tracking over time * Tree structure analysis for debugging **Deep Learning (TensorFlow, PyTorch):** * Layer-wise activation monitoring * Embedding drift detection * Custom metric support for complex architectures **Example - XGBoost Monitoring:** ```python theme={null} import xgboost as xgb from fiddler import FiddlerClient # Train XGBoost model model = xgb.XGBClassifier() model.fit(X_train, y_train) # Upload to Fiddler with automatic feature importance client = FiddlerClient(api_key="fid_...") client.upload_model( project="credit-risk", model_name="xgb_risk_model", model=model, task="binary_classification", enable_shap=True # Native XGBoost SHAP support ) ``` ## Integration Architecture Patterns ### Pattern 1: MLflow-Centric Workflow Use MLflow as the central hub for all ML operations: ``` Data Preparation ↓ Experimentation (MLflow Tracking) ↓ Model Registry (MLflow) ↓ (webhook on stage transition) Fiddler Auto-Onboarding ↓ Production Monitoring (Fiddler + MLflow metrics export) ``` **Configuration:** ```python theme={null} # One-time setup: Configure MLflow webhook client = FiddlerClient(api_key="fid_...") client.configure_mlflow_webhook( mlflow_tracking_uri="https://mlflow.example.com", webhook_secret="webhook_secret_key", on_stage_transition={ "Production": "enable_full_monitoring", "Staging": "enable_basic_monitoring", "Archived": "disable_monitoring" } ) ``` ### Pattern 2: Databricks Unity Catalog Integration Leverage Databricks Unity Catalog for governance and Fiddler for monitoring: ``` Unity Catalog (Model Registry) ↓ Databricks Model Serving ↓ Production Traffic ↓ (streaming predictions) Fiddler Monitoring ↓ Alerts → Databricks Workflow Jobs (retraining) ``` **Configuration:** ```python theme={null} # Connect Fiddler to Unity Catalog client = FiddlerClient(api_key="fid_...") client.add_unity_catalog_integration( workspace_url="https://dbc-xxxxx.cloud.databricks.com", catalog="ml_models", schema="production", access_token=dbutils.secrets.get("fiddler", "databricks_token") ) ``` ### Pattern 3: Multi-Platform Model Tracking Monitor models across multiple ML platforms: ``` Training Platform Mix: ├── Databricks (Lakehouse models) ├── SageMaker (AWS-native models) ├── Vertex AI (GCP models) └── On-Premises (Legacy models) ↓ (all models sync to) Fiddler (Unified Monitoring) ``` ## Getting Started ### Prerequisites * **Fiddler Account** - Cloud or on-premises deployment * **ML Platform Access** - Databricks workspace or MLflow server * **Credentials** - Fiddler access token + ML platform credentials * **Network Connectivity** - Firewall rules for integration ### General Setup Steps **1. Configure ML Platform Connection** ```python theme={null} from fiddler import FiddlerClient client = FiddlerClient( api_key="fid_...", url="https://app.fiddler.ai" ) # Add ML platform integration client.add_integration( type="databricks", # or "mlflow" config={ "workspace_url": "https://dbc-xxxxx.cloud.databricks.com", "access_token": "dapi...", "auto_sync": True } ) ``` **2. Sync Existing Models (Optional)** ```python theme={null} # One-time sync of existing models models = client.sync_models_from_platform( platform="databricks", filter={"stage": "Production"} ) print(f"Synced {len(models)} models to Fiddler") ``` **3. Enable Auto-Monitoring** ```python theme={null} # Future model registrations will automatically be monitored client.configure_auto_monitoring( platform="databricks", enabled=True, default_config={ "enable_drift_detection": True, "enable_performance_tracking": True, "enable_explainability": True } ) ``` ## Advanced Integration Features ### Feature Store Integration Monitor models using features from Databricks Feature Store: ```python theme={null} from databricks.feature_store import FeatureStoreClient fs = FeatureStoreClient() # Create feature spec feature_spec = fs.create_feature_spec( table_name="ml_features.user_features", primary_keys=["user_id"] ) # Monitor model with feature store schema client.upload_model( project="recommendations", model="user_model", feature_spec=feature_spec, # Auto-generates schema from Feature Store enable_drift_detection=True ) ``` ### Automated Retraining Triggers Trigger retraining workflows when drift is detected: ```python theme={null} # Configure alert to trigger Databricks job client.create_alert( name="High Drift - Retrain Model", trigger_type="drift", threshold=0.15, model="credit_risk_model", actions=[{ "type": "databricks_job", "job_id": "12345", "parameters": { "model_name": "credit_risk_model", "reason": "drift_detected" } }] ) ``` ### Model Lineage Tracking Track complete model lineage from data to deployment: ```python theme={null} # Capture full model lineage lineage = { "data_source": "s3://bucket/training-data-v2.parquet", "feature_transformations": "feature_pipeline_v1", "training_framework": "xgboost==1.7.0", "mlflow_run_id": "run_67890", "parent_model": "credit_risk_model_v1" } client.update_model_metadata( project="credit-risk", model="credit_risk_model_v2", lineage=lineage ) ``` ## Integration Selector Choose the right ML platform integration for your workflow: | Your ML Platform | Recommended Integration | Why | | -------------------- | -------------------------- | ------------------------------------------- | | Databricks Lakehouse | **Databricks integration** | Native MLflow, Unity Catalog, Feature Store | | Self-hosted MLflow | **MLflow integration** | Open-source, cloud-agnostic | | AWS SageMaker | **SageMaker Pipelines** | AWS-native, Partner AI App compatible | | Azure ML | **MLflow integration** | Azure ML uses MLflow under the hood | | Vertex AI (GCP) | **MLflow integration** | Vertex AI supports MLflow | | Multiple platforms | **MLflow integration** | Universal compatibility | ## Bi-Directional Metric Sync Share metrics between Fiddler and your ML platform: ### Export Fiddler Metrics to MLflow ```python theme={null} # Log Fiddler metrics to MLflow experiments client.export_metrics_to_mlflow( fiddler_project="fraud-detection", fiddler_model="fraud_model_v3", mlflow_experiment_name="production_monitoring", metrics=["drift_score", "accuracy", "f1_score"], time_range="last_7_days" ) ``` ### Import MLflow Metrics to Fiddler ```python theme={null} # Import custom metrics from MLflow client.import_metrics_from_mlflow( mlflow_run_id="run_67890", fiddler_project="fraud-detection", fiddler_model="fraud_model_v3", metrics=["custom_business_metric", "validation_loss"] ) ``` ## Security & Access Control ### Authentication Methods **Databricks:** * Personal Access Tokens (development) * Service Principal OAuth (production) * Azure AD Integration (enterprise) **MLflow:** * HTTP Basic Authentication * Token-Based Authentication * Custom Auth Plugins ### Permission Requirements **Databricks Permissions:** * `CAN_MANAGE` on registered models * `CAN_READ` on Feature Store tables * `CAN_USE` on clusters (for SHAP computation) **MLflow Permissions:** * Read access to Model Registry * Read access to Experiment Tracking * Write access for metric export (optional) ## Monitoring MLOps Pipeline Health ### Track Integration Health ```python theme={null} # Check integration status status = client.get_integration_status("databricks") print(f"Status: {status.connected}") print(f"Last sync: {status.last_sync_time}") print(f"Models synced: {status.models_count}") ``` ### Alerts for Sync Failures ```python theme={null} # Alert on integration failures client.create_alert( name="MLflow Sync Failure", trigger_type="integration_error", integration="mlflow", notification_channels=["email", "slack"] ) ``` ## Troubleshooting ### Common Issues **Models Not Syncing:** * Verify MLflow/Databricks credentials are valid * Check network connectivity from Fiddler to ML platform * Ensure models are in the correct stage (e.g., "Production") * Validate webhook endpoint is reachable (for event-driven sync) **Schema Mismatches:** * Ensure feature names match between training and production * Verify data types are consistent * Check for missing features in production data **Performance Issues:** * For large models, use SHAP sampling instead of full computation * Enable lazy loading for model artifacts * Use incremental sync for model registry (don't sync all historical versions) ## Related Integrations * [**Data Platforms**](/integrations/data-platforms-and-pipelines/data-platforms) - Connect to Snowflake, BigQuery for training data * [**Cloud Platforms**](/integrations/cloud-platforms-and-deployment/cloud-platforms) - Deploy Fiddler on AWS, Azure, GCP * [**Agentic AI**](/integrations/agentic-ai-and-llm-frameworks/agentic-ai) - Monitor LangGraph and LLM applications * [**Monitoring & Alerting**](/integrations/monitoring-and-alerting/monitoring-alerting) - Alert on model issues *** # Databricks Source: https://docs.fiddler.ai/integrations/ml-platforms/databricks-integration Discover how Fiddler helps monitor, explain, and analyze models in Databricks Workspace. Integrate with MLFlow and Spark to manage, validate, and monitor models. Fiddler allows your team to monitor, explain and analyze your models developed and deployed in [Databricks Workspace](https://docs.databricks.com/introduction/index.html) by integrating with [MLflow](https://docs.databricks.com/mlflow/index.html) for model asset management and utilizing Databricks Spark environment for data management. To validate and monitor models built on Databricks using Fiddler, you can follow these steps: 1. [Create a Fiddler model](/developers/python-client-guides/model-onboarding/create-a-project-and-model) using sample data or model information from MLflow 2. [Publish production data](/developers/client-library-reference/publishing-production-data) streaming live or in batches #### Prerequisites This guide assumes you have: * A Databricks account and valid credentials * A Fiddler environment with an account and valid credentials * Know how to [connect and use ](/developers/python-client-guides/installation-and-setup)the [Fiddler Python Client SDK](/sdk-api/python-client/connection) #### Begin with a Databricks Notebook Launch a [Databricks notebook](https://docs.databricks.com/notebooks/index.html) from your workspace and run the following code: ```bash theme={null} pip install -q fiddler-client ``` ```python theme={null} import fiddler as fdl ``` Now that you have the Fiddler library installed, you can connect to your Fiddler environment. You will need your authentication token from the [Credentials](/reference/administration/settings#credentials) tab in Application Settings. ```python theme={null} URL = "" AUTH_TOKEN = "" fdl.init(url=URL, token=AUTH_TOKEN) ``` Finally, you can set up a new [project](/sdk-api/python-client/connection) using: ```python theme={null} # The project.id is required when creating models project = fdl.Project(name='YOUR_PROJECT_NAME') project.create() ``` #### Creating the Fiddler Model **Quickest Option: Let Fiddler Automate Model Creation** The quickest way to onboard a Fiddler model is to get a sample of data from which Fiddler can infer model schema and metadata. Ideally you will have baseline, testing, or training data that is representative of your model schema. Fiddler can infer your model schema from this sample dataset. You can download baseline or training data from a [delta table](https://docs.databricks.com/getting-started/dataframes-python.html) and share it with Fiddler as a baseline dataset: ```python theme={null} sample_dataset = spark.read.table("YOUR_DATASET").select("*").toPandas() ``` Now that you have sample data, you can easily create a Fiddler model, as demonstrated in our [Simple Monitoring Quick Start Guide](/developers/quick-starts/simple-ml-monitoring). A rough outline of the steps follows: ```py theme={null} # Define a ModelSpec that tells Fiddler what role each column # in your model schema serves. model_spec = fdl.ModelSpec( inputs=['feature_input_column', ...], outputs=['output_column'], targets=['label_column'], metadata=['id_column', 'data_segment_column', ...], ) # Identify the task your ML model performs as Fiddler will use this # to generate the performance metrics appropriate to the task. # ModelTask.NOT_SET is also an option if performance metrics are not needed. model_task = fdl.ModelTask.BINARY_CLASSIFICATION task_params = fdl.ModelTaskParams(target_class_order=['no', 'yes']) # Use Model.from_data() to define your model's ModelSchema automatically by # passing the sample_dataset in the source parameter for schema inference. model = fdl.Model.from_data( name='name_for_display_in_Fiddler', project_id=project.id, source=sample_dataset, spec=model_spec, task=model_task, task_params=task_params, event_id_col='your_unique_event_id_column', event_ts_col='event_timestamp_column' ) # Create the model in Fiddler model.create() ``` **Option: Using the MLflow Model Registry** Another option is to manually construct your model's schema from the details contained in the MLflow registry. Using the MLflow API, you can query the model registry and get the model signature, which describes the inputs and outputs as a dictionary. You can use this dictionary to build the Model, ModelSchema, and ModelSpec objects that define the tabular schema of your model. ```python theme={null} import mlflow from mlflow.tracking import MlflowClient # Initiate MLFlow Client client = MlflowClient() # Get the model URI model_version_info = client.get_model_version(model_name, model_version) model_uri = client.get_model_version_download_uri(model_name, model_version_info) #Get the Model Signature mlflow_model_info = mlflow.models.get_model_info(model_uri) model_inputs_schema = mlflow_model_info.signature.inputs.to_dict() model_inputs = [ sub['name'] for sub in model_inputs_schema ] ``` Refer to this [example notebook](https://github.com/fiddler-labs/fiddler-examples/blob/main/quickstart/examples/create_model_from_constructor.ipynb) in GitHub, which demonstrates manually defining your Fiddler model's schema. #### Publishing Events Now you can publish all the events from your models. You can do this in two ways: **Batch Models** If your models run batch processes with your models or your aggregate model outputs over a time frame, then you can use the table change feed from Databricks to select only the new events and send them to Fiddler: ```python theme={null} import fiddler as fdl from pyspark.sql import SparkSession # Get the active Spark session spark = SparkSession.builder.getOrCreate() changes_df = ( spark.read.format("delta") .option("readChangeFeed", "true") .option("startingVersion", last_version) .option("endingVersion", new_version) .table("inferences") .toPandas() ) # Assumes an initialized Python client session and instantiated Model job = model.publish_batch( source=changes_df, environment=fdl.EnvType.PRODUCTION, ) print(f'Initiated Production dataset upload with Job ID = {job.id}') ``` **Live Models** For models with live predictions or real-time applications, you can add the following code snippet to your prediction pipeline and send every event to Fiddler in real-time: ```python theme={null} # Turn your model's output in a pandas dataframe example_event = model_output.toJSON().map(lambda x: json.loads(x)).collect() # Assumes an initialized Python client session and instantiated Model event_id = model.publish_stream( events=example_event, environment=fdl.EnvType.PRODUCTION, ) print(f'Published {event_id_list}') ``` # MLflow Source: https://docs.fiddler.ai/integrations/ml-platforms/ml-flow-integration Explore how Fiddler helps your team onboard, monitor, explain, and analyze models with MLFlow. Learn to ingest model metadata and artifacts for observability. Fiddler allows your team to onboard, monitor, explain, and analyze your models developed with [MLflow](https://mlflow.org/). This guide shows you how to ingest the model metadata and artifacts stored in your MLflow model registry and use them to set up model observability in the Fiddler Platform: 1. Exporting Model Metadata from MLflow to Fiddler 2. Uploading Model Artifacts to Fiddler for XAI ### Onboarding a Model Refer to this [section](/integrations/ml-platforms/databricks-integration#creating-the-fiddler-model) of the Databricks integration guide for onboarding your model to Fiddler using model information from MLflow. ### Uploading Model Artifacts Using the [**MLflow API**](https://mlflow.org/docs/latest/python_api/mlflow.html) you can query the model registry and get the **model signature** which describes the inputs and outputs as a dictionary. #### Uploading Model Files Sharing your model artifacts helps Fiddler explain your models. By leveraging the MLflow API you can download these model files: ```python theme={null} import os import mlflow from mlflow.store.artifact.models_artifact_repo import ModelsArtifactRepository model_name = "example-model-name" model_stage = "Staging" # Should be either 'Staging' or 'Production' mlflow.set_tracking_uri("databricks") os.makedirs("model", exist_ok=True) local_path = ModelsArtifactRepository( f'models:/{model_name}/{model_stage}' ).download_artifacts("", dst_path="model") print(f'{model_stage} Model {model_name} is downloaded at {local_path}') ``` Once you have the model file, you can create a package.py file in this model directory that describes how to access this model. Finally, you can upload all the model artifacts to Fiddler: ```python theme={null} # Assumes an initialized Python client session and instantiated Model job = model.add_artifact( model_dir=MODEL_ARTIFACTS_DIR, ) job.wait() ``` Alternatively, you can skip uploading your model and use Fiddler to generate a surrogate model to get low-fidelity explanations for your model. Please refer to the Explainability guide for detailed information on model artifacts, packages, and surrogate models. # Datadog Source: https://docs.fiddler.ai/integrations/monitoring-alerting/datadog-integration Learn about Fiddler’s Datadog integration to bring AI Observability metrics into your dashboards. Follow steps to centralize ML model and application monitoring. Fiddler offers an integration with Datadog which allows Fiddler and Datadog customers to bring their AI Observability metrics from Fiddler into their centralized Datadog dashboards. Additionally, a Fiddler license can now be procured through the [Datadog Marketplace](https://www.datadoghq.com/blog/tag/datadog-marketplace/). This [integration](https://www.datadoghq.com/blog/monitor-machine-learning-models-fiddler/) enables you to centralize your monitoring of ML models and the applications that utilize them within one unified platform. ### Integrating Fiddler with Datadog Instructions for integrating Fiddler with Datadog can be found on the "Integrations" section of your Datadog console. Simply search for "Fiddler" and follow the installation instructions provided on the "Configure" tab. Please reach out to \<[support@fiddler.ai](mailto:support@fiddler.ai)> with any issues or questions. Fiddler displayed as installed in the Datadog marketplace Integrations tab The Fiddler Datadog integration app Overview tab The Fiddler Datadog integration app Configuration tab # PagerDuty Source: https://docs.fiddler.ai/integrations/monitoring-alerting/pagerduty Discover how customer churn prediction works with Fiddler’s AI observability platform. Follow our example to detect and diagnose issues step by step. Fiddler offers powerful alerting tools for monitoring models. By integrating with PagerDuty services, you gain the ability to trigger PagerDuty events within your monitoring workflow. > 📘 If your organization has already integrated with PagerDuty, then you may skip to the [Setup: In Fiddler](#setup-in-fiddler) section to learn more about setting up PagerDuty within Fiddler. ### Setup: In PagerDuty 1. Within your PagerDuty Team, navigate to **Services** → **Service Directory**. 2. Within the Service Directory: * If you are creating a new service for integration, select **+New Service** and follow the prompts to create your service. * Click the **name of the service** you want to integrate with. 3. Navigate to **Integrations** within your service, and select **Add a new integration to this service**. 4. Enter an **Integration Name**, and under **Integration Type** select the option **Use our API directly**. Then, select the **Add Integration** button to save your new integration. You will be redirected to the Integrations page for your service. 5. Copy the **Integration Key** for your new integration. ### Setup: In Fiddler 1. Within **Fiddler**, navigate to the **Settings** page, and then to the **PagerDuty Integration** menu. If your organization **already has a PagerDuty service integrated with Fiddler**, you will be able to find it in the list of services. 2. If you are looking to integrate with a new service, select the **`+`** box on the top right. Then, enter the name of your service, as well as the Integration Key copied from the end of the [Setup: In PagerDuty](#setup-in-pagerduty) section above. After creation, confirm that your new entry is now in the list of available services. > 🚧 Creating, editing, and deleting these services is an **ADMINISTRATOR**-only privilege. Please contact an **ADMINISTRATOR** within your organization to set up any new PagerDuty services ### PagerDuty Alerts in Fiddler 1. Within the **Projects** page, select the model you wish to use with PagerDuty. 2. Select **Monitor** → **Alerts** → **Add Alert**. 3. Enter the condition you would like to alert on, and under **PagerDuty Services**, select all services you would like the alert to trigger for. Additionally, select the **Severity** of this alert, and hit **Save**. 4. After creation, the alert will now trigger for the specified PagerDuty services. > 📘 Info > > Check out the [alerts documentation](/developers/python-client-guides/alerts-with-fiddler-client) for more information on setting up alerts. ### FAQ **Can Fiddler integrate with multiple PagerDuty services?** * Yes. So long as the service is present within **Settings** → **PagerDuty Services**, anyone within your organization can select that service to be a recipient for an alert. # Monitoring & Alerting Overview Source: https://docs.fiddler.ai/integrations/monitoring-and-alerting/monitoring-alerting Connect Fiddler alerts to incident management, observability, and communication tools Route Fiddler AI observability alerts to your existing incident management and communication tools. Integrate with observability platforms, on-call systems, and team collaboration tools to ensure AI issues are detected, triaged, and resolved quickly. ## Why Alert Integration Matters AI models fail in unique ways—drift, data quality issues, performance degradation, safety violations. Fiddler's alert integrations ensure your team responds immediately: * **Unified Incident Management** - AI alerts flow into the same systems as infrastructure alerts * **Faster Response Times** - On-call engineers notified via existing escalation policies * **Context-Rich Alerts** - Model context, affected predictions, and root cause analysis included * **Reduced Alert Fatigue** - Intelligent grouping and deduplication across tools * **Automated Remediation** - Trigger workflows to rollback models or scale resources ## Integration Categories ### 📊 Observability Platforms Send Fiddler metrics and alerts to enterprise observability platforms for unified monitoring. **Supported Platforms:** * [**Datadog**](/integrations/monitoring-alerting/datadog-integration) - Application performance monitoring and infrastructure observability ✓ **GA** **Common Use Cases:** * Correlate AI model issues with infrastructure metrics * Build unified dashboards combining Fiddler + infrastructure data * Use Datadog's anomaly detection on Fiddler metrics * Alert on compound conditions (model drift + high latency) ### 🚨 Incident Management Connect alerts to on-call systems for immediate engineer notification. **Supported Platforms:** * [**PagerDuty**](/integrations/monitoring-alerting/pagerduty) - Incident management and on-call scheduling ✓ **GA** **Common Use Cases:** * Page on-call ML engineers for critical model failures * Escalate unresolved AI incidents automatically * Track MTTR (Mean Time To Resolution) for model issues * Integrate with incident runbooks and response workflows ### 💬 Team Collaboration Send alerts to team communication tools for visibility and collaboration. **Supported Platforms:** * **Slack** - Team messaging and collaboration ✓ **GA** *(Coming Soon)* * **Microsoft Teams** - Enterprise communication platform ✓ **GA** *(Coming Soon)* **Common Use Cases:** * Notify ML team channel when drift is detected * Alert data science team on data quality issues * Share model performance reports automatically * Collaborative incident triage in team channels ## Observability Platform Integrations ### Datadog Integrate Fiddler with Datadog for unified application and AI monitoring. **Why Datadog + Fiddler:** * **Unified Dashboards** - Combine infrastructure, application, and AI model metrics * **Correlated Alerts** - Alert on compound conditions (e.g., "high model drift + high API latency") * **Service Map Integration** - See model health in Datadog service dependency graphs * **Anomaly Detection** - Leverage Datadog's ML-based alerting on Fiddler metrics **Key Features:** * **Metric Export** - Send Fiddler drift, performance, and data quality metrics to Datadog * **Event Streaming** - Stream model events (predictions, drift detections) as Datadog events * **Alert Forwarding** - Route Fiddler alerts to Datadog for unified incident management * **Tag Propagation** - Maintain consistent tagging across platforms (model, environment, team) **Status:** ✓ **GA** - Production-ready [**Get Started with Datadog →**](/integrations/monitoring-alerting/datadog-integration) **Quick Start:** ```python theme={null} from fiddler import FiddlerClient client = FiddlerClient(api_key="fid_...") # Configure Datadog integration client.add_datadog_integration( api_key="datadog_api_key", app_key="datadog_app_key", site="datadoghq.com", # or datadoghq.eu # Metric export configuration export_metrics=True, metric_prefix="fiddler.model.", tags=["env:production", "team:ml-platform"], # Event export configuration export_events=True, event_priority="normal" # or "low" ) ``` **Example Datadog Dashboard:** ```yaml theme={null} # Datadog dashboard combining infrastructure + AI metrics widgets: - title: "Model Latency vs API Latency" type: timeseries queries: - metric: fiddler.model.latency.p95 scope: model:fraud_detector - metric: trace.flask.request.duration.p95 scope: service:fraud-api - title: "Model Drift Detection" type: query_value queries: - metric: fiddler.model.drift.score aggregation: max conditional_formats: - comparator: ">" value: 0.1 palette: "red" ``` ## Incident Management Integrations ### PagerDuty Route critical AI alerts to on-call engineers via PagerDuty. **Why PagerDuty + Fiddler:** * **On-Call Escalation** - Page the right ML engineer based on escalation policies * **Incident Deduplication** - Prevent alert storms from related model issues * **Incident Timeline** - Track when AI issues were detected, acknowledged, resolved * **Postmortem Integration** - Include model context in incident reports **Key Features:** * **Severity Mapping** - Map Fiddler alert criticality to PagerDuty severity levels * **Service Integration** - Associate alerts with PagerDuty services (e.g., "Fraud Detection Service") * **Custom Payloads** - Include model metadata, drift scores, affected predictions * **Bidirectional Updates** - Acknowledge/resolve incidents in PagerDuty or Fiddler **Status:** ✓ **GA** - Production-ready [**Get Started with PagerDuty →**](/integrations/monitoring-alerting/pagerduty) **Quick Start:** ```python theme={null} from fiddler import FiddlerClient client = FiddlerClient(api_key="fid_...") # Configure PagerDuty integration client.add_pagerduty_integration( integration_key="pagerduty_integration_key", service_name="ML Models - Production", # Alert routing rules severity_mapping={ "critical": "critical", # Fiddler → PagerDuty severity "high": "error", "medium": "warning", "low": "info" } ) # Create alert with PagerDuty notification client.create_alert( name="Critical Model Drift", project="fraud-detection", model="fraud_detector_v3", metric="drift_score", threshold=0.15, severity="critical", notification_channels=["pagerduty"] ) ``` **Example PagerDuty Incident:** ```json theme={null} { "incident_key": "fiddler_drift_fraud_detector_v3", "type": "trigger", "description": "High drift detected on fraud_detector_v3", "details": { "model": "fraud_detector_v3", "project": "fraud-detection", "drift_score": 0.23, "affected_features": ["transaction_amount", "merchant_category"], "time_window": "2024-11-10 14:00 - 14:30 UTC", "fiddler_url": "https://app.fiddler.ai/projects/fraud-detection/models/fraud_detector_v3/drift" }, "client": "Fiddler AI Observability", "client_url": "https://app.fiddler.ai" } ``` ## Team Collaboration Integrations ### Slack *(Coming Soon)* **Planned Features:** * **Channel Notifications** - Post alerts to team Slack channels * **Interactive Messages** - Acknowledge, snooze, or resolve alerts from Slack * **Scheduled Reports** - Daily/weekly model performance summaries * **Threaded Discussions** - Collaborate on incident resolution in threads **Example Configuration:** ```python theme={null} # Future Slack integration API client.add_slack_integration( webhook_url="https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXX", channel="#ml-alerts", username="Fiddler", icon_emoji=":robot_face:" ) ``` ### Microsoft Teams *(Coming Soon)* **Planned Features:** * **Adaptive Cards** - Rich, interactive alert notifications * **Team Channels** - Route alerts to relevant team channels * **Bot Commands** - Query model status from Teams chat * **Integration with Workflows** - Trigger Teams workflows on alerts ## Alert Routing Patterns ### Pattern 1: Severity-Based Routing Route alerts to different channels based on severity: ```python theme={null} # Critical alerts → PagerDuty (page on-call) client.create_alert( name="Model Offline", severity="critical", notification_channels=["pagerduty"] ) # High alerts → Slack (notify team) client.create_alert( name="High Drift Detected", severity="high", notification_channels=["slack"] ) # Medium alerts → Datadog (track as events) client.create_alert( name="Minor Data Quality Issue", severity="medium", notification_channels=["datadog"] ) ``` ### Pattern 2: Team-Based Routing Different teams get different alerts: ```python theme={null} # ML Engineering team client.create_alert( name="Model Performance Degradation", project="fraud-detection", notification_channels=["slack"], slack_channel="#ml-engineering", tags=["team:ml-engineering"] ) # Data Engineering team client.create_alert( name="Data Pipeline Failure", project="fraud-detection", notification_channels=["slack"], slack_channel="#data-engineering", tags=["team:data-engineering"] ) # On-Call team (escalation) client.create_alert( name="Critical Model Failure", project="fraud-detection", notification_channels=["pagerduty"], pagerduty_service="ml-models-production", tags=["team:on-call"] ) ``` ### Pattern 3: Composite Alerting Alert on compound conditions across multiple platforms: ```python theme={null} # Example: Alert if BOTH model drift is high AND API latency is high # (Indicates model update needed + production impact) # Configure in Datadog (using Fiddler + Datadog metrics) datadog_composite_alert = { "name": "Model Drift + High Latency", "query": """ avg(last_5m):fiddler.model.drift.score{model:fraud_detector} > 0.1 AND avg(last_5m):trace.flask.request.duration.p95{service:fraud-api} > 500 """, "message": "@pagerduty-ml-oncall Model drift detected with production latency impact", "tags": ["model:fraud_detector", "alert:composite"] } ``` ## Metric Export Patterns ### Export Fiddler Metrics to Datadog ```python theme={null} from fiddler import FiddlerClient client = FiddlerClient(api_key="fid_...") # Configure metric export client.configure_metric_export( destination="datadog", metrics=[ "drift_score", "data_quality_score", "prediction_latency_p95", "prediction_count", "error_rate" ], export_interval=60, # seconds tags=["source:fiddler", "env:production"] ) ``` **Exported Metrics:** * `fiddler.model.drift.score` - Overall drift score (0-1) * `fiddler.model.drift.feature.<feature_name>` - Per-feature drift * `fiddler.model.performance.<metric>` - Model performance metrics * `fiddler.model.data_quality.score` - Data quality score * `fiddler.model.predictions.count` - Prediction volume * `fiddler.model.predictions.latency` - Prediction latency percentiles ### Query Fiddler Metrics in Datadog ```python theme={null} # Datadog Metrics Query Language (MQL) queries = { "high_drift_models": """ avg:fiddler.model.drift.score{*} by {model} > 0.1 """, "low_performance_models": """ avg:fiddler.model.performance.accuracy{*} by {model} < 0.85 """, "high_volume_models": """ sum:fiddler.model.predictions.count{*} by {model}.as_count() """ } ``` ## Alert Lifecycle Management ### Alert States Fiddler alerts transition through these states: ``` Triggered → Acknowledged → Investigating → Resolved → Closed ↓ ↑ Escalated --------------------------------┘ ``` **Synchronization with External Tools:** * **PagerDuty**: Bidirectional state sync (acknowledge, resolve) * **Datadog**: Event-based updates * **Slack**: Interactive message updates ### Alert Deduplication Prevent alert storms with intelligent deduplication: ```python theme={null} # Configure deduplication rules client.configure_alert_deduplication( project="fraud-detection", model="fraud_detector_v3", # Group related alerts grouping_window=300, # seconds grouping_keys=["model", "metric"], # Suppress similar alerts suppression_window=3600, # seconds max_alerts_per_window=3 ) ``` ## Custom Webhook Integrations For platforms not natively supported, use generic webhooks: ```python theme={null} # Send alerts to any webhook endpoint client.add_webhook_integration( name="custom-alerting-system", url="https://your-system.com/webhook/fiddler", method="POST", headers={ "Authorization": "Bearer your-token", "Content-Type": "application/json" }, payload_template={ "alert_name": "{{alert.name}}", "model": "{{model.name}}", "severity": "{{alert.severity}}", "timestamp": "{{alert.timestamp}}", "details": "{{alert.details}}" } ) # Use webhook in alerts client.create_alert( name="Custom Alert", notification_channels=["webhook:custom-alerting-system"] ) ``` **Webhook Payload Example:** ```json theme={null} { "alert_name": "High Drift Detected", "model": "fraud_detector_v3", "project": "fraud-detection", "severity": "high", "timestamp": "2024-11-10T14:32:01Z", "metric": "drift_score", "current_value": 0.23, "threshold": 0.15, "fiddler_url": "https://app.fiddler.ai/projects/fraud-detection/models/fraud_detector_v3", "affected_features": ["transaction_amount", "merchant_category"], "recommended_actions": [ "Investigate feature distribution changes", "Consider model retraining", "Review data pipeline for issues" ] } ``` ## Monitoring Integration Health ### Track Integration Status ```python theme={null} # Check integration health integrations = client.list_integrations() for integration in integrations: status = client.get_integration_health(integration.name) print(f"{integration.name}: {status.status}") print(f" Last successful send: {status.last_success}") print(f" Failed alerts (24h): {status.failed_count}") ``` ### Alerts on Integration Failures ```python theme={null} # Alert if alert delivery fails client.create_meta_alert( name="Alert Delivery Failure", trigger="integration_failure", integration="pagerduty", threshold=3, # failures time_window=3600, # seconds notification_channels=["email"] # use different channel! ) ``` ## Best Practices ### Alert Fatigue Prevention **1. Use Appropriate Severity Levels:** ```python theme={null} # Reserve "critical" for page-worthy issues severity_guidelines = { "critical": "Model offline, safety violations, production outages", "high": "Significant drift, performance degradation", "medium": "Minor data quality issues, gradual drift", "low": "Informational, trend observations" } ``` **2. Implement Alert Throttling:** ```python theme={null} client.create_alert( name="Drift Detection", threshold=0.1, evaluation_window=300, # 5 minutes cooldown_period=3600, # Don't re-alert for 1 hour max_alerts_per_day=5 # Cap daily alerts ) ``` **3. Use Alert Grouping:** ```python theme={null} # Group related alerts into single notification client.configure_alert_grouping( group_name="Feature Drift Alerts", alerts=["drift_feature_1", "drift_feature_2", "drift_feature_3"], send_as_digest=True, digest_interval=1800 # 30 minutes ) ``` ### Incident Response Runbooks Include runbook links in alert payloads: ```python theme={null} client.create_alert( name="High Model Drift", metadata={ "runbook_url": "https://wiki.company.com/ml/runbooks/drift-response", "on_call_team": "ml-platform", "escalation_policy": "ml-models-production", "sla": "30 minutes to acknowledge, 2 hours to investigate" } ) ``` ## Security & Compliance ### Secure Credential Management **Never hardcode credentials:** ```python theme={null} import os # Use environment variables client.add_pagerduty_integration( integration_key=os.environ['PAGERDUTY_INTEGRATION_KEY'] ) # Or use secret management systems from secret_manager import get_secret client.add_datadog_integration( api_key=get_secret('datadog-api-key'), app_key=get_secret('datadog-app-key') ) ``` ### Alert Data Privacy **PII Redaction in Alerts:** ```python theme={null} client.configure_alert_privacy( redact_pii=True, pii_fields=["email", "ssn", "phone_number"], redaction_string="[REDACTED]" ) ``` ### Audit Logging **Track alert delivery:** ```python theme={null} # Query alert delivery audit log audit_log = client.get_alert_audit_log( start_time="2024-11-01", end_time="2024-11-10", include_payload=True ) for entry in audit_log: print(f"Alert: {entry.alert_name}") print(f"Delivered to: {entry.channel}") print(f"Status: {entry.status}") print(f"Timestamp: {entry.timestamp}") ``` ## Troubleshooting ### Common Issues **Alerts Not Delivered:** * Verify integration credentials are valid and not expired * Check network connectivity from Fiddler to external platform * Ensure webhook endpoints are reachable (not blocked by firewall) * Validate alert thresholds are actually being triggered **Duplicate Alerts:** * Enable alert deduplication with appropriate time windows * Check if multiple notification channels are configured * Verify integration isn't configured twice **Missing Alert Context:** * Ensure `include_context=True` in alert configuration * Check payload template includes necessary fields * Verify external platform supports rich payloads (some SMS gateways don't) ## Integration Selector Choose the right integration for your use case: | Your Need | Recommended Integration | Why | | -------------------------- | ------------------------- | ------------------------------------------ | | On-call engineer paging | **PagerDuty** | Escalation policies, incident management | | Infrastructure correlation | **Datadog** | Unified metrics, correlated dashboards | | Team notifications | **Slack** *(Coming Soon)* | Channel-based, collaborative triage | | Custom internal tools | **Generic Webhooks** | Flexible, integrate with any HTTP endpoint | | Multi-tool strategy | **Datadog + PagerDuty** | Metrics + incidents in one workflow | ## Related Integrations * [**Cloud Platforms**](/integrations/cloud-platforms-and-deployment/cloud-platforms) - Deploy Fiddler on AWS, Azure, GCP * [**Data Platforms**](/integrations/data-platforms-and-pipelines/data-platforms) - Ingest data from Snowflake, Kafka * [**ML Platforms**](/integrations/ml-platforms-and-tools/ml-platforms) - Integrate with Databricks, MLflow * [**Agentic AI**](/integrations/agentic-ai-and-llm-frameworks/agentic-ai) - Monitor LangGraph and Strands Agents *** # Custom Metrics for Agentic Applications Source: https://docs.fiddler.ai/observability/agentic/custom-metrics Define custom metrics for your agentic and GenAI applications using FQL and span attributes to track business KPIs, quality scores, and operational signals beyond built-in metrics. ### Overview Custom metrics let you define measurements that align precisely with your agentic application's requirements. Whether tracking business KPIs, aggregating quality scores from enrichments, or computing cost and latency signals, custom metrics let you tailor observability to your specific needs. Once defined, they are available in charts and dashboards. Custom metrics for agentic applications are defined using [Fiddler Query Language (FQL)](/observability/platform/fiddler-query-language) and reference **span attributes** captured from your application's OpenTelemetry traces. This differs from ML custom metrics, which reference model schema columns. Custom metrics can be **organization-level** (visible across all projects) or **project-scoped** (visible only within a specific project). See [Metric Visibility](#metric-visibility-organization-vs-project) below. ### Metric Visibility: Organization vs Project When creating a custom metric, you choose whether it is **organization-level** (global) or **project-scoped**. This determines who can see it and who can delete it, and cannot be changed after creation. #### Organization-level metrics Created without selecting a project. Visible across all projects in the organization. The metric name is reserved org-wide — no other metric in the organization can share the same name. | Action | Roles | | ------ | --------------------- | | Create | Org Admin, Org Member | | View | Org Admin, Org Member | | Delete | Org Admin | #### Project-scoped metrics Created with a specific project selected. Visible only to users who have access to that project. The same metric name can be reused in a different project as long as the projects don't overlap. | Action | Roles | | ------ | --------------------------------------------------------------- | | Create | Project Admin, Project Writer (on that project) | | View | Project Admin, Project Writer, Project Viewer (on that project) | | Delete | Project Admin (on that project) | Metric visibility is **immutable** — an organization-level metric cannot be changed to project-scoped or vice versa after creation. ### The `attribute()` Function The `attribute()` function is the GenAI-specific FQL primitive for referencing span data. It replaces the column references used in ML custom metrics. #### Syntax ``` attribute('name', type='user', scope='span') attribute('name', type='user', scope='span', value='category_value') attribute('name', type='system', scope='span') ``` | Parameter | Required | Description | | --------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `name` | Yes | The attribute name as it appears in your trace data (e.g., `gen_ai.usage.input_tokens`) | | `scope` | Yes | The attribute scope. Currently only `'span'` is supported. | | `type` | Yes | The attribute source: `'user'` for attributes your application sets, or `'system'` for attributes emitted by OpenTelemetry instrumentation (e.g., `gen_ai.usage.input_tokens`). | | `value` | No | Filters to spans where the attribute equals this string; returns the value if matched, `null` otherwise. Used for categorical attributes (e.g., `attribute('status', value='error')`). When set, the attribute is always treated as a string. | #### Type inference Fiddler infers the attribute type from context — you do not need to declare it explicitly: * When used inside a numeric aggregate like `sum()` or `average()`, the attribute is treated as a number. * When used with string functions like `length()` or `match()`, the attribute is treated as a string. * When the `value` keyword is provided, the attribute is always treated as a string. ### Adding a Custom Metric 1. Navigate to the **Custom Metrics** section in the Fiddler UI. 2. Click **Add Custom Metric**. 3. Enter a **Metric name**, an optional **Description**, and the **Metric definition**. 4. Optionally select a **project** to scope the metric to. If no project is selected, the metric is created as an **organization-level** metric visible across all projects. 5. Click **Create Metric**. Custom metric creation form in the Fiddler UI ### Using Custom Metrics in Charts After saving a custom metric, you can use it in chart definitions: 1. Open or create a chart in the Fiddler UI. 2. Set **Metric Type** to **Custom Metric**. 3. Select your custom metric from the list. ### Deleting Custom Metrics To delete a custom metric, click the trash icon next to the metric in the **Custom Metrics** tab. Deletion runs as a background job that automatically: * Removes the metric from any charts that reference it * Deletes charts that have no remaining metrics after cleanup * Updates dashboard layouts to remove deleted charts * Deletes dashboards that become empty as a result ### Examples Custom metrics must return either an aggregate (produced by aggregate functions) or a combination of aggregates. See the [FQL reference](/observability/platform/fiddler-query-language) for the full list of supported operators and functions. #### Average input token usage Track the mean number of input tokens consumed per span to monitor LLM cost drivers over time. ``` average(attribute('gen_ai.usage.input_tokens', type='system', scope='span')) ``` → Returns a `Number` (e.g., `312.4`) #### Premium user ratio Measure the fraction of spans attributed to premium-tier users by filtering on a categorical attribute. ``` count(attribute('tier', type='user', scope='span', value='premium')) / count(attribute('tier', type='user', scope='span')) ``` → Returns a `Number` between 0 and 1 (e.g., `0.34`) #### P95 response latency Use the `quantile()` function to track the 95th-percentile response time. This is more robust than averages for catching tail latency issues. ``` quantile(attribute('response_time_ms', type='user', scope='span'), level=0.95) ``` → Returns a `Number` in the same unit as the attribute (e.g., `1420.0` ms) #### Conditional cost (weighted by outcome) Apply different weights to successful and failed spans to surface the true cost impact of errors. The `if(condition, true_value, false_value)` function evaluates the condition per span and returns one of two values. ``` average(if(attribute('status', type='user', scope='span') == 'error', attribute('cost', type='user', scope='span') * 2, attribute('cost', type='user', scope='span'))) ``` → Returns a `Number` (e.g., `0.0042`) #### Latency range Track the spread of response times across spans in a time window. A widening range can signal instability or the emergence of slow outlier requests. ``` max(attribute('response_time_ms', type='user', scope='span')) - min(attribute('response_time_ms', type='user', scope='span')) ``` → Returns a `Number` in the same unit as the attribute (e.g., `3850.0` ms) #### Minimum token usage Find the smallest input token count across all spans in a window. Useful for detecting unusually short requests that may indicate truncated inputs or misconfigured clients. ``` min(attribute('gen_ai.usage.input_tokens', type='system', scope='span')) ``` → Returns a `Number` (e.g., `12`) #### Null-safe cost with markup Apply a price adjustment to spans that have a cost attribute, while preserving `null` for spans where cost data is absent — avoiding accidental zero-inflation of the average. ``` average(if(is_null(attribute('cost', type='user', scope='span')), null, attribute('cost', type='user', scope='span') * 1.15)) ``` → Returns a `Number` representing the average marked-up cost, excluding null-cost spans (e.g., `0.0048`) Use `is_null()` to test whether an attribute is absent. The `null` keyword is for use as a **return value** in expressions (e.g., `if(condition, value, null)`) to propagate missing data explicitly. ### Related Resources * [Fiddler Query Language (FQL)](/observability/platform/fiddler-query-language) — full reference for operators, aggregate functions, and expression syntax * [Custom Metrics for ML Models](/observability/platform/custom-metrics) — custom metrics using model schema columns instead of span attributes * [Agentic Observability](/observability/agentic/index) — overview of dashboards, metrics, and integrations for agentic applications * [Custom Metrics glossary entry](/glossary/custom-metrics) # Agentic Observability Source: https://docs.fiddler.ai/observability/agentic/index Monitor AI agents and multi-step workflows with specialized dashboards, metrics, and trace visualization Agentic observability provides specialized observability for AI agents and multi-step workflows through dedicated dashboards, metrics, and trace visualization. Unlike traditional monitoring, which tracks single-shot inferences, agentic observability captures the complete lifecycle of autonomous-agent behavior—from initial reasoning through tool execution and final response. ## Dashboards & Visualization Agentic observability uses a dedicated UI with Projects → Applications (instead of the legacy Projects → Models structure) designed specifically for observing agent workflows. ### Agentic Dashboards Access pre-built dashboards optimized for agentic workflows: * **Agent Performance Overview** - Monitor success rates, latency, and throughput across all agents * **Workflow Execution Traces** - Visualize complete multi-step reasoning chains from start to finish * **Tool Usage Analytics** - Track which external tools and APIs your agents are calling * **Error & Exception Tracking** - Identify where agent workflows fail and why ### Trace Visualization Every agent interaction is captured as a hierarchical trace showing: * **Agent Steps** - Each decision point in the agent's reasoning process * **LLM Calls** - All language model interactions with inputs, outputs, and metadata * **Tool Invocations** - External function calls, API requests, and data retrievals * **Timing Information** - Duration of each step to identify performance bottlenecks * **Parent-Child Relationships** - How multi-agent systems coordinate and delegate tasks **Viewing Traces:** 1. Navigate to your Application in the Fiddler UI 2. Select a conversation or workflow from the list 3. Click on any trace to expand the full execution tree 4. Drill down into individual spans to see inputs, outputs, and metadata ### Custom Dashboards Create custom dashboards to monitor specific agent behaviors: * Combine multiple charts to track KPIs relevant to your use case * Filter by agent type, user segments, or time periods * Share dashboards with team members * Set up alerts based on dashboard metrics ## Metrics & Analytics Agentic observability provides specialized metrics that go beyond traditional model monitoring: ### Agent-Specific Metrics * **Agent Success Rate** - Percentage of workflows that complete successfully * **Tool Call Distribution** - Which tools agents use most frequently * **Reasoning Chain Length** - Average number of steps per workflow * **Agent Handoffs** - How often agents delegate to other agents * **Retry & Recovery Rate** - How often agents recover from errors ### Performance Metrics * **End-to-End Latency** - Total time from user request to final response * **Per-Step Latency** - Duration of individual reasoning steps, LLM calls, and tool invocations * **Token Usage** - Track LLM consumption across all agent interactions * **API Call Volume** - Monitor external tool and API usage ### Quality Metrics * **Response Accuracy** - Validate agent outputs against expected results (requires ground truth) * **Hallucination Detection** - Identify when agents generate unsupported claims * **Safety & Guardrails** - Track safety violations and guardrail activations * **User Satisfaction** - Capture feedback signals from end users ### Analyzing Metrics All metrics are available in: * **Real-time Dashboards** - Monitor live agent performance * **Historical Trends** - Analyze patterns over days, weeks, or months * **Comparative Analysis** - Compare different agent versions or configurations * **Custom Queries** - Use Fiddler Query Language (FQL) for advanced analysis ## Integration Options Agentic observability ingests OpenTelemetry spans and traces from your agent applications. Choose the integration method that fits your framework: ### LangGraph Applications **Best for:** Applications built with LangGraph or LangChain The Fiddler LangGraph SDK provides automatic instrumentation with zero code changes required. ```bash theme={null} pip install fiddler-langgraph ``` → [**LangGraph SDK Quick Start**](/developers/quick-starts/langgraph-sdk-quick-start) - Get started in 10 minutes → [**LangGraph SDK Documentation**](/sdk-api/langgraph/fiddler-client) - Complete integration guide ### Strands Agent Framework **Best for:** Applications built with Strands Agents The Fiddler Strands SDK integrates directly with the Strands framework for seamless monitoring. ```bash theme={null} pip install fiddler-strands ``` → [**Strands Agent SDK Quick Start**](/developers/quick-starts/strands-agent-quick-start) - Get started in 15 minutes → [**Strands SDK Documentation**](/sdk-api/strands/strands-agent-instrumentor) - Complete integration guide ### Custom Instrumentation (OpenTelemetry) **Best for:** Custom agent frameworks or non-Python applications Use OpenTelemetry directly for maximum flexibility and control. ```bash theme={null} pip install opentelemetry-api opentelemetry-sdk ``` → [**OpenTelemetry Quick Start**](/developers/quick-starts/opentelemetry-quick-start) - Get started in 20 minutes → [**OpenTelemetry Documentation**](/integrations/agentic-ai/opentelemetry-integration) - Complete integration guide ### Integration Comparison | Feature | LangGraph SDK | Strands SDK | OpenTelemetry | | ----------------------------- | -------------------- | -------------------- | -------------------------- | | **Automatic Instrumentation** | ✅ Zero code changes | ✅ Native integration | ❌ Manual setup | | **Framework Support** | LangGraph, LangChain | Strands Agents | Any framework | | **Language Support** | Python | Python | Python, Java, Go, JS, etc. | | **Setup Time** | \~10 minutes | \~10 minutes | \~15 minutes | | **Customization** | Medium | Medium | High | ## Next Steps * **Getting Started:** Learn the concepts behind agentic observability in our [Agentic Observability Getting Started Guide](/getting-started/agentic-monitoring) * **Choose Integration:** Pick your framework and follow the quick start guide above * **Explore Features:** Set up dashboards, configure alerts, and analyze agent performance * **Advanced Topics:** Learn about [custom metrics](/observability/platform/custom-metrics), [alerts](/observability/platform/alerts-platform), and [segmentation](/observability/platform/segments) # Explorer Source: https://docs.fiddler.ai/observability/agentic/trace-explorer Explore, filter, and search every span ingested into your GenAI application with the Explorer DataGrid. Explorer is in **Public Preview**. See [Feature Maturity Definitions](/reference/feature-maturity-definitions#public-preview) for what this means. ## Overview The Explorer is a spans-first exploration surface for GenAI applications. It gives you a paginated, filterable, searchable view of every span ingested into a single application — useful for debugging individual requests, investigating evaluator failures, drilling into latency outliers, and validating instrumentation. Open the **Explorer** tab on any GenAI Application Details page. ## Concepts | Term | Meaning | | -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Span** | A single unit of work in your application — an LLM call, a tool invocation, an agent step, or a chain step. The Explorer grid is one row per span. | | **Trace** | A collection of spans that share a `trace_id` and represent one end-to-end request through your application. | | **Session** | A higher-level grouping (typically a multi-turn conversation) identified by a `session_id`. A session may contain multiple traces. | | **Time range** | Mandatory. The Explorer always filters by a time window. The UI defaults to the last 7 calendar days (ending at end-of-day UTC). The time range is enforced server-side to keep queries fast against the underlying ClickHouse partitioning. | *** ## Using the UI ### Where it lives Open any GenAI Application Details page, then select the **Explorer** tab. ### The DataGrid Each row in the grid is a span. The grid is server-side paginated and sorted, with rich column controls. #### Columns visible by default | Column | Notes | | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------ | | Type | Span type — typically one of `llm`, `tool`, `agent`, `chain` | | Name | Span operation name | | Input | LLM or tool input content. Query via the search bar with the **Input** scope selector (see [Searching in the UI](#searching-in-the-ui)). | | Output | LLM or tool output content. Query via the search bar with the **Output** scope selector (see [Searching in the UI](#searching-in-the-ui)). | | Timestamp | When the span started | | Duration | Span duration (displayed in human-friendly units) | | Status | OpenTelemetry status code (`Ok`, `Error`, `Unset`) | | **Actions** | Pinned to the right of the grid; always visible. Contains the **View Trace** icon. | #### Columns hidden by default These columns are available via the column picker but are not shown out of the box: * Session ID * Trace ID * Span ID * Agent * Agent ID #### Dynamic columns Explorer adds columns automatically based on your application's schema: * **Evaluator output columns** — one column per output of every evaluator rule configured for the application. * **User-defined span attribute columns** — one column per attribute you've instrumented (for example, `user_id`, `model_version`, `environment`). * **Token count columns** — `gen_ai.usage.input_tokens`, `gen_ai.usage.output_tokens`, `gen_ai.usage.total_tokens`. See [Span and Resource Attributes](/integrations/agentic-ai/attributes) for the full attribute catalog and naming conventions. ### Filtering in the UI Open the filter panel from any filterable column header, or from the toolbar. Filters are applied server-side. By default, filter rules are combined with **AND**; the MUI filter panel also lets you switch to **OR** within a single column. * **ID columns** (`Session ID`, `Trace ID`, `Span ID`) — `equals` only in the UI (enable the column via the column picker first; these are hidden by default). * **String columns** (Name, Agent, span attributes) — `is`, `is not`, `is any of` (autocomplete) or `equals` / `does not equal` (free text), depending on whether the field has a known value set. * **Numeric columns** (Duration, token counts, numeric attributes) — `=`, `!=`, `>`, `>=`, `<`, `<=`. * **Enum columns** (Type, Status) — single- or multi-select. * **Boolean evaluator outputs** — `is` or `is not` with values `true` or `false`. ### Searching in the UI Use the search bar at the top of the grid to run a case-insensitive substring match against prompt and response content captured on your spans. | Setting | Detail | | ---------- | ----------------------------------------------------------------------------------------------- | | **Length** | 3 to 64 characters | | **Match** | Case-insensitive substring | | **Index** | Backed by a dedicated content table with n-gram and token bloom-filter indexes for fast lookups | The **scope selector** next to the search bar restricts which content fields are searched: | Scope | Searches | | ----------------- | ---------------------------------------------- | | **All** (default) | LLM input, LLM output, tool input, tool output | | **Input** | LLM input + tool input | | **Output** | LLM output + tool output | Search runs in addition to any structured filters — both must match for a span to appear in results. ### Sorting in the UI The grid is sorted by **Timestamp** (most recent first) by default. Click the **Timestamp** or **Duration** column header to change the sort. Other columns are not sortable in the UI in this release. ### Opening the trace drawer To inspect the full trace context for a span, click the **View Trace** (eye) icon in the rightmost **Actions** column. This opens a side drawer that loads every span in the row's session and renders them as a tree. * The drawer is **session-scoped**, not trace-scoped — if a session contains multiple traces, all of them are visible in the drawer. * The View Trace icon is **disabled** for spans without a `session_id`, with the tooltip *"No trace found"*. *** ## Related Resources * [Custom Metrics for Agentic Applications](/observability/agentic/custom-metrics) — define custom metrics over the same span data using FQL * [Span and Resource Attributes](/integrations/agentic-ai/attributes) — full attribute catalog and naming conventions * [Agentic Observability](/observability/agentic/index) — overview of dashboards, metrics, and integrations * [OpenTelemetry Trace Export](/integrations/agentic-ai/otel-trace-export) — export pre-existing OpenTelemetry traces to Fiddler from your own storage or pipeline *** ## Limitations & Roadmap (Public Preview) The following are not available in this release and are tracked for future work: * **Session-attribute filters.** You can filter by `session_id`, but filters over session-level attributes are not yet supported. * **Multi-pattern structural filters.** Constructs such as "trace contains tool X *then* LLM Y" or "trace where root has positive feedback" — sometimes written with `->` (temporal) or `=>` (parent / child) operators in other tools — are not yet supported. * **Saved filter sets.** Filters live for the current session; they cannot be named, saved, or shared yet. * **CSV / notebook export.** Bulk export of filtered results is not yet available. We're prioritizing these based on customer feedback during public preview — please reach out to your Customer Success Manager or file a ticket if any of the above are blocking your workflow. # Events Table in RCA Source: https://docs.fiddler.ai/observability/analytics/data-table-in-rca Learn how to use Fiddler's root cause analysis features to quickly hone in on the data issues adversely impacting your ML models and LLM applications. Allow visualizing events corresponding to a certain bin in a monitoring chart. Note that this view is to provide example rows used for the computation. The maximum number of rows that can viewed is 1000. ### Analyzing a Sample of Events * Navigate to the `Charts` tab in your Fiddler AI instance * Click on the `Add Chart` button on the top right * In the modal, select a project * Select **Monitoring** * Create a Monitoring chart and click on a time range * This will display the RCA (Root Cause Analysis) tab * In RCA, select the `Events Table` tab ### Support This visualization is supported for any model and data type. ### Represented data The displayed events are production events coming from the selected model and bin, and segment if it was selected in the monitoring chart. Monitoring Chart Configuration Event Table Example ### Available Controls * **Column selection**: On the top right side of the table, select the columns to be displayed. By default all non-vector columns are displayed. Event Table Column Selection * **Vector columns**: By default the vector columns are not fetched for latency reasons. Toggle on if vectors need to be fetched. Event Table Vectors displayed * **Download**: Download the sample events to `CSV` or `PARQUET` format. Event Table Vectors Download # Feature Analytics Source: https://docs.fiddler.ai/observability/analytics/feature-analytics-chart Dive into our guide on creating feature analytics charts and visualizations for important features in your ML Models and LLM applications. ### Creating a Feature Analytics Chart To create a Feature Analytics chart, follow these steps: * Navigate to the `Charts` tab in your Fiddler AI instance * Click on the `Add Chart` button on the top right * In the modal, select a project * Select **Feature Analytics** Add Chart modal dialog ### Support Feature analytics is supported for any model task type, but does not support time stamps or columns of type `string` or `vector`. ### Available Right-Side Controls | Parameter | Value | | ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Model | List of models in the project | | Version | List of versions for the selected model | | Environment | `Production` or `Pre-Production` | | Dataset | Displayed only if `Pre-Production` is selected. List of pre-production env uploaded for the model version. | | Visual | List of possible visualizations, Feature Distribution or Feature Correlation. | | Segment | \

- Selecting a saved segment\
- Defining an applied (on the fly) segment. This applied segment isn’t saved (unless specifically required by the user) and is applied for analysis purposes.\

| | Feature | \

- Feature Distribution: Select a single column of a supported data type to view the distribution of its values\
- Feature Correlation: Select two columns to visualize their correlation\
- Correlation Matrix: Select up to eight columns to visualize their pairwise correlations\

| ### Available In-Chart Controls | Control | Value | | -------------------- | -------------------------------------------------------------------------------------------------------------------------- | | Time range selection | Selecting start time and end time or time label for production data. Default is last 30 days | | Display | Select how to display the chart, Histogram or Kernel Density Estimate, depending on the data type of the feature selected. | ### Displays for Feature Distribution #### Kernel Density Estimate For numeric column types, visualize feature distribution as a Kernel Density Estimate chart. Feature distribution chart configured with Kernel Density Estimate rendering #### Histogram Categorical and boolean value may only be displayed as Histograms, but other column types may also be displayed as such. Feature distribution chart configured with histogram rendering ### Displays for Feature Correlation #### Line Plot Line plot example of Feature Correlation chart #### Scatter Plot Scatter plot example of Feature Correlation chart #### Stacked Bar Plot Stacked bar example of Feature Correlation chart #### Box Plot Box plot example of Feature Correlation chart ### Correlation Matrix Interactions Clicking a cell in the correlation matrix opens the Feature Correlation chart, enabling a more detailed analysis of the relationship between the selected features. Correlation matrix interactions # Analytics Source: https://docs.fiddler.ai/observability/analytics/index Explore our UI guide to Fiddler analytics. Learn about interfaces for various analytics charts and root cause analysis to better understand your models. ## Analytics Charts There are three supported analytics chart types: 1. ***Performance Analytics*** — Visualize various performance metrics tailored to different task types, such as confusion matrices, prediction scatterplots, and more. 2. ***Feature Analytics*** — Analyze the behavior and relationships between features, helping to identify patterns and insights within the data, using feature distribution, feature correlation, and correlation matrix charts. 3. ***Metric Card*** — Display a single numeric representation of a metric, offering a concise overview of performance, data quality, data integrity, or custom metrics on a card. ## Root Cause Analysis The Root Cause Analysis (RCA) experience consists of four parts, all based on the FQL segment and time range provided in the monitoring chart: 1. ***Events*** — Browse a sample of 1,000 events. 2. ***Data Drift*** — View a breakdown of drift for your features, along with prediction drift impact. 3. ***Data Integrity*** — Review a summary of data integrity violations, including counts across range, type, and missing value issues. 4. ***Analyze*** — View performance and feature analytics charts. Root Cause Analyze Experience # Metric Card Source: https://docs.fiddler.ai/observability/analytics/metric-card Dive into our guide for metric card creation. Follow step-by-step instructions to create metric cards, use custom metrics, right-side controls, and save charts. ### Creating a Metric Card Chart To create a Metric Card, follow these steps: * Navigate to the `Charts` tab in your Fiddler AI instance * Click on the `Add Chart` button on the top right * In the modal, select a project * Select **Metric Card** ### Support Metric card is supported for any model task type and for both production and pre-production data. Metric card allows displaying of Custom Metric, Data Drift, Data Integrity, Performance, Traffic, and Statistic metrics. ### Available Right-Side Controls | Parameter | Value | | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | Model | List of models in the project | | Version | List of versions for the selected model | | Environment | `Production` or `Pre-Production` | | Dataset | Displayed only if `Pre-Production` is selected. List of pre-production env uploaded for the model version. | | Metric | Selecting a metric across Custom Metrics, Data Drift, Data Integrity, Performance, Traffic, and Statistic to display as an aggregated number. Select up to 4 metrics to display on the chart. | | Segment | \

- Selecting a saved segment\
- Defining an applied (on the fly) segment. This applied segment isn’t saved (unless specifically required by the user) and is applied for analysis purposes.\

| ### Available In-Chart Controls | Control | Model Task | Value | | ------------------------ | --------------------- | -------------------------------------------------------------------------------------------- | | Time range selection | All | Selecting start time and end time or time label for production data. Default is last 30 days | | Positive class threshold | Binary classification | For performance metrics, select a threshold to be applied for computation. Default is 0.5 | | Top-K | Ranking | For performance metrics, select a top-k value to be applied for computation. Default is 20. | ### Saving the Chart Once you're satisfied with your metric card Chart, you can save it which allows it to be added to Dashboards and viewed individually from the Charts page. Root Cause Analyze Experience # Performance Charts Creation Source: https://docs.fiddler.ai/observability/analytics/performance-charts-creation Discover our guide to creating performance charts. Learn key steps to select charts, use right-side and in-chart controls, and save your customized charts. ### Creating a Performance Chart To create a Performance chart, follow these steps: * Navigate to the `Charts` tab in your Fiddler AI instance * Click on the `Add Chart` button on the top right * In the modal, Select the project that has a model with Custom features * Select **Performance Analytics** Add Chart modal dialog ### Available Performance charts | Model task | Available Chart(s) | | -------------------------- | ------------------------------------------------------------------------------------------ | | Binary classification | \

- Confusion Matrix\
- ROC\
- Precision Recall\
- Calibration Plot Charts\

| | Multi-class Classification | - Confusion Matrix | | Regression | \

- Prediction Scatterplot\
- Error Distribution\

| | Ranking / LLM / Not Set | *Not available* | ### Available right side controls | Parameter | Value | | --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Model | List of models in the project | | Version | List of versions for the selected model | | Environment | `Production` or `Pre-Production` | | Dataset | Displayed only if `Pre-Production` is selected. List of pre-production env uploaded for the model version. | | Visual | List of possible [performance visualization](/observability/analytics/performance-charts-visualization) depending on the model task. | | Segment | \

- Selecting a saved segment\
- Defining an applied (on the fly) segment. This applied segment isn’t saved (unless specifically required by the user) and is applied for analysis purposes.\

| | Max Sample size | \

Integer representing the maximum number of rows used for computing the chart, up to 500,000. If the data selected has less rows, we will use all the available rows with non null target and output(s).\
Fiddler select the \n\ first number of rows from the selected slice.\
\
\Note: Clickhouse is configured using multiple shards, which means slightly different results can be observed if data is only selected on a specific shard (usually when little observation are queried).\\

| ### Available in-chart controls | Control | Model Task | Value | | ------------------------ | -------------------------- | -------------------------------------------------------------------------------------------------- | | Time range selection | All | Selecting start time and end time or time label for production data. Default to last 30 days | | Positive class threshold | Binary classification | Selecting threshold applied for computation / visualization. Default to 0.5 | | Displayed labels | Multi-class Classification | Selecting the labels to display on the confusion matrix (up to 12). Default to the 12 first labels | ### Saving the Chart Once you're satisfied with your visualization, you can save the chart. This chart can then be added to a Dashboard. This allows you to revisit the Performance visualization at any time easily either directly going to the Chart or to the dashboard. # Performance Charts Visualization Source: https://docs.fiddler.ai/observability/analytics/performance-charts-visualization Dive into our guide on performance charts and visualizations used to monitor the behavior and performance of your ML models. ### Performance Charts Visualizations for ML and LLM Models List of possible performance visualization depending on the model task. To see how to create a Performance chart, visit [this page](/observability/analytics/performance-charts-creation). ### Binary Classification #### Confusion Matrix A 2x2 table that shows how many predicted and actual values exist for positive and negative classes. Also referred to as an error matrix. The percentage is computed per row. #### Receiver Operating Characteristic (ROC) Curve A graph showing the performance of a classification model at different classification thresholds. Plots the true positive rate (TPR), also known as recall, against the false positive rate (FPR). #### Precision-Recall Curve A graph that plots the precision against the recall for different classification thresholds. #### Calibration Plot A graph that tell us how well the model is calibrated. The plot is obtained by dividing the predictions into 10 quantile buckets (0-10th percentile, 10-20th percentile, etc.). The average predicted probability is plotted against the true observed probability for that set of points. ### Multi-class Classification #### Confusion Matrix A table that shows how many predicted and actual values exist for different classes. Also referred to as an error matrix. The percentage is computed per row (using all classes). In the full view, up to 15 classes can be displayed. In the chart creation mode, up to 12 classes can be displayed. The displayed labels can be controlled in the chart. ### Regression #### Prediction Scatterplot Plots the predicted values against the actual values. The more closely the plot hugs the `y=x line`, the better the fit of the model. #### Error Distribution A histogram showing the distribution of errors (differences between model predictions and actuals). The closer to 0 the errors are, the better the fit of the model. # Dashboard Interactions Source: https://docs.fiddler.ai/observability/dashboards/dashboard-interactions Explore our guide to dashboard interactions. Learn to remove, edit, zoom into charts, switch between bar and line views, and undo toolbar changes. ### Remove a Chart If you want to remove a chart from your dashboard, simply click on the "X" located at the top right of the chart. This will remove the chart from the dashboard, but it will still be available in the saved charts list for future use. If you change your mind and decide to add the chart back to the dashboard, you can simply find it in the saved charts list and add it back to the dashboard at any time. Example Auto Insurance Dashboard with drift and accuracy charts. ### Edit a Saved Chart To edit a saved chart, simply click on the chart title within your dashboard. This will open the chart studio in a new tab, where you can make any necessary changes. Once you have made your changes, be sure to select the `Default` time range and then use the Dashboard refresh button to see your updated chart. Displays chart title selected for editing mode. ### Zoom Into Details To zoom into a chart within your dashboard, you have two different utilities at your disposal. The first one is located on the top right of the chart component, in the toolbar. After clicking on the **zoom icon**, you can drag your cursor over the data points you wish to zoom into. Example of a region of an accuracy chart selected for zoom. You can also use the **horizontal zoom bar** located at the base of the chart to zoom in. Once you've identified the time range you want to focus on, you can use the zoom bar to drag the range across time. For instance, if you want to analyze your data weekly over the past six months, you can use the toolbar or horizontal zoom bar to zoom in on the desired time range and then click and drag the selected range using the base horizontal zoom bar. Examples of using the horizontal time range control underneath charts to narrow the date range. ### Bar & Line Charts You can switch between visualizing your chart as a line or a bar chart using the toolbar icons. Click on the line chart icon on the top right of the chart to switch to the line chart view. Likewise, select the bar chart icon in the toolbar to switch to the bar chart view. > Note that these views are only temporary and any settings you specify using the toolbar will not be saved to the dashboard. Highlight of the line/bar chart type toggle button. ### Undo Chart Toolbar Changes You can easily restore the changes you applied to your chart using the chart toolbar options, including zoom, switch to line chart, and switch to bar chart. The restore option, which is the last icon in the toolbar, allows you to undo any changes you made and return to the original chart configuration. Highlight of the undo button used to restore the chart to its original configuration. # Dashboard Utilities Source: https://docs.fiddler.ai/observability/dashboards/dashboard-utilities Discover dashboard utilities on Fiddler’s platform. Learn to rename, save, share, copy links, or delete dashboards to manage your collection effortlessly. ## Dashboard Name To rename your dashboard, simply click on the "Untitled Dashboard" title on the top-left corner of the dashboard studio. This will allow you to give your dashboard a more descriptive name that reflects its purpose and contents, making it easier to find and manage among your other dashboards. Once you've clicked on the "Untitled Dashboard" title to rename your dashboard, simply type in the desired name and hit "Enter" on your keyboard to save the new name. If you change your mind and want to discard the changes, simply click anywhere on the page outside of the name box. This will cancel the renaming process and leave the dashboard name as it was before. ## Save, Copy Link, and Delete You can easily manage your dashboard by using the control panel located on the top left of the dashboard studio. This panel allows you to save your dashboard, copy a link to it, or delete it entirely. By using these controls, you can easily share your dashboard with others or remove it from your collection if it is no longer needed. ## Save It's important to note that dashboards are not automatically saved, so you'll need to manually save your dashboard in order to lock in the current charts and filters. Once you've made the desired changes to your dashboard, simply click the "Save" button to save your progress. This will also enable you to share or delete your dashboard as needed. By saving your dashboard frequently, you can ensure that you never lose important information or data visualizations. ## Copy Link If you want to share your dashboard with other users on Fiddler, the first step is to ensure that they have access to the project that the dashboard belongs to. Once you've confirmed that they have access, you can easily share the dashboard by copying the dashboard link and sending it to them. This makes it simple to collaborate and share insights with others who are working on the same project or who have an interest in your findings. Note that you can't share a dashboard link until you've saved the dashboard. ## Delete To delete a dashboard, click the overflow button next to the copy link icon. NOTE: Once a dashboard has been deleted it cannot be recovered. # Creating Dashboards Source: https://docs.fiddler.ai/observability/dashboards/dashboards-creating Navigate our guide for the Dashboard page. Learn how to select new or existing dashboards and access them to monitor performance, drift, integrity, and traffic. ### Creating Dashboards To begin using our dashboard feature, navigate to the dashboard page by clicking on "Dashboards" from the top-level navigation bar. On the Dashboards page, you can choose to either select from previously created dashboards or create a new one. This simple process allows you to quickly access your dashboards and begin monitoring your models' performance, data drift, data integrity, and traffic. When creating a new dashboard, it's important to note that each dashboard is tied to a specific project space. This means that only models and charts associated with that project can be added to the dashboard. To ensure you're working within the correct project space, select the desired project space before entering the dashboard editor page, then click "Continue." This will ensure that you can add relevant charts and models to your dashboard. #### Auto-Generated Dashboards Fiddler will automatically generate model monitoring dashboards for all models registered to the platform. Depending on the task type, these dashboards will include charts spanning Performance, Traffic, Drift, and Data Integrity metrics. Auto-generated model monitoring dashboard Auto-generated model monitoring dashboard Auto-generated dashboard are automatically set as the default dashboards for each model, and can be accessed via the Insights button on the Homepage or Model Schema pages, or alternatively all dashboards are always accessible in the Dashboards list page. Default dashboards and their charts can easily be modified to display the desired set of [monitoring](/observability/platform/monitoring-charts-platform) and [embedding](/observability/llm/embedding-visualization-with-umap) visualizations to meet any use case. ### Add Monitoring Charts Once you’ve created a dashboard, you can add previously saved monitoring charts that display these metrics over time, making it easy to track changes and identify patterns. To create a new monitoring chart for your dashboard, simply select "New Monitoring Chart" from the "Add" dropdown menu. For more information on creating and customizing monitoring charts, check out our [Monitoring Charts UI Guide](/observability/platform/monitoring-charts-platform). If you'd like to add an existing chart to your dashboard, select "Saved Charts" to display a full list of monitoring charts that are available in your project space. This makes it easy to quickly access and add the charts you need to your dashboard for monitoring and reporting purposes. To further customize your dashboard, you can select the saved monitoring charts of interest by clicking on their respective cards. For instance, you might choose to add charts for Accuracy, Drift, Traffic, and Range Violation to your dashboard for a more comprehensive model overview. By adding these charts to your dashboard, you can quickly access important metrics and visualize your model's performance over time, enabling you to identify trends and patterns that might require further investigation. ### Dashboard Filters There are three main filters that can be applied to all the charts within dashboards, these include date range, time zone, and bin size. #### Date Range When the `Default` time range is selected, the data range, time zone, and bin size that each monitoring chart was originally saved with will be applied. This enables you to create a dashboard where each chart shows a unique filter set to highlight what matters to each team. Updating the date range will unlock the time zone and bin size filters. You can select from a number of predefined ranges or choose `Custom` to select a start and end date-time. #### Bin Size Bin size controls the frequency at which data is displayed on your monitoring charts. You can select from the following bin sizes: `Hour`, `Day`, `Week`, or `Month`. > 📘 Note: Hour bin sizes are not supported for time ranges above 90 days. > > For example, if we select the `6M` data range, we see that the `Hourly` bin selection is disabled. This is disabled to avoid long computation and dashboard loading times. #### Saved Model Updates If you recently created or updated a saved chart and are not seeing the changes either on the dashboard itself or the Saved Charts list, click the refresh button on the main dashboard studio or within the saved charts list to reflect updates. ### Model Comparison With our dashboard feature, you can also compare multiple models side-by-side, making it easy to see which models are performing the best and which may require additional attention. To create model-to-model comparison dashboards, ensure the models you wish to compare belong to the same project. Create the desired charts for each model and then add them to a single dashboard. By creating a single dashboard that tracks the health of all of your models, you can save time and simplify your AI monitoring efforts. With these dashboards, you can easily share insights with your team, management, or stakeholders, and ensure that everyone is up-to-date on your AI performance. Refer to our [Dashboard Utilities ](/observability/dashboards/dashboard-utilities)and [Dashboard Interactions](/observability/dashboards/dashboard-interactions) pages for more info on dashboard usage. # Dashboards Source: https://docs.fiddler.ai/observability/dashboards/index Explore our guide to Fiddler’s dashboards for centralized monitoring. Discover key features like filters, utilities, default dashboards, and performance. ### Overview With Fiddler, you can create comprehensive dashboards that bring together all of your monitoring data in one place. This includes monitoring charts for data drift, traffic, data integrity, and performance metrics. Adding monitoring charts to your dashboards lets you create a detailed view of your model's performance. These dashboards can inform your team, management, or stakeholders, and help make data-driven decisions that improve your AI performance. View a list of the [**available metrics for monitoring charts here**](/observability/platform/monitoring-charts-platform#supported-metric-types). Model monitoring dashboard including performance, drift, traffic, custom metrics, and segment analysis. ### Key Features Dashboards offer a powerful way to analyze the overall health and performance of your models, as well as to compare multiple models. #### Dashboard Filters * [Flexible filters](/observability/dashboards/dashboards-creating#dashboard-filters) including date range, time zone, and bin size to customize your view #### Chart Utilities * [Leverage the chart toolbar](/observability/dashboards/dashboard-interactions#zoom-into-details) to zoom into data and toggle between line and bar chart types #### Automatic & Default Dashboards * Fiddler automatically creates a [monitoring dashboard](/observability/dashboards/dashboards-creating#auto-generated-dashboards) for all your models that can be accessed as Insights throughout the product. #### [Dashboard Basics](/observability/dashboards/dashboard-utilities) * Perform model-to-model comparison * Plot drift or data integrity for multiple columns in one view * Easily save and share your dashboard Checkout more on the [Dashboards Guide](/observability/dashboards/dashboards-creating). # Fairness Source: https://docs.fiddler.ai/observability/fairness Explore our walkthrough of ML model fairness and bias. Review the sample calculations you can customize to your data and use with Fiddler's custom metrics. Thanks to Fiddler charts visuals and our [custom metrics](/observability/platform/custom-metrics), you can define your fairness metric of choice to detect model bias on your dataset or production data and set up alerts. ## Definitions of Fairness Models are trained on real-world examples to mimic past outcomes on unseen data. The training data could be biased, which means the model will perpetuate the biases in the decisions it makes. While there is not a universally agreed upon definition of fairness, we define a ‘fair’ ML model as a model that does not favor any group of people based on their characteristics. Ensuring fairness is key before deploying a model in production. For example, in the US, the government prohibited discrimination in credit and real-estate transactions with fair lending laws like the Equal Credit Opportunity Act (ECOA) and the Fair Housing Act (FHAct). The Equal Employment Opportunity Commission (EEOC) acknowledges 12 factors of discrimination:[\[1\]](#reference) age, disability, equal pay/compensation, genetic information, harassment, national origin, pregnancy, race/color, religion, retaliation, sex, sexual harassment. These are what we call protected attributes. ## Fairness Metrics Among others, some popular metrics are: * Disparate Impact * Group Benefit * Equal Opportunity * Demographic Parity The choice of the metric is use case-dependent. An important point to make is that it's impossible to optimize all the metrics at the same time. This is something to keep in mind when analyzing fairness metrics. ## Disparate Impact Disparate impact is a form of **indirect and unintentional discrimination**, in which certain decisions disproportionately affect members of a protected group. Mathematically, disparate impact compares the pass rate of one group to that of another. The pass rate is the rate of positive outcomes for a given group. It's defined as follows: pass rate = passed / (num of ppl in the group) Disparate impact is calculated by: `DI = (pass rate of group 1) / (pass rate of group 2)` Groups 1 and 2 are interchangeable. Therefore, the following formula can be used to calculate disparate impact: `DI = min{pr_1, pr_2} / max{pr_1, pr_2}.` The disparate impact value is between 0 and 1. The Four-Fifths rule states that the disparate impact has to be greater than 80%. For example: `pass-rate_1 = 0.3, pass-rate_2 = 0.4, DI = 0.3/0.4 = 0.75` `pass-rate_1 = 0.4, pass-rate_2 = 0.3, DI = 0.3/0.4 = 0.75` > 📘 Info > > Disparate impact is the only legal metric available. The other metrics are not yet codified in US law. ## Demographic Parity Demographic parity states that the proportion of each segment of a protected class should receive the positive outcome at equal rates. Mathematically, demographic parity compares the pass rate of two groups. The pass rate is the rate of positive outcomes for a given group. It is defined as follows: `pass rate = passed / (num of ppl in the group)` If the decisions are fair, the pass rates should be the same. ## Group Benefit Group benefit aims to measure the rate at which a particular event is predicted to occur within a subgroup compared to the rate at which it actually occurs. Mathematically, group benefit for a given group is defined as follows: `Group Benefit = (TP+FP) / (TP + FN).` Group benefit equality compares the group benefit between two groups. If the two groups are treated equally, the group benefit should be the same. ## Equal Opportunity Equal opportunity means that all people will be treated equally or similarly and not disadvantaged by prejudices or bias. Mathematically, equal opportunity compares the true positive rate (TPR) between two groups. TPR is the probability that an actual positive will test positive. The true positive rate is defined as follows: `TPR = TP/(TP+FN)` If the two groups are treated equally, the TPR should be the same. ## Intersectional Fairness We believe fairness should be ensured to all subgroups of the population. We extended the classical metrics (which are defined for two classes) to multiple classes. In addition, we allow multiple protected features (e.g. race *and* gender). By measuring fairness along overlapping dimensions, we introduce the concept of intersectional fairness. To understand why we decided to go with intersectional fairness, we can take a simple example. In the figure below, we observe that equal numbers of black and white people pass. Similarly, there is an equal number of men and women passing. However, this classification is unfair because we don’t have any black women and white men that passed, and all black men and white women passed. Here, we observe bias within subgroups when we take race and gender as protected attributes. The EEOC provides examples of past intersectional discrimination/harassment cases.[\[2\]](#reference) For more details about the implementation of the intersectional framework, please refer to this [research paper](https://arxiv.org/pdf/2101.01673.pdf). ## Model Behavior In addition to the fairness metrics, we suggest tracking model outcomes and model performance for each subgroup of population. ## Reference \[^1]: USEEOC article on [*Discrimination By Type*](https://www.eeoc.gov/know-your-rights-workplace-discrimination-illegal) \[^2]: USEEOC article on [*Intersectional Discrimination/Harassment*](https://www.eeoc.gov/initiatives/e-race/significant-eeoc-racecolor-casescovering-private-and-federal-sectors#intersectional) # Embedding Visualizations Source: https://docs.fiddler.ai/observability/llm/embedding-visualization-with-umap Explore our guide on embedding visualization to enhance LLM monitoring. Discover UMAP techniques, analyze high-dimensional data, and uncover patterns with ease. Discover how embedding visualization enhances LLM monitoring and analysis by simplifying complex data relationships and delivering actionable insights. This guide explains how to implement Fiddler’s LLM visualization techniques, such as UMAP, to uncover patterns, clusters, and anomalies in high-dimensional data. Charts: UMAP embedding visualization ### What is Embedding Visualization and Why It Matters for LLM Monitoring Embedding visualization is a powerful technique for understanding and interpreting complex relationships in high-dimensional data. By reducing the dimensionality of custom features into a 2D or 3D space, patterns, clusters, and outliers become easier to identify, offering valuable insights for LLM embedding analysis and vector embedding visualization. In Fiddler, high-dimensional data like embeddings and vectors are ingested as a [Custom Feature](/observability/platform/vector-monitoring-platform#define-custom-features). This approach allows you to visualize embeddings and perform vector embedding visualization effectively, enabling detailed analysis and uncovering hidden patterns in your data. ### Using UMAP for LLM Embedding Visualization in High-Dimensional Data We use the [UMAP](https://umap-learn.readthedocs.io/en/latest/) (Uniform Manifold Approximation and Projection) technique to embed visualizations. UMAP is a dimensionality reduction method particularly effective at preserving the local structure of data, making it ideal for visualizing embeddings, including those from embedded LLM models. Reducing high-dimensional embeddings to a 3D space allows for easier interpretation and analysis. UMAP supports both text embedding visualization and image embedding as a [Custom Feature](/observability/platform/vector-monitoring-platform#define-custom-features). Our [guide](#using-umap-for-llm-embedding-visualization-in-high-dimensional-data) teaches you how to apply UMAP visualizations to your application data, unlocking deeper insights into your embedded LLM data. ### How UMAP Embedding Visualization Enhances Generative Applications UMAP embedding visualizations are extremely helpful in understanding common themes and topics in the data corpus for generative AI applications. When evaluating prompts and responses, it is paramount to see which concept clusters emerge and which exhibit the most problems. Users can identify the clusters with the most issues by coloring them with various LLM and GenAI correctness and safety metrics. Identifying a cluster of prompts with Jailbreak attempts via UMAP To create an embedding visualization chart, follow the Guide [here](#using-umap-for-llm-embedding-visualization-in-high-dimensional-data). # Enrichments Source: https://docs.fiddler.ai/observability/llm/enrichments Explore our guide on how Fiddler can enrich your LLM application's data to help analyze and evaluate application behavior and performance. For a complete list of all LLM enrichments with output columns and sub-metrics, see the [LLM Observability Metrics Reference](/reference/llm-observability-metrics). ## Introduction to Enrichments Enrichments are specialized evaluation features that augment your LLM application data with automatically generated trust and safety metrics. By defining enrichments during model onboarding, you instruct Fiddler to analyze published prompts and responses using purpose-built models that assess dimensions like faithfulness, toxicity, relevance, and safety compliance. The enrichment framework processes your application's inputs and outputs to generate quantitative scores that integrate directly with Fiddler's monitoring dashboards, alerting systems, and root cause analysis tools. This approach enables proactive detection of model drift, content safety violations, and performance degradation without requiring manual evaluation or external API dependencies. * Enrichments are [custom features](/observability/platform/vector-monitoring-platform#define-custom-features) designed to augment the data provided in events * Enrichments augment existing columns with new metrics that are defined during model onboarding * The new metrics are available for use within the analysis, charting, and alerting functionalities in Fiddler The following example demonstrates how to configure a TextEmbedding enrichment to enable vector-based monitoring and visualization of your LLM application's text inputs. TextEmbedding enrichments convert unstructured text into high-dimensional vector representations that capture semantic meaning, enabling Fiddler to detect drift in the topics and themes of your prompts or responses over time. In this configuration, the enrichment transforms text from the `question` column into numerical embeddings stored in `question_embedding`. These embeddings power Fiddler's 3D UMAP visualizations, allowing you to visually identify clusters of similar content, detect outliers, and spot shifts in user behavior patterns. The `TextEmbedding` feature also enables drift detection by comparing the distribution of embeddings between your baseline and production data, providing early warning when your application encounters significantly different types of content than expected. ```py theme={null} import fiddler as fdl # Define a TextEmbedding enrichment for vector-based monitoring fiddler_custom_features = [ fdl.TextEmbedding( name='question_cf', # Internal name for the custom feature source_column='question', # Original text column to analyze column='question_embedding', # Generated embedding vector column ), ] model_spec = fdl.ModelSpec( inputs=['question'], custom_features=fiddler_custom_features, ) ``` *** ### Embedding Embeddings are numerical representations (vectors) generated by a model for input text. Each number within the vector represents a different dimension of the text input. The meaning of each number depends on how the embedding generating model was trained. Fiddler uses publicly available embeddings to power the 3D UMAP experience. Because the same model generates all embeddings, the points will naturally cluster, enabling quick visual anomaly detection. To create embeddings and leverage them for the UMAP visualization, you must create a new TextEmbedding enrichment on your unstructured text column. If you want to bring your own embeddings onto the Fiddler platform, you can direct Fiddler to consume the embeddings vector directly from your data. **Example 1: Fiddler-Generated Embeddings** This example automatically generates text embeddings on a text column called `prompt`: ```python theme={null} import fiddler as fdl fiddler_custom_features = [ fdl.TextEmbedding( name='Prompt TextEmbedding', # name of generated column (for internal use, required) source_column='prompt', # source - raw text column='Enrichment Prompt Embedding', # name of the vector output n_clusters=5, # Number of clusters for k-means clustering n_tags=5, # Top n tags used as summary tags per cluster ), ] model_spec = fdl.ModelSpec( inputs=['prompt'], custom_features=fiddler_custom_features, ) ``` **Generated Columns:** | Column | Type | Description | | ----------------------------------------- | ------- | -------------------------------------------------- | | Enrichment Prompt Embedding | vector | Embeddings corresponding to string column `prompt` | | Prompt Text Embedding | integer | Column for internal use | | Prompt Text Embedding - Centroid Distance | float | Centroid Distance to string column `prompt` | **Example 2: User-Provided Embeddings** This example demonstrates leveraging an existing vector column of text embeddings called `pre_existing_prompt_embedding`: Vector embeddings must use data type List(float) for compatibility. Using CSV for source data often requires preprocessing after initial loading into a pandas dataframe. ```python theme={null} import ast import numpy as np import pandas as pd import fiddler as fdl df = pd.read_csv(PATH_TO_SAMPLE_CSV) # Convert string representation to list df['pre_existing_prompt_embedding'] = df['pre_existing_prompt_embedding'].apply( ast.literal_eval ) fiddler_custom_features = [ fdl.TextEmbedding( name='User-provided Text Embedding', # name of the generated column source_column='prompt', # source - raw text column='pre_existing_prompt_embedding', # name of your vector column ), ] model_spec = fdl.ModelSpec( inputs=['prompt'], metadata=['pre_existing_prompt_embedding'], custom_features=fiddler_custom_features, ) ``` **Generated Columns:** | Column | Type | Description | | ------------------------------------------------ | ------- | ------------------------------------------- | | User-provided Text Embedding | integer | Column for internal use | | User-provided Text Embedding - Centroid Distance | float | Centroid Distance to string column `prompt` | *** ### Centroid Distance Fiddler uses KMeans to determine cluster membership for a given enrichment. The Centroid Distance enrichment provides information about the distance between the selected point and the closest centroid. Centroid Distance is automatically added if the TextEmbedding enrichment is created for any given model. Centroid Distance columns are automatically generated when you create a TextEmbedding enrichment. See the [Embedding](#embedding) section above for complete usage examples. *** ### Personally Identifiable Information The PII (Personally Identifiable Information) enrichment tool is a critical tool for detecting and flagging sensitive information in textual data. Whether user-entered or system-generated, this enrichment aims to identify instances where PII may be exposed, helping prevent privacy breaches and misuse of personal data. In an era where digital privacy concerns are paramount, mishandling or unintentionally leaking PII can have serious repercussions, including privacy violations, identity theft, and significant legal and reputational damage. PII enrichment is integrated with [Presidio](https://microsoft.github.io/presidio/analyzer/languages/) for entity detection. **Python Configuration:** ```python theme={null} import fiddler as fdl fiddler_custom_features = [ fdl.Enrichment( name='Rag PII', enrichment='pii', columns=['question'], # one or more columns allow_list=['fiddler'], # Optional: list of strings that are white listed score_threshold=0.85, # Optional: float value for minimum possible confidence ), ] model_spec = fdl.ModelSpec( inputs=['question'], custom_features=fiddler_custom_features, ) ``` **Generated Columns:** | Column | Type | Description | | ------------------------------- | ---- | --------------------------------------------------------------------------------------- | | FDL Rag PII (question) | bool | Whether any PII was detected | | FDL Rag PII (question) Matches | str | What matches in raw text were flagged as potential PII (ex. 'Douglas MacArthur,Korean') | | FDL Rag PII (question) Entities | str | What entities these matches were tagged as (ex. 'PERSON') | **Supported PII Entity Types:** CREDIT\_CARD, CRYPTO, DATE\_TIME, EMAIL\_ADDRESS, IBAN\_CODE, IP\_ADDRESS, LOCATION, PERSON, PHONE\_NUMBER, URL, US\_SSN, US\_DRIVER\_LICENSE, US\_ITIN, US\_PASSPORT *** ### Evaluate This enrichment provides n-gram-based metrics for comparing two passages of text, such as BLEU, ROUGE, and METEOR. Created initially to compare an AI-generated translation or summary to a human-generated one, these metrics have some use in RAG summarization tasks. They score highest when the reference and generated texts contain overlapping sequences. Additionally, these metrics are not as effective for long passages of text. **Python Configuration:** ```python theme={null} import fiddler as fdl fiddler_custom_features = [ fdl.Enrichment( name='QA Evaluate', enrichment='evaluate', columns=['correct_answer', 'generated_answer'], config={ 'reference_col': 'correct_answer', # required 'prediction_col': 'generated_answer', # required 'metrics': ['bleu', 'rouge', 'meteor'], # optional, this is the default } ), ] model_spec = fdl.ModelSpec( inputs=['question'], custom_features=fiddler_custom_features, ) ``` **Generated Columns:** | Column | Type | Description | | --------------------------- | ----- | ------------------------------------------------------ | | FDL QA Evaluate (bleu) | float | BLEU score: Measures precision of word n-grams | | FDL QA Evaluate (rouge1) | float | ROUGE-1 score: Unigram recall | | FDL QA Evaluate (rouge2) | float | ROUGE-2 score: Bigram recall | | FDL QA Evaluate (rougel) | float | ROUGE-L score: Longest common subsequence | | FDL QA Evaluate (rougelsum) | float | ROUGE-L summary score | | FDL QA Evaluate (meteor) | float | METEOR score: Precision, recall, and semantic matching | *** ### Textstat The Textstat enrichment generates various text statistics such as character/letter count, Flesch-Kincaid, and other metrics on the target text column. **Python Configuration:** ```python theme={null} import fiddler as fdl fiddler_custom_features = [ fdl.Enrichment( name='Text Statistics', enrichment='textstat', columns=['question'], config={ 'statistics': [ 'char_count', 'dale_chall_readability_score', ] }, ), ] model_spec = fdl.ModelSpec( inputs=['question'], custom_features=fiddler_custom_features, ) ``` **Generated Columns:** | Column | Type | Description | | -------------------------------------------------------------- | ----- | ------------------------------------------------ | | FDL Text Statistics (question) char\_count | int | Character count of string in `question` column | | FDL Text Statistics (question) dale\_chall\_readability\_score | float | Readability score of string in `question` column | **Supported Statistics:** char\_count, letter\_count, miniword\_count, words\_per\_sentence, polysyllabcount, lexicon\_count, syllable\_count, sentence\_count, flesch\_reading\_ease, smog\_index, flesch\_kincaid\_grade, coleman\_liau\_index, automated\_readability\_index, dale\_chall\_readability\_score, difficult\_words, linsear\_write\_formula, gunning\_fog, long\_word\_count, monosyllabcount *** ### Sentiment The Sentiment enrichment uses NLTK's VADER lexicon to generate a score and corresponding sentiment for all specified columns. To enable, set the enrichment parameter to `sentiment`. **Python Configuration:** ```python theme={null} import fiddler as fdl fiddler_custom_features = [ fdl.Enrichment( name='Question Sentiment', enrichment='sentiment', columns=['question'], ), ] model_spec = fdl.ModelSpec( inputs=['question'], custom_features=fiddler_custom_features, ) ``` **Generated Columns:** | Column | Type | Description | | ------------------------------------------- | ------ | ------------------------------------------- | | FDL Question Sentiment (question) compound | float | Raw score of sentiment | | FDL Question Sentiment (question) sentiment | string | One of `positive`, `negative`, or `neutral` | *** ### Profanity The Profanity enrichment is designed to detect and flag the use of offensive or inappropriate language within textual content. This enrichment is essential for maintaining the integrity and professionalism of digital platforms, forums, social media, and any user-generated content areas. The profanity enrichment searches the target text for words from the two sources below: * The Obscenity List from [SurgeAI](https://github.com/surge-ai/) * Google banned words \<[https://github.com/coffee-and-fun/google-profanity-words/blob/main/data/en.txt](https://github.com/coffee-and-fun/google-profanity-words/blob/main/data/en.txt)> **Python Configuration:** ```python theme={null} import fiddler as fdl fiddler_custom_features = [ fdl.Enrichment( name='Profanity', enrichment='profanity', columns=['prompt', 'response'], config={'output_column_name': 'contains_profanity'}, ), ] model_spec = fdl.ModelSpec( inputs=['prompt', 'response'], custom_features=fiddler_custom_features, ) ``` **Generated Columns:** | Column | Type | Description | | -------------------------------------------- | ---- | ------------------------------------------------------------------------- | | FDL Profanity (prompt) contains\_profanity | bool | Indicates if input contains profanity in the value of the prompt column | | FDL Profanity (response) contains\_profanity | bool | Indicates if input contains profanity in the value of the response column | *** ### Regex Match The Regex Match enrichment evaluates text responses or content for adherence to specific patterns defined by regular expressions (regex). By accepting a regex as input, this metric offers a highly customizable way to check if a string column in the dataset matches the given pattern. This functionality is essential for scenarios requiring precise formatting, specific keyword inclusion, or adherence to particular linguistic structures. **Python Configuration:** ```python theme={null} import fiddler as fdl fiddler_custom_features = [ fdl.Enrichment( name='Regex - only digits', enrichment='regex_match', columns=['prompt', 'response'], config={ 'regex': '^\d+$', } ), ] model_spec = fdl.ModelSpec( inputs=['prompt', 'doc_0', 'doc_1', 'doc_2', 'response'], custom_features=fiddler_custom_features, ) ``` **Generated Columns:** | Column | Type | Description | | ----------------------- | -------- | ---------------------------------------------------------------------------------------- | | FDL Regex - only digits | category | Match or No Match, depending on the regex specified in the config matching in the string | *** ### Topic The Topic enrichment leverages the capabilities of [Zero Shot Classifier](https://huggingface.co/tasks/zero-shot-classification) models to categorize textual inputs into a predefined list of topics, even without having been explicitly trained on those topics. This approach to text classification is known as zero-shot learning, a groundbreaking method in natural language processing (NLP) that enables models to intelligently classify text they haven't encountered during training. It's beneficial for applications that require understanding and organizing content dynamically across a broad range of subjects or themes. **Python Configuration:** ```python theme={null} import fiddler as fdl fiddler_custom_features = [ fdl.Enrichment( name='Topics', enrichment='topic_model', columns=['response'], config={'topics': ['politics', 'economy', 'astronomy']}, ), ] model_spec = fdl.ModelSpec( inputs=['prompt', 'doc_0', 'doc_1', 'doc_2', 'response'], custom_features=fiddler_custom_features, ) ``` **Generated Columns:** | Column | Type | Description | | ------------------------------------------ | ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | FDL Topics (response) topic\_model\_scores | list\[float] | Probability of the given column in each of the topics specified in the Enrichment config. Each float value indicates the probability of the given input being classified in the corresponding topic, in the same order as topics. Each value will be between 0 and 1. The sum of values does not equal 1, as each classification is performed independently of other topics. | | FDL Topics (response) max\_score\_topic | string | Topic with the maximum score from the list of topic names specified in the Enrichment config | *** ### Banned Keyword Detector The Banned Keyword Detector enrichment is designed to scrutinize textual inputs for the presence of specified terms, with a particular focus on identifying content that includes potentially undesirable or restricted keywords. This enrichment operates based on a list of terms defined in its configuration, making it highly adaptable to various content moderation, compliance, and content filtering needs. **Python Configuration:** ```python theme={null} import fiddler as fdl fiddler_custom_features = [ fdl.Enrichment( name='Banned KW', enrichment='banned_keywords', columns=['prompt', 'response'], config={ 'output_column_name': 'contains_banned_kw', 'banned_keywords': ['nike', 'adidas', 'puma'], }, ), ] model_spec = fdl.ModelSpec( inputs=['prompt', 'doc_0', 'doc_1', 'doc_2', 'response'], custom_features=fiddler_custom_features, ) ``` **Generated Columns:** | Column | Type | Description | | --------------------------------------------- | ---- | ---------------------------------------------------------------------------------------------------- | | FDL Banned KW (prompt) contains\_banned\_kw | bool | Indicates if input contains one of the specified banned keywords in the value of the prompt column | | FDL Banned KW (response) contains\_banned\_kw | bool | Indicates if input contains one of the specified banned keywords in the value of the response column | *** ### Language Detector The Language Detector enrichment identifies the language of the source text. This enrichment is based on a pretrained text identification model and leverages [fasttext models](https://fasttext.cc/docs/en/language-identification.html) for language detection. **Python Configuration:** ```python theme={null} import fiddler as fdl fiddler_custom_features = [ fdl.Enrichment( name='Language', enrichment='language_detection', columns=['prompt'], ), ] model_spec = fdl.ModelSpec( inputs=['prompt'], custom_features=fiddler_custom_features, ) ``` **Generated Columns:** | Column | Type | Description | | ------------------------------------------- | ------ | --------------------------------------------- | | FDL Language (prompt) language | string | Language prediction for input text | | FDL Language (prompt) language\_probability | float | Confidence probability of language prediction | *** ### Answer Relevance The Answer Relevance enrichment evaluates the pertinence of AI-generated responses to their corresponding prompts. This enrichment assesses whether a response accurately addresses the question or topic posed by the initial prompt, providing a simple yet effective binary outcome: relevant or not. Its primary function is to ensure that the output of AI systems, such as chatbots, virtual assistants, and content generation models, remains aligned with the user's informational needs and intentions. Looking for more granular relevance scoring? The [Evals SDK](/developers/quick-starts/experiments-quick-start) and [Agentic Monitoring](/getting-started/agentic-monitoring) offer **Answer Relevance 2.0** with ordinal scoring (High/Medium/Low) as part of the [RAG Health Metrics](/concepts/rag-health-diagnostics) diagnostic triad. **Python Configuration:** ```python theme={null} import fiddler as fdl answer_relevance_config = { 'prompt': 'prompt_col', 'response': 'response_col', } fiddler_custom_features = [ fdl.Enrichment( name='Answer Relevance', enrichment='answer_relevance', columns=['prompt_col', 'response_col'], config=answer_relevance_config, ), ] model_spec = fdl.ModelSpec( inputs=['prompt_col', 'response_col'], custom_features=fiddler_custom_features, ) ``` **Generated Columns:** | Column | Type | Description | | -------------------- | ---- | ---------------------------------------------------------------------- | | FDL Answer Relevance | bool | Binary metric, which is True if `response` is relevant to the `prompt` | *** ### Faithfulness The Faithfulness (Groundedness) enrichment is a binary indicator that evaluates the accuracy and reliability of the facts presented in AI-generated text responses. It specifically assesses whether the information used in the response aligns with and is grounded in the provided context, often through referenced documents or data. This enrichment plays a critical role in ensuring that the AI's outputs are not only relevant but also factually accurate, given the context it was provided. **Faithfulness (LLM-as-a-Judge) vs Faithfulness (Centor Model):** This LLM-based Faithfulness enrichment (`faithfulness`) uses `context` and `response` config keys. [Faithfulness (Centor Model)](#faithfulness-centor-model) (`ftl_response_faithfulness`) uses Fiddler's proprietary Centor Model for Faithfulness for lower latency. For RAG pipeline diagnostics with detailed reasoning, see [RAG Faithfulness](/concepts/rag-health-diagnostics#rag-faithfulness-vs-faithfulness-centor-model) in the Evals SDK and Agentic Monitoring. **Python Configuration:** ```python theme={null} import fiddler as fdl faithfulness_config = { 'context': ['doc_0', 'doc_1', 'doc_2'], 'response': 'response_col', } fiddler_custom_features = [ fdl.Enrichment( name='Faithfulness', enrichment='faithfulness', columns=['doc_0', 'doc_1', 'doc_2', 'response_col'], config=faithfulness_config, ), ] model_spec = fdl.ModelSpec( inputs=['doc_0', 'doc_1', 'doc_2', 'response_col'], custom_features=fiddler_custom_features, ) ``` **Generated Columns:** | Column | Type | Description | | ---------------- | ---- | ---------------------------------------------------------------------------------------------------------- | | FDL Faithfulness | bool | Binary metric, which is True if the facts used in `response` are correctly used from the `context` columns | *** ### Coherence The Coherence enrichment assesses the logical flow and clarity of AI-generated text responses, ensuring they are structured in a way that makes sense from start to finish. This enrichment is crucial for evaluating whether the content produced by AI maintains a consistent theme, argument, or narrative, without disjointed thoughts or abrupt shifts in topic. Coherence is key to making AI-generated content not only understandable but also engaging and informative for the reader. **Python Configuration:** ```python theme={null} import fiddler as fdl coherence_config = { 'response': 'response_col', } fiddler_custom_features = [ fdl.Enrichment( name='Coherence', enrichment='coherence', columns=['response_col'], config=coherence_config, ), ] model_spec = fdl.ModelSpec( inputs=['doc_0', 'doc_1', 'doc_2', 'response_col'], custom_features=fiddler_custom_features, ) ``` **Generated Columns:** | Column | Type | Description | | ------------- | ---- | ---------------------------------------------------------------------------------- | | FDL Coherence | bool | Binary metric, which is True if `response` makes coherent arguments that flow well | *** ### Conciseness The Conciseness enrichment evaluates the brevity and clarity of AI-generated text responses, ensuring that the information is presented in a straightforward and efficient manner. This enrichment identifies and rewards responses that effectively communicate their message without unnecessary elaboration or redundancy. In the realm of AI-generated content, where verbosity can dilute the message's impact or confuse the audience, maintaining conciseness is crucial for enhancing readability and user engagement. **Python Configuration:** ```python theme={null} import fiddler as fdl conciseness_config = { 'response': 'response_col', } fiddler_custom_features = [ fdl.Enrichment( name='Conciseness', enrichment='conciseness', columns=['response'], config=conciseness_config, ), ] model_spec = fdl.ModelSpec( inputs=['prompt', 'doc_0', 'doc_1', 'doc_2', 'response'], custom_features=fiddler_custom_features, ) ``` **Generated Columns:** | Column | Type | Description | | --------------- | ---- | ---------------------------------------------------------------------------- | | FDL Conciseness | bool | Binary metric, which is True if `response` is concise and not overly verbose | *** ### Safety The Safety enrichment evaluates the safety of the text along eleven different dimensions: `illegal, hateful, harassing, racist, sexist, violent, sexual, harmful, unethical, jailbreaking, roleplaying`. The Safety enrichment is powered by the [Centor Model for Safety](/observability/llm/llm-based-metrics). **Python Configuration:** ```python theme={null} import fiddler as fdl fiddler_custom_features = [ fdl.Enrichment( name='Prompt Safety', enrichment='ftl_prompt_safety', columns=['prompt'], config={'classifiers': ['jailbreaking', 'illegal']} # Optional: specify dimensions ), ] model_spec = fdl.ModelSpec( inputs=['prompt'], custom_features=fiddler_custom_features, ) ``` **Generated Columns:** For each dimension specified (or all 11 dimensions if not specified): | Column | Type | Description | | -------------------------------------------- | ----- | --------------------------------------------------------------------------- | | FDL Prompt Safety (prompt) `dimension` | bool | Binary metric, which is True if the input is deemed unsafe, False otherwise | | FDL Prompt Safety (prompt) `dimension` score | float | Confidence probability of safety prediction | **Supported Dimensions:** illegal, hateful, harassing, racist, sexist, violent, sexual, harmful, unethical, jailbreaking, roleplaying *** ### Faithfulness (Centor Model) The Faithfulness (Centor Model) enrichment is designed to evaluate the accuracy and reliability of facts presented in AI-generated text responses. It is powered by the [Centor Model for Faithfulness](/observability/llm/llm-based-metrics). The faithfulness threshold defaults to 0.5 but can be adjusted in the configuration to control the sensitivity of the faithfulness scoring. Lower thresholds result in stricter faithfulness detection, while higher thresholds are more permissive. **Python Configuration:** ```python theme={null} import fiddler as fdl fiddler_custom_features = [ fdl.Enrichment( name='Faithfulness', enrichment='ftl_response_faithfulness', columns=['context', 'response'], config={ 'context_field': 'context', 'response_field': 'response', 'threshold': '0.5' # Optional parameter, default is 0.5 } ), ] model_spec = fdl.ModelSpec( inputs=['context', 'response'], custom_features=fiddler_custom_features, ) ``` **Generated Columns:** | Column | Type | Description | | ------------------------------- | ----- | ---------------------------------------------------------------------------------------------------------- | | FDL Faithfulness faithful | bool | Binary metric, which is True if the facts used in `response` are correctly used from the `context` columns | | FDL Faithfulness faithful score | float | Confidence probability of faithfulness prediction | *** ### Token Count The Token Count enrichment counts the number of tokens in a string. This enrichment uses the [tiktoken](https://github.com/openai/tiktoken) library for token counting. **Python Configuration:** ```python theme={null} import fiddler as fdl fiddler_custom_features = [ fdl.Enrichment( name='TokenCount', enrichment='token_count', columns=['question'], ), ] model_spec = fdl.ModelSpec( inputs=['question'], custom_features=fiddler_custom_features, ) ``` **Generated Columns:** | Column | Type | Description | | --------------------------- | ---- | ------------------------------ | | FDL Token Counts (question) | int | Number of tokens in the string | *** ### SQL Validation The SQL Validation enrichment is designed to evaluate different query dialects for syntax correctness. Query validation is syntax based and does not check against any existing schema or databases for validity. **Python Configuration:** ```python theme={null} import fiddler as fdl # The following dialects are supported: # 'athena', 'bigquery', 'clickhouse', 'databricks', 'doris', 'drill', 'duckdb', # 'hive', 'materialize', 'mysql', 'oracle', 'postgres', 'presto', 'prql', # 'redshift', 'risingwave', 'snowflake', 'spark', 'spark2', 'sqlite', # 'starrocks', 'tableau', 'teradata', 'trino', 'tsql' fiddler_custom_features = [ fdl.Enrichment( name='SQLValidation', enrichment='sql_validation', columns=['query_string'], config={ 'dialect': 'mysql' } ), ] model_spec = fdl.ModelSpec( inputs=['query_string'], custom_features=fiddler_custom_features, ) ``` **Generated Columns:** | Column | Type | Description | | -------------------- | ---- | ----------------------------------------------------------------------------------------------------------------------------------- | | SQL Validator valid | bool | True if the query string is syntactically valid for the specified dialect, False if not | | SQL Validator errors | str | If syntax errors are found they will be present as a JSON serialized string containing a list of dictionaries describing the errors | *** ### JSON Validation The JSON Validation enrichment is designed to validate JSON for correctness and optionally against a user-defined schema for validation. This enrichment uses the [python-jsonschema](https://python-jsonschema.readthedocs.io) library for JSON schema validation. The defined `validation_schema` must be a valid python-jsonschema schema. **Python Configuration:** ```python theme={null} import fiddler as fdl fiddler_custom_features = [ fdl.Enrichment( name='JSONValidation', enrichment='json_validation', columns=['json_string'], config={ 'strict': 'true', 'validation_schema': { '$schema': 'https://json-schema.org/draft/2020-12/schema', 'type': 'object', 'properties': { 'prop_1': {'type': 'number'} # ... additional properties }, 'required': ['prop_1'], # ... additional required fields 'additionalProperties': False } } ), ] model_spec = fdl.ModelSpec( inputs=['json_string'], custom_features=fiddler_custom_features, ) ``` **Generated Columns:** | Column | Type | Description | | --------------------- | ---- | ------------------------------------------------------------------------------------------------------------------- | | JSON Validator valid | bool | String is valid JSON | | JSON Validator errors | str | If the string failed to parse to JSON any parsing errors will be returned as a serialized JSON list of dictionaries | # LLM Monitoring Source: https://docs.fiddler.ai/observability/llm/index Explore our guide to LLM application monitoring. Learn how Fiddler generates enrichments using trust and safety metrics for alerting, analysis, and debugging. ### Monitoring LLM Applications with Fiddler Monitoring Large Language Model (LLM) applications with Fiddler requires publishing the LLM application's inputs and outputs, including prompts, prompt context, responses, and the source documents retrieved (for RAG-based applications). Fiddler will then generate enrichments, which are LLM trust and safety metrics, for alerting, analysis, or debugging purposes. Fiddler is a pioneer in the AI Trust domain and, as such, offers the most extensive set of AI safety and trust metrics available today. ### Selecting Enrichments to Enhance Monitoring Fiddler offers many enrichments that each measure different aspects of an LLM application. For detailed information about which enrichment to select for any specific use case, visit [this](/observability/llm/selecting-enrichments) page. Some enrichments use Fiddler Centor Models to generate these scores. Compare Centor Models cost to third-party LLM evaluators with the [Fiddler Evals TCO calculator](https://www.fiddler.ai/evals-tco-calculator). ### Generating Enrichments with Fiddler LLM application owners must specify the enrichments to be generated by Fiddler during model onboarding. The enrichment pipeline then generates enrichments for the LLM application's inputs and outputs as events are published to Fiddler. Fiddler Enrichment Framework diagram displaying sample inputs and outputs flowing into the Fiddler enrichment pipeline. Figure 1. The Fiddler Enrichment Framework After the LLM application's raw, unstructured inputs and outputs are published to Fiddler, the enrichment framework augments them with various AI trust and safety metrics. These metrics can monitor the application's overall health and alert users to any performance degradation. Fiddler dashboard showing LLM application performance using enrichment metrics. Figure 2. A Fiddler dashboard showing LLM application performance Using the metrics produced by the enrichment framework, users can monitor LLM application performance over time and conduct root-cause analysis when problematic trends are identified. During model onboarding, application owners can opt in to the various, ever-expanding Fiddler enrichments by specifying [Enrichments](/observability/llm/enrichments) as custom features in the Fiddler ModelSpec object. # LLM-Based Metrics Source: https://docs.fiddler.ai/observability/llm/llm-based-metrics Explore our guide on LLM-specific metrics useful for evaluating AI-generated content for use cases like chatbots, writing assistants, or content creation tools. For a complete reference of all LLM enrichments, see the [LLM Observability Metrics Reference](/reference/llm-observability-metrics). LLM-based metrics use large language models to evaluate the quality of text generated by AI. This approach is much closer to how humans judge text, making these metrics particularly useful for evaluating AI-generated content for use cases such as chatbots, writing assistants, or content creation tools. LLM-based metrics can adapt to different topics and types of text because LLMs have been trained on a wide range of information, making them a valuable tool for developers and researchers looking to enhance the quality of AI-generated text. Currently, Fiddler supports three types of LLM-based metrics: LLM-as-a-Judge evaluators (including RAG Health Metrics), OpenAI-based enrichments, and Fiddler Centor Model metrics. ## RAG Health Metrics (LLM-as-a-Judge Evaluators) RAG Health Metrics are a purpose-built diagnostic triad for evaluating RAG applications. These evaluators use LLM-as-a-Judge approaches and are available in **Agentic Monitoring** and **Experiments**: * **Answer Relevance 2.0** — Ordinal scoring (High/Medium/Low = 1.0/0.5/0.0) measuring how well the response addresses the query. Also available in LLM Observability. * **Context Relevance** — Ordinal scoring measuring whether retrieved documents support the query. Available in Agentic Monitoring and Experiments only. * **RAG Faithfulness** — Binary scoring (Yes/No = 1/0) assessing whether the response is grounded in retrieved documents. Also available in LLM Observability. See [RAG Health Diagnostics](/concepts/rag-health-diagnostics) for a conceptual guide to using these evaluators together for root cause analysis. **RAG Faithfulness vs Faithfulness (Centor Model):** These are **separate evaluators** with different architectures. RAG Faithfulness is an LLM-as-a-Judge evaluator using external LLMs with inputs `user_query`, `rag_response`, and `retrieved_documents`. Faithfulness (Centor Model) (below) is powered by the Centor Model for Faithfulness using `context` and `response`. See the [enrichment glossary](/glossary/enrichment) for a detailed comparison. ## OpenAI-based metrics * These metrics are generated through the OpenAI API, which may introduce latency due to network communication and processing time. * OpenAI API access token MUST BE provided by the user, which will be configured during onboarding. * The specific model to be used for these metrics will also be chosen during onboarding. Currently, the below metrics are OpenAI-based: * [Answer Relevance](/observability/llm/enrichments#answer-relevance) * [Faithfulness](/observability/llm/enrichments#faithfulness) * [Coherence](/observability/llm/enrichments#coherence) * [Conciseness](/observability/llm/enrichments#conciseness) ## Fiddler Centor Model metrics * These metrics are generated through Fiddler's in-house, purpose-built SLMs. * These metrics can be generated in air-gapped environments and do not rely on any over-the-network connection to generate such scores. Currently, the below metrics are Fiddler Centor Model-based: * [Safety](/observability/llm/enrichments#safety) — Evaluates safety across 11 dimensions including jailbreaking, toxicity, and harmful content. Powered by the Centor Model for Safety. * [Faithfulness (Centor Model)](/observability/llm/enrichments#faithfulness-centor-model) — Powered by the Centor Model for Faithfulness for hallucination detection. Not to be confused with RAG Faithfulness above. # LLM Evaluation Prompt Specs Source: https://docs.fiddler.ai/observability/llm/llm-evaluation-prompt-specs Prompt specs is a framework Fiddler provides for leveraging a general-purpose LLM to quickly create custom scoring functions without the need to manually tune an evaluation prompt. ## The Challenge With LLM Evaluation When building production LLM applications, evaluation is critical, but it's often the most time-consuming bottleneck in your development workflow. Traditional approaches to creating LLM-as-a-Judge evaluators require you to: * **Hand-craft natural language prompts** for each new use case or data schema * **Iteratively tune prompts** through trial-and-error until the model produces reliable outputs * **Manually rewrite entire prompt templates** every time your input fields or output categories change * **Struggle with inconsistent results** as small prompt variations lead to unpredictable model behavior * **Spend weeks perfecting prompts** before you can move to production monitoring This manual process doesn't scale when you need to evaluate multiple aspects of your LLM application or adapt to evolving requirements. ## How Prompt Specs Solve This Problem Fiddler's Prompt Specs eliminate the prompt engineering bottleneck by letting you **declare your evaluation logic using simple JSON schemas** instead of writing prompts. Here's the key difference: ### Manual Prompt Engineering (Traditional Approach) ``` You are an expert classifier. Given a news summary, classify it into one of these topics: World, Sports, Business, Technology. News summary: {news_summary} Consider the main subject matter and classify accordingly. Provide your reasoning. Output format: Topic: [your classification] Reasoning: [your explanation] ``` *Every schema change requires rewriting and retuning the entire prompt* ### Schema-Based Evaluation Using Prompt Specs ```json theme={null} { "input_fields": { "news_summary": { "type": "string" } }, "output_fields": { "topic": { "type": "string", "choices": ["Business", "Sci/Tech", "Sports", "World"] }, "reasoning": { "type": "string" } } } ``` *Schema changes are simple JSON updates—no prompt rewriting needed* ## When to Use Prompt Specs Prompt Specs are ideal for scenarios where you need: **Domain-Specific Classification** * Content moderation with custom policy categories for example finance-specific metrics * Topic classification * Product categorization using your taxonomy **Quality Assessment** * Response relevance scoring for your specific use case * Conciseness and coherence evaluation * Completeness checking for required information elements **Safety and Compliance** * Custom content policy enforcement * Regulatory compliance checking (e.g., financial disclosures, medical claims) * Brand safety evaluation with organization-specific criteria Prompt Specs work particularly well when you need multiple output fields, such as confidence ranges and reasoning, alongside the classification and when classification accuracy is more important than the flexibility of fully custom prompts. ## Benefits for Technical Teams **Faster Development Cycles** * Reduce evaluation setup from weeks to hours * Eliminate iterative prompt tuning cycles * Enable rapid schema evolution without prompt rewrites **Improved Reliability** * Consistent structured output guaranteed by schema validation * Higher classification accuracy compared to guided choice decoding * Built-in reasoning capture for debugging and explainability **Better Maintainability** * Version control friendly JSON schemas * Clear separation between evaluation logic and implementation * Seamless integration with existing Fiddler monitoring workflows ## Benefits for Risk and Compliance Teams **Enhanced Auditability** * Clear, declarative evaluation criteria in version-controlled schemas * Consistent evaluation logic across all model versions * Traceable reasoning for every evaluation decision **Improved Governance** * Schema-based approach prevents evaluation drift over time * Standardized evaluation framework across teams and use cases * Integration with Fiddler's monitoring and alerting capabilities for continuous oversight **Regulatory Compliance** * Documented evaluation criteria that can be reviewed by compliance teams * Consistent application of evaluation logic for audit purposes * Historical tracking of schema changes and their impacts on evaluation outcomes ## How Prompt Specs Work Prompt Specs follow a simple three-step workflow that takes you from evaluation idea to production monitoring: ### 1. Define Your Evaluation Schema Create a JSON schema specifying your input fields and desired output format. Supported field types include: * `string` (with optional `choices` array for categorical outputs) * `integer` * `boolean` * `number` ### 2. Validate and Test Your Schema Use Fiddler's validation and prediction APIs to ensure your schema works correctly with sample data. ### 3. Deploy for Production Monitoring Deploy your validated Prompt Spec as a Fiddler [enrichment](/glossary/enrichment) for ongoing monitoring. **Ready to try it yourself?** Follow our step-by-step [Quickstart Guide](/evaluate-and-test/prompt-specs-quick-start) to build your first evaluation in minutes. ## Performance and Cost Considerations ### Prompt Specs Benefits * **Higher accuracy**: Classification accuracy is very high using meaningful field names and labels * **Consistent structure**: Yields reliably structured LLM output without guided decoding * **Performance optimization**: System prompts remain consistent across invocations, enabling KV caching benefits * **Customization**: Easy to add descriptions to fields and tasks for better accuracy **Trade-offs:** * Structured output is not 100% guaranteed * Less flexibility than fully custom prompts for highly nuanced evaluations * Best suited for classification and structured scoring tasks rather than open-ended evaluation ## Integration With Fiddler's Monitoring Platform Prompt Specs integrate seamlessly with Fiddler's existing monitoring capabilities: **Enrichment Pipeline Integration** * Deploy Prompt Specs as [enrichments](/glossary/enrichment) alongside other Fiddler [trust and safety metrics](/glossary/trust-score) * Combine schema-based evaluations with [built-in enrichments](/observability/llm/enrichments) like toxicity detection and PII identification * Use evaluation results in [alerting rules](/observability/platform/alerts-platform) and [dashboard visualizations](/observability/dashboards) **Monitoring and Alerting** * Set up automated alerts based on Prompt Spec outputs (e.g., alert when helpfulness scores drop below threshold) * Track evaluation trends over time alongside other model performance metrics * Use reasoning outputs for [root cause analysis](/observability/analytics) when issues are detected ## Validation Rules and Schema Requirements When creating Prompt Specs, ensure your schema follows these rules: * **Required fields**: Input fields and output fields must each have at least one item * **Field naming**: Field names must be valid Python variable names * **Uniqueness**: Field names must be unique between input and output sections * **Type specification**: `type` is required for all fields and must be one of: `string`, `integer`, `number`, `boolean` * **Optional elements**: Top-level `task_instruction` and field-level `description` are optional * **Choices arrays**: Must have at least 2 items and are only allowed when `type` is `string` ## When Not to Use Prompt Specs Prompt Specs may not be the best choice when: * You need highly nuanced evaluation requiring extensive domain context that can't be captured in field descriptions * Your evaluation criteria change frequently and unpredictably in ways that require prompt-level modifications * You require real-time evaluation with sub-100ms latency requirements * Your use case is already well-served by existing Fiddler enrichments like Faithfulness (Centor Model) * You need the full flexibility of custom prompt templates ## Comparison With Other Evaluation Approaches | Approach | Setup Time | Accuracy | Consistency | Flexibility | Maintenance | | ----------------------------- | ---------- | --------- | ----------- | ----------- | ----------- | | **Prompt Specs** | Hours | High | High | Medium | Low | | **Manual Prompt Engineering** | Weeks | Very High | Medium | Very High | High | | **Pre-built Enrichments** | Minutes | High | High | Low | None | Prompt Specs occupy a sweet spot between the quick deployment of pre-built enrichments and the full customization of manual prompt engineering, making them ideal for customers who need domain-specific evaluation without extensive prompt tuning effort. ## Getting Started ### Prompt Specs Quick Start The fastest way to get started is with the Prompt Spec Quick Start Guide: **🚀** [**Follow the Quickstart Guide**](/evaluate-and-test/prompt-specs-quick-start) - Build and deploy your first evaluation in minutes # Selecting Enrichments Source: https://docs.fiddler.ai/observability/llm/selecting-enrichments Learn about Fiddler’s enrichments and monitor key aspects of LLM applications. Discover the different factors to analyze for your specific use case. For a complete reference of all LLM enrichments with output columns and sub-metrics, see the [LLM Observability Metrics Reference](/reference/llm-observability-metrics). Fiddler offers enrichments out of the box to monitor different aspects of LLM applications. Use the below table to select the right enrichment for your specific use case. This table provides high level information on the metric, the enrichment to use to measure the metric, if the metric uses LLMs, and if so, what LLM it uses. If you have a use case not covered by the below enrichments out of the box, please contact your administrator. | Metric | Metric Category | Description | Enrichment | LLM Used? | LLM Type | | --------------------------------------------------------------------------------------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | --------- | ------------ | | [Faithfulness](/observability/llm/enrichments#faithfulness) | Hallucination | This enrichment identifies the accuracy and reliability of facts presented in AI-generated texts | `faithfulness` | Yes | OpenAI | | [Faithfulness (Centor Model)](/observability/llm/enrichments#faithfulness-centor-model) | Hallucination | This enrichment identifies the accuracy and reliability of facts presented in AI-generated texts. It is powered by the Centor Model for Faithfulness | `ftl_response_faithfulness` | Yes | Centor Model | | [Answer Relevance](/observability/llm/enrichments#answer-relevance) | Hallucination | This enrichment measures the pertinence of AI-generated responses to their inputs | `answer_relevance` | Yes | OpenAI | | [Conciseness](/observability/llm/enrichments#conciseness) | Hallucination | This enrichment evaluates the brevity and clarity of AI-generated responses | `conciseness` | Yes | OpenAI | | [Coherence](/observability/llm/enrichments#coherence) | Hallucination | This enrichment assesses the logical flow and clarity of AI-generated responses | `coherence` | Yes | OpenAI | | [Safety](/observability/llm/enrichments#safety) | Safety | This enrichment generates 11 different safety metrics to measure texts upon. These metrics are: `illegal, hateful, harassing, racist, sexist, violent, sexual, harmful, unethical, jailbreaking, roleplaying` | `ftl_prompt_safety` | Yes | Centor Model | | [PII](/observability/llm/enrichments#personally-identifiable-information) | Safety | This enrichment flags the presence of sensitive information within textual data | `pii` | No | | | [Regex Match](/observability/llm/enrichments#regex-match) | Safety | This enrichment compares the text with a regular expression string | `regex_match` | No | | | [Topic](/observability/llm/enrichments#topic) | Safety | This enrichment classifies the text into several preset dimensions using a zero-shot classifier | `topic_model` | No | | | [Banned Keywords](/observability/llm/enrichments#banned-keyword-detector) | Safety | This enrichment detects the presence of banned keywords configured by the user | `banned_keywords` | No | | | [Profanity](/observability/llm/enrichments#profanity) | Safety | This enrichment flags the use of offensive or inappropriate language | `profanity` | No | | | [Language Detection](/observability/llm/enrichments#language-detector) | Safety | This enrichment identifies the language of the source text | `language_detection` | No | | | [Evaluate](/observability/llm/enrichments#evaluate) | Text Statistics | This enrichment provides classic text evaluation methods such as BLEU, ROUGE, and Meteor | `evaluate` | No | | | [Sentiment](/observability/llm/enrichments#sentiment) | Text Statistics | This enrichment provides sentiment analysis of the target text | `sentiment` | No | | | [TextStat](/observability/llm/enrichments#textstat) | Text Statistics | This enrichment provides various text statistics such as character/letter count, Flesch-Kincaid, and others | `textstat` | No | | | [Token Count](/observability/llm/enrichments#token-count) | Text Statistics | The Token Count enrichment is designed to count the number of tokens in a string. | `token_count` | No | | | [SQLValidation](/observability/llm/enrichments#sql-validation) | Text Validation | Evaluates different query dialects for syntax correctness. | `sql_validation` | No | | | [JSONValidation](/observability/llm/enrichments#json-validation) | Text Validation | Validates JSON for correctness and optionally against a user-defined schema. | `json_validation` | No | | # Model UI Source: https://docs.fiddler.ai/observability/model-ui/index Learn about Fiddler's no-code Model Editor for streamlined ML model onboarding, featuring draft mode for iterative development and team collaboration. ### Adding and Editing Models in the UI #### Overview UI-based Model Onboarding lets you add models to Fiddler without writing Python code. You can define schemas, validate data, and register models directly through the Fiddler interface—making model onboarding accessible to more team members and streamlining the process. Key benefits: * No coding required - Onboard models through an intuitive web interface * Faster deployment - Use automatic schema inference and guided validation to reduce setup time * Early error detection - Identify issues like missing categories, incorrect ranges, or invalid data types immediately * Draft mode flexibility - Save work-in-progress schemas, consult with your team, and validate sample data before publishing ### Model Onboarding Modes Fiddler offers two approaches to model onboarding through the UI: Standard Onboarding and enhanced Draft Mode. #### Standard Onboarding With Standard Onboarding, you proceed directly through the complete process by: * Uploading your dataset * Reviewing the inferred schema * Making necessary adjustments * Publishing the model immediately #### Draft Mode Draft Mode provides additional flexibility when you need to refine your model configuration before publication: * Iterate without commitment - Save a draft version to refine column names, data types, and inferred ranges * Collaborate with your team - Share and review the draft before finalizing * Validate with sample data - Upload sample data to visualize charts and validate before production rollout * Refine as needed - Return to the onboarding process to make additional adjustments at any time #### Technical Considerations * File size limits: CSV uploads are limited to 2 GB * Schema validation: All fundamental schema mismatches must be corrected before publication * Draft limitations: While you can visualize sample data in drafts, some features like saving charts have limitations For detailed instructions and best practices, see the [Model Editor](/observability/model-ui/model-editor) documentation. # Model Editor Source: https://docs.fiddler.ai/observability/model-ui/model-editor Step-by-step instructions for onboarding ML models using Fiddler's UI-based editor, from dataset upload to schema validation and publication. ## Model Onboarding Process 1. Access your project * Sign in to Fiddler and navigate to the Projects tab * Select an existing project or create a new one 2. Add a model * Select Add Model in the top-right corner * Choose a model task type: Not Set, Regression, Binary Classification, or Multi-Class Classification 3. Upload and analyze your dataset * Upload your CSV file * Review the automatically inferred schema * Verify flagged columns that need additional attention 4. Choose your onboarding approach * For immediate publication: Enter a model name and select Create Model * For draft mode: Select Save as Draft 5. Work with your draft (Draft Mode) * Access your draft from the Draft Models tab * Edit schema details as needed * Publish sample data to validate your configuration * When ready, publish the finalized model For specific details and best practices see the [Model Schema Editing Guide](/observability/model-ui/model-schema-editing). # Model Schema Editing Source: https://docs.fiddler.ai/observability/model-ui/model-schema-editing Learn how to modify numeric ranges, edit categorical features, and add metadata columns to keep your model schema aligned with evolving production data. ## Overview This guide explains how to edit your model's schema in Fiddler to better align with production data. Schema editing helps you maintain accurate monitoring as your data evolves. Key capabilities * Adjust numeric feature ranges when real-world data deviates from your original sample data * Edit categorical feature values to add or remove categories as new patterns emerge * Add metadata columns to include additional contextual information for improved insights * Customize histogram bin boundaries for numerical columns to better represent data distributions ### Adjusting numeric feature ranges **Access the Schema tab** 1. Navigate to the Model Page of your desired model 2. Select the Schema tab **Edit numeric column range** 1. Find the numeric column you want to adjust 2. Select the edit icon (✏️) next to the column name 3. In the dialog box, modify the minimum and/or maximum values 4. Select Update to save your changes **Impact of changes** * **Data drift metrics**: Changes apply to all data, including historical data * A job will run to recalculate aggregates and update metrics * **Data integrity metrics**: Changes only apply to new data going forward #### Editing histogram bins You can customize the histogram bin boundaries for numerical columns to better represent your data distribution (e.g., quantile-based bins instead of uniform). **Edit bins for a numeric column** 1. Find the numeric column you want to adjust 2. Select the edit icon (✏️) next to the column name 3. In the dialog box, enter comma-separated bin boundary values in the **Bins** field * Example: `350, 450, 550, 650, 750, 850` * Values must be strictly increasing, span the column's \[min, max] range, and have at most 16 boundary values (15 bins) 4. To revert to auto-generated uniform bins, clear the Bins field 5. Select Update to save your changes **Impact of changes** * **Data drift metrics**: Changes apply to all data, including historical data * A job will run to recalculate aggregates and update histogram metrics * **Feature distribution charts**: Histogram visualizations will use the new bin boundaries #### Editing categorical variables **Access the Schema tab** 1. Navigate to the Model Page of your desired model 2. Select the **Schema** tab **Edit categorical column** 1. Locate the categorical column you want to modify 2. Select the edit icon (✏️) next to the column name 3. Add or remove categories as needed 4. Select Update to save your changes **Impact of changes** * For both data drift and data integrity metrics: * Changes only apply to new data going forward * Historical data remains unchanged #### Adding metadata columns **Access the Schema tab** 1. Navigate to the Model Page of your desired model 2. Select the Schema tab **Add a Metadata Column** 1. Select Add Metadata 2. Provide the required information: * Column Name: Specify the name of the new metadata column * Data Type: Choose a data type (integer, float, string, or boolean) * Range: For numeric types, define minimum and maximum values 3. Select Add to save **Impact of Changes** * New metadata columns are effective immediately for new data ### Best Practices * Analyze production data to set realistic range values and identify useful metadata columns * Monitor metrics after adjustments to ensure changes effectively address your needs * Use chart annotations for transparency to maintain a clear history of schema changes Schema updates that change numeric column properties (min, max, bins) trigger re-computation of historical aggregates. Models with more than 10 million events in any environment are not eligible for these updates. Contact support for assistance with large-scale schema changes. ### Frequently Asked Questions **Can I change column names or data types?** No, changing column names or data types is not supported. **What if I make a mistake?** You can edit the values again and save the updated schema. **How long do changes take to apply?** Application time depends on dataset size and complexity. For example, processing 10 million rows over six months takes approximately 12 minutes. **Can I delete a metadata column?** No, metadata columns cannot be deleted once added. **Can I customize histogram bins?** Yes, you can set custom bin boundaries for numerical columns via the Bins field in the schema editor, or programmatically via the Python client using `model.update()`. Leave the field empty to use auto-generated uniform bins. **What happens if I add a category that doesn't exist in the data?** The category will be listed but won't impact existing calculations. # Overview Source: https://docs.fiddler.ai/observability/monitoring Monitor production models in real-time with comprehensive observability The future of AI is agentic—autonomous systems that reason, plan, and coordinate across multiple agents to solve complex problems. Fiddler Observability is built for this future, providing comprehensive monitoring across traditional ML models, LLM applications, and emerging multi-agent systems. ## The Challenge: Exponential Complexity As AI evolves from static models to autonomous agents, observability complexity grows exponentially: * **Multi-agent systems require [26x more monitoring resources](https://www.capgemini.com/insights/expert-perspectives/ai-lab-the-efficient-use-of-tokens-for-multi-agent-systems/)** than single-agent applications * **Non-deterministic behavior** breaks traditional APM frameworks designed for predictable code * **Cascading failures** across agent hierarchies create unprecedented debugging challenges * **[90% of enterprises](https://www.pwc.com/us/en/tech-effect/ai-analytics/ai-agent-survey.html)** cite security, trust, and compliance as top concerns for agentic AI Fiddler provides the unified observability platform that scales from simple models to complex agentic workflows—all powered by the same family of Fiddler Centor Models. ## Agentic Observability Fiddler's agentic observability provides hierarchical visibility into multi-agent systems, tracking the complete lifecycle of autonomous reasoning and coordination. ### The Five Observable Stages Every agent operates through five distinct stages that require specialized monitoring: ```mermaid theme={null} graph LR Thought[1. Thought
Ingest, Retrieve, Interpret] --> Action[2. Action
Plan and Select Tools] Action --> Execute[3. Execution
Perform Tasks] Execute --> Reflect[4. Reflection
Evaluate and Adapt] Reflect --> Align[5. Alignment
Enforce Trust & Safety] Align -.->|Next Iteration| Thought style Thought fill:#e1f5ff style Action fill:#fff4e6 style Execute fill:#e6ffe6 style Reflect fill:#f0e6ff style Align fill:#ffe6e6 ``` **Stage-by-Stage Observability:** 1. **Thought**: Monitor how agents ingest data, retrieve context, and interpret information 2. **Action**: Track planning processes, tool selection, and decision-making logic 3. **Execution**: Observe task performance, API calls, and external integrations 4. **Reflection**: Capture self-evaluation, learning signals, and adaptation decisions 5. **Alignment**: Verify trust, safety, and policy enforcement at every step ### Hierarchical Monitoring Architecture Agentic systems operate across multiple levels of abstraction. Fiddler provides observability at each layer: ```mermaid theme={null} graph TD App[Application Level
Overall system performance & health] App --> Session1[Session Level
User interaction & conversation flow] App --> Session2[Session Level
Parallel user sessions] Session1 --> Agent1[Agent Level
Individual agent behavior & decisions] Session1 --> Agent2[Agent Level
Multi-agent coordination] Agent1 --> Span1[Span Level
Tool calls, LLM requests, actions] Agent1 --> Span2[Span Level
Granular operation tracing] Agent2 --> Span3[Span Level
Inter-agent communication] style App fill:#0891b2,color:#fff style Session1 fill:#06b6d4 style Session2 fill:#06b6d4 style Agent1 fill:#22d3ee style Agent2 fill:#22d3ee style Span1 fill:#a5f3fc style Span2 fill:#a5f3fc style Span3 fill:#a5f3fc ``` **Hierarchical Root Cause Analysis:** * Trace issues from user-facing symptoms down to individual tool calls * Understand cross-agent dependencies and coordination failures * Analyze patterns across sessions to identify systemic issues * Full context preservation for debugging non-deterministic behavior ### Framework & Integration Support **Supported Frameworks:** * **LangGraph** - Full SDK integration with native tracing * **Strands Agents** - Strands agent application monitoring * **OpenTelemetry** - Standard instrumentation for custom agents * **Custom Agents** - Fiddler Client SDK for any framework ## Unified Observability Platform All Fiddler observability capabilities—from traditional ML to agentic systems—are powered by a unified architecture built on Fiddler Centor Models: ```mermaid theme={null} graph TB subgraph Trust[Fiddler Centor Models] Safety[Centor Model for Safety
11 Dimensions] PII[Centor Model for PII/PHI
35+ Entities] Faith[Centor Model for Faithfulness
Hallucination Detection] Custom[Custom Metrics
Domain-Specific] end Trust --> ML[ML Observability
Drift, Performance, Integrity] Trust --> LLM[LLM Observability
Quality, Safety, RAG] Trust --> Agent[Agentic Observability
Lifecycle, Coordination, Trust] ML --> Dash[Unified Dashboards & Analytics] LLM --> Dash Agent --> Dash style Trust fill:#f0f0f0 style Safety fill:#e1f5ff style PII fill:#e1f5ff style Faith fill:#e1f5ff style Custom fill:#e1f5ff style ML fill:#fff4e6 style LLM fill:#e6ffe6 style Agent fill:#f0e6ff style Dash fill:#ffe6e6 ``` **Centor Models Advantages:** * **10-100x faster** than general-purpose LLMs for evaluation tasks * **Purpose-built models** optimized for safety, quality, and accuracy assessment * **Consistent, deterministic** evaluation at scale * **Air-gapped deployment** options for data sovereignty * **GDPR, HIPAA, CCPA** compliant monitoring ## Core Capabilities ### LLM Monitoring Comprehensive observability for generative AI applications with trust and safety at the core. **Key Features:** * **14+ Enrichment Metrics**: Auto-generated trust, safety, and quality scores * **RAG Monitoring**: Retrieval quality, source relevance, groundedness * **Embedding Analysis**: UMAP visualization, drift detection, clustering * **Prompt & Response Tracking**: Full conversation history and context **Trust & Safety Metrics:** * Safety (toxicity, jailbreaking, harmful content) * Privacy (PII/PHI detection across 35+ entity types) * Quality (faithfulness, coherence, conciseness, relevance) * Sentiment and tone analysis * [llm](/observability/llm) ### ML Model Observability Battle-tested monitoring for traditional machine learning models in production. **Key Features:** * **Drift Detection**: JSD and PSI metrics for distribution shifts * **Performance Tracking**: Accuracy, precision, recall, F1 across all deployments * **Data Integrity**: Missing values, type mismatches, range violations * **Traffic Monitoring**: Volume patterns and anomaly detection * **Vector Monitoring**: Specialized tools for embedding-based applications **Advanced Capabilities:** * Model segmentation and cohort analysis * Class imbalance handling * Statistical analysis (mean, std, distributions) * Model version comparison * Custom formula-based metrics * [platform](/observability/platform) ### Analytics & Root Cause Analysis Deep-dive investigation tools for understanding performance issues and data quality problems. **Four-Part Analysis Experience:** 1. **Events**: Browse sample of 1,000 recent events for pattern recognition 2. **Data Drift**: Feature-by-feature drift breakdown with prediction impact 3. **Data Integrity**: Violation summaries (range, type, missing value issues) 4. **Analyze**: Interactive charts for performance and feature analytics **Chart Types:** * Performance Analytics (confusion matrices, prediction scatterplots) * Feature Analytics (distributions, correlations, feature matrices) * Metric Cards (single KPI visualization) * [analytics](/observability/analytics) ### Dashboards & Visualization Customizable dashboards for monitoring your entire AI portfolio. **Features:** * **Auto-Generated Insights**: Every model gets an out-of-the-box dashboard * **Custom Dashboards**: Build your own views with flexible layouts * **Model Comparison**: Side-by-side performance tracking * **Multi-Column Plots**: Drift and integrity across all features * **Interactive Controls**: Date ranges, timezones, bin sizes, zoom * **Collaboration**: Save and share dashboards across teams * [dashboards](/observability/dashboards) ### Alerting & Response Proactive monitoring with intelligent alerting across all AI systems. **Alert Types:** * **Drift Alerts**: Detect distribution shifts in production data * **Data Integrity Alerts**: Flag missing values, type mismatches, range violations * **Performance Alerts**: Monitor accuracy degradation over time * **Custom Metric Alerts**: Formula-based alerts for business KPIs * **Traffic Alerts**: Volume and pattern anomaly detection **Alert Features:** * Warning and critical threshold configuration * Multiple notification channels (email, Slack, PagerDuty, webhooks) * Triggered revisions with real-time updates * Template-based alert creation * Alert history and audit logs ## Getting Started ### Choose Your Path **For LLM Applications:** * [LLM Monitoring Quick Start](/getting-started/llm-monitoring) - Set up enrichments and quality tracking * [LLM-Based Metrics Guide](/observability/llm/llm-based-metrics) - Configure trust and safety metrics **For Traditional ML Models:** * [ML Observability Quick Start](/getting-started/ml-observability) - Deploy drift detection and performance monitoring * [Monitoring Platform Guide](/observability/platform) - Configure alerts and data integrity checks **For Agentic Systems:** * [Agentic Monitoring Quick Start](/getting-started/agentic-monitoring) - Set up hierarchical tracing with LangGraph * [Agentic Observability Concepts](/glossary/agentic-observability) - Understand the agent lifecycle and monitoring approach ### Additional Resources **Platform Guides:** * [Analytics Deep Dive](/observability/analytics) - Root cause analysis and investigation * [Custom Dashboards](/observability/dashboards) - Build monitoring views for your team **Integration Documentation:** * [Python Client SDK Reference](/sdk-api/python-client/connection) - Programmatic access to all features # Alerts Source: https://docs.fiddler.ai/observability/platform/alerts-platform Discover how to enhance monitoring with Alerts. Learn about alert types and how to set up and view them using the alerts tab in the navigation bar. ### Overview Fiddler enables users to set up alert rules to track a model's health and performance over time. Fiddler alerts also enable users to dig into triggered alerts and perform root-cause analysis to identify what is causing a model to degrade. Users can set up alerts using the [Fiddler Python client SDK](/sdk-api/python-client/connection) and the Fiddler UI as demonstrated below. ### Supported Metric Types You can get alerts for the following metrics: * [**Traffic**](/observability/platform/traffic-platform) * The volume of traffic received by the model over time indicates the overall system's health. * [**Statistics**](/observability/platform/statistics) * Metrics for monitoring basic column aggregations. * [**Data Drift**](/observability/platform/data-drift-platform) * Model performance can be poor if models trained on a specific dataset encounter different data in production. * [**Data Integrity**](/observability/platform/data-integrity-platform) * Three types of violations can occur at model inference: missing feature values, type mismatches (e.g. sending a float input for a categorical feature type) or range mismatches (e.g. sending an unknown US State for a State categorical feature). * [**Performance**](/observability/platform/performance-tracking-platform) * The model performance tells us how well a model performs on its task. A poorly performing model can have significant business implications. * [**Custom Metrics**](/observability/platform/custom-metrics) * Create your own custom metric formulas and create Alerts on those metrics giving you ultimate flexibility in alerting behavior. ### Alert Configurations #### Comparison Types There are two options for alert threshold comparison: * **Absolute** — Compare the metric to an absolute value * Example: if traffic for a given hour is less than a threshold of 1,000, trigger alert. * **Relative** — Compare the metric to a previous period * Example: if traffic is down 10% or more than it was at the same time one week ago, trigger alert. #### Alert Rule Priority & Severity * **Priority**: Whether you're setting up an alert rule to keep tabs on a model in a test environment or for production scenarios, Fiddler has you covered. Easily set the Alert Rule Priority to indicate the importance of any given Alert Rule. Users can select from Low, Medium, and High priorities. * **Severity**: Up to two threshold values can be specified for additional flexibility. A **Critical** severity threshold value is always required when setting up an Alert Rule, and a **Warning** threshold value is optional. ### Why do we need alerts? * It’s not possible to manually track all metrics 24/7. * Sensible alerts are your first line of defense, and they are meant to warn about issues in production. #### Setting up Alert Rules To create a new alert in the Fiddler UI, click Add Alert on the Alerts tab. 1. Fill in the Alert Rule form with basic details like alert name, project, and model. 2. Choose an Alert Type (Traffic, Data Drift, Data Integrity, Performance, Statistic, or Custom Metric) and set up specific metrics, bin size, and columns. 3. Define comparison methods, thresholds, and notification preferences. Click Add Alert Rule to finish. In order to create and configure alerts using the Fiddler Python client SDK see [Alert Configuration with Fiddler Client](/developers/python-client-guides/alerts-with-fiddler-client). #### Alert Notification options You can select the following notification types for your alert. #### Delete an Alert Rule Delete an existing alert by clicking on the overflow button (⋮) on the right-hand side of any Alert Rule record and clicking `Delete`. To make any other changes to an Alert Rule, you will need to delete the alert and create a new one with the desired specifications. #### Triggered Alert Revisions Say goodbye to stale alerts! Triggered Alert Revisions mark a leap forward in alert intelligence, giving you the confidence to act decisively and optimize your operations. Alerts now adapt to changing data. If new information emerges that alters an alert's severity or value, the alert automatically updates you with highlights in the user interface and revised notifications. This approach empowers you to: * Make informed decisions based on real-time data: No more relying on outdated or inaccurate alerts. * Focus on critical issues: Updated alerts prioritize the most relevant information. Inspect Alert experience Inspect Alert experience Triggered Alert revision experience ### Sample Alert Email Here's a sample of an email that's sent if an alert is triggered: ### Integrations The Integrations tab is a read-only view of all the integrations your Admin has enabled for use. As of today, users can configure their Alert Rules to notify them via email or Pager Duty services. Admins can add new integrations by clicking on the setting cog icon in the main navigation bar and selecting the integration tab of interest. #### Pause alert notification This feature allows users to temporarily pause and resume notifications for specific alerts without affecting their evaluation and triggering mechanisms. It enhances user experience by providing efficient notification management.\\ **How to Use** **Using the Fiddler User Interface (UI)** * Locate the Alert Tool: Navigate to the alert rule table and identify the desired alert. * Toggle Notifications: * Click the notification bell icon. * The icon updates to indicate the new state (paused or resumed). * Confirm Action: * A loading indicator and a toast notification confirm the action. **Using the Fiddler Client SDK** For programmatic control, use the Fiddler client SDK's alert-rules method with the enable\_notification argument. * Details: Refer to the [Fiddler Python client SDK Reference](/sdk-api/langgraph/fiddler-client) for a complete explanation of SDK features. **Note** * No Impact on Evaluation: Pausing notifications does not affect the evaluation of alert conditions. The alert tool will continue to assess conditions and trigger alerts as usual. # Class Imbalanced Data Source: https://docs.fiddler.ai/observability/platform/class-imbalanced-data Explore how Fiddler uses weighting to help improve drift detection when class distribution is highly imbalanced. ### Discover How Class Imbalanced Data Impacts Feature Drift Drift is a measure of how different the production distribution is from the baseline distribution on which the model was trained. In practice, the distributions are approximated using histograms and then compared using divergence metrics like Jensen–Shannon divergence or Population Stability Index. Generally, when constructing the histograms, every event contributes equally to the bin counts. However, for scenarios with large class imbalance the minority class’ contribution to the histograms would be minimal. Hence, any change in production distribution with respect to the minority class would not lead to a significant change in the production histograms. Consequently, even if there is a significant change in distribution with respect to the minority class, the drift value would not change significantly. To solve this issue, Fiddler monitoring provides a way for events to be weighted based on the class distribution. For such models, when computing the histograms, events belonging to the minority class would be up-weighted whereas those belonging to the majority class would be down-weighted. ### Solving Issues with Class Imbalanced Data Fiddler has implemented two solutions for class imbalance use cases. #### Workflow 1: User provided global class weights * The user computes the class distribution on baseline data and then provides the class weights via the Model-Info object. * Class weights can either be manually entered by the user or computed from their dataset * To tease out drift in a class-imbalanced fraud use case, check the [class-imbalanced-notebook](/developers/tutorials/ml-monitoring/class-imbalance-monitoring-example) #### Workflow 2: User-provided event-level weights User provides event-level weights as a metadata column in baseline data and provides them while publishing events: * Users will add a `_weight` column of type metadata in the model's ModelSpec. * The baseline dataset requires this `_weight` column. Note that all rows must contain valid float values. We expect the user to enforce this assumption. * Note that using weighting parameters requires a model output in the baseline dataset. # Custom Metrics Source: https://docs.fiddler.ai/observability/platform/custom-metrics Dive into our guide to enhancing ML and LLM insights with custom metrics. Learn to define, add, access, modify, and delete custom metrics in charts and alerts. ### Overview Custom metrics offer the capability to define metrics that align precisely with your machine learning requirements. Whether it's tracking business KPIs, crafting specialized performance assessments, or computing weighted averages, custom metrics empower you to tailor measurements to your specific needs. Seamlessly integrate these custom metrics throughout Fiddler, leveraging them in dashboards, alerting, and performance tracking. Create user-defined metrics by employing a simple query language we call [Fiddler Query Language (FQL)](/observability/platform/fiddler-query-language). FQL enables you to leverage your model's features, metadata, predictions, and outcomes for new data fields using a rich array of aggregations, operators, and metric functions, thereby expanding the depth of your analytical insights. ### How to Define a Custom Metric Build custom metrics effortlessly with Fiddler's intuitive Excel-formula-like syntax. Once a custom metric is defined, Fiddler distinguishes itself by seamlessly managing time granularity and ranges within the charting, dashboarding, and analytics experience. This empowers you to effortlessly adjust time range and granularity without the need to modify your query, ensuring a smooth and efficient analytical experience. ### Adding a Custom Metric From the model schema page, you can access the model's custom metrics by clicking the **Custom Metrics** tab at the top of the page. Then click **Add Custom Metric** to add a new Custom Metric. Finally, enter the name, description, and FQL definition for your custom metric and click **Save**. ### Accessing Custom Metrics in Charts and Alerts After your custom metric is saved, you can use it in your chart and alert definitions. #### Charts Set `Metric Type` to `Custom Metric` and select your desired custom metric. #### Alerts When creating a new alert rule, set `Metric Type` to `Custom Metric`, and under the `Metric` field select your desired custom metric or author a new metric to use. ### Modifying Custom Metrics Since alerts can be set on Custom Metrics, making modifications to a metric may introduce inconsistencies in alerts. > 🚧 Therefore, custom metrics cannot be modified once they are created. If you'd like to try out a new metric, you can create a new one with a different name and definition. ### Deleting Custom Metrics To delete a custom metric using the Python client, see [CustomMetric.delete()](/sdk-api/python-client/connection). Alternatively, from the custom metrics tab, you can delete a metric by clicking the trash icon next to the metric record. ### Examples > 📘 Custom metrics must return either: > > * an aggregate (produced by aggregate functions or built-in metric functions) > * a combination of aggregates #### Simple Metric Given this example use case: > If an event is a false negative, assign a value of -40. If the event is a false positive, assign a value of -400. If the event is a true positive or true negative, then assign a value of 250. Create a new Custom Metric with the following FQL formula: ```text theme={null} average(if(fn(), -40, if(fp(), -400, 250))) ``` Fiddler offers many convenience functions such as `fp()` and `fn()`. Alternatively, we could also identify false positives and false negatives the old fashioned way. ```text theme={null} average(if(Prediction < 0.5 and Target == 1, -40, if(Prediction >= 0.5 and Target == 0, -400, 250))) ``` Here, we assume `Prediction` is the name of the output column for a binary classifier and `Target` is the name of our label column. #### Tweedie Loss In our next example, we provide an example implementation of the Tweedie Loss Function. Here, `Target` is the name of the target column and `Prediction` is the name of the prediction/output column. ```text theme={null} average((Target * Prediction ^ (1 - 0.5)) / (1 - 0.5) + Prediction ^ (2 - 0.5) / (2 - 0.5)) ``` #### Quantile/Percentile Metrics Quantile metrics are essential for understanding the distribution of your data and tracking percentile-based performance indicators. Unlike averages, which can be skewed by outliers, quantiles provide robust insights into the actual behavior of your model across different percentiles. **Use Case: Monitoring ML Model Latency** Track the median (50th percentile) inference time to understand typical model performance: ```text theme={null} quantile(inference_time_ms, level=0.5) ``` **Use Case: SLA Compliance Tracking** Monitor 95th percentile latency to ensure most requests meet performance SLAs: ```text theme={null} quantile(response_time_ms, level=0.95) ``` **Use Case: Outlier Detection** Track the 99th percentile of prediction scores to identify extreme predictions: ```text theme={null} quantile(prediction_score, level=0.99) ``` **Use Case: Statistical Distribution Analysis** Compute quartiles to understand the distribution of a feature or prediction: ```text theme={null} quantile(feature_value, level=0.25) # First quartile (Q1) quantile(feature_value, level=0.5) # Median (Q2) quantile(feature_value, level=0.75) # Third quartile (Q3) ``` > 📘 **Why use quantiles instead of averages?** > > Quantiles provide a more complete picture of your data's distribution. While averages can be heavily influenced by outliers, percentiles show you the actual values at specific points in your distribution. For example, a 95th percentile latency of 500ms means 95% of your requests complete in 500ms or less, regardless of how slow the remaining 5% might be. #### Gini Coefficient The Gini coefficient, derived from the Lorenz curve, measures how well a model's predicted scores rank actual values. It is available for all ML model task types, including regression. Higher values indicate better ranking ability (the normalized Gini coefficient yields 1 for a perfect model and 0 for a random model). `gini()` is available for ML custom metrics only. It is not supported for GenAI or agentic applications. Both `actual` and `predicted` are required keyword arguments of type `Number`. Column names must match your model schema exactly (case-sensitive). **Use case: Basic Gini coefficient** ```text theme={null} gini(actual=Target, predicted=Score) ``` **Use case: Normalized Gini coefficient** The `gini()` function returns the raw Gini coefficient. To obtain the normalized version — scaled so a perfect model yields 1 — divide by the ideal Gini where actuals are perfectly ranked by themselves: ```text theme={null} gini(actual=Target, predicted=Score) / gini(actual=Target, predicted=Target) ``` **Use case: Binary classification with categorical targets** For binary classification models where the target column is categorical (e.g. `'yes'`/`'no'`), use an `if` expression to convert to numeric 0/1 before passing to `gini()`: ```text theme={null} gini(actual=if(churn == 'yes', 1, 0), predicted=predicted_churn) / gini(actual=if(churn == 'yes', 1, 0), predicted=if(churn == 'yes', 1, 0)) ``` **Use case: Deriving normalized Gini from AUC (binary classification only)** For binary classification models, the normalized Gini coefficient is mathematically equivalent to `2 * AUC - 1`. You can use the built-in `auroc()` function to compute this directly without needing a separate `actual` column: ```text theme={null} 2 * auroc() - 1 ``` #### Min and Max Use `min()` and `max()` to compute the minimum or maximum value of a column or expression across all rows in a time window. **Use case: Feature range (spread)** Track how wide the distribution of a feature is over time. A growing range may indicate data drift. ```text theme={null} max(Prediction) - min(Prediction) ``` **Use case: Min/max ratio** Monitor how concentrated predictions are. A ratio close to 1 indicates a narrow spread; a ratio near 0 suggests extreme outliers are present. ```text theme={null} min(Prediction) / max(Prediction) ``` `min(x)` and `max(x)` aggregate a single expression **across rows**. To compare multiple already-computed aggregates, use `least(...)` and `greatest(...)` instead. #### Null-Safe Expressions Use the `null` keyword as a return value in conditional expressions to explicitly propagate missing data rather than substituting a placeholder. **Use case: Null-safe transformation** Apply a transformation to a column, but return `null` for rows where the input is missing instead of coercing a default value. ```text theme={null} average(if(is_null(Prediction), null, Prediction * 100)) ``` This computes the average only over rows where `Prediction` is non-null, which is equivalent to `average(Prediction) * 100` but makes the null-handling intent explicit. To test whether a value is null, always use `is_null(x)` or `is_not_null(x)`. The `null` keyword is intended for use as a **return value** only in the `if(condition, value, null)` expression. ### Modifying Custom Metrics Since alerts can be set on Custom Metrics, modifying a metric may introduce inconsistencies in those alerts. > 🚧 Therefore, custom metrics cannot be modified once they are created. If you'd like to try out a new metric, you can create a new one with a different name and definition. # Data Drift Source: https://docs.fiddler.ai/observability/platform/data-drift-platform Learn about data drift and how Fiddler can monitor your ML model data for drift to provide early detection of issues that could impact model performance. For a complete list of all built-in ML metrics including drift, see the [ML Metrics Reference](/reference/ml-metrics-reference). ### Monitor Model Performance Changes with Fiddler's Insights #### Monitoring Data Drift in ML Models Model performance can be poor if models trained on a specific dataset encounter different data in production. This is called data drift and it is a metric which is available on model inputs, outputs, and custom features. On the **Insights** dashboard for your model, Fiddler gives you a diverse set of visuals to explore different metrics. Fiddler monitoring dashboard Leverage the data drift chart to identify what data is drifting, when it’s drifting, and how it’s drifting. This is the first step in identifying possible model performance issues. Fiddler drift charts #### Drift Metrics Details Fiddler supports the following: * ***Drift Metrics*** * **Jensen–Shannon distance (JSD)** * A distance metric calculated between the distribution of a field in the [baseline](/glossary/baseline) and that same distribution for the time period of interest. For numerical columns, distributions are approximated using histograms with [configurable bin boundaries](/developers/python-client-guides/model-onboarding/customizing-your-model-schema#modifying-the-histogram-bins). * For more information on JSD, click [here](https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.jensenshannon.html). * **Population Stability Index (PSI)** * A drift metric based on the multinomial classification of a variable into bins or categories. For numerical columns, the bin boundaries can be customized via the column's `bins` property — see [Customizing Your Model Schema](/developers/python-client-guides/model-onboarding/customizing-your-model-schema#modifying-the-histogram-bins). By default, 10 uniform bins are auto-generated from the column's min and max values. The differences in each bin between the baseline and the time period of interest are then utilized to calculate it as follows: > 🚧 Note > > There is a possibility that PSI can shoot to infinity. To avoid this, PSI calculation in Fiddler is done such that each bin count is incremented with a base\_count=1. Thus, there might be a slight difference in the PSI values obtained from manual calculations. * ***Average Values*** – The mean of a field (feature or prediction) over time. This can be thought of as an intuitive drift score. * ***Drift Analytics*** – You can drill down into the features responsible for the prediction drift using the table at the bottom. * ***Feature Impact***: The contribution of a feature to the model’s predictions, averaged over the [baseline](/glossary/baseline). The contribution is calculated using random ablation feature impact. * ***Feature Drift***: Drift of the feature, calculated using the drift metric of choice. * ***Prediction Drift Impact***: A heuristic calculated using the product of the feature impact and the feature drift. The higher the score, the more this feature is likely to have contributed to the prediction drift. ### Determining Drift Root Cause In the Root Cause Analysis table of your drift charts, you can select a feature to see the feature distribution for both the time period under consideration and the baseline dataset. Feature drift chart with feature distribution comparison between baseline and production data ### Why Track Data Drift? * Data drift is a great proxy metric for **performance decline**, especially if there is delay in getting labels for production events. (e.g. In a credit lending use case, an actual default may happen after months or years.) * Monitoring data drift also helps you stay informed about **distributional shifts in the data for features of interest**, which could have business implications even if there is no decline in model performance. #### Taking Action on Observed Data Drift * High drift can occur as a result of *data integrity issues* (bugs in the data pipeline), or as a result of *an actual change in the distribution of data* due to external factors (e.g. a dip in income due to COVID). The former is more in our control to solve directly. The latter may not be solvable directly, but can serve as an indicator that further investigation (and possible retraining) may be needed. * You can drill down deeper into the data by examining it in the Analyze tab. # Data Integrity Source: https://docs.fiddler.ai/observability/platform/data-integrity-platform Dive into our guide on ensuring data integrity in ML models and LLMs. Learn to monitor violations with Fiddler’s auto-generated charts and alerts. For a complete list of all built-in ML metrics including data integrity, see the [ML Metrics Reference](/reference/ml-metrics-reference). ### Overview ML models are increasingly driven by complex feature pipelines and automated workflows that involve dynamic data. Data is transformed from source to model input which can result in data inconsistencies and errors. There are three types of violations that can occur at model inference: **missing values**, **type mismatches** (e.g. sending a float input for a categorical feature type) or **range violations** (e.g. sending an unknown US State for a State categorical feature). You can monitor all these violations with auto-generated Data Integrity charts and alerts, or create your own custom alerts and charts. The time series shown below tracks the violations of data integrity constraints set up for this model. ### What Is Being Tracked? Monitoring chart with missing values, type violations, and range violations The time series chart above tracks the violations of data integrity constraints set up for this model. Note that both raw count and percentage are available for data integrity metrics. * **Any Violation Any Column** — The count of any type of data integrity violation over all features for a given period of time. * **% Any Violation Any Column** — The percentage of any type of data integrity violation over all features for a given period of time. * **NULL Count Any Column** — The count of missing value violations over all features for a given period of time. * **Range Violation Count Any Column** — The count of range violations over all features for a given period of time. * **Type Violation Count Any Column** — The count of data type violations over all features for a given period of time. ### Why is it being tracked? Data integrity issues can cause incorrect data to flow into the model, leading to poor model performance and negatively impacting the business or end-user experience. ### How does it work? Setting up constraints for individual features when they number in the tens or hundreds can be tedious. To avoid this, the schema of a model is used as a reference to detect when features in the incoming production logs deviate from expected patterns established during model training. For example, feature values may be out of range (numerical inputs) or contain unknown values (categorical inputs). The minimums, maximums, and distinct categorical values for a model's features are collected during initial model onboarding and stored in the Fiddler model's `ModelSchema`. Monitoring chart with missing values, type violations, and range violations Fiddler will automatically generate constraints based on the data distribution of the sample data used to generate the model schema during model onboarding. * **Type mismatch**: A data integrity violation will be triggered when the type of a feature value differs from what was specified for that feature in the model's schema. * **Range mismatch**: * For categorical features, a data integrity violation will be triggered when it sees any value other than the ones specified in the model's schema. * For continuous variables, the violation will be triggered if the values are outside the range specified in the model's schema. * For [vector datatype](/observability/platform/vector-monitoring-platform), a range mismatch will be triggered when a dimension mismatch occurs compared to the expected dimension from the model's schema. # Embedding Visualization Source: https://docs.fiddler.ai/observability/platform/embedding-visualization-with-umap Dive into our guide on embedding visualization with UMAP in Fiddler. Learn to create charts, select parameters, and interact with visualizations. Example of embedding data rendered as a UMAP visualization chart. Embedding visualization is a powerful technique for understanding and interpreting complex relationships in high-dimensional data. Reducing the dimensionality of custom features into a 2D or 3D space makes identifying patterns, clusters, and outliers easier. In Fiddler, high-dimensional data like embeddings and vectors are ingested as a [custom feature](/observability/platform/vector-monitoring-platform#define-custom-features). Our goal in this document is to visualize these custom features. ### UMAP Technique for Embedding Visualization We use the [UMAP](https://umap-learn.readthedocs.io/en/latest/) (Uniform Manifold Approximation and Projection) technique for embedding visualizations. UMAP is a dimension reduction technique that is particularly good at preserving the local structure of the data, making it ideal for visualizing embeddings. We reduce the high-dimensional embeddings to a 3D space. UMAP is supported for both Text and Image embeddings using a custom feature ### Creating an Embedding Visualization Chart To create an embedding visualization chart, follow these steps: 1. Navigate to the **Charts** tab in your Fiddler AI instance 2. Click on the **Add Chart** button on the top right 3. In the modal, select the project that has a model with Custom features 4. Select **Embedding Visualization**. The Add Chart modal dialog form. #### Chart Parameters When creating an embedding visualization chart, you will need to specify the following parameters: * Model and model version * Embedding column * Display columns * Baseline * Segment * Date range * Sample size * Advanced fields * Number of neighbors * Minimum distance * Distance metric Please see below for details on these parameters. #### Model Select the model containing at least one embedding column. You may further refine to a model version if required. #### Embedding Column Choose the embedding column from your dataset that you wish to visualize. #### Display Columns Select the columns for which you want to display additional information when hovering over points in the visualization. When plot points are selected, these additional display columns will also be available in the data cards. #### Baseline Select a baseline for comparison. This is optional and will be helpful when comparing datasets, such as a pre-production dataset with a production dataset or two time periods in production. #### Segment Select an existing segment (or define a new segment) to filter the chart to a particular data cohort. This is optional, but it will be helpful when focusing on a specific cohort. #### Sample Size Decide the number of samples you want to include for performance and clarity in the visualization. Currently, sample sizes between 100 and 10,000 can be selected. In future releases, we will enable support for larger sample sizes. #### Number of Neighbors This parameter controls how UMAP balances local versus global structure in the data. It determines the number of neighboring points used in the manifold approximation. Low values of this parameter, such as 5, will lead UMAP to focus too much on the local structure, losing sight of the big picture. Conversely, bigger values will lead to a focus on the broader data. It is important to experiment on your dataset and use case to identify the value that provides the best results. Values from 2 to 100 are supported. #### Minimum Distance Controls how closely points can be placed to each other in the visualization. A smaller value (such as 0.1) allows points to cluster more tightly, revealing finer details and local structures in your data. A larger value forces points to spread out more evenly across the visualization space. ### Interactions on Embedding Visualization ### Choose Different Periods When generating the embedding visualization, you can choose different periods of production data to analyze. To do this: * Access the Date Range selector. * Choose the start and end dates for the period you are interested in. * The visualization will update to reflect the embeddings from the selected date range. The chart date range filter selector. ### Color By The 'Color By' feature enriches the visualization by categorizing your data points using different colors based on attributes. * Find the 'Color By' dropdown in your control panel. * Choose a categorical feature to color-code the data points. For example, select "data source" to color the data points according to whether they are baseline or production data. Using the 'Color By' feature can help uncover patterns in your data. For instance, in the above image, data points with varying 'target' column values demonstrate clustering, where similar values tend to group. You can also select points to delve deeper for further inspection. This ability to interactively color and select data points may be very useful for root cause analysis. ### Zoom Zooming in on the UMAP chart provides a closer look at clusters and individual data points. * Use the mouse scroll wheel to zoom in or out. * Click and drag the mouse to move the zoomed-in area around the chart. * Zooming helps to focus on areas of interest or to distinguish between closely packed points. ### Selection of Data Points You can select individual or groups of data points to analyze further. * Click on a data point to select it. Or use the Selector on the top right to select multiple points Example of embedding data rendered as a UMAP visualization with data points colored by category. ### Data Cards * Selected points will be highlighted on the chart, and details of the display columns of these cards are displayed in data cards, as shown below * Use this feature to identify and analyze specific data points In the following example, we use the categorical attribute "feedback", which contains three possible values: like, dislike, or None, as the legend indicates. After applying the 'color by' feature, the user selects specific data points to examine in greater detail. The selected data points are then presented as data cards below. Data cards displayed below UMAP chart upon data point selection. ### Hover on a Data Point Hovering over a data point reveals additional information about it, providing immediate insight without the need for selection. * Move the cursor over a data point on the chart * A tooltip will appear, displaying the data associated with that point, such as values of different display columns * Use this feature to quickly look up data without altering your current selection on the chart ## Saving the Chart Once you're satisfied with your visualization, you can save the chart. This chart can then be added to a dashboard. This allows you to revisit the UMAP visualization at any time easily, either directly from the Chart or from the dashboard. # Fiddler Query Language Source: https://docs.fiddler.ai/observability/platform/fiddler-query-language Explore our guide on using Fiddler Query Language to build custom metrics to drive additional business value in dashboards and extra capability in alerting. ## Overview [Custom Metrics](/observability/platform/custom-metrics) and [Segments](/observability/platform/segments) are defined using the **Fiddler Query Language (FQL)**, a flexible set of constants, operators, and functions which can accommodate a large variety of metrics. ## Definitions | Term | Definition | | ------------------ | -------------------------------------------------------------------------------------- | | Row-level function | A function which executes row-wise for a set of data. Returns a value for each row. | | Aggregate function | A function which executes across rows. Returns a single value for a given set of rows. | ## FQL Rules * Column names can be referenced by name either with double quotes ("my\_column") or with no quotes (my\_column). * Single quotes (') are used to represent string values. ## Data Types FQL distinguishes between three data types: | Data type | Supported values | Examples | Supported Model Schema Data Types | | --------- | --------------------------------------------------------- | ---------------------------------------------------------------------- | ---------------------------------------------------------------------------- | | Number | Any numeric value (integers and floats are both included) | \

\10\\
\2.34\\

| \

\DataType.INTEGER\\
\DataType.FLOAT\\

| | Boolean | Only `true` and `false` | \

\true\\
\false\\

| `DataType.BOOLEAN` | | String | Any value wrapped in single quotes (`'`) | \

\'This is a string.'\\
\'200.0'\\

| \

\DataType.CATEGORY\\
\DataType.STRING\\

| ## Constants | Symbol | Description | | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `true` | Boolean constant for true expressions | | `false` | Boolean constant for false expressions | | `null` | Represents an absent or missing value. Use as a return value in conditional expressions — for example: `if(is_null(x), null, x * 2)`. To test whether a value is null, use `is_null()` or `is_not_null()`. | ## Operators | Symbol | Description | Syntax | Returns | Examples | | ------- | ------------------------ | --------------------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | | `^` | Exponentiation | `Number ^ Number` | `Number` | \

\2.5 ^ 4\\
\(column1 - column2)^2\\

| | `-` | Unary negation | `-Number` | `Number` | `-column1` | | `*` | Multiplication | `Number * Number` | `Number` | \

\2 \* 10\\
\2 \* column1\\
\column1 \* column2\\
\sum(column1) \* 10\\

| | `/` | Division | `Number / Number` | `Number` | \

\2 / 10\\
\2 / column1\\
\column1 / column2\\
\sum(column1) / 10\\

| | `%` | Modulo | `Number % Number` | `Number` | \

\2 % 10\\
\2 % column1\\
\column1 % column2\\
\sum(column1) % 10\\

| | `+` | Addition | `Number + Number` | `Number` | \

\2 + 2\\
\2 + column1\\
\column1 + column2\\
\average(column1) + 2\\

| | `-` | Subtraction | `Number - Number` | `Number` | \

\2 - 2\\
\2 - column1\\
\column1 - column2\\
\average(column1) - 2\\

| | `<` | Less than | `Number < Number` | `Boolean` | \

\10 \< 20\\
\column1 \< 10\\
\column1 \< column2\\
\average(column2) \< 5\\

| | `<=` | Less than or equal to | `Number <= Number` | `Boolean` | \

\10 \<= 20\\
\column1 \<= 10\\
\column1 \<= column2\\
\average(column2) \<= 5\\

| | `>` | Greater than | `Number > Number` | `Boolean` | \

\10 > 20\\
\column1 > 10\\
\column1 > column2\\
\average(column2) > 5\\

| | `>=` | Greater than or equal to | `Number >= Number` | `Boolean` | \

\10 >= 20\\
\column1 >= 10\\
\column1 >= column2\\
\average(column2) >= 5\\

| | `==` | Equals | `Number == Number` | `Boolean` | \

\10 == 20\\
\column1 == 10\\
\column1 == column2\\
\average(column2) == 5\\

| | `!=` | Does not equal | `Number != Number` | `Boolean` | \

\10 != 20\\
\column1 != 10\\
\column1 != column2\\
\average(column2) != 5\\

| | `not` | Logical NOT | `not Boolean` | `Boolean` | \

\not true\\
\not column1\\

| | `and` | Logical AND | `Boolean and Boolean` | `Boolean` | \

\true and false\\
\column1 and column2\\

| | `or` | Logical OR | `Boolean or Boolean` | `Boolean` | \

\true or false\\
\column1 or column2\\

| ## Constant functions | Symbol | Description | Syntax | Returns | Examples | | ------ | ----------------------------------------------------- | ------ | -------- | --------------------------- | | `e()` | Base of the natural logarithm | `e()` | `Number` | `e() == 2.718281828459045` | | `pi()` | The ratio of a circle's circumference to its diameter | `pi()` | `Number` | `pi() == 3.141592653589793` | ## Row-level functions Row-level functions can be applied either to a single value or to a column/row expression (in which case they are mapped element-wise to each value in the column/row expression). | Symbol | Description | Syntax | Returns | Examples | | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------- | --------- | ------------------------------------------------------------------------------------------------------- | | `if(condition, value1, value2)` | \

Evaluates \condition\ and returns \value1\ if true, otherwise returns \value2\.\
\value1\ and \value2\ must have the same type.\

| `if(Boolean, Any, Any)` | `Any` | \

\if(false, 'yes', 'no') == 'no'\\
\if(column1 == 1, 'yes', 'no')\\

| | `length(x)` | Returns the length of string `x`. | `length(String)` | `Number` | `length('Hello world') == 11` | | `to_string(x)` | Converts a value `x` to a string. | `to_string(Any)` | `String` | \

\to\_string(42) == '42'\\
\to\_string(true) == 'true'\\

| | `startswith(str, prefix)` | Returns `true` if `str` starts with `prefix`. | `startswith(String, String)` | `Boolean` | `startswith('abcde', 'abc')` | | `substring(str, offset, length)` | Returns a substring of `str` of length `length` from offset `offset`. The first character has an offset of 1. | `substring(String, Number, Number)` | `String` | `substring('abcde', 2, 3) == 'bcd'` | | `match(str, regex)` | Returns `true` if `str` matches the pattern `regex` in [re2 regular syntax](https://github.com/google/re2/wiki/Syntax). | `match(String, String)` | `Boolean` | `match('abcde', 'a.c.*e')` | | `is_null(x)` | Returns `true` if `x` is null, otherwise returns `false`. | `is_null(Any)` | `Boolean` | \

\is\_null('') == true\\
\is\_null("column1")\\

| | `is_not_null(x)` | Returns `true` if `x` is not null, otherwise returns `false`. | `is_null(Any)` | `Boolean` | \

\is\_not\_null('') == false\\
\\`is\_not\_null("column1")\\

| | `abs(x)` | Returns the absolute value of number `x`. | `abs(Number)` | `Number` | `abs(-3) == 3` | | `exp(x)` | Returns `e^x`, where `e` is the base of the natural logarithm. | `exp(Number)` | `Number` | `exp(1) == 2.718281828459045` | | `log(x)` | Returns the natural logarithm (base `e`) of number `x`. | `log(Number)` | `Number` | `log(e) == 1` | | `log2(x)` | Returns the binary logarithm (base `2`) of number `x`. | `log2(Number)` | `Number` | `log2(16) == 4` | | `log10(x)` | Returns the common logarithm (base `10`) of number `x`. | `log10(Number)` | `Number` | `log10(1000) == 3` | | `sqrt(x)` | Returns the positive square root of number `x`. | `sqrt(Number)` | `Number` | `sqrt(144) == 12` | ## Aggregate functions Every Custom Metric must be wrapped in an aggregate function or be a combination of aggregate functions. | Symbol | Description | Syntax | Returns | Examples | | --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `sum(x)` | Returns the sum of a numeric column or row expression `x`. | `sum(Number)` | `Number` | `sum(column1 + column2)` | | `average(x)` | Returns the arithmetic mean/average value of a numeric column or row expression `x`. | `average(Number)` | `Number` | `average(2 * column1)` | | `count(x)` | Returns the number of non-null rows of a column or row expression `x`. | `count(Any)` | `Number` | `count(column1)` | | `min(x)` | Returns the minimum value of a numeric column or row expression `x`. | `min(Number)` | `Number` | `min(column1)` | | `max(x)` | Returns the maximum value of a numeric column or row expression `x`. | `max(Number)` | `Number` | `max(column1)` | | `quantile(x, level)` | Returns the quantile (percentile) of a numeric column or row expression `x` at the specified `level`. The `level` must be a constant between 0.0 and 1.0 (defaults to 0.5 if not specified). | `quantile(Number, level=Number)` | `Number` | \

\quantile(Output, level=0.5)\\
\quantile(latency\_ms, level=0.95)\\
\quantile(response\_time, level=0.99)\\

| | `greatest(agg1, agg2, ...)` | Returns the maximum value between multiple numerical aggregates | `greatest(Number, Number, ...)` | `Number` | `greatest(sum(col1), sum(col2), sum(col3))` | | `least(agg1, agg2, ...)` | Returns the minimum value between multiple numerical aggregates | `least(Number, Number, ...)` | `Number` | `least(sum(col1), sum(col2), sum(col3))` | **`min(x)` / `max(x)` vs `least(...)` / `greatest(...)`**: `min(x)` and `max(x)` aggregate a single row-level expression **across rows** (e.g., `min(column1)` returns the smallest value of `column1` across all rows in the time window). `least(...)` and `greatest(...)` compare **multiple aggregate results** and return the smallest or largest among them (e.g., `least(sum(col1), sum(col2))` compares two already-computed sums). Built-in metric functions are available for **ML models only** (classification, regression, and ranking tasks). They are not supported in custom metrics for agentic or GenAI applications. For agentic applications, use the `attribute()` function with aggregate functions instead — see [Custom Metrics for Agentic Applications](/observability/agentic/custom-metrics). ## Built-in metric functions | Symbol | Description | Syntax | Returns | Examples | | ------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `jsd(column, baseline)` | The Jensen-Shannon distance of column `column` with respect to baseline `baseline`. | `jsd(Any, String)` | `Number` | `jsd(column1, 'my_baseline')` | | `psi(column, baseline)` | The population stability index of column `column` with respect to baseline `baseline`. | `psi(Any, String)` | `Number` | `psi(column1, 'my_baseline')` | | `null_violation_count(column)` | Number of rows with null values in column `column`. | `null_violation_count(Any)` | `Number` | `null_violation_count(column1)` | | `range_violation_count(column)` | Number of rows with out-of-range values in column `column`. | `range_violation_count(Any)` | `Number` | `range_violation_count(column1)` | | `type_violation_count(column)` | Number of rows with invalid data types in column `column`. | `type_violation_count(Any)` | `Number` | `type_violation_count(column1)` | | `any_violation_count(column)` | Number of rows with at least one Data Integrity violation in `column`. | `any_violation_count(Any)` | `Number` | `any_violation_count(column1)` | | `traffic()` | Total row count. Includes null rows. | `traffic()` | `Number` | `traffic()` | | `tp(class)` | True positive boolean state. Available for binary classification and multiclass classification models. For multiclass, `class` is used to specify the positive class. | `tp(class=Optional[String])` | `Boolean` | \

\tp()\\
\tp(class='class1')\\

| | `tn(class)` | True negative boolean state. Available for binary classification and multiclass classification models. For multiclass, `class` is used to specify the positive class. | `tn(class=Optional[String])` | `Boolean` | \

\tn()\\
\tn(class='class1')\\

| | `fp(class)` | False positive boolean state. Available for binary classification and multiclass classification models. For multiclass, `class` is used to specify the positive class. | `fp(class=Optional[String])` | `Boolean` | \

\fp()\\
\fp(class='class1')\\

| | `fn(class)` | False negative boolean state. Available for binary classification and multiclass classification models. For multiclass, `class` is used to specify the positive class. | `fn(class=Optional[String])` | `Boolean` | \

\fn()\\
\fn(class='class1')\\

| | `precision(target, threshold)` | \

Precision between target and output. Available for binary classification model tasks.\
If \target\ is specified, it will be used in place of the default target column.\

| `precision(target=Optional[Any], threshold=Optional[Number])` | `Number` | \

\precision()\\
\precision(target=column1)\\
\precision(threshold=0.5)\\
\precision(target=column1, threshold=0.5)\\

| | `recall(target, threshold)` | \

Recall between target and output. Available for binary classification model tasks.\
If \target\ is specified, it will be used in place of the default target column.\

| `recall(target=Optional[Any], threshold=Optional[Number])` | `Number` | \

\recall()\\
\recall(target=column1)\\
\recall(threshold=0.5)\\
\recall(target=column1, threshold=0.5)\\

| | `f1_score(target, threshold)` | \

F1 score between target and output. Available for binary classification model tasks.\
If \target\ is specified, it will be used in place of the default target column.\

| `f1_score(target=Optional[Any], threshold=Optional[Number])` | `Number` | \

\f1\_score()\\
\f1\_score(target=column1)\\
\f1\_score(threshold=0.5)\\
\f1\_score(target=column1, threshold=0.5)\\

| | `fpr(target, threshold)` | \

False positive rate between target and output. Available for binary classification model tasks.\
If \target\ is specified, it will be used in place of the default target column.\

| `fpr(target=Optional[Any], threshold=Optional[Number])` | `Number` | \

\fpr()\\
\fpr(target=column1)\\
\fpr(threshold=0.5)\\
\fpr(target=column1, threshold=0.5)\\

| | `auroc(target)` | \

Area under the ROC curve between target and output. Available for binary classification model tasks.\
If \target\ is specified, it will be used in place of the default target column.\

| `auroc(target=Optional[Any])` | `Number` | \

\auroc()\\
\auroc(target=column1)\\

| | `geometric_mean(target, threshold)` | \

Geometric mean score between target and output. Available for binary classification model tasks.\
If \target\ is specified, it will be used in place of the default target column.\

| `geometric_mean(target=Optional[Any], threshold=Optional[Number])` | `Number` | \

\geometric\_mean()\\
\geometric\_mean(target=column1)\\
\geometric\_mean(threshold=0.5)\\
\geometric\_mean(target=column1, threshold=0.5)\\

| | `expected_calibration_error(target)` | \

Expected calibration error between target and output. Available for binary classification model tasks.\
If \target\ is specified, it will be used in place of the default target column.\

| `expected_calibration_error(target=Optional[Any])` | `Number` | \

\expected\_calibration\_error()\\
\expected\_calibration\_error(target=column1)\\

| | `log_loss(target)` | \

Log loss (binary cross entropy) between target and output. Available for binary classification model tasks.\
If \target\ is specified, it will be used in place of the default target column.\

| `log_loss(target=Optional[Any])` | `Number` | \

\log\_loss()\\
\log\_loss(target=column1)\\

| | `calibrated_threshold(target)` | \

Optimal threshold value for a high TPR and a low FPR. Available for binary classification model tasks.\
If \target\ is specified, it will be used in place of the default target column.\

| `calibrated_threshold(target=Optional[Any])` | `Number` | \

\calibrated\_threshold()\\
\calibrated\_threshold(target=column1)\\

| | `accuracy(target, threshold)` | \

Accuracy score between target and outputs. Available for multiclass classification model tasks.\
If \target\ is specified, it will be used in place of the default target column.\

| `accuracy(target=Optional[Any], threshold=Optional[Number])` | `Number` | \

\accuracy()\\
\accuracy(target=column1)\\
\accuracy(threshold=0.5)\\
\accuracy(target=column1, threshold=0.5)\\

| | `log_loss(target)` | \

Log loss score between target and outputs. Available for multiclass classification model tasks.\
If \target\ is specified, it will be used in place of the default target column.\

| `log_loss(target=Optional[Any])` | `Number` | \

\log\_loss()\\
\log\_loss(target=column1)\\

| | `r2(target)` | \

R-squared score between target and output. Available for regression model tasks.\
If \target\ is specified, it will be used in place of the default target column.\

| `r2(target=Optional[Any])` | `Number` | \

\r2()\\
\r2(target=column1)\\

| | `mse(target)` | \

Mean squared error between target and output. Available for regression model tasks.\
If \target\ is specified, it will be used in place of the default target column.\

| `mse(target=Optional[Any])` | `Number` | \

\mse()\\
\mse(target=column1)\\

| | `mae(target)` | \

Mean absolute error between target and output. Available for regression model tasks.\
If \target\ is specified, it will be used in place of the default target column.\

| `mae(target=Optional[Any])` | `Number` | \

\mae()\\
\mae(target=column1)\\

| | `mape(target)` | \

Mean absolute percentage error between target and output. Available for regression model tasks.\
If \target\ is specified, it will be used in place of the default target column.\

| `mape(target=Optional[Any])` | `Number` | \

\mape()\\
\mape(target=column1)\\

| | `wmape(target)` | \

Weighted mean absolute percentage error between target and output. Available for regression model tasks.\
If \target\ is specified, it will be used in place of the default target column.\

| `wmape(target=Optional[Any])` | `Number` | \

\wmape()\\
\wmape(target=column1)\\

| | `map(target)` | \

Mean average precision score. Available for ranking model tasks.\
If \target\ is specified, it will be used in place of the default target column.\

| `map(target=Optional[Any])` | `Number` | \

\map()\\
\map(target=column1)\\

| | `ndcg_mean(target)` | \

Mean normalized discounted cumulative gain score. Available for ranking model tasks.\
If \target\ is specified, it will be used in place of the default target column.\

| `ndcg_mean(target=Optional[Any])` | `Number` | \

\ndcg\_mean()\\
\ndcg\_mean(target=column1)\\

| | `query_count(target)` | \

Count of ranking queries. Available for ranking model tasks.\
If \target\ is specified, it will be used in place of the default target column.\

| `query_count(target=Optional[Any])` | `Number` | \

\query\_count()\\
\query\_count(target=column1)\\

| | `gini(actual, predicted)` | Gini coefficient derived from the Lorenz curve. Measures how well a model's predicted scores rank actual values. Available for ML custom metrics (all model task types, including regression). Both `actual` and `predicted` are required keyword arguments of type `Number`. To compute the **normalized Gini coefficient**, divide by the ideal Gini: `gini(actual=Target, predicted=Score) / gini(actual=Target, predicted=Target)`. For binary classification, the normalized Gini can also be derived from AUC: `2 * auroc() - 1`. | `gini(actual=Number, predicted=Number)` | `Number` | `gini(actual=Target, predicted=Score)` | # Monitoring Platform Source: https://docs.fiddler.ai/observability/platform/index Dive into our guide to optimizing ML models and LLM applications with Fiddler’s monitoring tools. Learn key metrics to track data drift, performance, and more. Fiddler Monitoring helps you detect performance issues in your production ML models and LLM applications. It provides five built-in metric types, plus support for custom metrics that you can monitor and track. * [**Data Drift**](/observability/platform/data-drift-platform) * [**Performance**](/observability/platform/performance-tracking-platform) * [**Data Integrity**](/observability/platform/data-integrity-platform) * [**Traffic**](/observability/platform/traffic-platform) * [**Statistic**](/observability/platform/statistics) * [**Custom Metrics**](/observability/platform/custom-metrics) These metrics can be visualized through Fiddler's Charts and Dashboards, alerted on using Alerts, and extended with Custom Metrics, allowing for quick root cause analysis alerts. # Model Versions Source: https://docs.fiddler.ai/observability/platform/model-versions Discover model versions in Fiddler. Learn structured approaches to managing related models, their use cases, capabilities, and how to create a model version. ### Overview Model versions in Fiddler provide a structured approach to managing related models, offering enhanced efficiency in tasks such as model retraining and champion vs. challenger analyses. Rather than creating entirely new model instances for updates, users can opt for creating versions of existing models, maintaining their foundational structure while accommodating necessary changes. These changes can span schema modifications, including column additions or removals, adjustments to data types and value ranges, updates to model specifications, and refinement of task parameters or Explainable AI (XAI) settings. ### Use Cases Model versions are particularly useful in scenarios where: * **Model Retraining**: Models require updating with new data or improved algorithms without disrupting existing deployments. * **Champion vs. Challenger Analyses**: Comparing the performance of different model versions to identify the most effective one for deployment. * **Historical Tracking**: Maintaining a clear record of model iterations and changes over time for auditing or analysis purposes. ### Capabilities With model versions, users can: * **Maintain Model Lineage**: Easily trace the evolution of models by keeping track of different versions and their respective changes. * **Efficiently Manage Updates**: Streamline the process of updating models by creating new versions with incremental changes, avoiding the need to re-upload entire model instances. * **Flexibly Modify Schemas**: Modify model schemas, including column structures, data types, and other specifications, to adapt models to evolving requirements. * **Adjust Parameters**: Refine task parameters, XAI settings, and other configurations to improve explainability, or tailor the task to better suit the model's purpose. * **Ensure Consistency**: Ensure consistency in model deployments by managing related models within the same versioning system, facilitating comparisons and deployments. ### Example of Creating a Model Version Utilizing from\_name() and duplicate() methods, we can efficiently create a new model version with modifications based on an existing model. First, we retrieve the existing model by specifying its name, project ID, and version. Subsequently, we duplicate this model while updating its version, transitioning, for instance, from `v3` to `v4`. Within the new version (`v4`), we tailor the value ranges of the 'Age' column to meet our requirements. Finally, the create() method is invoked to publish the newly minted model version `v4`. ```python theme={null} # Define project ID and model name PROJECT_ID = 'your_project_id' MODEL_NAME = 'your_model_name' # Retrieve the existing model version by name and project ID existing_model = fdl.Model.from_name(name=MODEL_NAME, project_id=PROJECT_ID, version='v3') # Duplicate the existing model to create a new version new_model = existing_model.duplicate(version='v4') # Modify the schema of the new version new_model.schema['Age'].min = 18 new_model.schema['Age'].max = 60 # Create the new version of the model new_model.create() ``` # Monitoring Charts Source: https://docs.fiddler.ai/observability/platform/monitoring-charts-platform Explore our guide to the monitoring charts UI. Learn how to create charts, explore functions, customize tabs, and track LLM metrics effectively. ### Getting Started with Fiddler’s Charts UI The Chart UI on Fiddler AI’s platform is designed to help you effectively monitor and analyze model performance metrics. Navigating to the Charts tab in the navigation bar allows you to easily access the tools needed to visualize key data and track your LLM and ML models’ performance. Choose to open a previously saved chart for ongoing analysis or create a new one tailored to specific metrics, such as response faithfulness, jailbreak attempts, data drift, and more. Plotting traffic on Fiddlers monitoring chart. #### Supported Metric Types Monitoring charts enable you to plot any combination of the following metric types for a given model: * [**Traffic**](/observability/platform/traffic-platform) * Model traffic volume over time provides insights into system usage patterns and overall operational health. * [**Statistics**](/observability/platform/statistics) * Aggregated metrics that monitor trends and changes in your model's data columns * [**Data Drift**](/observability/platform/data-drift-platform) * Data drift occurs when production data differs significantly from training data, potentially degrading model performance and accuracy. * [**Data Integrity**](/observability/platform/data-integrity-platform) * Monitors three critical data integrity issues: missing values, incorrect data types, and out-of-range values that violate model input requirements. * [**Performance**](/observability/platform/performance-tracking-platform) * Model performance measures how accurately your model accomplishes its intended task, directly impacting business outcomes and decision quality. * [**Custom Metrics**](/observability/platform/custom-metrics) * Build tailored monitoring metrics that align with your specific business rules and success criteria using custom formulas. ### What Are the Key Features and Functions of the Monitoring Chart UI? #### Multiple Charting Options You can [plot up to 20 columns](#customizing-columns-for-monitoring-charts) and 6 metric queries for a model enabling you to easily perform model-to-model comparisons and plot multiple metrics in a single chart view. #### Embedded Root Cause Analytics Root cause analysis information covers data drift and data integrity, and performance analytics charts for binary classification, multiclass classification, and regression models. #### Download Your Raw Data for Further Analysis You can [easily download the raw chart data](#breakdown-summary) to CSV or parquet files. This feature allows you to analyze your data further. ### How to Create a New Monitoring Chart To create a new monitoring chart, click on the Add Chart button on the Charts page. Search for and select the [project](/glossary#projects) to create the chart, and press Add Chart. How to add a new monitoring chart to a project. #### Save and Share Your Monitoring Chart Save your chart by clicking the Save button in the chart studio's top right corner. You can then share your chart by copying its link and sending it to other users who have access to the project. #### Undo and Redo Actions Easily control the following actions with the undo and redo buttons: * Metric query selection * Time range selections * Bin size selections To learn how to undo actions taken using the chart toolbar, see the Toolbar information in the next section. ### Exploring Chart Metric Queries & Filters #### Creating and Managing Metric Queries Start building your monitoring chart by creating a metric query. First, select a model from your project to analyze. Then, specify which metrics and columns you want to visualize. Note that you can only select models that exist within your current project. Select the type of metric you want to monitor: Performance, Data Drift, Data Integrity, Statistic, Traffic, or Custom Metric. Then choose specific metrics within that category. For instance, if you're monitoring a binary classification model, you might select Performance metrics and track accuracy over time. Analyzing metric queries in your monitoring chart. #### Customizing Columns for Monitoring Charts If you choose to chart data drift or data integrity, you can choose to plot up to 20 different columns from the following column categories: inputs, outputs, targets, metadata, and custom features. Adding multiple columns to your chart. #### Adding Multiple Metrics or Models Add up to 6 metric queries that allow you to chart different metrics from one or more models in a single chart view. Adding multiple metrics and/or models to a single chart. #### Using Chart Filters for Better Analysis Analyze specific slices of data using three key filtering tools: chart filters, the chart toolbar, and the zoom slider. These tools work together to help you investigate important patterns and trends in your data. How to add filters and use capabilities to analyze your monitoring chart. #### Tailored Filters You can customize your chart view using the date range and bin size filters. The date range can be one of the pre-defined time ranges or a custom range. The bin size selected controls the frequency for which the data is displayed. So selecting Day will show daily data over the date range selected. Customize your chart's time-based display using the date range and bin size filters. Choose from preset date ranges or define a custom period. The bin size determines how your data is grouped - for example, selecting 'Day' will show daily aggregated data across your chosen date range. #### Toolbar Functions The charts toolbar is made up of 5 functions: * Drag to zoom * Reset zoom * Toggle to a line chart * Toggle to a bar chart * Undo all toolbar actions > 📘 Note: If the zoom reset or toolbar undo is selected, this will also undo any actions taken with the zoom slider. Toolbar functions in a monitoring chart. **Line & Bar Chart Toggles** Toggle between line and bar chart views using the toolbar icons in the top right corner. While you can freely switch between these visualization types, please note that toolbar settings are temporary and won't be saved with your chart. Visualize metrics in bar chart mode. **Zoom Slider** Use the horizontal zoom bar at the bottom of the chart to focus on specific time periods. Select your desired time range by dragging the zoom bar handles, then slide the selected range left or right to analyze different periods. For example, to examine week-by-week data over six months, zoom to your preferred view and drag the range to explore different weeks. Focus your analysis in a specific time range. #### Breakdown Summary You can easily visualize your charts' raw data as a table within the fiddler chart studio, or download the content as a CSV or parquet file for further analysis. If you choose to chart multiple columns, as shown below, you can search for and sort by Model name, Metric name, Column name, or values for a specific date. Analyze your chart’s raw data as a table to get a breakdown summary. ### How to Customize Your Monitoring Chart #### Adjusting Scale and Range The Customize tab lets you adjust your chart's y-axis settings to improve data visualization. You can set minimum and maximum values to better utilize chart space, and apply logarithmic scaling to clearly display data with large variations in values. Customize the scale and range of the y-axis on your monitoring chart. #### Assigning Y-axis for Metric Queries Select the y-axis for your metric queries with enhanced flexibility to customize the scale and range for each axis. Customize the scale and range of each axis on your monitoring chart. ### Mastering our Chart UI to Effectively Track LLM and ML Performance Understanding how to use the chart UI is key to measuring and maintaining the performance of LLM and ML models. Fiddler’s model monitoring tools allow you to track key metrics, identify data drift, and gain valuable insights into model behavior. Customize your Fiddler charts to proactively address issues and ensure models remain accurate, reliable, and high-performing. # Performance Tracking Source: https://docs.fiddler.ai/observability/platform/performance-tracking-platform Learn to track performance with Fiddler. Discover why performance metrics matter and the steps to take when your model isn’t performing as expected. For a complete list of all built-in ML metrics, see the [ML Metrics Reference](/reference/ml-metrics-reference). ## Overview The model performance tells us how well a model performs on its task. A poorly performing model can have significant business implications. ## What is being tracked? ***Performance metrics*** | Model Task Type | Metric | Description | | --------------------- | -------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | | Binary Classification | Accuracy | (TP + TN) / (TP + TN + FP + FN) | | Binary Classification | True Positive Rate/Recall | TP / (TP + FN) | | Binary Classification | False Positive Rate | FP / (FP + TN) | | Binary Classification | Precision | TP / (TP + FP) | | Binary Classification | F1 Score | 2 \* ( Precision \* Recall ) / ( Precision + Recall ) | | Binary Classification | AUROC | Area Under the Receiver Operating Characteristic (ROC) curve, which plots the true positive rate against the false positive rate | | Binary Classification | Binary Cross Entropy | Measures the difference between the predicted probability distribution and the true distribution | | Binary Classification | Geometric Mean | Square Root of ( Precision \* Recall ) | | Binary Classification | Calibrated Threshold | A threshold that balances precision and recall at a particular operating point | | Binary Classification | Data Count | The number of events where target and output are both not NULL. ***This will be used as the denominator when calculating accuracy***. | | Binary Classification | Expected Calibration Error | Measures the difference between predicted probabilities and empirical probabilities | | Multi Classification | Accuracy | (Number of correctly classified samples) / ( Data Count ). Data Count refers to the number of events where the target and output are both not NULL | | Multi Classification | Log Loss | Measures the difference between the predicted probability distribution and the true distribution, in a logarithmic scale | | Regression | Coefficient of determination (R-squared) | Measures the proportion of variance in the dependent variable that is explained by the independent variables | | Regression | Mean Squared Error (MSE) | Average of the squared differences between the predicted and true values | | Regression | Mean Absolute Error (MAE) | Average of the absolute differences between the predicted and true values | | Regression | Mean Absolute Percentage Error (MAPE) | Average of the absolute percentage differences between the predicted and true values | | Regression | Weighted Mean Absolute Percentage Error (WMAPE) | The weighted average of the absolute percentage differences between the predicted and true values | | Ranking | Mean Average Precision (MAP)—for binary relevance ranking only | Measures the average precision of the relevant items in the top-k results | | Ranking | Normalized Discounted Cumulative Gain (NDCG) | Measures the quality of the ranking of the retrieved items, by discounting the relevance scores of items at lower ranks | ## Why is it being tracked? * Model performance tells us how well a model is doing on its task. A poorly performing model can have significant business implications. * The volume of decisions made on the basis of the predictions give visibility into the business impact of the model. ## What steps should I take based on this information? * For changes in model performance—again, the best way to cross-verify the results is by checking the [Data Drift Tab](/observability/platform/data-drift-platform). Once you confirm that the performance issue is not due to the data, you need to assess if the change in performance is due to temporary factors, or due to longer-lasting issues. * You can check if there are any lightweight changes you can make to help recover performance—for example, you could try modifying the decision threshold. * Retraining the model with the latest data and redeploying it is usually the solution that yields the best results, although it may be time-consuming and expensive. # Segments Source: https://docs.fiddler.ai/observability/platform/segments Learn to use model segments for monitoring diverse dimensions. Define, add, and modify segments to gain valuable insights into specific cohorts and dimensions. ### Overview A segment, sometimes referred to as a cohort or slice, represents a distinct subset of model values crucial for performance analysis and troubleshooting. Model segments can be defined using various model dimensions, such as specific time periods or sets of features. Analyzing segments proves invaluable for understanding or troubleshooting specific cohorts of interest, particularly in tasks like bias detection, where overarching datasets might obscure statistical intricacies. ### How to Define a Segment Fiddler makes it easy to define custom segments using either the Fiddler UI or the Fiddler Python client. Instructions for both approaches are covered in more detail below. In either case, Fiddler Segments are constructed using the [Fiddler Query Language (FQL)](/observability/platform/fiddler-query-language). You can use any of the constants, operators, and functions mentioned in the page linked above in a Segment definition. However, every Segment definition must return **a boolean row-level expression**. In other words, each inference will either satisfy the segment expression and thus belong to the segment or it will not. ### Examples Let us illustrate further by providing a few examples. A segment can be defined by: * A condition on some column (e.g. `age > 50`) * A condition on some combination of columns (e.g. `(age / max_age) < 1.0`) For details on all supported functions, see the [Fiddler Query Language (FQL)](/observability/platform/fiddler-query-language) page. ### Adding a Segment Using the Python Client ```python theme={null} model_id = 'your_model_identifier' segment_name = 'your_segment_name' model = fdl.Model.get(id_=model_id) # Use Fiddler Query Language (FQL) to define your custom segments segment = fdl.Segment( name=segment_name, model_id=model.id, definition="Age < 60", description='Users with Age under 60', ).create() ``` ### Applied Segments When using segments in the UI for Analytics or Monitoring Charts, applied segments offer a flexible way to define segments on the fly for exploratory analysis. These segments are not saved to the model by default, but will persist locally if the chart they are applied to is saved. At any time, an applied segment can be saved to the model. However, once a segment is saved to the model, it cannot be altered. ### Modifying Saved Segments Since alerts can be set on Segments, making modifications to a Segment may introduce inconsistencies in alerts. > 🚧 Therefore, **Saved segments cannot be modified once they are created**. If you'd like to experiment with a new segment, you can create one with a different definition or use applied segments within charts. #### Deleting Segments Delete a segment using the [Python client SDK](/sdk-api/python-client/connection). Alternatively, from the segments tab, you can delete a segment by clicking the trash icon next to the segment record. # Statistics Source: https://docs.fiddler.ai/observability/platform/statistics Discover Fiddler’s statistical metrics guide to monitor column aggregations. Learn what’s tracked, how to monitor metrics, and how to set up alerts. ### Overview Fiddler supports some simple statistic metrics which can be used to monitor basic aggregations over columns. These can be particularly useful when you have a custom metadata field which you would like to monitor over time in addition to Fiddler's other out-of-the-box metrics. ### What is being tracked? Specifically, we support: * **Average**: Takes the arithmetic mean of a numeric column * **Sum**: Calculates the sum of a numeric column * **Frequency**: Shows the count of occurrences for each value in a categorical or boolean column ### Monitoring Statistic Metrics #### Charting Statistic Metrics These metrics can be accessed in Charts and Alerts by selecting the Statistic Metric Type. #### Alerting on Statistic Metrics Alert rules can be established based on statistics too. Like an alert rule, these can be setup using the Fiddler UI, the Fiddler python client or using Fiddler's RESTful API. # Template-Based Alerts Source: https://docs.fiddler.ai/observability/platform/template-based-alerts Learn how to create and deploy template-based alerts in Fiddler using Google Sheets and YAML configurations for efficient model monitoring. The Template-Based Alerts feature streamlines alert rule configuration and generation, significantly reducing manual effort. By using a Google Sheet to input key data and generate a recipe YAML file, this feature enables the efficient and accurate creation of alert rules. This approach ensures more relevant alerts, enhancing monitoring capabilities and enabling proactive issue resolution. This guide outlines the process of generating and deploying template-based alerts to monitor your model's performance and data. ### Overview Template-based alerts involve two primary steps: 1. **Generate a YAML configuration:** This involves using a provided Google Sheet to define your alert rules. 2. **Consume the YAML configuration:** This utilizes a Python notebook from the Alert Recipes repository to create the alerts in your Fiddler deployment. ### Step 1: Generating the Alert Recipe YAML Configuration The first step is to create a YAML configuration file containing your desired alert rules. This is done using a pre-configured Google Sheet. #### 1.1 Copying the Alert Recipes Sheet To begin, you need to copy the Alert Recipes Google Sheet. This ensures you have a personal, editable version without affecting the base sheet. * **Action**: Copy the entire content of the Alert Recipes sheet, including the recipe generator script it contains. #### 1.2 Understanding the Sheet Structure Once copied, note that the Google Sheet is organized into several worksheets: * `AlertRecipes`: This is the main sheet where you define individual alert rules. * `RecipeParameters` and `NotificationPacks`: These sheets need to be edited according to your preferences. * `MetricIdMap` and `ThresholdTypeMap`: These sheets are locked and should not be edited unless you have a deep understanding of their function. #### 1.3 Configuring Recipe Parameters The `RecipeParameters` sheet is crucial for defining the context of your alerts. RecipeParameters Sheet * **Columns:** * **Project name**: Enter the name of your project. * **Model name**: Enter the name of your model. * **High-priority features**: List the key features for this project and model, separated by commas. * **Medium-priority features**: Provide a comma-separated list of features you consider medium priority for this project and model. * **Low-priority features**: Provide a comma-separated list of features you consider low priority for this project and model. **Important Note**: The script only considers the first row of this sheet. Any additional rows will be ignored. #### 1.4 Configuring notification packs Notification packs allow you to bundle email, PagerDuty, or webhook notifications to be applied to your alert rules. NotificationPacks Sheet * **Definition**: A notification pack is a collection of one or more notification types (email, PagerDuty, webhook) that can be attached to an alert rule. * **Customization**: * You can create custom notification packs in new rows. * Each new pack can contain any combination of email, PagerDuty service, and webhook UUID. * **Important Note**: The webhook user ID must be the actual UUID of the webhook, not its service name. * **Availability**: Any notification packs you define or modify in this sheet will be available for selection in the main `AlertRecipes` sheet. #### 1.5 Defining Alert Rules in AlertRecipes The `AlertRecipes` sheet is where you configure individual alert rules. AlertRecipes Sheet * **Columns:** * **Monitor type**: Specifies the type of metric on which the alert rule will be created. * **Alert rule name**: If provided, this name will be used for the alert rule. Otherwise, a name will be inferred from the monitor type, appended with a unique identifier. * **Time window**: Defines the time bin over which evaluations will happen and alerts will be raised. * **Enabled (Y or N)**: Determines whether this alert rule will be included in the generated YAML configuration. * **Features**: Select from 'High-Priority', 'Low-Priority', 'Medium-Priority', or 'All'. The specific features are chosen from the RecipeParameters sheet based on your selection. * **Threshold algo**: Currently, only 'standard deviation' is supported. * **Critical multiplier**: This multiplier is used to calculate the critical threshold dynamically. For example, a value of `2` means a critical alert will be raised if the metric value is 2 standard deviations away from the mean of the reference data. * **Warning multiplier**: This multiplier is used to calculate the warning threshold dynamically. For example, a value of `1` means a warning alert will be raised if the metric value is 1 standard deviation away from the mean of the reference data. These multipliers are customizable (e.g., 0.5, 1.5). * **Notification pack**: Select a pre-defined notification pack from the `NotificationPacks` sheet to attach to this alert rule. #### 1.6 Generating the Alert Recipe YAML Once you have configured the `RecipeParameters`, `NotificationPacks`, and `AlertRecipe` sheets, you can generate the YAML file. * **Action**: Click the "Generate Alert Recipe" button in the `AlertRecipe` Sheet. * **Permissions**: You will be prompted to grant specific permissions for the script to run. These permissions are necessary for the script to access your Google Drive (to save the YAML file) and to run within the Google Sheet environment. * **Output**: The YAML file will be generated. Copy its content. ### Step 2: Consuming the YAML Configuration After generating the YAML file, the next step is to use it to create the alert rules in your Fiddler deployment. This is done using the Alert Recipes repository and a Python notebook. #### 2.1 Setting Up the Alert Recipes Repository You'll need to work within the Alert Recipes repository. * **File Creation**: Inside the root of the repository, create two files: * `config.py` * `alert_recipes.yaml` * **Configuration**: * `config.py`: Populate this file with the correct URL and authentication token for your Fiddler deployment. You can copy the structure from existing example files(`config.py.example`). * `alert_recipes.yaml`: Paste the content of the YAML file you copied from the Google Sheet into this file. #### 2.2 Running the Python Notebook With the configuration files set up, you can now run the Python notebook to create the alert rules. * **Action**: Open the `create_alert_rules.ipynb` notebook within the Alert Recipes repository. * **Execution**: Run all cells within the notebook. * **Verification**: The logs in the notebook will show which new alert rules have been created. You can then verify the creation of these rules within your Fiddler deployment. # Traffic Source: https://docs.fiddler.ai/observability/platform/traffic-platform Learn how Fiddler tracks your ML and GenAI models' traffic patterns and when to take action when traffic patterns deviate from normal. Traffic as a service metric gives you basic insights into the operational health of your model's service in production. Example of a Fiddler Chart displaying a model's traffic. ## What is Being Tracked? * ***Traffic*** — The volume of traffic received by the model over time. ## Why is it Being Tracked? * Traffic is a basic high-level metric that informs us of the model's output activity. ## What Steps Should I Take When I See an Outlier? * A dip or spike in traffic needs to be investigated. For example, a dip could be due to a production model server going down; a spike could be an adversarial attack. # Vector Monitoring Source: https://docs.fiddler.ai/observability/platform/vector-monitoring-platform Dive into our vector monitoring guide to learn about model inputs represented as vectors and how to use Fiddler's custom features to monitor and detect drift. ## Detecting Drift in Multi-Dimensional ML and GenAI Model Data Many modern machine learning systems use input features that cannot be represented as a single number, such as text or image data. These complex features are typically represented by high-dimensional vectors obtained through vectorization methods like text embeddings generated by NLP models. Fiddler users often need to monitor groups of univariate features together and detect data drift in multidimensional feature spaces. To address these needs, Fiddler provides vector monitoring capabilities that enable you to define [custom features](#define-custom-features) and use advanced methods for monitoring data drift in multidimensional spaces. You can define custom features by grouping columns together in baseline and inference data. For NLP or image data, you can define custom features using columns that contain embedding vectors. ### Define Custom Features Users can use the Fiddler client to define one or more custom features. Custom features can be specified by: Use the Fiddler client to define one or more custom features. You can specify custom features in three ways: 1. Group dataset columns that need to be monitored together as a vector (custom\_feature\_1, custom\_feature\_2) 2. Use existing embedding vectors with the source column (custom\_feature\_3, custom\_feature\_4) 3. Define an enrichment that instructs Fiddler to generate embedding vectors automatically on ingestion (custom\_feature\_5) After you define and pass a list of custom features to Fiddler, Fiddler runs a clustering-based data drift detection algorithm for each custom feature. The system calculates a corresponding drift value between the baseline and published events for the selected time period. ```python theme={null} from fiddler import CustomFeature, TextEmbedding, ImageEmbedding # Group columns into vectors custom_feature_1 = CustomFeature.from_columns( ['f1', 'f2', 'f3'], custom_name='vector1' ) custom_feature_2 = CustomFeature.from_columns( ['f1', 'f2', 'f3'], n_clusters=5, custom_name='vector2' ) # Use existing embeddings custom_feature_3 = TextEmbedding( name='Document Text Embedding', column='text_embedding_col', source_column='text' ) custom_feature_4 = ImageEmbedding( name='Image Embedding', column='image_embedding_col', source_column='image_url' ) # Define automated text embedding enrichment custom_feature_5 = TextEmbedding( name='Document Text Embedding', source_column='doc_col', column='Enrichment Unstructured Embedding', n_tags=10, ) ``` ### Passing Custom Features List to ModelSpec After you define custom features for vector monitoring, add them to the `ModelSpec` and onboard the Model to Fiddler. ```python theme={null} from fiddler import ModelSpec, Model, Project model_spec = ModelSpec( inputs=[ 'creditscore', 'geography', 'gender', 'age', 'tenure', 'balance', 'numofproducts', 'hascrcard', 'isactivemember', 'estimatedsalary', 'doc_col', ], outputs=['predicted_churn'], targets=['churn'], # Note: Embedding columns you pass in must be included with the metadata columns. metadata=['customer_id', 'timestamp', 'text_embedding_col', 'image_embedding_col'], custom_features=[ custom_feature_1, custom_feature_2, custom_feature_3, custom_feature_4, custom_feature_5, ], ) model = Model.from_data( name='your_model_name', project_id=Project.from_name('your_project_name').id, source=sample_df, spec=model_spec, task=model_task, task_params=task_params, event_id_col=id_column, event_ts_col=timestamp_column, ) model.create() ``` ## Understanding Drift Detection Algorithm Fiddler's vector monitoring uses a clustering-based approach to detect drift in multidimensional spaces: 1. **Baseline clustering:** The system analyzes your baseline data to identify natural clusters using k-means clustering 2. **Production comparison:** New production data is compared against these established clusters 3. **Drift calculation:** The system calculates drift scores based on changes in cluster distributions and centroid distances ### Performance considerations * **Computational cost:** Vector monitoring requires more computational resources than univariate monitoring * **Memory usage:** High-dimensional vectors and clustering algorithms increase memory requirements * **Processing time:** Drift calculations may take longer for large datasets or high-dimensional vectors ### Best practices * **Choose appropriate cluster numbers:** Start with 3-8 clusters and adjust based on your data's natural groupings * **Monitor cluster stability:** Regularly review cluster formations to ensure they remain meaningful * **Set reasonable thresholds:** Establish drift thresholds that balance sensitivity with false positive rates ## Risk Considerations for AI/ML Applications When implementing vector monitoring, consider these potential risks: * **Bias amplification:** Clustering algorithms may amplify existing biases in your training data * **Concept drift detection:** Traditional clustering may miss subtle concept drift that affects model performance * **Interpretability challenges:** High-dimensional clusters can be difficult to interpret and explain to stakeholders > **Note:** For a complete example of NLP monitoring, see our [NLP monitoring quick start guide](/developers/tutorials/ml-monitoring/simple-nlp-monitoring-quick-start), which demonstrates embedding generation for unstructured inputs. ## Related topics * [Data drift platform](/observability/platform/data-drift-platform) * [Enrichments](/observability/llm/enrichments) * [Embedding visualization with UMAP](/observability/platform/embedding-visualization-with-umap) # Guardrails Source: https://docs.fiddler.ai/protection/guardrails Fiddler Guardrails is a powerful solution designed to serve as the first-line of defense to protect enterprises from costly GenAI and LLM risks in real-time environments. ## Overview Fiddler Guardrails provide real-time protection for GenAI applications—including LLM-powered systems and agentic AI workflows—by detecting and preventing harmful content, PII leaks, and hallucinations before they reach your users. Built on Fiddler Centor Models—Fiddler's proprietary small language models (SLMs)—Guardrails deliver enterprise-grade security with low-latency, high-throughput performance optimized for production environments. **Use Fiddler Guardrails to:** * Detect and block harmful or inappropriate content across 11 safety dimensions * Prevent personally identifiable information (PII) leaks in user inputs and model outputs * Identify hallucinations in retrieval-augmented generation (RAG) applications * Protect against prompt injection and jailbreaking attempts ## What Fiddler Guardrails Can Moderate Fiddler Guardrails are powered by Fiddler Centor Models, and you can apply them to moderate or block three categories of risk: * **Safety** - Detect harmful, toxic, or jailbreaking content * **Hallucination (faithfulness)** - Identify hallucinations in RAG applications * **PII/PHI** - Detect and redact sensitive information Guardrails are designed for **real-time content blocking** with more sensitive thresholds than enrichments used for monitoring and analytics. See the [Enrichments guide](/observability/llm/enrichments) for batch processing and monitoring use cases. ## Getting Started with Fiddler Guardrails ### Prerequisites * **Fiddler Environment** - Access to a Fiddler environment with Guardrails enabled * **API Key** - Generate your API key from Settings → [Credentials](/reference/administration/settings#credentials) * **HTTP Client** - Python 3.8+ with `requests` library, cURL, or any HTTP client Guardrails can be invoked directly via REST API from any programming language. The examples below demonstrate usage with cURL and Python. *** ## Safety For safety moderation, Fiddler Guardrails use the Centor Model for Safety, which evaluates the safety of text along eleven different dimensions: `illegal, hateful, harassing, racist, sexist, violent, sexual, harmful, unethical, jailbreaking, roleplaying`. This model requires a single string input for evaluation and outputs 11 distinct scores (floats between 0 and 1). **Starting in release 26.13, scores are calibrated so that `0.5` is the default decision threshold across all 11 dimensions — a score of 0.5 or above indicates unsafe content.** Lower thresholds increase sensitivity but may over-block; tune the threshold for your data and risk tolerance. **Threshold Guidance:** Starting in release 26.13, the Centor Model for Safety is calibrated so a single decision threshold of **0.5** applies across all 11 dimensions — no per-dimension tuning required. Lower the threshold to increase sensitivity (at the cost of more false positives), or raise it to reduce false positives. For monitoring use cases with enrichments, see [Safety Enrichment](/observability/llm/enrichments#safety) for monitoring thresholds. **Migrating from earlier releases:** If you previously used a threshold of `0.1` (calibrated for the older, uncalibrated model), adopt `0.5` for the 26.13 calibrated model — keeping `0.1` will over-block benign content. Choosing a stricter (lower) threshold remains a deliberate option for high-sensitivity use cases. ### Safety Example Code ```bash theme={null} curl --location 'https://{fiddler_endpoint}/v3/guardrails/ftl-safety' --header 'Content-Type: application/json' --header 'Authorization: Bearer {token}' --data '{ "data": { "input": "I am a dangerous person who will be wreaking havoc upon the world!!!" } }' ``` ```python theme={null} import requests import json token = "YOUR_FIDDLER_TOKEN_HERE" url = "FIDDLER_ENDPOINT_HERE" payload = json.dumps( { "data": { "input": "I am a dangerous person who will be wreaking havoc upon the world!!!" } } ) headers = {"Content-Type": "application/json", "Authorization": f"Bearer {token}"} response = requests.request( "POST", f"{url}/v3/guardrails/ftl-safety", headers=headers, data=payload ) print(response.text) ``` **Sample Response** ```json theme={null} { "fdl_harmful": 0.119, "fdl_violent": 0.073, "fdl_unethical": 0.043, "fdl_illegal": 0.016, "fdl_sexual": 0.005, "fdl_racist": 0.003, "fdl_jailbreaking": 0.002, "fdl_harassing": 0.001, "fdl_hateful": 0.001, "fdl_sexist": 0.001, "fdl_roleplaying": 0.051 } ``` **Interpreting Safety Scores:** Each dimension returns a score between 0 and 1: * **Closer to 0** - Safe content * **Closer to 1** - Unsafe content * **0.5 or above** - Meets or exceeds the calibrated default decision threshold (tunable for your use case) *** ## Hallucination (faithfulness) For hallucination moderation, Fiddler Guardrails use the Centor Model for Faithfulness, which evaluates the accuracy and reliability of facts presented in AI-generated text responses by comparing them to provided context documents. This model uses `response` and `context` inputs. **Not to be confused with RAG Faithfulness.** For real-time blocking, Fiddler Guardrails use the Centor Model for Faithfulness (`ftl_response_faithfulness`). RAG Faithfulness is a separate LLM-as-a-Judge evaluator available in Agentic Monitoring and Experiments for diagnostic evaluation. See [RAG Health Diagnostics](/concepts/rag-health-diagnostics) for details. This model requires a response string and contextual documents as input. The model outputs a single faithfulness score (float between 0 and 1). **Set a threshold of \< 0.5 for detection (any value less than 0.5 indicates unfaithful content).** **Threshold Guidance:** A score closer to **0** means unfaithful (the LLM hallucinated relative to the provided context), while a score closer to **1** means faithful (the LLM output did not hallucinate and is well-grounded in the provided context). For real-time guardrails, a threshold of **0.5** strikes a balance between sensitivity and accuracy. ### Faithfulness Example Code ```bash theme={null} curl --location 'https://{fiddler_endpoint}/v3/guardrails/ftl-response-faithfulness' --header 'Content-Type: application/json' --header 'Authorization: Bearer {token}' --data '{ "data": { "response": "The Yorkshire Terrier and the Cavalier King Charles Spaniel are both small breeds of companion dogs.", "context": "The Yorkshire Terrier is a small dog breed of terrier type, developed during the 19th century in Yorkshire, England, to catch rats in clothing mills.The Cavalier King Charles Spaniel is a small spaniel classed as a toy dog by The Kennel Club and the American Kennel Club" } }' ``` ```python theme={null} import requests import json token = "YOUR_FIDDLER_TOKEN_HERE" url = "FIDDLER_ENDPOINT_HERE" payload = json.dumps( { "data": { "response": "The Yorkshire Terrier and the Cavalier King Charles Spaniel are both small breeds of companion dogs.", "context": "The Yorkshire Terrier is a small dog breed of terrier type, developed during the 19th century in Yorkshire, England, to catch rats in clothing mills.The Cavalier King Charles Spaniel is a small spaniel classed as a toy dog by The Kennel Club and the American Kennel Club", } } ) headers = {"Content-Type": "application/json", "Authorization": f"Bearer {token}"} response = requests.request( "POST", f"{url}/v3/guardrails/ftl-response-faithfulness", headers=headers, data=payload, ) print(response.text) ``` **Sample Response** ```json theme={null} { "fdl_faithful_score": 0.194 } ``` **Interpreting Faithfulness Scores:** * **0.0 - 0.49** - Unfaithful (likely hallucination - block or flag for review) * **0.5 - 1.0** - Faithful (response is well-supported by the provided context) The example above shows a score of **0.194**, which is **below the 0.5 threshold**, indicating the response may contain hallucinated information not supported by the context. *** ## PII/PHI For PII/PHI moderation, Fiddler Guardrails use the Centor Model for PII/PHI, which detects, flags, and redacts PII leakage in both user inputs and model responses. PII/PHI moderation supports a comprehensive set of label types, including: `person, address, email, email address, credit card number, credit card expiration date, cvv, cvc, bank account number, iban, social security number, date of birth, ip address, phone number, mobile phone number, landline phone number, passport number, driver's license number, tax identification number, cpf, cnpj, account number, license plate number, fax number, website, digital signature, postal code`. See the [PII & PHI Tutorial](/developers/tutorials/guardrails/guardrails-pii) for the full entity list. The Centor Model for PII/PHI supports a different entity set than the [PII Enrichment](/observability/llm/enrichments#personally-identifiable-information) (which uses Presidio). For monitoring and batch processing, see the PII Enrichment documentation. **PHI Detection also supported.** Fiddler Guardrails also detect Protected Health Information (PHI) for HIPAA compliance, including: `medication, medical condition, health insurance number, health insurance id number, national health insurance number, birth certificate number, serial number`. Pass `"entity_categories": "PHI"` in your request body. See the [PII & PHI Tutorial](/developers/tutorials/guardrails/guardrails-pii) for full entity lists and example code. This model accepts a single text string and returns all detected PII spans with their labels, confidence scores, and character offsets. ### PII/PHI Example Code ```bash theme={null} curl --location 'https://{fiddler_endpoint}/v3/guardrails/sensitive-information' --header 'Content-Type: application/json' --header 'Authorization: Bearer {token}' --data '{ "data": { "input": "Some of my colleagues share their contact info as well. Jane Smith's email is jane.smith@company.com, and her office is located at 432 Oak Avenue, Suite 210, Chicago, IL 60611. You can call her mobile at 312-555-7890." } }' ``` ```python theme={null} import requests import json token = "YOUR_FIDDLER_TOKEN_HERE" url = "FIDDLER_ENDPOINT_HERE" payload = json.dumps( { "data": { "input": "Some of my colleagues share their contact info as well. Jane Smith's email is jane.smith@company.com, and her office is located at 432 Oak Avenue, Suite 210, Chicago, IL 60611. You can call her mobile at 312-555-7890." } } ) headers = {"Content-Type": "application/json", "Authorization": f"Bearer {token}"} response = requests.request( "POST", f"{url}/v3/guardrails/sensitive-information", headers=headers, data=payload ) print(response.text) ``` **Sample Response** ```json theme={null} { "fdl_sensitive_information_scores": [ { "score": 0.987, "label": "email", "start": 78, "end": 100, "text": "jane.smith@company.com" }, { "score": 0.945, "label": "address", "start": 131, "end": 175, "text": "432 Oak Avenue, Suite 210, Chicago, IL 60611" }, { "score": 0.987, "label": "mobile phone number", "start": 204, "end": 216, "text": "312-555-7890" } ] } ``` **Response Fields:** * `score` - Confidence score (0.0 to 1.0) * `label` - Entity type (e.g., "email", "social security number") * `text` - The detected sensitive information * `start` / `end` - Character positions in the input text *** ## Summary Fiddler Guardrails provide real-time protection for GenAI applications, powered by Fiddler Centor Models, across three categories of risk: * **Safety** - Detect harmful content across 11 safety dimensions with a calibrated default decision threshold of 0.5 (tunable) * **Hallucination (faithfulness)** - Identify hallucinations in RAG applications with a recommended threshold of \< 0.5 * **PII/PHI** - Detect and redact PII and PHI across a comprehensive set of entity types All guardrails use Fiddler Centor Models—Fiddler's proprietary small language models—optimized for sub-second latency in production environments. ## Next Steps * **Quick Start** - [Get started with Fiddler Guardrails in 15 minutes](/developers/quick-starts/guardrails-quick-start) * **API Reference** - [Complete Guardrails API documentation](/sdk-api/guardrails-api-reference) * **Tutorials** - Explore detailed tutorials for [Safety](/developers/tutorials/guardrails/guardrails-safety), [PII](/developers/tutorials/guardrails/guardrails-pii), and [Faithfulness](/developers/tutorials/guardrails/guardrails-faithfulness) * **Concepts** - [Understand Fiddler Centor Models and enrichments](/observability/llm/enrichments) * **Monitoring** - [Integrate guardrails with LLM monitoring](/observability/llm/enrichments#safety) # Guardrails FAQ Source: https://docs.fiddler.ai/protection/guardrails-faq Find answers to common questions about Fiddler Guardrails, including setup, implementation, and general information for protecting your LLM applications. ## Fiddler Guardrails: Frequently Asked Questions ### Deployment & Latency **Q: Why am I getting much higher latencies than advertised?** **A:** Fiddler Guardrails achieves its lowest latencies when requests are made to a Fiddler environment within the same network boundaries as your application. Network distance between your application and the Fiddler environment adds round-trip time. Latency spikes can also occur due to temporary usage surges, even though we provision for peak capacity. If you’re consistently experiencing higher latencies, please contact us on the #fiddler-guardrails-support channel. **Q: What does this error code mean? How do I fix it?** **A:** Please visit the [Guardrails tutorials](/developers/tutorials/guardrails) for detailed information about error codes and their solutions. ### Service Features **Q: What's included in Fiddler Guardrails?** **A:** Fiddler Guardrails includes: * Real-time safety moderation across 11 dimensions * Faithfulness (hallucination) detection for RAG applications * PII/PHI detection and redaction * Integration options with NVIDIA NeMo Guardrails and LangChain ### General Information & Future Plans **Q: What are Fiddler Centor Models?** **A:** Integral to the Fiddler AI Observability and Security platform, Fiddler Centor Models are a series of proprietary, fine-tuned small language models (SLMs) that enable high-quality LLM monitoring and scoring in live environments with the fastest guardrails in the industry. For added security, Centor Models can be deployed in VPC or air-gapped environments, ensuring enterprises maintain strict data control and safeguard LLM applications. **Q: How does Fiddler Guardrails use Fiddler Centor Models?** **A:** At \<100ms latency, Fiddler Guardrails is the fastest in the industry. It leverages the scoring of Fiddler Centor Models to evaluate prompts and responses and moderate harmful outputs for hallucination, toxicity, and jailbreaks. Simply specify your desired metric thresholds and let Fiddler Guardrails handle the enforcement. **Q: What languages are supported?** **A:** Fiddler Guardrails currently only supports English. Based on user feedback, we're evaluating support for additional languages. **Q: How can I stay updated on service improvements?** **A:** Stay informed about regular updates to Fiddler Guardrails by: * Following our [product updates page](/changelog/product-releases) * Subscribing to our [newsletter](https://www.fiddler.ai/blog#subscribe) * Joining the [Fiddler Community Slack](https://www.fiddler.ai/slackinvite) **Q: Where can I share feedback or request features?** **A:** We welcome your input! Please reach out to our team on Slack in the #fiddler-guardrails-support channel. Your feedback helps us prioritize improvements. **Q: Is Fiddler Guardrails an experimental or beta product?** **A:** No, Fiddler Guardrails is a fully supported feature of the Fiddler AI Observability and Security platform. # Guardrails Quick Start Source: https://docs.fiddler.ai/protection/guardrails-quick-start Set up access to Fiddler Guardrails in your Fiddler environment and make your first API call to protect your LLM applications. Fiddler Guardrails is available via the REST API. This page covers how to set up access and make your first call. For a full implementation walkthrough with code for every guardrail type, see the [Guardrails developer quick start](/developers/quick-starts/guardrails-quick-start). ## Prerequisites * Access to a Fiddler environment with Guardrails enabled * Permission to generate an API key in that environment ## Set up access Sign in to Fiddler. Guardrails is served from the same environment at `https://{fiddler_endpoint}/v3/guardrails/*`. If you are not sure whether Guardrails is enabled for your environment, contact your Fiddler representative. Generate a Fiddler API key from **Settings → [Credentials](/reference/administration/settings#credentials)**. You pass this key as a bearer token on every Guardrails request. Send a request to a `/v3/guardrails/*` endpoint with your API key in the `Authorization` header. The example below calls the safety guardrail. ```bash theme={null} curl --location 'https://{fiddler_endpoint}/v3/guardrails/ftl-safety' \ --header 'Content-Type: application/json' \ --header 'Authorization: Bearer {token}' \ --data '{ "data": { "input": "I am a dangerous person who will be wreaking havoc upon the world!!!" } }' ``` For API specifications and model details, see the [Guardrails API Reference](/sdk-api/guardrails-api-reference). For implementation examples in Python and other languages, see the [Guardrails developer quick start](/developers/quick-starts/guardrails-quick-start). ### Explore Fiddler Guardrails Features * [Frequently Asked Questions](/protection/guardrails-faq) * Notebook Tutorials: * [**Safety Guardrails Quick Start**](/developers/tutorials/guardrails/guardrails-safety) * [**PII Detection Quick Start**](/developers/tutorials/guardrails/guardrails-pii) * [**Faithfulness Quick Start**](/developers/tutorials/guardrails/guardrails-faithfulness) # Overview Source: https://docs.fiddler.ai/protection/index Ensure AI safety and compliance with guardrails and monitoring Fiddler Protect provides comprehensive AI safety through real-time guardrails, continuous monitoring, and intelligent alerting—all powered by Fiddler Centor Models. Built on purpose-optimized evaluation models that are 10-100x faster than general-purpose LLMs, Fiddler Protect helps you prevent harmful outputs, detect privacy violations, ensure factual accuracy, and maintain compliance across your AI applications. ## Protection Layers Fiddler Protect operates through multiple complementary layers of defense: ```mermaid theme={null} graph TB Input[User Input] --> RTG[Real-Time Guardrails] RTG --> Safety{Safety Check} RTG --> PII{PII Detection} RTG --> Secrets{Secret Detection} RTG --> Faith{Faithfulness} Safety -->|Pass| LLM[LLM Processing] PII -->|Pass| LLM Secrets -->|Pass| LLM Faith -->|Pass| LLM Safety -->|Fail| Block[Blocked/Filtered] PII -->|Fail| Block Secrets -->|Fail| Block Faith -->|Fail| Block LLM --> Output[AI Response] Output --> Monitor[Continuous Monitoring] Monitor --> Enrich[Safety Enrichments] Monitor --> Drift[Data Integrity & Drift] Enrich --> Alert{Alert Threshold?} Drift --> Alert Alert -->|Yes| Notify[Send Notifications] Alert -->|No| Log[Audit Log] Notify --> Log style RTG fill:#e1f5ff style Monitor fill:#fff4e6 style Alert fill:#ffe6e6 style Block fill:#ffcccc style Output fill:#e6ffe6 ``` ### Real-Time Guardrails Fast, pre-deployment protection that evaluates and filters AI inputs and outputs before they reach users. #### Safety Guardrails Detect and prevent harmful content across 11 safety dimensions: * **Harmful Behaviors**: Jailbreaking attempts, prompt injection, illegal content promotion * **Offensive Content**: Hate speech, harassment, racism, sexism * **Inappropriate Content**: Violence, explicit sexual content, unethical scenarios * **Risk Categories**: Toxic language, dangerous information, inappropriate roleplaying The Centor Model for Safety provides real-time evaluation with sub-second latency, making it practical for high-volume production deployments. Each dimension returns a confidence score (0-1 range) allowing you to set custom thresholds based on your risk tolerance. #### PII/PHI Detection Protect user privacy by automatically detecting sensitive information in model inputs and outputs: * **Personal Identifiers**: Names, dates of birth, email addresses, phone numbers * **Financial Data**: Credit card numbers, bank accounts, tax IDs * **Government IDs**: Social security numbers, passport numbers, driver's licenses * **Healthcare Information**: Medications, medical conditions, health insurance numbers, birth certificate numbers (HIPAA compliance) * **Custom Entities**: Organization-specific sensitive patterns (employee IDs, API keys, internal codes) The Centor Model for PII/PHI identifies a comprehensive set of PII and PHI entity types, returning exact positions and confidence scores for each detected instance. #### Secret Detection Prevent credentials and API keys from leaking through LLM prompts or responses: * **LLM Provider Keys**: Anthropic, OpenAI, Hugging Face, Replicate * **Cloud Credentials**: AWS, Google, Azure, DigitalOcean, Heroku * **Source Control Tokens**: GitHub, GitLab, Bitbucket personal access tokens * **Infrastructure Secrets**: HashiCorp Vault, Terraform Cloud, Supabase, Vercel * **Communication Keys**: Slack, Discord, SendGrid, Twilio, Mailgun * **Generic Secrets**: JWT tokens, PEM private keys, database connection strings, high-entropy strings The Centor Secret Detector uses \~42 compiled regex patterns plus Shannon entropy analysis to catch both known credential formats and unknown high-entropy secrets. Returns character-level spans for precise redaction. #### Faithfulness & Accuracy Prevent hallucinations and ensure AI responses stay grounded in source material: * **Hallucination Detection**: Evaluate whether AI responses are factually consistent with provided context * **RAG Validation**: Verify that generated content accurately reflects retrieved documents * **Source Grounding**: Ensure answers don't introduce information not present in reference materials The Centor Model for Faithfulness compares AI-generated responses against source documents to detect when models fabricate information or misrepresent facts. #### Performance Advantage All guardrail models are **10-100x faster** than general-purpose LLMs like GPT-4 for evaluation tasks, enabling: * Real-time filtering without noticeable latency * High-volume production deployment * Cost-effective safety at scale * No external API dependencies for enhanced security ### Continuous Monitoring Post-deployment protection through ongoing analysis of production traffic. #### Safety Enrichments Monitor your production AI systems for safety and quality issues: * **Toxicity Detection**: Identify toxic language patterns using advanced classification models * **Profanity Filtering**: Detect offensive language in both inputs and outputs * **PII Monitoring**: Continuously scan for privacy violations in production data * **Sentiment Analysis**: Track emotional tone and user experience signals * **Custom Classification**: Apply organization-specific categorization rules These enrichments run automatically on your production traffic, providing visibility into safety issues that may emerge over time or in specific contexts. #### Data Integrity & Drift Protect against data quality issues and distribution changes: * **Missing Value Detection**: Identify incomplete inputs that may cause unpredictable behavior * **Type Validation**: Catch data type mismatches (e.g., strings where numbers expected) * **Range Monitoring**: Detect out-of-range values that violate expected constraints * **Distribution Drift**: Track when production data diverges from training or baseline data * **Embedding Visualization**: Use 3D UMAP plots to visually identify anomalies in high-dimensional data ### Alerting & Response Automated notification system for proactive risk management: * **Drift Alerts**: Detect when production data or model behavior changes significantly * **Data Integrity Alerts**: Flag missing values, type mismatches, or range violations * **Performance Alerts**: Monitor for model accuracy degradation over time * **Custom Metric Alerts**: Define formula-based alerts for business-specific KPIs * **Traffic Alerts**: Track system volume for capacity planning and anomaly detection Configure alerts with warning and critical thresholds, and route notifications to your team via email, Slack, PagerDuty, or custom webhooks. All alerts include triggered revisions that update in real-time as new data arrives. ## Fiddler Centor Models All protection capabilities are powered by Fiddler Centor Models—purpose-built evaluation models optimized for safety, quality, and accuracy assessment. Unlike general-purpose LLMs repurposed for evaluation, Centor Models are specifically designed for these tasks, delivering: * **Speed**: 10-100x faster evaluation than GPT-4 * **Security**: Air-gapped deployment options with no external API dependencies * **Privacy**: Full data sovereignty for GDPR, HIPAA, and CCPA compliance * **Reliability**: Consistent, deterministic evaluation at scale ```mermaid theme={null} graph LR subgraph Trust[Fiddler Centor Models] Fast1[Centor Model for Safety
11 Dimensions] Fast2[Centor Model for PII/PHI
PII & PHI Entities] Fast3[Centor Secret Detector
~42 Secret Types] Fast4[Centor Model for Faithfulness
Hallucination Detection] end App[Your Application] --> Fast1 App --> Fast2 App --> Fast3 App --> Fast4 Fast1 --> Score1[Safety Scores
0-1 per dimension] Fast2 --> Score2[Entity Detection
+ Positions] Fast3 --> Score3[Secret Spans
Label + Position] Fast4 --> Score4[Faithfulness Score
0-1 range] Score1 --> Decision{Policy
Enforcement} Score2 --> Decision Score3 --> Decision Score4 --> Decision Decision -->|Safe| Allow[✓ Allow Response] Decision -->|Unsafe| Block[✗ Block Response] style Trust fill:#f0f0f0 style Fast1 fill:#e1f5ff style Fast2 fill:#e1f5ff style Fast3 fill:#e1f5ff style Allow fill:#e6ffe6 style Block fill:#ffcccc ``` ## Key Use Cases ### Content Safety Prevent your AI applications from generating harmful, offensive, or inappropriate content: * Filter toxic language and hate speech in real-time * Block jailbreaking attempts and prompt injection attacks * Detect violent, sexual, or otherwise inappropriate outputs before they reach users * Maintain brand reputation by ensuring responsible AI behavior ### Privacy Protection Safeguard user privacy and maintain compliance with data protection regulations: * Automatically detect and redact PII in both inputs and outputs * Support HIPAA compliance through PHI detection * Configure custom entity detection for organization-specific sensitive data * Monitor for privacy violations in production traffic ### Accuracy & Truthfulness Ensure your AI systems provide accurate, grounded information: * Detect hallucinations in RAG applications before presenting to users * Validate that generated content reflects source documents accurately * Monitor for factual consistency across your AI responses * Maintain trust by preventing fabricated or misleading information ### Regulatory Compliance Meet compliance requirements while maintaining comprehensive audit trails: * GDPR compliance through PII detection and data sovereignty options * HIPAA compliance with PHI detection and air-gapped deployment * Complete audit logging of all safety events and policy enforcement * Bias and fairness monitoring for regulatory reporting ## Getting Started ### Quick Start Guides Get up and running with Fiddler Protect in minutes: * [**Guardrails Quick Start**](/protection/guardrails-quick-start) - Set up real-time protection * [**Safety Guardrails Quick Start**](/developers/tutorials/guardrails/guardrails-safety) - Implement content safety filters * [**PII Detection Quick Start**](/developers/tutorials/guardrails/guardrails-pii) - Protect user privacy * [**Secret Detection Quick Start**](/developers/tutorials/guardrails/guardrails-secrets) - Prevent credential leakage * [**Faithfulness Quick Start**](/developers/tutorials/guardrails/guardrails-faithfulness) - Prevent hallucinations ### Documentation & References Dive deeper into Fiddler Protect capabilities: * [**Guardrails API Reference**](/sdk-api/guardrails-api-reference) - Complete API documentation * [**LLM-Based Metrics**](/observability/llm/llm-based-metrics) - Quality and safety metrics * [**Enrichments Guide**](/observability/llm/enrichments) - Continuous monitoring enrichments * [**Alerts Platform**](/observability/platform/alerts-platform) - Configure alerting and notifications * [**Guardrails FAQ**](/protection/guardrails-faq) - Common questions and answers ### Additional Resources Learn more about the underlying technology: * [**Centor Models Overview**](/glossary/centor-models) - Learn about the evaluation platform * [**Guardrails Glossary**](/glossary/guardrails) - Key concepts and terminology *** **Ready to get started?** Try the [Guardrails Quick Start](/protection/guardrails-quick-start) to implement your first safety guardrail in minutes. # LiteLLM Guardrails Source: https://docs.fiddler.ai/protection/litellm-guardrails Use Fiddler as a guardrail provider for the LiteLLM proxy gateway — blocking and redacting PII and secrets in real time before requests reach your LLM. # LiteLLM Guardrails ## Overview Fiddler implements the [LiteLLM Generic Guardrail API](https://docs.litellm.ai/docs/adding_provider/generic_guardrail_api) spec, allowing you to plug Fiddler's guardrails directly into a LiteLLM proxy gateway. Once configured, every LLM request routed through the proxy is checked by Fiddler before it reaches the model. **Fiddler checks for:** * **Secrets** — API keys, tokens, credentials, and connection strings in prompts * **PII** — Personal identifiable information (names, emails, phone numbers, SSNs, credit cards, etc.) Each check can independently block or redact — see [Check Behavior](#check-behavior) for details. *** ## How It Works ```mermaid theme={null} graph LR Client["Client
(coding agent, app, curl)"] Client -->|"POST /v1/chat/completions"| LiteLLM["LiteLLM Proxy"] LiteLLM -->|"POST /v3/guardrails/litellm/beta/litellm_basic_guardrail_api
(pre_call / post_call)"| Fiddler["Fiddler Guardrails API"] Fiddler -->|"action: BLOCKED"| LiteLLM Fiddler -->|"action: NONE or GUARDRAIL_INTERVENED → proceed"| LiteLLM LiteLLM -->|"Sanitized request"| LLM["LLM Provider
(OpenAI, Vertex AI, etc.)"] style Client fill:#e1f5ff style LiteLLM fill:#fff4e6 style Fiddler fill:#ffe6e6 style LLM fill:#e6ffe6 ``` LiteLLM calls the Fiddler endpoint with the extracted text from the request (or response). Fiddler returns one of three actions: | Action | Meaning | LiteLLM behavior | | ---------------------- | -------------------------- | ------------------------------------------ | | `NONE` | No issues detected | Forwards the request unchanged | | `GUARDRAIL_INTERVENED` | Sensitive content redacted | Forwards the request with redacted `texts` | | `BLOCKED` | Request must not proceed | Returns an error to the client | *** ## Supported Modes Fiddler supports all three LiteLLM guardrail modes. Set `mode` in your proxy config to one or more of: | Mode | When it runs | What gets checked | Can modify input? | | ------------- | ----------------------------- | ----------------- | -------------------------- | | `pre_call` | Before the LLM call | PII + Secrets | Yes (redact in place) | | `post_call` | After the LLM call | PII + Secrets | Yes (redact in place) | | `during_call` | In parallel with the LLM call | PII + Secrets | No (accept or reject only) | `during_call` runs the guardrail concurrently with the LLM call — the response is held until the check completes, but latency is hidden behind the LLM round-trip. Use it when you want lower end-to-end latency and don't need input redaction (block-only is sufficient). You can combine modes. For example, `mode: [pre_call, post_call]` scans both input and output: ```yaml theme={null} guardrails: - guardrail_name: "fiddler" litellm_params: guardrail: generic_guardrail_api mode: [pre_call, post_call] ``` ### Supported Endpoints The guardrail runs on all LiteLLM proxy endpoints that carry text content, including `/v1/chat/completions` (OpenAI format) and `/v1/messages` (Anthropic format). LiteLLM extracts text from the request and forwards it to the Fiddler endpoint regardless of the upstream provider format. *** ## What Gets Scanned | Check | `pre_call` | `post_call` | `during_call` | Free-text messages | Tool-call args | | ----------- | ---------- | ----------- | ------------- | ------------------ | -------------- | | **PII** | ✓ | ✓ | ✓ | Redact | Block | | **Secrets** | ✓ | ✓ | ✓ | Redact | Block | * **Free-text messages** — user, assistant, and system messages. PII/secrets are redacted in place (e.g. `[REDACTED EMAIL_ADDRESS]`). * **Tool-call arguments** — structured JSON in `tool_calls[].function.arguments`. Detections are **always blocked** (cannot safely redact inside structured JSON — see [Tool Call Handling](#tool-call-handling)). *** ## Quick Start ### Step 1: Configure LiteLLM Add the Fiddler guardrail to your LiteLLM `config.yaml`: ```yaml theme={null} guardrails: - guardrail_name: "fiddler" litellm_params: guardrail: generic_guardrail_api mode: [pre_call] api_base: https:///v3/guardrails/litellm default_on: true # Block if the Fiddler endpoint is unreachable (network error / 5xx). # Covers transport failures. Default: fail_closed. unreachable_fallback: fail_closed headers: Authorization: "Bearer " additional_provider_specific_params: # Block if an internal check fails to complete (inference timeout/error). # Covers detector failures. Default when omitted: open. failure_mode: closed # Wall-clock timeout (seconds) for the guardrail check. How long the # endpoint blocks before returning. Default: 12. Max: 60. timeout: 12 pii: enabled: true config: threshold: 0.8 mode: redact # "redact" (default) or "block" secrets: enabled: true config: mode: redact # "redact" (default) or "block" ``` LiteLLM appends `/beta/litellm_basic_guardrail_api` to `api_base` automatically. The full endpoint called will be `https:///v3/guardrails/litellm/beta/litellm_basic_guardrail_api`. ### Step 2: Start the proxy ```bash theme={null} litellm --config config.yaml --port 4000 ``` ### Step 3: Verify Send a request with a known secret: ```bash theme={null} curl -i http://localhost:4000/v1/chat/completions \ -H "Content-Type: application/json" \ -H "Authorization: Bearer " \ -d '{"model":"gpt-4o-mini","messages":[{"role":"user","content":"My API key is sk-ant-api03-abcdefghijklmnopqrstu"}]}' ``` The secret will be redacted to `[REDACTED ANTHROPIC_API_KEY]` before the request reaches the model. *** ## Per-Request Control With `default_on: true` (the recommended config above), the guardrail runs on every request automatically. You can also control it per request. ### Selective activation (`default_on: false`) Set `default_on: false` in the proxy config, then activate the guardrail on individual requests by passing `guardrails` in the request body: ```json theme={null} { "model": "gpt-4o-mini", "messages": [{"role": "user", "content": "..."}], "guardrails": ["fiddler"] } ``` Requests without `"guardrails": ["fiddler"]` will bypass the guardrail entirely. *** ## Check Behavior Each check is configured entirely in the LiteLLM proxy's `additional_provider_specific_params`: * **`enabled`** (`true` / `false`) — whether the check runs at all. * **`mode`** (`redact` / `block`) — what happens when a detection is found. Default is `redact` for PII and secrets. * **`threshold`** and **`entities`** — detection sensitivity. If **any** of `pii` or `secrets` is specified in `additional_provider_specific_params`, only the checks explicitly listed with `enabled: true` will run. To tune one check without silently disabling the other, list both keys with explicit `enabled: true` or `enabled: false`. ### Secrets Detects credentials, API keys, and tokens. | Mode | Behavior in free-text messages | Behavior in tool call arguments | | ------------------ | ---------------------------------------------------------- | --------------------------------------------------------- | | `redact` (default) | Value replaced with `[REDACTED ]`, request forwarded | **Always blocked** — cannot safely redact structured JSON | | `block` | Request blocked entirely | Request blocked | ```yaml theme={null} secrets: enabled: true config: mode: redact # "redact" (default) or "block" ``` ### PII Detects personal identifiable information. | Mode | Behavior in free-text messages | Behavior in tool call arguments | | ------------------ | ---------------------------------------------------------- | --------------------------------------------------------- | | `redact` (default) | Value replaced with `[REDACTED ]`, request forwarded | **Always blocked** — cannot safely redact structured JSON | | `block` | Request blocked entirely | Request blocked | Entities checked by default include: `person`, `email`, `phone number`, `social security number`, `credit card number`, `bank account number`, `passport number`, `driver's license number`, `date of birth`, `address`, `ip address`, `iban`, `cvv`, `cvc`, `tax identification number`, `digital signature`, `license plate number`, `postal code`, and more. For the complete list see the [PII Detection tutorial](/developers/tutorials/guardrails/guardrails-pii#supported-entity-types). ```yaml theme={null} pii: enabled: true config: mode: redact # "redact" (default) or "block" threshold: 0.8 # detection confidence threshold (default: 0.8) entities: # optional: override default entity list - person - email - phone number ``` *** ## Tool Call Handling When an LLM's `tool_calls` contain PII or secrets, Fiddler **always blocks** rather than redacts. **Why:** Tool call arguments are structured JSON that the downstream application will parse and execute. Replacing a value like an email address with `[REDACTED EMAIL_ADDRESS]` would cause `send_email` to attempt delivery to a nonsensical address — producing unpredictable behavior that is worse than blocking outright. **Example — blocked tool call:** ```json theme={null} { "role": "assistant", "tool_calls": [{ "id": "call_abc123", "type": "function", "function": { "name": "send_email", "arguments": "{\"to\": \"jane.doe@example.com\", \"body\": \"Phone: 555-867-5309\"}" } }] } ``` Fiddler returns: ```json theme={null} {"action": "BLOCKED", "blocked_reason": "PII or secrets detected in tool call arguments. Cannot redact tool call arguments — blocking request."} ``` LiteLLM then translates this into an error for the client (HTTP 400 on LiteLLM ≥ 1.88.0, HTTP 500 on earlier versions). ### Tool Results Fiddler does **not** claim redaction coverage for tool results. Whether tool result content reaches the scanner depends on the LiteLLM gateway: LiteLLM must include the tool result in the `texts[]` it forwards to Fiddler. This is not guaranteed for all gateway configurations or versions, and is known not to work on customer-managed or self-hosted gateways that do not extract `role:tool` / `tool_result` messages into `texts[]`. Additionally, tool results are typed as `any` in the GenAI semantic conventions — they can be plain strings, JSON objects, or arrays. Even when the text does reach the scanner, in-place character-span redaction on a serialized JSON payload is not safe if the downstream application re-parses the result as structured data. For reliable protection against secrets in tool output, use `mode: block` on secrets and treat tool result content as untrusted. *** ## Failure Mode Two settings control what happens when the guardrail cannot complete a check — one at the LiteLLM proxy level, one at the Fiddler endpoint level. Both should be set for end-to-end fail-closed. ### `unreachable_fallback` (LiteLLM proxy) Controls what happens when the Fiddler endpoint is **unreachable** (network error, HTTP 502/503/504). ```yaml theme={null} litellm_params: unreachable_fallback: fail_closed # default: fail_closed ``` | Value | Behavior | | ----------------------- | ------------------------------------------ | | `fail_closed` (default) | Block the request — the LLM never sees it | | `fail_open` | Allow the request through without scanning | This is a [standard LiteLLM Generic Guardrail API setting](https://docs.litellm.ai/docs/adding_provider/generic_guardrail_api). ### `failure_mode` (Fiddler endpoint) Controls what happens when an **internal** check fails to complete — an inference timeout, an inference server error, or an unexpected exception in the detection pipeline. The LiteLLM proxy cannot see these failures because the Fiddler endpoint still returns HTTP 200. ```yaml theme={null} additional_provider_specific_params: failure_mode: closed # default when omitted: open ``` | Value | Behavior | | ---------------- | ------------------------------------------------------------------------- | | `open` (default) | Allow the request through — the failed check is logged but does not block | | `closed` | Block the request — unscanned content never reaches the LLM | The default is `open` for backward compatibility. For security-sensitive deployments, set `failure_mode: closed`. When both `unreachable_fallback: fail_closed` and `failure_mode: closed` are set, no request can bypass scanning — whether the failure is at the transport or detector level. *** ## Limits & Timeouts ### Text Length The maximum total text length scanned per request is controlled by the `GUARDRAILS_MAX_TEXT_LENGTH` environment variable on the Fiddler server (default: **50,000 characters**). Messages are concatenated until this cap is reached; text beyond the cap is handled as follows: | Content type | Fail-open (`failure_mode: open`) | Fail-closed (`failure_mode: closed`) | | ------------------- | ----------------------------------------------- | ------------------------------------ | | Free-text messages | Skipped (unscanned, request proceeds) | **Blocked** | | Tool-call arguments | **Always blocked** (regardless of failure mode) | **Blocked** | ### Timeouts The guardrail check has a single customer-facing timeout: the **wall-clock deadline** for the whole check pipeline — how long the endpoint blocks before returning. Set it per request via `timeout` (seconds) in `additional_provider_specific_params`: ```yaml theme={null} additional_provider_specific_params: timeout: 12 # default: 12, max: 60 ``` What you set is what you get — there is no hidden padding. Omitted or invalid values fall back to the default (12s); values above the maximum are clamped to 60s. When the deadline is reached before the checks complete, the outcome is governed by `failure_mode` — under `open` the request proceeds unscanned, under `closed` it is blocked. The internal inference-call timeouts (`GUARDRAILS_GATEWAY_READ_TIMEOUT`, default 10s, and `GUARDRAILS_GATEWAY_CONN_TIMEOUT`, default 3s) are server-side plumbing for the connection to the detection models. They are lower than the wall-clock `timeout` and are not part of the customer-facing config. *** ## Observed Behavior **Minimum required version: LiteLLM ≥ 1.88.0.** Earlier versions return HTTP 500 for all guardrail blocks due to a bug in `GuardrailRaisedException` (missing `status_code` attribute). The Fiddler team identified and fixed this upstream in [BerriAI/litellm#27617](https://github.com/BerriAI/litellm/pull/27617). The fix shipped in LiteLLM 1.88.0. On 1.88.0+, blocked requests correctly return HTTP 400. | Scenario | Action | HTTP status | Notes | | ------------------------------------------------------------------- | ---------------------------------------------- | -------------------- | -------------------------------------------------------------- | | Secret in user message | `GUARDRAIL_INTERVENED` | 200 | Redacted in-place; LLM receives sanitized text | | PII in user message | `GUARDRAIL_INTERVENED` | 200 | Redacted in-place | | PII in tool call arguments | `BLOCKED` | 400 (500 pre-1.88.0) | Cannot redact structured JSON | | Detector timeout (`failure_mode: open`) | `NONE` | 200 | Request proceeds unscanned | | Detector timeout (`failure_mode: closed`) | `BLOCKED` | 200 | Request blocked; unscanned content never reaches LLM | | Guardrail service unreachable (`unreachable_fallback: fail_closed`) | *(LiteLLM-side block — Fiddler never reached)* | 400 | LiteLLM rejects the request before forwarding to the guardrail | ### Client-Facing Error Body When a request is blocked, LiteLLM returns an error to the client. Your application should handle this shape: ```json theme={null} { "error": { "message": "Guardrail fiddler rejected the request. PII or secrets detected in tool call arguments. Cannot redact tool call arguments — blocking request.", "type": "None", "param": "None", "code": "400" } } ``` The `message` field contains the `blocked_reason` from Fiddler's response, prefixed by LiteLLM with the guardrail name. HTTP status is 400 on LiteLLM ≥ 1.88.0. *** ## API Reference ### Endpoint ``` POST /v3/guardrails/litellm/beta/litellm_basic_guardrail_api ``` Authentication: `Authorization: Bearer ` ### Request ```json theme={null} { "texts": ["string"], "tool_calls": [{"id": "...", "type": "function", "function": {"name": "...", "arguments": "..."}}], "tools": [{"type": "function", "function": {"name": "get_weather", "description": "Get current weather", "parameters": {"type": "object", "properties": {"location": {"type": "string"}}, "required": ["location"]}}}], "structured_messages": [{"role": "user", "content": "..."}], "images": ["base64-encoded-string"], "request_data": {"user_api_key_alias": "my-key", "user_api_key_team_id": "team-123"}, "request_headers": {"content-type": "application/json"}, "input_type": "request", "additional_provider_specific_params": { "failure_mode": "closed", "timeout": 12, "pii": {"enabled": true, "config": {"threshold": 0.8, "mode": "redact"}}, "secrets": {"enabled": true, "config": {"mode": "redact"}} }, "litellm_call_id": "uuid", "litellm_trace_id": "uuid", "litellm_version": "1.88.0" } ``` Only `texts` and `tool_calls[].function.arguments` are scanned by guardrail checks. The remaining fields are accepted for LiteLLM protocol compatibility. | Field | Type | Required | Description | | ------------------------------------- | --------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | | `texts` | `string[]` | Yes | Extracted text strings from the request messages (scanned) | | `request_data` | `object` | Yes | LiteLLM virtual key metadata (user, team, org, key hash) | | `input_type` | `"request"` \| `"response"` | Yes | Whether this is a pre-call or post-call check | | `tool_calls` | `object[]` \| `null` | No | Tool invocations in OpenAI format (arguments are scanned) | | `tools` | `object[]` \| `null` | No | Tool definitions in OpenAI format (not scanned) | | `structured_messages` | `object[]` \| `null` | No | Full messages array in OpenAI format (not scanned) | | `images` | `string[]` \| `null` | No | Base64-encoded images (not scanned) | | `request_headers` | `object` \| `null` | No | Inbound request headers (not scanned) | | `additional_provider_specific_params` | `object` \| `null` | No | Per-check configuration plus `failure_mode` and `timeout` (see [Quick Start](#quick-start), [Failure Mode](#failure-mode), and [Timeouts](#timeouts)) | | `litellm_call_id` | `string` \| `null` | No | LiteLLM call ID for tracing | | `litellm_trace_id` | `string` \| `null` | No | LiteLLM trace ID for tracing | | `litellm_version` | `string` \| `null` | No | LiteLLM library version | ### Response Fields with `null` values are omitted from the wire (`exclude_none=True`). The response shape varies by action: ```json theme={null} // action: NONE {"action": "NONE"} // action: BLOCKED {"action": "BLOCKED", "blocked_reason": "PII or secrets detected in tool call arguments. Cannot redact tool call arguments — blocking request."} // action: GUARDRAIL_INTERVENED {"action": "GUARDRAIL_INTERVENED", "texts": ["My key is [REDACTED ANTHROPIC_API_KEY]"]} ``` | Field | Type | Description | | ---------------- | ---------- | -------------------------------------------------------------------- | | `action` | `string` | One of `NONE`, `BLOCKED`, or `GUARDRAIL_INTERVENED` | | `blocked_reason` | `string` | Human-readable reason; present only when `action` is `BLOCKED` | | `texts` | `string[]` | Redacted texts; present only when `action` is `GUARDRAIL_INTERVENED` | *** ## Related Documentation * [Guardrails overview](/protection/guardrails) * [LiteLLM Integration (observability)](/integrations/agentic-ai/litellm-integration) * [LiteLLM Generic Guardrail API spec](https://docs.litellm.ai/docs/adding_provider/generic_guardrail_api) # Authentication Management Source: https://docs.fiddler.ai/reference/access-control/authn-authentication-management-console ## AuthN Management Console Guide This guide provides step-by-step instructions for using the Fiddler AuthN management console to configure authentication methods and manage users. ### Overview The Fiddler AuthN management console is a dedicated interface for authentication administration that allows you to: * Configure Single Sign-On (SSO) integrations with identity providers * Manage user accounts for email authentication * Assign administrative roles for authentication management * Monitor authentication settings and user status The console uses our new identity and access management framework, to provide secure and flexible authentication capabilities for the Fiddler platform. ### How to Sign In to the AuthN Console The AuthN console is accessed through a separate URL from your main Fiddler instance. **To access the AuthN console:** 1. Navigate to your AuthN console URL. The URL format is your Fiddler base URL with `authn-` prepended: * If your Fiddler URL is `https://acme.cloud.fiddler.ai` * Your AuthN console URL is `https://authn-acme.cloud.fiddler.ai` 2. For a new deployment and the first user sign-in: 1. If you are using email authentication use the credentials provided by your Fiddler representative during initial setup or those you created using the email invitation sent during onboarding 2. If you are using SSO your user account will be created automatically on your first sign-in 3. Select your organization from the dropdown menu * You may see a *fiddler* organization, but this is reserved for system use * Select your company's organization from the available options ### Understanding the Root User The **root user** is the default authentication administrator created during your Fiddler deployment setup. This user is reserved for Fiddler use with deployments managed by Fiddler. Fiddler will use the root user account to either configure your SSO integration or will assign one or more of your organization's users for managing your authentication set up moving forward. ### Understanding AuthN Roles There are two roles specific to the AuthN management console and not to the Fiddler application: the Org Owner and the Org User Manager roles. The Org Owner can configure settings at the organization level which includes the authentication configuration and the ability to assign roles to other users. The Org User Manager is limited to managing user access to Fiddler. #### Org Owner Role Capabilities Users with the Org Owner role can perform all authentication management tasks, including: * **Identity Provider Management**: Configure and manage SSO integrations with external identity providers * **User Management**: Create, modify, and deactivate user accounts * **Role Assignment**: Grant Org Owner or Org User Manager roles to other users * **Authentication Methods**: Configure email authentication and SSO options ### How to Assign the Org Owner Role The Org Owner role provides full administrative access to authentication management. Assign this role to users who need to manage identity provider integrations, additional Org Owners or Org User Managers, and user accounts. **To assign the Org Owner role:** 1. Sign in to the AuthN console with an existing Org Owner account 2. Navigate to the **Organizations** tab in the main navigation and ensure your organization is selected 3. Locate the user account you want to modify 4. Select the **+** button on the top right to open the role assignment window 5. Select **Org Owner** from the available roles 6. Select the *Add* button to confirm the role assignment AuthN console role assignment modal **Important Considerations:** * Ensure at least one user always maintains the Org Owner role to prevent administrative lockout * Org Owner users have full access to authentication settings—assign this role only to trusted administrators * Users with Org Owner roles can manage both SSO integrations and email authentication users ### Assign the Org User Manager Role The Org User Manager role provides limited administrative access focused on user management. This role is designed for administrators who need to manage users but should not have access to identity provider configuration. To assign the Org User Manager role **f**ollow the same process as described for the Org owner role. #### Org User Manager Capabilities and Limitations **Org User Manager users can:** * **Create Users**: Add new user accounts for email authentication * **Manage User Status**: Activate and deactivate user accounts * **Reset Passwords**: Assist users with password-related issues * **Send Invitations**: Issue setup invitations for email authentication * **View User Information**: Access user account details and authentication status **Org User Manager users cannot:** * **Configure Identity Providers**: Cannot create or modify SSO integrations * **Edit IdP Settings**: Cannot access identity provider configuration * **Manage Organization Settings**: Cannot modify authentication policies * **Assign Administrative Roles**: Cannot grant Org Owner or Org User Manager roles to other users #### When to Use Org User Manager The Org User Manager role is ideal for: * Help desk personnel who assist with user account issues * Team leads who need to add new team members using email authentication * Administrators in mixed environments where some users authenticate via email rather than SSO * Situations where you want to delegate user management without granting full administrative access ### User Management for Email Authentication **Important**: Users only need to be manually created and managed in the AuthN console when using email authentication. SSO users are automatically provisioned when they first sign in through their identity provider. #### When Manual User Management Is Required Manual user creation and management is necessary for: * Organizations using email authentication instead of SSO * Mixed authentication environments where some users need email authentication * Adding users who don't have access to your organization's identity provider * Creating service accounts or special-purpose accounts #### Email Authentication User Lifecycle **User Creation Process:** 1. **Access Console**: Navigate to the AuthN console with appropriate administrative privileges 2. **Create Account**: Use the **Users** section to add new user accounts 3. **Send Invitation**: Users receive setup instructions via email 4. **User Activation**: Users complete their account setup and choose authentication methods 5. **Fiddler Access**: After authentication setup, users can access the Fiddler platform Authn console add new user form authn-console-user-list **Ongoing Management:** * **Account Status**: Monitor and modify user account status as needed * **Password Support**: Assist users with password resets and authentication issues * **Role Assignment**: Coordinate with Fiddler application administrators for platform role assignments ### Navigation and Interface Overview #### Main Console Sections * **Home**: Organization overview and quick access to common tasks * **Users**: User account management for email authentication * **Organizations**: Role assignment and organization-level settings * **Settings**: Authentication configuration and identity provider management * **Login and Access**: Authentication method configuration * **Identity Providers**: SSO integration setup and management ### Best Practices and Security Recommendations #### Administrative Role Management * **Multiple Org Owners**: Maintain at least two users with Org Owner roles to prevent administrative lockout * **Role Separation**: Use Org User Manager roles for personnel who only need user management capabilities * **Regular Review**: Periodically audit administrative role assignments * **Documentation**: Maintain records of who has administrative access and why #### User Management * **Consistent Naming**: Establish clear naming conventions for user accounts * **Account Lifecycle**: Implement processes for user onboarding and offboarding * **Mixed Authentication**: Clearly document which users use email authentication versus SSO * **Security Policies**: Apply appropriate password and account security policies #### Identity Provider Integration * **Testing Environment**: Test SSO integrations before deploying to production * **Backup Authentication**: Maintain email authentication capabilities as a backup * **Configuration Documentation**: Document IdP configuration details for troubleshooting * **Regular Monitoring**: Monitor SSO integration status and user authentication patterns ### Troubleshooting Common Issues #### Access Issues **Cannot Access AuthN Console:** * Verify the console URL format (`authn-` prefix) * Check network connectivity and firewall settings * Confirm user account has appropriate administrative role * Contact your Fiddler representative for credential verification #### User Management Issues **Cannot Create Users:** * Verify user account has Org Owner or Org User Manager role * Check that email authentication is enabled for your organization * Confirm user email addresses are unique and properly formatted **Invitation Emails Not Received:** * Verify email addresses are correct and properly formatted * Check spam and junk mail folders * Confirm email delivery settings in your organization's configuration * Resend invitations if necessary using console tools #### Role Assignment Issues **Cannot Assign Roles:** * Confirm you have Org Owner privileges (Org User Managers cannot assign roles) * Verify target user account exists and is active * Check that you're working in the correct organization context ### Getting Support For additional assistance with the AuthN console: * **Documentation**: Reference specific identity provider integration guides for SSO setup * **Fiddler Support**: Contact your Fiddler representative with specific error messages or console screenshots * **System Logs**: Review authentication logs for troubleshooting authentication issues * **Best Practices**: Consult your organization's IT security team for authentication policy guidance # Email Login Source: https://docs.fiddler.ai/reference/access-control/email-login This page documents the details of Fiddler's native email-based authentication including user account creation and password policy. This guide covers email-based authentication in Fiddler, including user management, security requirements, and administrative procedures. ## Overview Email authentication is Fiddler's built-in authentication method for organizations that don't use Single Sign-On (SSO) or need to provide access to users outside their SSO system. With email authentication, users log in using their email address and a password they create during the account setup process. ## When to Use Email Authentication Email authentication is ideal for: * Organizations without an identity provider * Adding specific users who don't have SSO access * Mixed environments where some users need different authentication methods * Adding service accounts **Note**: Each user account can only use one authentication method—either email authentication or SSO, not both. ## User Management with Authentication Console Fiddler provides a separate UI for managing your authentication: the AuthN console. The URL to the AuthN management console is your Fiddler instance base URL preprended with `authn-`. For example, if your base URL is `https://acme.cloud.fiddler.ai` then you can access the AuthN management console at `https://authn-acme.cloud.fiddler.ai`. ### Prerequisites for User Management To manage email authentication users, you need: * **Administrator access**: Your user account must have the "Org Owner" or "Org User Manager" role in the authentication management system * **Console access**: Access to the Fiddler authentication management console ### Adding Users to Fiddler **Step 1: Access the Authentication Management Console** * Navigate to the Fiddler AuthN authentication management console The URL to the AuthN management console is your Fiddler instance base URL preprended with \`authn-\`. For example, if your base URL is \`\<[https://acme.cloud.fiddler.ai\\\\\`](https://acme.cloud.fiddler.ai\\\\`)> then you can access the AuthN management console at \`\<[https://authn-acme.cloud.fiddler.ai\\\\\`](https://authn-acme.cloud.fiddler.ai\\\\`)>. * Ensure you have the necessary administrator permissions. To assign user management privilege to another user, add either the "Org Owner" or "Org User Manager" role in the Organizations tab of the AuthN console: Adding a manager using Fiddler user management console Organizations tab Selecting a role for a user in the Fiddler user management console **Step 2: Create User Account** * The email and username fields must match exactly * Only lower-case letters should be used to avoid case-sensitivity issues 1. In the authentication console, navigate to **Users** 2. Click **New** to create a new user. Authn console add new user form 3. Fill in the required contact details: * **Email address**: This will be the user's login identifier and must be unique * **User Name**: This field must contain the email address exactly * **First name** and **Last name** * **Email Verified**: Choose whether to mark the email as "verified" automatically * **Set Initial Password**: Choose whether to set the password yourself or allow the new user to set their own It is recommended to leave both the Email Verified and the Set Initial Password checkboxes unchecked. Doing so results in the user receiving an email with a link to Fiddler to confirm their invitation and choose their password. * Checking Email Verified means the user does not need to validate that they own the email address assigned * If both checkboxes are checked, the user will receive no email, and the AuthN admin must communicate the sign-in credentials **Step 3: Configure Authentication Setup** Choose one of the following authentication setup options: **Option A: Set up Authentication Later** * Select **"Setup authentication later for this user"** * Use this option if you want to prepare the account before the user needs access * The user will not be able to log in until they set up an authentication method * Useful for preparing accounts for future employees **Option B: Send Invitation Email (Recommended)** * Select **"Send an invitation E-Mail for authentication setup and E-Mail verification"** * The user will receive an email with instructions to set up their authentication * The user can choose their preferred authentication method (password, passkey, or external SSO) * This provides the most flexibility for users **Option C: Set Initial Password** * Select **"Set an initial password for the user"** * Enter a temporary password for the user * The user will receive an email notification about their account * The user should change this password on first login **Step 4: Complete User Creation** 1. Click **Create** to save the user account 2. The system will process the user creation based on your selected authentication option 3. If you chose email invitation, the user will automatically receive setup instructions ### Managing User Invitations **Invitation and Setup Process**: **Email Verification and Initial Setup**: * By default, users receive an initialization email with a verification code * Users must verify this code on their first login * If you marked the email as "verified" during creation, this step may be skipped **Authentication Method Selection**: * Users can choose from available authentication methods based on your organization's configuration: * **Password**: Traditional username/password authentication * **Passkey**: Modern passwordless authentication using biometrics or security keys * **External SSO**: If configured, users can authenticate through external identity providers **Invitation Properties**: * Email invitations do not expire automatically * Users can complete their setup at any time after receiving the invitation * Account setup must be completed before users can access Fiddler **Resending Invitations**: If you need to resend setup instructions to a user: 1. Go to the **Users** section in the authentication console 2. Find the specific user account 3. Use the available options to resend invitation or setup emails 4. Users who haven't completed setup will receive fresh instructions ### User Account Lifecycle **Account Activation**: When users receive their setup email, they: 1. Click the setup link in the email 2. Verify their email address (if required) 3. Choose and configure their preferred authentication method: * **Password**: Create a password meeting security requirements * **Passkey**: Set up biometric or security key authentication * **External SSO**: Link to configured external identity providers (if available) 4. Complete their profile information if prompted 5. Confirm their account to gain access to Fiddler **Account Management**: * **User deactivation**: Temporarily disable user access * **User deletion**: Permanently remove user accounts * **Password reset**: Users can reset forgotten passwords through the login interface ### Password Management **Forgotten Passwords**: Users can reset forgotten passwords by: 1. Clicking **Forgot Password** on the login page 2. Entering their email address 3. Following the instructions in the password reset email 4. Creating a new password that meets security requirements ### User Role Considerations **AuthN Administrative Roles**: Ensure at least one user has the "Org Owner" or "Org User Manager" role to continue managing email authentication users. **Fiddler Roles**: After email authentication users log in, Org Admins can assign appropriate Fiddler application roles (Org Admin, Org Member, etc.) for access control. ## Troubleshooting ### Common Issues **Users Cannot Access Console**: * Verify the user has "Org Owner" or "Org User Manager" role * Check authentication console network accessibility * Confirm user account status **Invitation Links Not Working**: * Verify the invitation hasn't been revoked * Check for email delivery issues * Regenerate invitation links if necessary **Login Problems**: * Verify password meets all requirements * Check for account lockouts due to failed attempts * Confirm user account is active and not suspended # Google OIDC Source: https://docs.fiddler.ai/reference/access-control/google-integration Learn how to configure Fiddler with Google for Single Sign-On (SSO) using the OpenID Connect (OIDC) protocol. ## Overview This integration allows your users to sign in to Fiddler using their existing Google account, without needing a separate Fiddler password. Users are automatically provisioned on their first successful login — no manual invitations required. Google OIDC does not support group synchronization — Google does not include group membership in its OIDC tokens. Users are provisioned individually; assign them to Fiddler teams and roles manually. ## Prerequisites Before starting, ensure you have: * **Google Cloud Access**: Permissions to create and configure OAuth 2.0 credentials in a Google Cloud project. * **Fiddler AuthN Administrator Access**: Org Owner role in Fiddler's AuthN management console. * **Deployment Information**: The hostname of your Fiddler deployment, e.g. `idpexample.dev.fiddler.ai`. ## Configuring Google Fiddler requires two redirect URIs on the Google OAuth client. You will add both when creating the client below: * `https://authn-{base_url}/ui/login/login/externalidp/callback` * `https://authn-{base_url}/idps/callback` Replace `{base_url}` with your Fiddler deployment host (e.g. `idpexample.dev.fiddler.ai`). 1. In the [Google Cloud Console](https://console.cloud.google.com/), select your project and go to *APIs & Services → OAuth consent screen*. 2. In *App information*, enter the *App name* and *User support email*. 3. In *Audience*, select *Internal* or *External* depending on your organization's setup and access requirements. 4. In *Contact Information*, add the required email addresses. 5. Agree to the *Google API Services: User Data Policy*, then select *Create*. If you selected *External*, the app starts in testing mode — only accounts added under *Test users* can sign in until you publish the app (set it to *In production*). See [Manage app audience](https://support.google.com/cloud/answer/15549945) for details. 1. Go to *APIs & Services → Credentials*, then select *Create Credentials → OAuth client ID*. Google Cloud create OAuth client 2. Select *Web application* for the *Application type* and enter a name, e.g. `Fiddler IdP Example`. 3. Under *Authorized redirect URIs*, add both redirect URIs (replace the host with your deployment): * `https://authn-idpexample.dev.fiddler.ai/ui/login/login/externalidp/callback` * `https://authn-idpexample.dev.fiddler.ai/idps/callback` Google Cloud OAuth client name, type, and redirect URIs 4. Select *Create*. 5. Copy the *Client ID* and *Client Secret* — you will need them when configuring Fiddler. Google Cloud OAuth client credentials ## Configuring Fiddler The URL to the Fiddler AuthN management console is your Fiddler instance base URL prepended with `authn-`. For example, if your Fiddler base URL is `https://idpexample.dev.fiddler.ai` then you will access the AuthN management console at `https://authn-idpexample.dev.fiddler.ai`. Sign in using the AuthN console Org Owner user account credentials provided by your Fiddler representative. Fiddler AuthN console sign-in page Ensure your organization is selected in the dropdown. You may see the *fiddler* organization, but this is reserved for system use and should not be edited. Here we are using the *idpexample* organization. Fiddler AuthN console home page Select *Settings* tab from the top menu and then select *Identity Providers* from the left navigation menu. Fiddler AuthN console add provider page 1. Select the *Google* option in the *Add provider* section, which brings up the Google Provider form. 2. Note the callback URL shown in the form — it corresponds to the redirect URIs you registered in Google earlier, so no further changes are needed in Google. Fiddler AuthN console add new Google provider form with callback URL In the Google Provider form, paste the *Client ID* and *Client Secret* copied from Google earlier. Fiddler AuthN console Google provider client credentials 1. Expand the *optional* section. 2. Ensure the *Scopes List* includes `openid`, `profile`, and `email`. 3. Ensure the *Automatic create* and *Automatic update* checkboxes are selected. 4. Set the *Determines whether an identity will be prompted to be linked to an existing account* dropdown to *Check for existing Username*. Fiddler AuthN console automatic create/update and check existing username settings Select the *Create* button and then select the *Save* button. You will be returned to the Organization Settings page. Fiddler AuthN console with newly created Google OIDC IdP 1. Select your IdP from the list and select the *Activate* button on the identity provider page. Fiddler AuthN console activate new Google OIDC IdP 2. Close the settings and then select *Login Behavior and Security* from the left nav menu and ensure the *External login allowed* checkbox is selected. Fiddler AuthN console allow external login behavior 3. Select the *Save* button. Fiddler AuthN console external login allowed Select the *Actions* tab from the top menu. Fiddler AuthN console new custom Action script 1. Select the *New* button in the *Scripts* section to create a new action script. 2. Copy the *Google OIDC Action Script* below and paste it into the script text area. 3. Enter `setAttributesOnGoogleOIDCAuth` in the *Name* text box. 4. Select the *Add* button. **File:** `Google OIDC Action Script` ```javascript theme={null} function setAttributesOnGoogleOIDCAuth(ctx, api) { let firstName = ctx.v1.providerInfo.getFirstName(); let lastName = ctx.v1.providerInfo.getLastName(); let email = ctx.v1.providerInfo.getEmail(); let nameParts = [firstName, lastName]; let filteredParts = nameParts.filter(part => part); let displayName = filteredParts.join(' '); if (firstName != undefined) { api.setFirstName(firstName); } if (lastName != undefined) { api.setLastName(lastName); } if (email != undefined) { email = email.toLowerCase(); api.setEmail(email); api.setEmailVerified(true); api.setPreferredUsername(email); } if (displayName) { api.setDisplayName(displayName); } api.v1.user.appendMetadata('fiddler_authentication_type', 'SSO:GOOGLE:OIDC'); api.v1.user.appendMetadata('fiddler_groups', []); } ``` Scroll down to the *Flows* section. Fiddler AuthN console new Action trigger creation 1. Select the *External Authentication* option for the *Flow Type* dropdown. 2. Select the *+ Add trigger* button. 3. Select the *Post Authentication* option for the *Trigger Type* dropdown. 4. Select the *setAttributesOnGoogleOIDCAuth* option for the *Actions* dropdown. 5. Select the *Save* button. Add an organization metadata key so Fiddler can correctly identify and process this SSO connection. Set this once during setup. 1. Go to the *Metadata* section and select *Edit*. Fiddler AuthN console organization metadata section 2. Select the *Add* button, then enter the key `fiddler_sso_authentication_type` with the value `SSO:GOOGLE:OIDC`. Fiddler AuthN console organization metadata with Google OIDC authentication type 3. Select the *Save* button next to the new entry. Before validating, make sure your Google account can sign in: for an *Internal* consent screen it must belong to your Google Workspace organization; for an *External* app still in testing it must be added as a *Test user*. 1. Open your Fiddler URL (e.g. `https://idpexample.dev.fiddler.ai`). 2. Ensure you see the Fiddler sign-in page and that it displays the Google SSO login button. Fiddler application homepage displaying the new SSO login method in addition to the email sign-in form 3. Select the button and confirm that the Fiddler application loads. Fiddler application landing page The first user to sign in to the Fiddler application is automatically assigned the Fiddler Org Admin role; subsequent members are Org Members by default. ## Getting Help If sign-in fails, verify the OAuth client configuration in the Google Cloud Console (redirect URIs, consent screen status, client credentials). For Fiddler-side issues, see the [SSO Authentication Guide](/reference/access-control/sso-authentication-guide). If the issue persists, contact your Fiddler representative with the specific error message. ## Important Notes * **Data Storage**: Fiddler stores the following profile attributes from Google: first name, last name, display name, and email address. * **No Group Synchronization**: Google OIDC does not provide group membership, so group sync to Fiddler teams is not available. Assign users to teams and roles manually. * **API Access**: For programmatic API access, users create an API key from the *Credentials* tab in Fiddler's *Settings* page. * **Single Authentication Method**: Users can only authenticate via either SSO or email authentication, not both. ## Next Steps After successful integration: * **Train Users**: Provide guidance on accessing Fiddler through Google SSO. * **Assign Roles**: Manually assign users to the appropriate Fiddler teams and roles after their first login. * **Monitor Usage**: Review authentication logs and user access patterns. # Access Control Source: https://docs.fiddler.ai/reference/access-control/index Explore our guides on authentication options with leading IDPs like Okta and PingOne. Dive deep into authorization topics using the Fiddler UI. This section covers how to configure user access, authentication, and authorization in Fiddler. ## Overview Managing access to your Fiddler instance involves these key components: * **Authentication**: Verifying user identities through Single Sign-On (SSO) or email-based methods * **User Management**: Adding and managing users in the Fiddler AuthN console or dynamically with SSO integration * **Authorization**: Configuring what users can access through role-based permissions in the Fiddler UI or dynamically with SSO integration ## Getting Started with Authentication Management Fiddler provides a dedicated authentication management console to deliver secure, flexible user management. As an administrator, you'll use the Fiddler AuthN console to configure authentication methods and manage users. ### Initial Setup For new Fiddler deployments: * A Fiddler representative will work with you to set up your initial authentication configuration * Choose your preferred authentication method: SSO, email-based authentication, or both * At least one user in your organization must be assigned the "Org Owner" or "Org User Manager" role in the Fiddler AuthN console. * An "Org Owner" can administer their SSO integration with Fiddler as well as manage users * An "Org User Manager" can manage users when leveraging email-based authentication ## Authentication Methods Choose the authentication method that best fits your organization's infrastructure: ### Single Sign-On (SSO) SSO users are automatically provisioned when they first log in with valid credentials from your identity provider. | Identity Provider | Protocol | Guide | | -------------------------------------- | -------- | --------------------------------------------------------------------------------------- | | Okta | OIDC | [Okta OIDC SSO Integration](/reference/access-control/okta-integration) | | Okta | SAML | [Okta SAML SSO Integration](/reference/access-control/okta-integration-saml) | | Microsoft Entra ID (formerly Azure AD) | OIDC | [Azure AD OIDC SSO Integration](/reference/access-control/single-sign-on-with-azure-ad) | | PingOne | SAML | [PingOne SAML SSO Integration](/reference/access-control/ping-identity-saml) | | Google | OIDC | [Google OIDC SSO Integration](/reference/access-control/google-integration) | ### Email-Based Authentication For organizations without an identity provider or when you need to add specific users outside your SSO system. | Guide | Description | | ------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------ | | [Email Login Configuration](/reference/access-control/email-login) | Configure Fiddler's email-based authentication and learn how to add users through the authentication management console. | ### Mixed Authentication You can use both SSO and email authentication simultaneously: * SSO users are automatically provisioned on first login * Email users must be manually added through the authentication management console * Each user account can only use one authentication method ## Authorization and Access Control Authorization settings are managed in the Fiddler UI using Fiddler's role-based access control system and optional LDAP syncing with your IDP: | Guide | Description | | ------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ | | [Role-Based Access Control](/reference/access-control/role-based-access) | Understand and configure user permissions through pre-defined roles | | Mapping Identity Provider Groups to Fiddler Teams and Roles | Synchronize external user groups with Fiddler teams and organization roles for streamlined access management | ## Configuration Sequence For organizations new to Fiddler access management, we recommend this sequence: 1. **Set up authentication management access in the Fiddler AuthN console**: Ensure you have the appropriate AuthN administrator role: Org Owner 2. **Configure authentication**: Choose and implement your authentication method (SSO, email, or both) 3. **Add initial users**: Use the authentication management console to add users or configure SSO for automatic provisioning when users first sign in 4. **Configure authorization**: Set up role-based access control within the Fiddler UI's Access tab in the Settings page 5. **Create teams**: Organize users into teams for efficient permission management 6. **Map external groups** (if applicable): Connect your identity provider groups to Fiddler teams and manage Fiddler roles ## Troubleshooting and Support If you encounter issues with authentication or user management: * Check the authentication management console for authentication logs and user status * Verify that your SSO configuration matches your identity provider settings * Ensure users have the correct administrative roles for user management tasks * Contact your Fiddler representative for assistance with authentication configuration # Mapping IdP Groups to Teams Source: https://docs.fiddler.ai/reference/access-control/mapping-ad-groups-to-fiddler-teams This document describes the naming convention and rules for mapping internal AD groups to Fiddler Teams automatically. This guide describes how to configure automatic synchronization between your identity provider (IdP) groups and Fiddler teams using the [Fiddler AuthN management console](/reference/access-control/authn-authentication-management-console), enabling streamlined access control and role management. ## Overview Group synchronization automatically maps users from your IdP groups to corresponding Fiddler teams and roles. This eliminates the need for manual user role assignment, ensuring that access permissions remain synchronized with your organizational structure. **Supported Identity Providers**: * Okta (OIDC and SAML) * Microsoft Entra ID (formerly Azure AD) with OIDC (requires additional configuration steps) * PingOne (SAML) Google OIDC does not support group synchronization due to limitations in Google's OIDC implementation. ## Prerequisites Before configuring group synchronization, ensure you have: * **SSO Integration**: A working SSO integration with a supported identity provider * **Administrator Access**: Both identity provider admin access and Fiddler AuthN admin "Org Owner" permissions * **Group Configuration**: Proper group setup in your identity provider with appropriate naming conventions * **User Assignment**: Users assigned to relevant groups in your identity provider ## Group Naming Convention All identity provider groups must follow a set naming pattern to be recognized by Fiddler: ``` fiddler_ ``` The default group prefix is `fiddler_`, but this can be customized during the configuration process. **Team name constraints**: The identifier portion of the group name (used as the Fiddler team name) must satisfy these rules: * Must be at least 2 characters and no more than 256 characters long * Must start with a letter (`a`–`z` or `A`–`Z`) * May contain only: letters (`a`–`z`, `A`–`Z`), digits (`0`–`9`), underscores (`_`), and hyphens (`-`) Identifiers with uppercase characters (e.g., `DataScientists`, `ML_Engineers`) are valid; they are normalized to lowercase before the team is created (so `DataScientists` becomes `datascientists`, and `ML_Engineers` becomes `ml_engineers`). Examples of invalid identifiers: `123team` (must start with a letter), `team!` (contains disallowed character). ### Team Identifiers Any other identifier creates a corresponding team in Fiddler: * `fiddler_data_scientist` - Creates/assigns users to the "data\_scientist" team * `fiddler_ml_engineers` - Creates/assigns users to the "ml\_engineers" team * `fiddler_product_team` - Creates/assigns users to the "product\_team" team ### Group Naming Examples | Identity Provider Group | Result in Fiddler | | ------------------------ | ---------------------------------------- | | `fiddler_ORG_ADMIN` | User assigned "Org Admin" role | | `fiddler_ORG_MEMBER` | User assigned "Org Member" role | | `fiddler_data_scientist` | User added to "data\_scientist" team | | `fiddler_finance_team` | User added to "finance\_team" team | | `fiddler_` | **Invalid** - Will be ignored | | `data_scientist` | **Invalid** - Missing "fiddler\_" prefix | ## Configuration Steps **Identity Provider-Specific Requirements**: **Okta**: * Ensure the `groups` scope is included in your OIDC application * Configure Groups claim in the "Sign On" section of your application **Microsoft Entra ID**: * Add the `groups` claim to your application's token configuration * Grant `GroupMember.Read.All` API permissions * Additional configuration steps are required (see the Advanced Configuration section) **PingOne**: * Configure group attribute mapping in your SAML application * Ensure group membership is included in SAML assertions 1. Access your identity provider's admin console 2. Create groups following the `fiddler_<identifier>` naming convention or choose your own prefix, e.g. `company_fiddler_` 3. Assign appropriate users to each group 4. Configure group claims/attributes in your SSO application The URL to the AuthN management console is your Fiddler instance base URL, prepended with `authn-`. For example, if your base URL is `https://acme.cloud.fiddler.ai` then you can access the AuthN management console at `https://authn-acme.cloud.fiddler.ai`. **Access Organization Settings**: 1. Log into Fiddler with AuthN console "Org Owner" privileges 2. Navigate to the *Organization* tab at the top 3. Ensure that your organization is selected in the top left dropdown (this will never be "fiddler" which is reserved) 4. Locate the *METADATA* section Fiddler AuthN admin console organization home page **Configure Group Sync Settings**: 1. Select the *Edit* button in the *METADATA* section 2. Configure these key-value pairs: * *fiddler\_group\_prefix*: Set the group prefix (defaults to `fiddler_` unless manually modified) * *fiddler\_group\_sync\_enabled*: Set to `true` 3. Save your changes by selecting the *Save* disk icon adjacent to each key value pair Mapping users to Fiddler organization roles is optional. All new users will be Org Members by default, and the Org Admin role can be assigned in the Fiddler UI as needed. Setting up automatic [organization role](/reference/access-control/role-based-access#understanding-roles) mappings uses these additional metadata keys: * *fiddler\_org\_admin\_mapper*: Custom mapping key for the Org Admin role * *fiddler\_org\_member\_mapper*: Custom mapping key for Org Member role **To configure automatic role mapping**: 1. In the *METADATA* section, add the mapper keys as needed 2. Set the values to match your identity provider's group naming convention, noting that the METADATA key values should not include the Fiddler group prefix, which is the default `fiddler_` in this example 1. Create a group in your IdP for Fiddler Org Admin users named `fiddler_org_admins` 2. Set the `fiddler_org_admin_mapper` metadata key value to `org_admins` 3. Create a group in your IdP for Fiddler Org Member users named fiddler\_org\_members 4. Set the `fiddler_org_member_mapper` metadata key value to `org_members` 3. Save your changes by selecting the *Save* disk icon adjacent to each key value pair Fiddler AuthN admin console add org mapper keys **Test Group Synchronization**: 1. Log in with a test user who belongs to the mapped groups 2. Verify the user is assigned to the correct Fiddler roles/teams 3. Check that team memberships update when identity provider groups change 4. Confirm that new groups create corresponding Fiddler teams automatically ## Role Precedence for Multi-Group Membership If a user belongs to multiple IdP groups that each map to a different Fiddler organization role, Fiddler assigns the highest-privilege matched role. This commonly occurs in directory structures where all users belong to a general member group and a subset are also assigned to an admin group. **Upgrading to 26.10.1 or later?** Before this release, role assignment depended on the order in which your IdP returned groups, so users in both an admin-mapped and a member-mapped group may have been assigned **Org Member**. Starting in 26.10.1, those users will be promoted to **Org Admin** on their next login. Audit your IdP group memberships before deploying this release to confirm role assignments are correct. Example: A user belonging to both `fiddler_ORG_ADMIN` and `fiddler_ORG_MEMBER` groups is assigned the Org Admin role. Resolution is order-independent. The role assigned does not depend on the order in which the IdP returns groups in the SAML or OIDC response. ## Advanced Configuration ### Custom Group Prefixes You can customize the group prefix if `fiddler_` doesn't fit your naming conventions: 1. In the Organization *METADATA* section, update `fiddler_group_prefix` 2. For example, set to `company_fiddler_` to require groups like `company_fiddler_data_team` 3. All group names in your identity provider must use your custom prefix ### Team Hierarchy and Permissions #### Automatic Team Creation * Teams are automatically created when users with new group mappings first log in * Team names match the identifier portion of the group name * Teams inherit default permissions, which can be customized through the Fiddler UI #### Team Management: * Organization admins can modify team permissions through Fiddler settings * Project-specific access can be configured per team * Teams persist even if all members are removed ## Troubleshooting ### Common Issues #### Groups Not Synchronizing * **Verify Group Sync Enable**: Check that `fiddler_group_sync_enabled` is set to `true` * **Check Group Names**: Ensure groups follow the correct naming convention with your configured prefix * **Validate Claims**: Confirm your identity provider includes group claims in authentication tokens * **Review Permissions**: Verify your SSO application has appropriate permissions to read group membership #### Users Not Assigned to Correct Teams * **Group Membership**: Confirm users are actually members of the expected groups in your identity provider * **Name Matching**: Ensure group names exactly match the expected format (case-sensitive) * **Re-authentication**: Users may need to log out and back in for group changes to take effect #### Custom Role Mapping Issues * **Mapper Configuration**: Verify that custom role mapper keys are configured correctly in the *METADATA* section * **Group Assignment**: Ensure users are assigned to groups that match the custom mapper values * **User in Multiple Role Groups**: If a user belongs to both an admin-mapped and a member-mapped group, the higher-privilege role (Org Admin) is applied automatically. See [Role Precedence for Multi-Group Membership](#role-precedence-for-multi-group-membership) for details. ## Best Practices ### Identity Provider Management * **Consistent Naming**: Establish clear naming conventions for Fiddler-related groups * **Group Documentation**: Maintain documentation of group purposes and membership criteria * **Regular Audits**: Periodically review group memberships and access levels * **Change Management**: Implement processes for group creation, modification, and deletion ### Fiddler Team Organization * **Logical Grouping**: Align Fiddler teams with your organizational structure and project needs * **Permission Planning**: Design team permissions to match job functions and access requirements * **Scalability**: Consider how your team structure will scale as your organization grows ### Security Considerations * **Least Privilege**: Apply the principle of least privilege when designing group access levels * **Regular Reviews**: Conduct periodic access reviews to ensure appropriate permissions * **Separation of Duties**: Consider separating administrative and operational roles * **Audit Trails**: Monitor group membership changes and access patterns ## Getting Help For additional assistance with group synchronization: * **Organization Settings**: Check the Organization METADATA section for configuration details * **Identity Provider Support**: Consult your identity provider's documentation for group configuration * **Fiddler Support**: Contact your Fiddler representative with group sync configuration details * **Testing Environment**: Use a test environment to validate group sync before production deployment ## Related Documentation * [Role-Based Access Control](/reference/access-control/role-based-access) - Understanding Fiddler roles and permissions * [Okta OIDC SSO Integration](/reference/access-control/okta-integration) - Okta-specific group sync setup * [Microsoft Entra ID OIDC SSO Integration](/reference/access-control/single-sign-on-with-azure-ad) - Entra ID group sync configuration * [PingOne SAML SSO Integration](/reference/access-control/ping-identity-saml) - PingOne group sync setup * [General SSO Authentication Guide](/reference/access-control/sso-authentication-guide) - Overview of SSO concepts # Okta OIDC Source: https://docs.fiddler.ai/reference/access-control/okta-integration Learn how to configure Fiddler with Okta for Single Sign-On (SSO) using the OpenID Connect (OIDC) protocol. ## Overview This integration allows your users to sign in to Fiddler using their existing Okta account, without needing a separate Fiddler password. Users are automatically provisioned on their first successful login — no manual invitations required. ## Prerequisites Before starting, ensure you have: * **Okta Administrator Access**: Permissions to create and configure applications in your Okta organization. * **Fiddler AuthN Administrator Access**: Org Owner role in Fiddler's AuthN management console. * **Deployment Information**: The hostname of your Fiddler deployment, e.g. `idpexample.dev.fiddler.ai`. ## Configuring Okta Fiddler requires two redirect URIs on the Okta application. You will add both when creating the Okta application below: * `https://authn-{base_url}/ui/login/login/externalidp/callback` * `https://authn-{base_url}/idps/callback` Replace `{base_url}` with your Fiddler deployment host (e.g. `idpexample.dev.fiddler.ai`). 1. In the Okta admin console, navigate to *Applications* and select the *Create App Integration* button. Select *OIDC - OpenID Connect* for the *Sign-in method* and *Web Application* for the *Application type*, then select *Next*. Okta admin console applications list 2. Assign a name for your application integration in the *App integration name* text box, then configure the redirect URIs: 1. Enter both redirect URIs into the *Sign-in redirect URIs* field using the *+ Add URI* button: * `https://authn-idpexample.dev.fiddler.ai/ui/login/login/externalidp/callback` * `https://authn-idpexample.dev.fiddler.ai/idps/callback` 2. Enter your Fiddler deployment URL (without the `authn-` prefix) into the *Sign-out redirect URIs* text box, e.g. `https://idpexample.dev.fiddler.ai`. Okta admin console application page with redirect and sign-out URIs 3. Select the *Save* button to create the application. 4. Copy the following values — you will need them when configuring Fiddler: 1. On the *General* tab, copy the *Client ID* and *Client Secret* values. Okta admin console application page with client id and secret 2. On the *Sign On* tab, copy the *Issuer* URL. Okta admin console application page with the Issuer URL ## Configuring Fiddler The URL to the Fiddler AuthN management console is your Fiddler instance base URL prepended with `authn-`. For example, if your Fiddler base URL is `https://idpexample.dev.fiddler.ai` then you will access the AuthN management console at `https://authn-idpexample.dev.fiddler.ai`. Sign in using the AuthN console Org Owner user account credentials provided by your Fiddler representative. Fiddler AuthN console sign-in page Ensure your organization is selected in the dropdown. You may see the *fiddler* organization, but this is reserved for system use and should not be edited. Here we are using the *idpexample* organization. Fiddler AuthN console home page Select *Settings* tab from the top menu and then select *Identity Providers* from the left navigation menu. Fiddler AuthN console add provider page 1. Select the *Generic OIDC* option in the *Add provider* section, which brings up the OIDC Provider form. 2. Note the callback URL shown in the form — it corresponds to the redirect URIs you registered in Okta earlier, so no further changes are needed in Okta. Fiddler AuthN console add new OIDC provider form with callback URL 1. In the OIDC Provider form, enter the following values: 1. Enter a name in the *Name* text box. This name is displayed on the SSO login button on the Fiddler sign-in page, so choose one your users will recognize. 2. In the *Issuer* text box, paste the Issuer URL copied from the Okta admin console. 3. In the *Client ID* and *Client Secret* text boxes, paste those values copied from the Okta admin console. Fiddler AuthN console OIDC provider name 1. Expand the *optional* section. 2. Add the text `groups` to the *Scopes List* text box and ensure it is listed along with `openid`, `profile`, and `email`. 3. Ensure the *Automatic create* and *Automatic update* checkboxes are selected. Fiddler AuthN console automatic create and update settings 4. Set the *Determines whether an identity will be prompted to be linked to an existing account* dropdown to *Check for existing Username*. Fiddler AuthN console check for existing username setting Select the *Create* button and then select the *Save* button. You will be returned to the Organization Settings page. Fiddler AuthN console with newly created Okta OIDC IdP 1. Select your IdP from the list and select the *Activate* button on the identity provider page. Fiddler AuthN console activate new Okta OIDC IdP 2. Close the settings and then select *Login Behavior and Security* from the left nav menu and ensure the *External login allowed* checkbox is selected. Fiddler AuthN console allow external login behavior 3. Select the *Save* button. Fiddler AuthN console external login allowed Select the *Actions* tab from the top menu. Fiddler AuthN console new custom Action script 1. Select the *New* button in the *Scripts* section to create a new action script. 2. Copy the *Okta OIDC Action Script* below and paste it into the script text area. 3. Enter `setAttributesOnOktaOIDCAuth` in the *Name* text box. 4. Select the *Add* button. **File:** `Okta OIDC Action Script` ```javascript theme={null} function setAttributesOnOktaOIDCAuth(ctx, api) { let firstName = ctx.v1.providerInfo.getFirstName(); let lastName = ctx.v1.providerInfo.getLastName(); let email = ctx.v1.providerInfo.getEmail(); let groups = ctx.getClaim('groups'); let nameParts = [firstName, lastName]; let filteredParts = nameParts.filter(part => part); let displayName = filteredParts.join(' '); if (firstName != undefined) { api.setFirstName(firstName); } if (lastName != undefined) { api.setLastName(lastName); } if (email != undefined) { email = email.toLowerCase(); api.setEmail(email); api.setEmailVerified(true); api.setPreferredUsername(email); } if (displayName) { api.setDisplayName(displayName); } api.v1.user.appendMetadata('fiddler_authentication_type', 'SSO:OKTA:OIDC'); if (groups === null || groups === undefined){ groups = [] } api.v1.user.appendMetadata('fiddler_groups', groups); } ``` Scroll down to the *Flows* section. Fiddler AuthN console new Action trigger creation 1. Select the *External Authentication* option for the *Flow Type* dropdown. 2. Select the *+ Add trigger* button. 3. Select the *Post Authentication* option for the *Trigger Type* dropdown. 4. Select the *setAttributesOnOktaOIDCAuth* option for the *Actions* dropdown. 5. Select the *Save* button. Add an organization metadata key so Fiddler can correctly identify and process this SSO connection. Set this once during setup. 1. Go to the *Metadata* section and select *Edit*. Fiddler AuthN console organization metadata section 2. Select the *Add* button, then enter the key `fiddler_sso_authentication_type` with the value `SSO:OKTA:OIDC`. Fiddler AuthN console organization metadata edit 3. Select the *Save* button next to the new entry. Before validating, ensure your Okta user account is assigned to the new Okta application you created. 1. Open your Fiddler URL (e.g. `https://idpexample.dev.fiddler.ai`). 2. Ensure you see the Fiddler sign-in page and that it displays an SSO login button labeled with the name you configured (e.g. *Okta OIDC*). Fiddler application homepage displaying the new SSO login method in addition to the email sign-in form 3. Select the button and confirm that the Fiddler application loads. Fiddler application landing page The first user to sign in to the Fiddler application is automatically assigned the Fiddler Org Admin role; subsequent members are Org Members by default. ## Getting Help If sign-in fails, check the **Okta System Log** (*Reports → System Log*) for the failed attempt and its reason. For Fiddler-side issues, see the [SSO Authentication Guide](/reference/access-control/sso-authentication-guide). If the issue persists, contact your Fiddler representative with the specific error message. ## Important Notes * **Data Storage**: Fiddler stores the following profile attributes from Okta: first name, last name, display name, email address, and group memberships (used to map users to Fiddler teams). * **API Access**: For programmatic API access, users create an API key from the *Credentials* tab in Fiddler's *Settings* page. * **Single Authentication Method**: Users can only authenticate via either SSO or email authentication, not both. ## Next Steps After successful integration: * **Train Users**: Provide guidance on accessing Fiddler through Okta SSO. * **Configure Teams**: Map your identity provider groups to Fiddler teams — see [Mapping AD Groups to Fiddler Teams](/reference/access-control/mapping-ad-groups-to-fiddler-teams). * **Test Group Sync**: Verify automatic group synchronization is working as expected. * **Monitor Usage**: Review authentication logs and user access patterns. # Okta SAML Source: https://docs.fiddler.ai/reference/access-control/okta-integration-saml Learn how to configure Fiddler with Okta for Single Sign-On (SSO) using the Security Assertion Markup Language (SAML) protocol. ## Overview This integration allows your users to sign in to Fiddler using their existing Okta account, without needing a separate Fiddler password. Users are automatically provisioned on their first successful login — no manual invitations required. ## Prerequisites Before starting, ensure you have: * **Okta Administrator Access**: Permissions to create and configure applications in your Okta organization. * **Fiddler AuthN Administrator Access**: Org Owner role in Fiddler's AuthN management console. * **Deployment Information**: The hostname of your Fiddler deployment, e.g. `idpexample.dev.fiddler.ai`. ## Configuring Okta and Fiddler for Integration The URL to the Fiddler AuthN management console is your Fiddler instance base URL prepended with `authn-`. For example, if your Fiddler base URL is `https://idpexample.dev.fiddler.ai` then you will access the AuthN management console at `https://authn-idpexample.dev.fiddler.ai`. Sign in using the AuthN console Org Owner user account credentials provided by your Fiddler representative. Fiddler AuthN console sign-in page Ensure your organization is selected in the dropdown. You may see the *fiddler* organization, but this is reserved for system use and should not be edited. Here we are using the *idpexample* organization. Fiddler AuthN console home page Select *Settings* tab from the top menu and then select *Identity Providers* from the left navigation menu. Fiddler AuthN console add provider page 1. Select the *SAML* option in the *Add provider* section, which brings up the Sign in with SAML form. 2. Enter a name for the integration. This name is displayed on the SSO login button on the Fiddler sign-in page, so choose one your users will recognize. 3. Paste the following placeholder value into the *Metadata XML* text area. AuthN needs it to generate the URLs used when you create the Okta app integration; you will replace it in a later step. **File:** `Placeholder Metadata XML value` ``` PD94bWwgdmVyc2lvbj0iMS4wIj8+DQo8bWQ6RW50aXR5RGVzY3JpcHRvciB4bWxuczptZD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOm1ldGFkYXRhIg0KICAgICAgICAgICAgICAgICAgICAgdmFsaWRVbnRpbD0iMjAyNS0wOC0zMFQxMzo0NToxM1oiDQogICAgICAgICAgICAgICAgICAgICBjYWNoZUR1cmF0aW9uPSJQVDYwNDgwMFMiDQogICAgICAgICAgICAgICAgICAgICBlbnRpdHlJRD0iaHR0cDovL2xvY2FsaG9zdDo4MDgwIj4NCiAgICA8bWQ6U1BTU09EZXNjcmlwdG9yIEF1dGhuUmVxdWVzdHNTaWduZWQ9ImZhbHNlIiBXYW50QXNzZXJ0aW9uc1NpZ25lZD0iZmFsc2UiIHByb3RvY29sU3VwcG9ydEVudW1lcmF0aW9uPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6cHJvdG9jb2wiPg0KICAgICAgICA8bWQ6TmFtZUlERm9ybWF0PnVybjpvYXNpczpuYW1lczp0YzpTQU1MOjEuMTpuYW1laWQtZm9ybWF0OnVuc3BlY2lmaWVkPC9tZDpOYW1lSURGb3JtYXQ+DQogICAgICAgIDxtZDpBc3NlcnRpb25Db25zdW1lclNlcnZpY2UgQmluZGluZz0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmJpbmRpbmdzOkhUVFAtUE9TVCINCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMb2NhdGlvbj0iaHR0cDovL2xvY2FsaG9zdDo4MDgwL2NvbnN1bWUvZGF0YSINCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmRleD0iMSIgLz4NCiAgICAgICAgDQogICAgPC9tZDpTUFNTT0Rlc2NyaXB0b3I+DQo8L21kOkVudGl0eURlc2NyaXB0b3I+ ``` Fiddler AuthN console new SAML configuration Select the *Create* button and then select the *Save* button. You will be returned to the Organization Settings page. Fiddler AuthN console saving new SAML IdP Select your IdP from the list. Four URLs are displayed — copy the following three for the Okta app integration steps: * ZITADEL Metadata URL * ZITADEL ACS Login Form URL * ZITADEL ACS Intent API URL Fiddler AuthN console SAML IdP URLs required for Okta configuration 1. In the Okta admin console, navigate to *Applications* and select the *Create App Integration* button. Select *SAML 2.0* for the *Sign-in method*, then select *Next*. Okta admin console Applications page 2. Enter a name for your application, e.g. `Fiddler IdP Example`, and select *Next*. Okta admin console enter your new app name 1. Enter the *ZITADEL ACS Login Form URL* copied from the AuthN console into the *Single sign-on URL* text box. Ensure the *Use this for Recipient URL and Destination URL* checkbox is selected. 2. Enter the *ZITADEL Metadata URL* from the AuthN console into the *Audience URI (SP Entity ID)* text box. Okta admin console configure SAML settings 3. Expand the *Advanced Settings* section. 4. In the *Other Requestable SSO URLs* section, select the *+ Add Another* button, enter the *ZITADEL ACS Intent API URL* copied from the AuthN console, and enter `0` for the *Index*. Okta admin console configure SAML settings - requestable URL 5. Select *Next*, then select *Finish* to complete the application creation. 6. On the created application, go to the *Sign On* tab, then select *Show legacy configuration* under *Attribute Statements*. Add the following attributes with *Name format* set to *Basic*, then select *Save*: 1. Name=`firstName`, Value=`user.firstName` 2. Name=`lastName`, Value=`user.lastName` 3. Name=`email`, Value=`user.email` Okta admin console SAML attribute statements 7. On the *Sign On* tab, go to *Settings → Sign on methods → SAML 2.0* and copy the *Metadata URL*. Okta admin console SAML 2.0 metadata URL 1. Return to the identity provider form in the Fiddler AuthN console (where you left off in step 4 — *Add and Configure New SAML Provider*). 2. Clear the *Metadata XML* text area. 3. Paste the *Metadata URL* copied from Okta into the *Metadata URL* text box. Fiddler AuthN console Metadata URL 1. Expand the *optional* section. 2. Ensure the *Automatic create* and *Automatic update* checkboxes are selected. 3. Set the *Determines whether an identity will be prompted to be linked to an existing account* dropdown to *Check for existing Username*. Fiddler AuthN console automatic create/update and check existing username settings Select the *Save* button. You will be returned to the Organization Settings page. Fiddler AuthN console with newly created Okta SAML IdP 1. Select your IdP from the list and select the *Activate* button on the identity provider page. Fiddler AuthN console activate new Okta SAML IdP 2. Close the settings and then select *Login Behavior and Security* from the left nav menu and ensure the *External login allowed* checkbox is selected. Fiddler AuthN console allow external login behavior 3. Select the *Save* button. Fiddler AuthN console external login allowed Select the *Actions* tab from the top menu. Fiddler AuthN console new custom Action script 1. Select the *New* button in the *Scripts* section to create a new action script. 2. Copy the *Okta SAML Action Script* below and paste it into the script text area. 3. Enter `setAttributesOnOktaSAMLAuth` in the *Name* text box. 4. Select the *Add* button. **File:** `Okta SAML Action Script` ```javascript theme={null} function setAttributesOnOktaSAMLAuth(ctx, api) { let firstName = ctx.v1.providerInfo.attributes["firstName"]; let lastName = ctx.v1.providerInfo.attributes["lastName"]; let email = ctx.v1.providerInfo.attributes["email"]; let groups = ctx.v1.providerInfo.attributes["groups"]; let nameParts = [firstName, lastName]; let filteredParts = nameParts.filter(part => part); let displayName = filteredParts.join(' '); if (firstName != undefined) { api.setFirstName(firstName); } if (lastName != undefined) { api.setLastName(lastName); } if (email != undefined) { email = String(email).toLowerCase(); api.setEmail(email); api.setEmailVerified(true); api.setPreferredUsername(email); } if (displayName) { api.setDisplayName(displayName); } api.v1.user.appendMetadata('fiddler_authentication_type', 'SSO:OKTA:SAML'); if (groups === null || groups === undefined){ groups = [] } api.v1.user.appendMetadata('fiddler_groups', groups); } ``` Scroll down to the *Flows* section. Fiddler AuthN console new Action trigger creation 1. Select the *External Authentication* option for the *Flow Type* dropdown. 2. Select the *+ Add trigger* button. 3. Select the *Post Authentication* option for the *Trigger Type* dropdown. 4. Select the *setAttributesOnOktaSAMLAuth* option for the *Actions* dropdown. 5. Select the *Save* button. Add an organization metadata key so Fiddler can correctly identify and process this SSO connection. Set this once during setup. 1. Go to the *Metadata* section and select *Edit*. Fiddler AuthN console organization metadata section 2. Select the *Add* button, then enter the key `fiddler_sso_authentication_type` with the value `SSO:OKTA:SAML`. Fiddler AuthN console organization metadata with Okta SAML authentication type 3. Select the *Save* button next to the new entry. Before validating, ensure your Okta user account is assigned to the new Okta application you created. 1. Open your Fiddler URL (e.g. `https://idpexample.dev.fiddler.ai`). 2. Ensure you see the Fiddler sign-in page and that it displays an SSO login button labeled with the name you configured (e.g. *Okta SAML*). Fiddler application homepage displaying the new SSO login method in addition to the email sign-in form 3. Select the button and confirm that the Fiddler application loads. Fiddler application landing page The first user to sign in to the Fiddler application is automatically assigned the Fiddler Org Admin role; subsequent members are Org Members by default. ## Getting Help If sign-in fails, check the **Okta System Log** (*Reports → System Log*) for the failed attempt and its reason. For Fiddler-side issues, see the [SSO Authentication Guide](/reference/access-control/sso-authentication-guide). If the issue persists, contact your Fiddler representative with the specific error message. ## Important Notes * **Data Storage**: Fiddler stores the following profile attributes from Okta: first name, last name, display name, email address, and group memberships (used to map users to Fiddler teams). * **API Access**: For programmatic API access, users create an API key from the *Credentials* tab in Fiddler's *Settings* page. * **Single Authentication Method**: Users can only authenticate via either SSO or email authentication, not both. ## Next Steps After successful integration: * **Train Users**: Provide guidance on accessing Fiddler through Okta SSO. * **Configure Teams**: Map your identity provider groups to Fiddler teams — see [Mapping AD Groups to Fiddler Teams](/reference/access-control/mapping-ad-groups-to-fiddler-teams). * **Test Group Sync**: Verify automatic group synchronization is working as expected. * **Monitor Usage**: Review authentication logs and user access patterns. # PingOne SAML Source: https://docs.fiddler.ai/reference/access-control/ping-identity-saml Learn how to configure Fiddler with PingOne for Single Sign-On (SSO) using the Security Assertion Markup Language (SAML) protocol. ## Overview This integration allows your users to sign in to Fiddler using their existing PingOne account, without needing a separate Fiddler password. Users are automatically provisioned on their first successful login — no manual invitations required. ## Prerequisites Before starting, ensure you have: * **PingOne Administrator Access**: Permissions to create and configure applications in your PingOne environment. * **Fiddler AuthN Administrator Access**: Org Owner role in Fiddler's AuthN management console. * **Deployment Information**: The hostname of your Fiddler deployment, e.g. `idpexample.dev.fiddler.ai`. ## Configuring PingOne and Fiddler for Integration The URL to the Fiddler AuthN management console is your Fiddler instance base URL prepended with `authn-`. For example, if your Fiddler base URL is `https://idpexample.dev.fiddler.ai` then you will access the AuthN management console at `https://authn-idpexample.dev.fiddler.ai`. Sign in using the AuthN console Org Owner user account credentials provided by your Fiddler representative. Fiddler AuthN console sign-in page Ensure your organization is selected in the dropdown. You may see the *fiddler* organization, but this is reserved for system use and should not be edited. Here we are using the *idpexample* organization. Fiddler AuthN console home page Select *Settings* tab from the top menu and then select *Identity Providers* from the left navigation menu. Fiddler AuthN console add provider page 1. Select the *SAML* option in the *Add provider* section, which brings up the Sign in with SAML form. 2. Enter a name for the integration. This name is displayed on the SSO login button on the Fiddler sign-in page, so choose one your users will recognize. 3. Paste the following placeholder value into the *Metadata XML* text area. AuthN needs it to generate the URLs used when you create the PingOne app integration; you will replace it in a later step. **File:** `Placeholder Metadata XML value` ``` PD94bWwgdmVyc2lvbj0iMS4wIj8+DQo8bWQ6RW50aXR5RGVzY3JpcHRvciB4bWxuczptZD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOm1ldGFkYXRhIg0KICAgICAgICAgICAgICAgICAgICAgdmFsaWRVbnRpbD0iMjAyNS0wOC0zMFQxMzo0NToxM1oiDQogICAgICAgICAgICAgICAgICAgICBjYWNoZUR1cmF0aW9uPSJQVDYwNDgwMFMiDQogICAgICAgICAgICAgICAgICAgICBlbnRpdHlJRD0iaHR0cDovL2xvY2FsaG9zdDo4MDgwIj4NCiAgICA8bWQ6U1BTU09EZXNjcmlwdG9yIEF1dGhuUmVxdWVzdHNTaWduZWQ9ImZhbHNlIiBXYW50QXNzZXJ0aW9uc1NpZ25lZD0iZmFsc2UiIHByb3RvY29sU3VwcG9ydEVudW1lcmF0aW9uPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6cHJvdG9jb2wiPg0KICAgICAgICA8bWQ6TmFtZUlERm9ybWF0PnVybjpvYXNpczpuYW1lczp0YzpTQU1MOjEuMTpuYW1laWQtZm9ybWF0OnVuc3BlY2lmaWVkPC9tZDpOYW1lSURGb3JtYXQ+DQogICAgICAgIDxtZDpBc3NlcnRpb25Db25zdW1lclNlcnZpY2UgQmluZGluZz0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmJpbmRpbmdzOkhUVFAtUE9TVCINCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMb2NhdGlvbj0iaHR0cDovL2xvY2FsaG9zdDo4MDgwL2NvbnN1bWUvZGF0YSINCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmRleD0iMSIgLz4NCiAgICAgICAgDQogICAgPC9tZDpTUFNTT0Rlc2NyaXB0b3I+DQo8L21kOkVudGl0eURlc2NyaXB0b3I+ ``` Fiddler AuthN console new SAML configuration Select the *Create* button and then select the *Save* button. You will be returned to the Organization Settings page. Fiddler AuthN console saving new SAML IdP Select your IdP from the list. Four URLs are displayed — copy the following three for the PingOne app integration steps: * ZITADEL Metadata URL * ZITADEL ACS Login Form URL * ZITADEL ACS Intent API URL Fiddler AuthN console SAML IdP URLs required for PingOne configuration 1. In the PingOne admin console, navigate to *Applications* and select the *+* icon. 2. Enter a name for your application, e.g. `Fiddler IdP Example`, select *SAML Application*, then select *Configure*. PingOne admin console SAML application name and type 1. Under *Provide Application Metadata*, select *Manually Enter*. 2. Enter the *ZITADEL ACS Login Form URL* into the *ACS URL* text box. 3. Add the *ZITADEL ACS Intent API URL* as a second ACS URL. 4. Enter the *ZITADEL Metadata URL* into the *Entity ID* text box. 5. Select *Save*. PingOne admin console SAML configuration 1. Open the created application and go to the *Configuration* section. Select the edit icon and ensure *Sign Assertion and Response* is selected, then select *Save*. PingOne admin console sign assertion and response setting 2. Go to the *Attribute Mappings* section. Select the edit icon and add the following mappings, then select *Save*: 1. Name=`email`, Value=`Email Address` 2. Name=`firstName`, Value=`Given Name` 3. Name=`lastName`, Value=`Family Name` 4. Name=`groups`, Value=`Group Names` PingOne admin console SAML attribute mappings 3. At the top of the application, toggle it to *Active*. 4. Go to the *Overview* section, then under *Connection Details*, copy the *IDP Metadata URL*. PingOne admin console application overview with IDP Metadata URL 1. Return to the identity provider form in the Fiddler AuthN console (where you left off in step 4 — *Add and Configure New SAML Provider*). 2. Clear the *Metadata XML* text area. 3. Paste the *IDP Metadata URL* copied from PingOne into the *Metadata URL* text box. Fiddler AuthN console Metadata URL 1. Expand the *optional* section. 2. Ensure the *Automatic create* and *Automatic update* checkboxes are selected. 3. Set the *Determines whether an identity will be prompted to be linked to an existing account* dropdown to *Check for existing Username*. Fiddler AuthN console automatic create/update and check existing username settings Select the *Save* button. You will be returned to the Organization Settings page. Fiddler AuthN console with newly created PingOne SAML IdP 1. Select your IdP from the list and select the *Activate* button on the identity provider page. Fiddler AuthN console activate new PingOne SAML IdP 2. Close the settings and then select *Login Behavior and Security* from the left nav menu and ensure the *External login allowed* checkbox is selected. Fiddler AuthN console allow external login behavior 3. Select the *Save* button. Fiddler AuthN console external login allowed Select the *Actions* tab from the top menu. Fiddler AuthN console new custom Action script 1. Select the *New* button in the *Scripts* section to create a new action script. 2. Copy the *PingOne SAML Action Script* below and paste it into the script text area. 3. Enter `setAttributesOnPingSAMLAuth` in the *Name* text box. 4. Select the *Add* button. **File:** `PingOne SAML Action Script` ```javascript theme={null} function setAttributesOnPingSAMLAuth(ctx, api) { let firstName = ctx.v1.providerInfo.attributes["firstName"]; let lastName = ctx.v1.providerInfo.attributes["lastName"]; let email = ctx.v1.providerInfo.attributes["email"]; let groups = ctx.v1.providerInfo.attributes["groups"]; let nameParts = [firstName, lastName]; let filteredParts = nameParts.filter(part => part); let displayName = filteredParts.join(' '); if (firstName != undefined) { api.setFirstName(firstName); } if (lastName != undefined) { api.setLastName(lastName); } if (email != undefined) { email = String(email).toLowerCase(); api.setEmail(email); api.setEmailVerified(true); api.setPreferredUsername(email); } if (displayName) { api.setDisplayName(displayName); } api.v1.user.appendMetadata('fiddler_authentication_type', 'SSO:PING:SAML'); if (groups === null || groups === undefined) { groups = [] } api.v1.user.appendMetadata('fiddler_groups', groups); } ``` Scroll down to the *Flows* section. Fiddler AuthN console new Action trigger creation 1. Select the *External Authentication* option for the *Flow Type* dropdown. 2. Select the *+ Add trigger* button. 3. Select the *Post Authentication* option for the *Trigger Type* dropdown. 4. Select the *setAttributesOnPingSAMLAuth* option for the *Actions* dropdown. 5. Select the *Save* button. Add an organization metadata key so Fiddler can correctly identify and process this SSO connection. Set this once during setup. 1. Go to the *Metadata* section and select *Edit*. Fiddler AuthN console organization metadata section 2. Select the *Add* button, then enter the key `fiddler_sso_authentication_type` with the value `SSO:PING:SAML`. Fiddler AuthN console organization metadata with PingOne SAML authentication type 3. Select the *Save* button next to the new entry. Before validating, ensure your PingOne user account is assigned to the new PingOne application you created. 1. Open your Fiddler URL (e.g. `https://idpexample.dev.fiddler.ai`). 2. Ensure you see the Fiddler sign-in page and that it displays an SSO login button labeled with the name you configured (e.g. *PingOne SAML*). Fiddler application homepage displaying the new SSO login method in addition to the email sign-in form 3. Select the button and confirm that the Fiddler application loads. Fiddler application landing page The first user to sign in to the Fiddler application is automatically assigned the Fiddler Org Admin role; subsequent members are Org Members by default. ## Getting Help If sign-in fails, check the **PingOne Audit Log** (*Monitoring → Audit*) for the failed attempt and its reason. For Fiddler-side issues, see the [SSO Authentication Guide](/reference/access-control/sso-authentication-guide). If the issue persists, contact your Fiddler representative with the specific error message. ## Important Notes * **Data Storage**: Fiddler stores the following profile attributes from PingOne: first name, last name, display name, email address, and group memberships (used to map users to Fiddler teams). * **API Access**: For programmatic API access, users create an API key from the *Credentials* tab in Fiddler's *Settings* page. * **Single Authentication Method**: Users can only authenticate via either SSO or email authentication, not both. ## Next Steps After successful integration: * **Train Users**: Provide guidance on accessing Fiddler through PingOne SSO. * **Configure Teams**: Map your identity provider groups to Fiddler teams — see [Mapping AD Groups to Fiddler Teams](/reference/access-control/mapping-ad-groups-to-fiddler-teams). * **Test Group Sync**: Verify automatic group synchronization is working as expected. * **Monitor Usage**: Review authentication logs and user access patterns. # Role-Based Access Control Source: https://docs.fiddler.ai/reference/access-control/role-based-access Learn how Fiddler uses role-based access control with resources and roles. Discover how to manage access with resources, roles, and permissions in your company. ### Overview of Role-Based Access Control Fiddler supports Role-Based Access Control (RBAC) using resources and roles. This documentation outlines the resources, roles, and permissions available in Fiddler, enabling you to manage access control for your organization. ### Understanding Resources Resources are entities within Fiddler that users can access and interact with. There are two main resource types: #### Organization Resources * Organization: Represents your entire Fiddler setup, including projects and users. * Settings: General information, login details, notification settings, and integration configurations. * Users: Individual users with accounts in your Fiddler organization. * Teams: Groups of users within your organization. * Each user can be a member of zero or more teams. * Team roles are associated with project roles, i.e., teams can be granted\ **Project Viewer**, **Project Writer**, or **Project Admin** permissions for a project. * Evaluators: Predefined and custom metrics used to assess model or application outputs. * Global Agentic Custom Metrics: Organization-wide custom metrics for GenAI applications. #### Project Resources * Projects: Contain models, data, and configurations for a specific ML application. * Models: Machine learning models onboarded to Fiddler for monitoring and explainability. * Project Settings: Configurations related to project access and user permissions. * Alerts: Notifications generated by Fiddler based on monitoring data. * Charts & Dashboards: Visualizations of your model performance and data insights. * Application: GenAI applications for agentic workflows. * Evaluator Rules: Rules that define which evaluators run against application spans and how inputs are mapped. * Project-Scoped Agentic Custom Metrics: Project-scoped custom metrics for GenAI applications. ### Understanding Roles Roles define the level of access a user has to Fiddler resources: #### Organization Roles * Org Admin: Has access to manage users, teams, projects, and organization settings. However, this role cannot access the project data unless explicitly given access by the Project Admin. * Org Member: Limited access to organization settings and cannot create projects. #### Project Roles * Project Admin: Manages all aspects of a project, including models, settings, alerts, and user access (except deleting the project). * Project Writer: Can view and edit most project details (models, settings, alerts), but cannot delete the project or invite other users. * Project Viewer: Can view project details and model content, but cannot edit anything except charts and dashboards (read-only access). ### Understanding Permissions #### Permission types Permission types are used in combination with resources and roles to define the access control rules in Fiddler. Fiddler's RBAC access control uses the following permission types to define the level of access a user has to resources: * List: This permission allows users to view a list of resources, but does not grant access to view details or interact with the resources in any way. For example, a user with the "List" permission for projects can see a list of project names, but cannot view project details or settings. * Read: This permission enables users to view details of a resource, but does not grant access to edit or modify the resource in any way. * Create: This permission allows users to create new resources, such as projects, models, or alerts. * Edit: This permission enables users to modify existing resources, such as updating project settings or editing model configurations. * Delete: This permission allows users to delete resources, such as deleting a project or a model. #### Organization Level permissions * Org Admin: Full access to organization settings and resources. * Org Member: Limited access to organization settings. **Legend:** ✅ = Granted ❌ = Not Granted N/A = Not Implemented
ResourceRoleListReadCreateEditDelete
Org Settings: General, Credentials, Email, PagerDuty, WebhookAdmin
Member
Org Settings / Access / Teams & InvitationsAdmin
Member
Org Settings / Access / UsersAdmin
Member
ProjectAdmin
Member
Project / Project SettingsAdmin
Member
EvaluatorsAdminN/AN/A
MemberN/AN/A
Global Agentic Custom MetricsAdminN/A
MemberN/A
#### Project Level permissions An “Org Admin” or “Org Member” user can have the following access to the Projects * Project Admin: Full access to project resources. * Project Writer: Limited access to project resources, excluding deletion and user invitation. * Project Viewer: Read-only access to project resources.
ResourceRoleReadCreateEditDelete
ProjectAdmin
Writer
Viewer
Project / Project SettingsAdmin
Writer
Viewer
Project / Models: Schema, Artifact, Baseline, Dataset, Custom Metric, SegmentsAdmin
Writer
Viewer
Project / Model / AlertsAdmin
Writer
Viewer
Project / BookmarksAdmin
Writer
Viewer
Project / ChartsAdmin
Writer
Viewer
Project / DashboardsAdmin
Writer
Viewer
Model DeploymentAdmin
Writer
Viewer
ApplicationAdminN/A
WriterN/A
ViewerN/A
Evaluator RulesAdminN/A
WriterN/A
ViewerN/A
Project-Scoped Agentic Custom MetricsAdminN/A
WriterN/A
ViewerN/A
### Getting Started * The default "Org Admin" role is created during Fiddler installation. * Assign roles to users and teams to control access to resources. * Use the permissions matrix to understand the access levels for each role. Click [here](/reference/administration/settings#access) for more information on teams. # Microsoft Entra ID OIDC Source: https://docs.fiddler.ai/reference/access-control/single-sign-on-with-azure-ad Learn how to configure Fiddler with Microsoft Entra ID (formerly Azure AD) for Single Sign-On (SSO) using the OpenID Connect (OIDC) protocol. ## Overview This integration allows your users to sign in to Fiddler using their existing Microsoft Entra ID account, without needing a separate Fiddler password. Users are automatically provisioned on their first successful login — no manual invitations required. Entra ID group memberships can be synchronized to Fiddler teams. ## Prerequisites Before starting, ensure you have: * **Microsoft Entra ID Administrator Access**: Permissions to register applications and grant admin consent in your Entra ID tenant. * **Fiddler AuthN Administrator Access**: Org Owner role in Fiddler's AuthN management console. * **Deployment Information**: The hostname of your Fiddler deployment, e.g. `idpexample.dev.fiddler.ai`. * **Entra ID P2 License** (cloud-native group sync only): required to emit group display names for cloud-native groups. Not needed for basic SSO or for groups synced from on-premises AD. ## Configuring Microsoft Entra ID Fiddler requires two redirect URIs on the Entra ID application — one added during registration, the second under *Authentication*: * `https://authn-{base_url}/ui/login/login/externalidp/callback` * `https://authn-{base_url}/idps/callback` Replace `{base_url}` with your Fiddler deployment host (e.g. `idpexample.dev.fiddler.ai`). 1. In the [Microsoft Entra admin center](https://entra.microsoft.com/), go to *Entra ID → App registrations* and select *New registration*. 2. Enter a *Name*, e.g. `Fiddler IdP Example`. 3. Under *Supported account types*, select *Accounts in this organizational directory only (Default Directory only - Single tenant)*. 4. Under *Redirect URI*, select the *Web* platform and enter the first redirect URI (replace the host with your deployment): `https://authn-idpexample.dev.fiddler.ai/ui/login/login/externalidp/callback`. 5. Select *Register*. Microsoft Entra ID app registration 1. In the registered application, go to *Manage → Authentication*. 2. Under *Redirect URI configuration*, select *Add Redirect URI*. 3. Select *Web* and add the second redirect URI (replace the host with your deployment): `https://authn-idpexample.dev.fiddler.ai/idps/callback`. 4. Select *Configure*. Microsoft Entra ID add second redirect URI 1. In the registered application, go to *Certificates & secrets*. Under *Client secrets*, select *New client secret*. 2. Add a description, choose an expiry, and select *Add*. 3. Copy the secret *Value* immediately — it is shown only once. Microsoft Entra ID client secret 1. In the registered application, go to *API permissions* and select *Add a permission → Microsoft Graph → Delegated permissions*. 2. Select `openid`, `email`, `profile`, `offline_access`, and `User.Read`, then select *Add permissions*. 3. Select *Grant admin consent for Default Directory*. Microsoft Entra ID API permissions Add the claims Fiddler needs to the ID token. 1. In the registered application, go to *Token configuration*. 2. Select *Add optional claim*, choose the *ID* token type, and add `email`, `given_name`, and `family_name`. When prompted, enable the option to turn on the Microsoft Graph `email` and `profile` permissions (required for these claims to appear in the token), then select *Add*. Microsoft Entra ID add optional claims 3. Select *Add groups claim*, choose *Groups assigned to the application*, select the *ID* token, then select *Add*. Only the ID token is required for Fiddler. By default Entra emits group IDs (GUIDs); to emit the group **names** that Fiddler maps to teams, complete [Enable Group Sync](#enable-group-sync) below. Microsoft Entra ID groups claim configuration From the registered application's *Overview* page, copy the *Application (client) ID* and the *Directory (tenant) ID*. You will need these, along with the client secret, when configuring Fiddler. Microsoft Entra ID application overview with client and tenant IDs ## Configuring Fiddler The URL to the Fiddler AuthN management console is your Fiddler instance base URL prepended with `authn-`. For example, if your Fiddler base URL is `https://idpexample.dev.fiddler.ai` then you will access the AuthN management console at `https://authn-idpexample.dev.fiddler.ai`. Sign in using the AuthN console Org Owner user account credentials provided by your Fiddler representative. Fiddler AuthN console sign-in page Ensure your organization is selected in the dropdown. You may see the *fiddler* organization, but this is reserved for system use and should not be edited. Here we are using the *idpexample* organization. Fiddler AuthN console home page Select *Settings* tab from the top menu and then select *Identity Providers* from the left navigation menu. Fiddler AuthN console add provider page 1. Select the *Microsoft* option in the *Add provider* section, which brings up the Microsoft Provider form. 2. Note the callback URL shown in the form — it corresponds to the redirect URIs you registered in Entra ID earlier, so no further changes are needed in Entra ID. Fiddler AuthN console add new Microsoft provider form with callback URL 1. In the Microsoft Provider form, enter the following values: 1. Enter a name in the *Name* text box. This name is displayed on the SSO login button on the Fiddler sign-in page, so choose one your users will recognize. 2. In the *Client ID* and *Client Secret* text boxes, paste those values copied from Entra ID. Fiddler AuthN console Microsoft provider client credentials 1. Expand the *optional* section. 2. Ensure the *Scopes List* includes `openid`, `profile`, and `email`. 3. Under *Tenant Type*, select *Tenant ID* and paste your *Directory (tenant) ID*. 4. Ensure the *Automatic create* and *Automatic update* checkboxes are selected. 5. Set the *Determines whether an identity will be prompted to be linked to an existing account* dropdown to *Check for existing Username*. Fiddler AuthN console automatic create/update and check existing username settings Select the *Create* button and then select the *Save* button. You will be returned to the Organization Settings page. Fiddler AuthN console with newly created Microsoft Entra ID IdP 1. Select your IdP from the list and select the *Activate* button on the identity provider page. Fiddler AuthN console activate new Microsoft Entra ID IdP 2. Close the settings and then select *Login Behavior and Security* from the left nav menu and ensure the *External login allowed* checkbox is selected. Fiddler AuthN console allow external login behavior 3. Select the *Save* button. Fiddler AuthN console external login allowed Select the *Actions* tab from the top menu. Fiddler AuthN console new custom Action script 1. Select the *New* button in the *Scripts* section to create a new action script. 2. Copy the *Microsoft Entra ID Action Script* below and paste it into the script text area. 3. Enter `setAttributesOnAzureOIDCAuth` in the *Name* text box. 4. Select the *Add* button. **File:** `Microsoft Entra ID Action Script` ```javascript theme={null} function setAttributesOnAzureOIDCAuth(ctx, api) { let firstName = ctx.getClaim('given_name'); let lastName = ctx.getClaim('family_name'); let email = ctx.getClaim('email'); let groups = ctx.getClaim('groups'); let nameParts = [firstName, lastName]; let filteredParts = nameParts.filter(part => part); let displayName = filteredParts.join(' '); if (firstName != undefined) { api.setFirstName(firstName); } if (lastName != undefined) { api.setLastName(lastName); } if (email != undefined) { email = email.toLowerCase(); api.setEmail(email); api.setEmailVerified(true); api.setPreferredUsername(email); } if (displayName) { api.setDisplayName(displayName); } api.v1.user.appendMetadata('fiddler_authentication_type', 'SSO:AZURE:OIDC'); if (groups === null || groups === undefined){ groups = [] } api.v1.user.appendMetadata('fiddler_groups', groups); } ``` Scroll down to the *Flows* section. Fiddler AuthN console new Action trigger creation 1. Select the *External Authentication* option for the *Flow Type* dropdown. 2. Select the *+ Add trigger* button. 3. Select the *Post Authentication* option for the *Trigger Type* dropdown. 4. Select the *setAttributesOnAzureOIDCAuth* option for the *Actions* dropdown. 5. Select the *Save* button. Add an organization metadata key so Fiddler can correctly identify and process this SSO connection. Set this once during setup. 1. Go to the *Metadata* section and select *Edit*. Fiddler AuthN console organization metadata section 2. Select the *Add* button, then enter the key `fiddler_sso_authentication_type` with the value `SSO:AZURE:OIDC`. Fiddler AuthN console organization metadata with Microsoft Entra ID authentication type 3. Select the *Save* button next to the new entry. Before validating, ensure your Entra ID account is assigned to the registered application (or that user assignment is not required). 1. Open your Fiddler URL (e.g. `https://idpexample.dev.fiddler.ai`). 2. Ensure you see the Fiddler sign-in page and that it displays an SSO login button labeled with the name you configured. Fiddler application homepage displaying the new SSO login method in addition to the email sign-in form 3. Select the button and confirm that the Fiddler application loads. Fiddler application landing page The first user to sign in to the Fiddler application is automatically assigned the Fiddler Org Admin role; subsequent members are Org Members by default. ## Enable Group Sync Fiddler maps identity provider group **names** (with a configurable prefix) to Fiddler teams and roles — see [Mapping AD Groups to Fiddler Teams](/reference/access-control/mapping-ad-groups-to-fiddler-teams) for the naming convention. By default, Entra ID emits group **IDs** (GUIDs) in the token, which Fiddler cannot map — so group sync requires emitting group display names. ### Cloud-native groups Emitting display names for cloud-native groups requires an **Entra ID P2** license. 1. In *Enterprise applications*, open your application, go to *Users and groups*, and assign the users and groups that should be sent to Fiddler. Only groups assigned to the application are returned. 2. In the registered application, go to *Manage → Manifest*. Download a copy of the manifest first as a backup, then update it: 1. Set `groupMembershipClaims` to `ApplicationGroup`. 2. In `optionalClaims.idToken`, set the `groups` claim's `additionalProperties` to `["cloud_displayname"]` so display names are returned. 3. Save the manifest. Microsoft Entra ID manifest group membership claims Microsoft Entra ID manifest groups claim cloud_displayname ### On-premises-synced groups For groups synced from on-premises AD, set the groups claim format to `sAMAccountName` in *Token configuration*. This requires no manifest change or P2 license. ## Getting Help If sign-in fails, review the Entra ID sign-in logs (*Entra ID → Monitoring & health → Sign-in logs*) for the failed attempt and its reason. Common Entra error codes: * `AADSTS50105` — the user is not assigned to the application. Assign the user (or their group) to the registered application. * `AADSTS700016` — the application was not found. Verify the Client ID and tenant are correct. * `AADSTS90094` — admin consent is required. Grant admin consent for the API permissions. For Fiddler-side issues, see the [SSO Authentication Guide](/reference/access-control/sso-authentication-guide). If the issue persists, contact your Fiddler representative with the specific error message. ## Important Notes * **Data Storage**: Fiddler stores the following profile attributes from Entra ID: first name, last name, display name, email address, and group memberships (used to map users to Fiddler teams). * **API Access**: For programmatic API access, users create an API key from the *Credentials* tab in Fiddler's *Settings* page. * **Single Authentication Method**: Users can only authenticate via either SSO or email authentication, not both. * **Client Secret Expiration**: Entra ID client secrets expire. Track the expiry date and rotate the secret before it lapses to avoid login outages. ## Next Steps After successful integration: * **Train Users**: Provide guidance on accessing Fiddler through Microsoft Entra ID SSO. * **Configure Teams**: Map your Entra ID groups to Fiddler teams — see [Mapping AD Groups to Fiddler Teams](/reference/access-control/mapping-ad-groups-to-fiddler-teams). * **Test Group Sync**: Verify automatic group synchronization is working as expected. * **Monitor Usage**: Review authentication logs and set a reminder for client secret expiration. # SSO Authentication Guide Source: https://docs.fiddler.ai/reference/access-control/sso-authentication-guide Configure Single Sign-On authentication for Fiddler with Okta, Azure AD, Google, Ping, and others. Complete setup guide with troubleshooting tips. This guide covers Single Sign-On authentication in Fiddler, including setup procedures, supported identity providers, and user management workflows. ## Overview Single Sign-On (SSO) authentication allows users to access Fiddler using their existing organizational credentials from identity providers like Okta, Microsoft Entra ID, Google, and PingOne. SSO streamlines user access and reduces password management overhead. ## When to Use SSO Authentication SSO authentication is ideal for: * Organizations with existing identity providers * Environments requiring centralized user management * Compliance requirements mandating enterprise authentication * Large user bases where manual user provisioning is impractical ## How SSO Works with Fiddler ### User Provisioning **Automatic User Creation**: When users successfully authenticate through your SSO provider for the first time, Fiddler automatically creates their user account with basic profile information. **No Manual Creation Required**: Unlike email authentication, SSO users don't need to be manually created in the AuthN console—they gain access automatically upon successful SSO authentication. Note that auto-provisioned users will be created with the Fiddler Org Member role by default. Edit a user's Organization role in the [Access tab of the Settings page](/reference/administration/settings#users). ### Authentication Flow 1. **User Access**: User navigates to Fiddler login page 2. **SSO Redirect**: User clicks "Sign in with SSO" and is redirected to your identity provider 3. **Identity Provider Authentication**: User authenticates with their organizational credentials 4. **Automatic Provisioning**: If first login, Fiddler creates the user account automatically 5. **Access Granted**: User gains access to Fiddler as an Org Member and potentially additional privileges if [Group Syncing](/reference/access-control/mapping-ad-groups-to-fiddler-teams) is implemented ## Supported Identity Providers Fiddler supports major enterprise identity providers through industry-standard protocols: | Identity Provider | Supported Protocols | Configuration Guide | | ------------------------------------------ | ------------------- | ----------------------------------------------------------------------------------- | | **Okta** | OIDC | [Okta OIDC Integration](/reference/access-control/okta-integration) | | **Okta** | SAML | [Okta SAML Integration](/reference/access-control/okta-integration-saml) | | **Microsoft Entra ID** (formerly Azure AD) | OIDC | [Azure AD OIDC Integration](/reference/access-control/single-sign-on-with-azure-ad) | | **Google** | OIDC | [Google OIDC Integration](/reference/access-control/google-integration) | | **PingOne** | SAML | [PingOne SAML Integration](/reference/access-control/ping-identity-saml) | ## SSO Configuration Process ### Prerequisites Before configuring SSO, ensure you have: * Administrative access to your identity provider * Access to the Fiddler AuthN management console * Access to the AuthN user account having the "Org Owner" role * Required information from your identity provider (client IDs, metadata URLs, certificates) ### General Configuration Steps These are the basic steps to follow for most IdPs. Follow the specific guide for your required IdP and protocol. **Step 1: Access Authentication Management Console** 1. Log into the AuthN authentication management console AuthN console login page 2. Select your customer organization from the dropdown AuthN console home page 3. Navigate to **Settings > Login and Access > Identity Providers** AuthN console org settings page 4. Select your desired provider by selecting its icon in the **Add Provider section** **Step 2: Configure Identity Provider Integration** More specific configuration steps are in each IdP + protocol guide. 1. **Provider Name**: Enter a descriptive name for your SSO integration 2. **Copy AuthN Settings**: If required, copy AuthN settings to use in creating the application in your IdP 3. **IdP Required Fields**: Populate your IdP's required fields 4. **Connection Details**: Copy required settings from your IdP: * Client ID or Application ID * Metadata URL or Issuer URL * Client Secret (if required) * Certificate information (for SAML) **Step 3: Enable User Provisioning** Expand the optional section and configure automatic user provisioning settings: * ✅ **Enable "Automatic creation"** - Creates new users on first successful login * ✅ **Enable "Automatic update"** - Updates user information from identity provider * ✅ **Select "Check for existing username"** - Links identities to existing accounts when appropriate **Step 4: Configure Attribute Mapping** Ensure proper mapping of user attributes from your identity provider to Fiddler. These values will differ between IdPs and protocols: **Example Required Attributes**: * **First Name** (`firstName`, `given_name`) * **Last Name** (`lastName`, `family_name`) * **Email Address** (`email`) **Optional Attributes**: * **Groups** (`groups`) - For automated group-based access control see [Mapping LDAP Groups](/reference/access-control/mapping-ad-groups-to-fiddler-teams) guide **Step 5: IdP-specific Action Script and Trigger** Each IdP integration guide will provide an action script and trigger type: Action Script * Paste the Fiddler-provided script into the text area * Paste the script name into the Name text box Trigger * Set the Trigger Type option per the guide * Set the Actions dropdown option per the guide **Step 5: Test and Validate** 1. Save your SSO configuration 2. Test authentication with a sample user account 3. Verify user information is properly mapped 4. Confirm automatic provisioning works as expected ## Group Synchronization ### Supported Providers Group synchronization is available for these identity providers: * **Okta** (OIDC and SAML) * **Microsoft Entra ID** (OIDC with proper configuration) * **PingOne** (SAML) ## User Management with SSO ### Automatic User Provisioning **First Login Process**: 1. User authenticates successfully through SSO 2. Fiddler automatically creates user account with information from the IdP 3. User receives default organization member role (the very first user to login will be assigned the Org Admin role) 4. Additional permissions can be assigned through Fiddler teams or individual roles **Ongoing User Updates**: * User information automatically updates from the IdP on each login * Group memberships sync automatically (if configured) * User status changes (deactivation/reactivation) can be managed through the IdP (note that Fiddler deactivates user accounts rather than deletes) ## Mixed Authentication Environments ### Combining SSO and Email Authentication Organizations can use both SSO and email authentication simultaneously: * **SSO Users**: Automatically provisioned from identity provider * **Email Users**: Manually added through the AuthN management console * **Separate Login Paths**: Users choose appropriate authentication method at login if more than one path has been enabled ### User Account Constraints * **Single Authentication Method**: Each user account uses either SSO or email authentication, not both * **Account Linking**: Existing email-authenticated users can be linked to SSO identities under specific conditions ## Troubleshooting Common Issues ### External User Not Found If you see the "External User Not Found" screen after SSO login, follow these steps in order: External User Not Found error screen after SSO login **Step 1: Verify identity provider settings** In the AuthN management console, navigate to the Identity Provider configuration and ensure the following settings are configured: * Enable the **Automatic creation** toggle — creates a Fiddler user on first sign-in * Enable the **Automatic update** toggle — syncs profile fields (name, email) on subsequent sign-ins * Set the **Determines whether an identity will be prompted to be linked to an existing account** dropdown to **Check for existing username** — matches the incoming identity to an existing user before creating a duplicate Updating other configuration within the Identity Provider section can sometimes reset these settings. Always verify these are enabled and save after making any changes. **Step 2: Verify the action script** Ensure the action script corresponding to your identity provider is added and configured correctly in the AuthN management console under Actions. Refer to the integration guide for your specific identity provider for the canonical action script. **Step 3: Check for missing user attributes** If the email, first name, last name, or username fields are not populated on the error screen, the action script is unable to parse the response from your identity provider. This means either: * Your identity provider is not configured to pass the attributes that the Fiddler action script expects (e.g., for SAML: `firstName`, `lastName`, `email`, `groups`; for OIDC: `given_name`, `family_name`, `email`, `groups`) * The attribute names in your identity provider do not match the attribute names in the action script * The action script was not copy-pasted correctly and has a syntax error — verify the script has no broken string literals or missing quotes Verify your identity provider's attribute mapping configuration and confirm it returns the expected attributes in the SAML assertion or OIDC response. ### Debugging Identity Provider Attribute Responses To confirm exactly what attributes your identity provider is returning, you can temporarily enable logging in the action script. Add the following lines after the variable declarations in your existing action script: ```javascript theme={null} let logger = require("zitadel/log"); logger.log('****** Action debugging start ******'); logger.log('email present: ' + (email != undefined) + ', type: ' + typeof email); logger.log('firstName present: ' + (firstName != undefined) + ', type: ' + typeof firstName); logger.log('lastName present: ' + (lastName != undefined) + ', type: ' + typeof lastName); logger.log('****** Action debugging end ******'); ``` After adding the logging lines, attempt an SSO sign-in and ask your Fiddler representative to check the Zitadel application logs. The logs will show whether each attribute was returned by your identity provider and its data type, without logging actual values. Remember to remove the logging lines from the action script after debugging is complete. #### Verifying SAML Assertion Attributes For SAML identity providers, you can inspect the raw SAML assertion to verify that the expected attributes are present in the response from your identity provider: 1. Open Chrome DevTools (**F12** or **Ctrl+Shift+I**) and navigate to the **Network** tab 2. Enable **Preserve log** to retain network entries across redirects 3. Attempt an SSO sign-in through your SAML identity provider 4. In the Network tab, locate the `POST` request to `https://authn-{base_url}/ui/login/login/externalidp/saml/acs` Chrome DevTools Network tab showing the SAML ACS POST request 5. Open the **Payload** tab for that request and copy the `SAMLResponse` value Chrome DevTools Payload tab showing the SAMLResponse value 6. Decode the `SAMLResponse` locally using your terminal — this returns an XML document. The decoded SAML assertion contains email, names, group memberships, and signed identity claims. Decode it locally rather than pasting into an online Base64 decoder or SAML inspector. * macOS: `pbpaste | base64 -d` * Linux: `xclip -selection clipboard -o | base64 -d` (or `xsel -b | base64 -d`) * Cross-platform: `echo "" | base64 -d` * Windows PowerShell: `[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String(""))` 7. In the decoded XML, verify that the attributes your action script expects (e.g., for SAML: `firstName`, `lastName`, `email`, `groups`; for OIDC: `given_name`, `family_name`, `email`, `groups`) are present and contain the correct values ### Authentication Failures **Redirect URI Mismatch**: * Verify redirect URI in identity provider matches: `{fiddler_url}/api/sso/{provider}/callback` * Check for HTTP vs. HTTPS mismatches **Certificate or Secret Expiration**: * Monitor client secret expiration dates (typically 6-24 months) * Update expired certificates or secrets in both identity provider and Fiddler configuration **Attribute Mapping Issues**: * Verify required attributes (`firstName`, `lastName`, `email`) are included in authentication response * Check attribute name consistency between identity provider and Fiddler configuration ### User Provisioning Issues **Users Not Auto-Provisioned**: * Confirm "Automatic creation" setting is enabled * Verify user has appropriate permissions in identity provider * Check authentication logs for error messages **Missing User Information**: * Validate attribute mappings in identity provider configuration * Ensure identity provider includes required claims in authentication tokens **Group Synchronization Problems**: * Verify `groups` attribute is included in identity provider claims * Check that corresponding teams exist in Fiddler * Confirm group names match between identity provider and Fiddler teams ## Next Steps After reading this overview: 1. **Choose Your Provider**: Review the provider-specific integration guides 2. **Plan Implementation**: Coordinate with your identity provider administrator 3. **Test Configuration**: Set up a test environment before production deployment 4. **Train Users**: Provide documentation on the new authentication process *** **Note**: SSO configuration requires coordination between Fiddler administrators and identity provider administrators. Plan accordingly for configuration, testing, and rollout phases. # AWS VPC Endpoint Setup Source: https://docs.fiddler.ai/reference/administration/aws-vpc-endpoint-setup Automated script to create AWS VPC endpoints for secure communication with Fiddler Cloud using AWS Virtual PrivateLink. This guide provides an automated approach to creating AWS VPC endpoints for Fiddler Cloud integration. For manual configuration steps, see the [AWS Virtual PrivateLink Setup](/reference/administration/aws-vpl-setup) guide. This script automates the VPC endpoint creation process described in the manual setup guide. Ensure you have completed initial coordination with the Fiddler team before running this script. ## Overview The VPC endpoint creation script automates the following tasks: * Creates and configures security groups with HTTPS access * Establishes VPC endpoints in specified subnets * Configures private DNS for seamless Fiddler Cloud access * Validates configuration and handles cross-region endpoints ## Prerequisites Before running the script, ensure you have: * **AWS CLI** installed and configured with appropriate credentials * **jq** tool installed for JSON parsing * **yq** tool installed for YAML parsing * AWS IAM permissions to create: * VPC endpoints * Security groups * Route53 DNS records * Required information from the Fiddler team: * VPC endpoint service name * Stack name identifier * Your AWS environment details: * VPC ID * Subnet IDs * AWS region ## Installation ### Step 1: Install Required Tools The following tools are required: * AWS CLI * jq for JSON parsing * yq for YAML parsing ```sh theme={null} brew install awscli, jq, yq ``` ```sh theme={null} sudo apt-get install -y awscli, jq, yq ``` It is recommended to manually install the AWS CLI on these operating systems. Download the bundle [directly](https://aws.amazon.com/cli/) from AWS. ```sh theme={null} sudo yum install jq yq ``` ### Step 2: Configure AWS CLI If not already configured, set up your AWS credentials: ```bash theme={null} aws configure ``` ### Step 3: Download and Prepare the Script 1. Request the script and configuration file template from your Fiddler representative 2. Make the script executable: ```bash theme={null} chmod +x create-vpc-endpoint.sh ``` ## Configuration ### Step 1: Gather Required Information Collect the following information before configuration: **From the Fiddler team:** * **Service name**: The VPC endpoint service name for your Fiddler environment * **Stack name**: The unique identifier for your endpoint **From your AWS environment:** * **VPC ID**: The ID of your VPC (e.g., `vpc-12345678`) * **Subnet IDs**: IDs of subnets where the endpoint will be created * **Region**: The AWS region where your VPC is located ### Step 2: Update Configuration File Edit the `config.yaml` file with your specific values: ```yaml theme={null} # Required: VPC Private Link service name (provided by Fiddler) service_name: # Required: Stack name (provided by Fiddler) stack_name: -endpoint # Required: VPC ID where endpoint will be created vpc_id: # Required: List of subnet IDs (at least one required) subnet_ids: - - - # Required: AWS region (must match your VPC region) region: # Optional: DNS configuration dns: enabled: true custom_domain: authn-.cloud.fiddler.ai zone_name: cloud.fiddler.ai ``` The `service_name` and `stack_name` must be obtained from the Fiddler team. Do not use placeholder values. ## Running the Script ### Basic Usage Run the script with the default configuration file `config.yaml`: ```bash theme={null} ./create-vpc-endpoint.sh ``` ### Using a Custom Configuration File Name Specify an alternative configuration file: ```bash theme={null} ./create-vpc-endpoint.sh my-config.yaml ``` ### Script Execution Process The script performs the following operations: 1. **Validates configuration** - Ensures all required fields are present 2. **Creates security group** - Establishes HTTPS access rules if not specified 3. **Creates VPC endpoint** - Establishes the endpoint in your VPC 4. **Configures DNS** - Sets up private DNS for easy access (if enabled) The script is idempotent and safe to run multiple times. It will not create duplicate resources. ### Example Output ``` [INFO] Reading configuration from: config.yaml [INFO] Configuration loaded successfully [INFO] Creating VPC endpoint for service: com.amazonaws.vpce.us-west-2.vpce-svc-1234567890abcdef0 [INFO] Using AWS region: us-west-2 [INFO] Checking if VPC endpoint with tag Name=myapp-endpoint already exists... [INFO] No existing VPC endpoint found - proceeding with creation [INFO] Creating security group for VPC endpoint... [INFO] Security group created successfully: sg-1234567890abcdef0 [INFO] Creating VPC endpoint... [INFO] VPC endpoint created successfully! [INFO] Setting up DNS for new endpoint... [DNS] DNS setup completed successfully! [INFO] VPC endpoint creation initiated successfully! ``` ## Advanced Configuration ### Using Existing Security Groups To use pre-existing security groups instead of creating new ones: ```yaml theme={null} security_group_ids: * sg-12345678 * sg-87654321 ``` ### Disabling DNS Setup If you prefer to manage DNS separately: ```yaml theme={null} dns: enabled: false ``` ### Cross-Region Endpoints The script automatically handles cross-region endpoints when the service is in a different region than your VPC: ```yaml theme={null} service_name: com.amazonaws.vpce.us-east-1.vpce-svc-1234567890abcdef0 # Service in us-east-1 region: us-west-2 # Your VPC region ``` ## Troubleshooting ### Common Issues and Solutions #### AWS CLI not configured ```bash theme={null} aws configure ``` Enter your AWS access key, secret key, default region, and output format. #### Missing required tools Install jq and yq as described in the Installation section. #### VPC or subnet not found * Verify the VPC ID and subnet IDs in your configuration * Ensure you have access to the specified resources * Confirm the resources exist in the specified region #### Permission denied errors Ensure your AWS credentials have the following permissions: * `ec2:CreateVpcEndpoint` * `ec2:CreateSecurityGroup` * `ec2:AuthorizeSecurityGroupIngress` * `ec2:CreateTags` * `ec2:DescribeVpcs` * `ec2:DescribeSubnets` * `route53:CreateHostedZone` * `route53:ChangeResourceRecordSets` ### Getting Help For script usage information: ```bash theme={null} ./create-vpc-endpoint.sh -h ``` ## Security Considerations * The script creates security groups allowing HTTPS (port 443) access from your VPC CIDR range * All DNS zones are created as private hosted zones * Resources are tagged for easy identification and management * VPC endpoints use AWS PrivateLink for secure, private communication ## Verification After running the script: 1. Verify the endpoint status in the AWS VPC console shows "Available" 2. Check that security group rules are correctly configured 3. Test DNS resolution within your VPC: ```bash theme={null} nslookup .cloud.fiddler.ai ``` 4. Access the Fiddler UI at `https://<your-subdomain>.cloud.fiddler.ai` ## Next Steps * Review the [AWS Virtual PrivateLink Setup](/reference/administration/aws-vpl-setup) guide for additional context * Configure your applications to use the private endpoint * Set up monitoring for the VPC endpoint connection * Contact Fiddler [support](mailto:support@fiddler.ai) if you encounter any issues # AWS Virtual PrivateLink Setup Source: https://docs.fiddler.ai/reference/administration/aws-vpl-setup Step-by-step guide to configure AWS Virtual PrivateLink for secure communication between your AWS VPC and Fiddler Cloud. **Automated Setup Available**: We now provide an automated script that simplifies the VPC endpoint creation process. For most users, we recommend using the [AWS VPC Endpoint Automation Script](/reference/administration/aws-vpc-endpoint-setup) instead of this manual process. This guide remains available for reference, troubleshooting, and those who prefer manual configuration. This guide illustrates configuring an AWS Virtual PrivateLink (VPL) between your company VPC and Fiddler Cloud environment to establish secure communication channels. Fiddler Customers must complete these steps only after the Fiddler team has completed the customer's private-link-based environment deployment. Your Fiddler environment will use the private DNS name: `<customer-subdomain>.cloud.fiddler.ai`, where `<customer-subdomain>` is typically your company name. If you have specific subdomain requirements or restrictions, notify your Fiddler representative before VPL configuration. ## Prerequisites * AWS account with VPC access * Fiddler-provided service name * Fiddler-provided DNS name * VPC CIDR range information * Appropriate AWS IAM permissions to create VPC endpoints ## Step 1: Navigate to the AWS VPC Console 1. Log in to your AWS Management Console 2. Navigate to the VPC service 3. In the left navigation panel, click on "Endpoints" 4. Click the Create endpoint button Create an endpoint ## Step 2: Configure the Fiddler Endpoint Service 1. Enter a descriptive name tag for your endpoint 2. Select "PrivateLink Ready partner services" from the service categories 3. Enter the Fiddler-provided service name 4. Click Verify Service to confirm the service details Fiddler will provide the service name before you proceed with this step. Contact your Fiddler representative if you haven't received this information. Provide the endpoint service name ## Step 3: Select VPC and Subnets 1. Select your VPC from the dropdown 2. Choose all subnets where your client applications are running 3. Ensure the selected subnets have appropriate routing within your VPC to the endpoint Select the VPC ## Step 4: Configure Security Group 1. Create a new security group if one doesn't exist 2. Add an inbound rule to allow: * Port: 443 (HTTPS) * Source: Your VPC CIDR range 3. Select the security group ID to associate with the endpoint ### Example security group configuration: * Inbound rule: TCP 443 from VPC CIDR * Outbound rule: All traffic (default) Create a new security group ## Step 5: Create the Endpoint 1. Review all configuration settings 2. Click Create endpoint to initiate the endpoint creation 3. Wait for the endpoint status to change to "Available" ## Step 6: Configure Private DNS 1. Select the newly created endpoint 2. From the Actions menu, choose "Modify private DNS name" 3. Enable private DNS names by checking the "Enable for this endpoint" checkbox 4. **Important**: The private DNS name will be in the format: `<customer-subdomain>.cloud.fiddler.ai` * Example: If your company name is "acme", the DNS name would be `acme.cloud.fiddler.ai` 5. Click Save changes Once enabled, AWS will automatically configure DNS resolution for your assigned Fiddler subdomain in the format `<customer-subdomain>.cloud.fiddler.ai`. Select action "Modify the private DNS name" Modify the private DNS name ## Step 7: Verify Configuration 1. Wait for the endpoint status to show as "Available" 2. Verify that the private DNS name is enabled 3. Confirm the security group rules are properly configured ## Step 8: Access Fiddler Once the configuration is complete, you can access the Fiddler UI within your VPC using the configured DNS name: `https://<customer-subdomain>.cloud.fiddler.ai` ## Troubleshooting If you encounter issues: * Verify the endpoint status in the AWS console * Check security group rules and network ACLs * Confirm DNS resolution within your VPC * Contact Fiddler support with your endpoint ID and any error messages ## Next Steps * For automated setup, see the [AWS VPC Endpoint Automation Script](/reference/administration/aws-vpc-endpoint-setup) * [Configure your applications to use the private endpoint](https://docs.aws.amazon.com/vpc/latest/userguide/endpoint-services-overview.html) * [Set up monitoring for the VPL connection](https://docs.aws.amazon.com/vpc/latest/userguide/monitoring.html) * [Review security best practices](https://docs.aws.amazon.com/vpc/latest/userguide/security.html) # LLM Gateway Source: https://docs.fiddler.ai/reference/administration/llm-gateway Configure LLM provider credentials to enable AI-powered features in Fiddler using your own API keys from OpenAI, Anthropic, Gemini, and other providers. The **LLM Gateway** allows you to manage and securely configure credentials for multiple Large Language Model (LLM) providers, enabling you to use your own API keys for AI-powered features throughout the Fiddler platform. ## Overview LLM Gateway provides centralized management of LLM provider credentials, giving you control over which models and API keys power Fiddler's AI features such as: * **Custom Evaluators** - Use your preferred LLM to evaluate model outputs * **LLM Enrichments** - Generate AI-powered insights on your monitoring data * **Content Analysis** - Assess response quality, detect hallucinations, and monitor trust metrics ### Key Capabilities * **Multiple Provider Support** - Configure credentials for OpenAI, Anthropic, Gemini, Vertex AI, Databricks, AWS Bedrock, Azure OpenAI, Azure AI, and Fiddler * **Credential Redundancy** - Add multiple API keys per provider for failover and load balancing * **Flexible Key Management** - Organize credentials by team, environment, or purpose * **Secure Storage** - API keys are encrypted and stored securely *** ## Prerequisites Before configuring LLM Gateway, ensure you have: * **Admin Permissions** - Only administrators can access the LLM Gateway settings * **Provider API Keys** - Valid API credentials from your chosen LLM providers (OpenAI, Anthropic, Gemini, Vertex AI, Databricks, AWS Bedrock, Azure OpenAI, Azure AI, or Fiddler) **Note:** Each provider requires a separate API key. Obtain keys from your provider's developer portal before proceeding. *** ## Configure LLM Providers ### Add a New Provider Follow these steps to add an LLM provider to your Fiddler organization: From the top navigation bar, click the **Settings** icon (gear icon) and select the **LLM Gateway** tab. Click the **Add Provider** button to open the provider configuration dialog. Choose your LLM provider from the dropdown menu: * **OpenAI** - OpenAI GPT models * **Anthropic** - Anthropic Claude models * **Gemini** - Google Gemini models * **Vertex AI** - Google Cloud Vertex AI Model Garden (Gemini and Anthropic Claude) * **AWS Bedrock** - Bedrock-hosted models (Anthropic, Amazon Nova, Meta, Mistral AI) * **Azure OpenAI** - OpenAI models on Azure infrastructure * **Azure AI** - Anthropic Claude models via the Azure AI catalog * **Databricks** - Foundation models served through Databricks Model Serving * **Fiddler** - Fiddler-hosted LLM services a. Click **Add Credential** b. Enter a **Nickname** for the credential (for example, `Production Team Key` or `Test Environment`) **Tip:** Use clear, descriptive nicknames to differentiate between test and production keys or to identify which team owns the credential. c. Paste your **API Key** into the credential field Some providers use authentication methods other than — or in addition to — an API key. For example, **Microsoft Entra ID** (Azure), **AWS Access Key** (Bedrock), **GCP Service Account** (Vertex AI), and **OAuth Client Credentials** (Databricks). Vertex AI, for instance, uses a GCP Service Account instead of an API key. See [Supported Providers](#supported-providers) for the credential fields each provider requires. d. The provider's available models will be automatically populated Click **Update Provider** to save your configuration, or **Cancel** to discard changes. Your provider is now configured and ready to use with Fiddler's AI-powered features. ### Add Multiple Credentials to a Provider You can add multiple API keys to a single provider for redundancy, load balancing, or to separate keys by environment or team. **Why Use Multiple Credentials?** * **Redundancy** - Automatic failover if one key reaches rate limits or expires * **Load Balancing** - Distribute API calls across multiple keys to improve throughput * **Key Rotation** - Safely test new credentials before removing old ones * **Environment Separation** - Use different keys for development, staging, and production **To Add Additional Credentials:** 1. Navigate to **Settings → LLM Gateway** 2. Click the **edit** icon next to the provider you want to modify 3. In the Edit Provider dialog, click **Add Credential** 4. Enter a nickname and paste the new API key 5. Click **Update Provider** to save All credentials for a provider will be available for use across Fiddler features. The platform handles credential selection and failover automatically. ### Edit an Existing Provider You can modify provider configurations, update credentials, or rename existing keys. **To Edit a Provider:** 1. Navigate to **Settings → LLM Gateway** 2. Locate the provider you want to edit 3. Click the **edit** icon next to the provider name 4. Make your changes: * **Update Credentials** - Click the edit icon next to a credential to modify the API key * **Rename Credentials** - Update the nickname to reflect the key's purpose * **Add More Credentials** - Click **Add Credential** to add another API key * **Remove Credentials** - Delete individual credentials that are no longer needed 5. Click **Update Provider** to save your changes Removing a credential that is actively in use may impact running evaluations or enrichments. Ensure you have alternate credentials configured before removing a key. *** ## Supported Providers The LLM Gateway supports the following providers: ### OpenAI * **Models Available:** GPT-5 (including mini and nano), GPT-4.1 (including mini and nano), GPT-4o, and GPT-4o mini * **API Key Location:** [OpenAI Platform - API Keys](https://platform.openai.com/api-keys) * **Use Cases:** Custom evaluators, content generation, response quality assessment ### Anthropic * **Models Available:** Claude Opus 4.1, Claude Opus 4, Claude Sonnet 4, and Claude 3.5 Haiku * **API Key Location:** [Anthropic Console](https://console.anthropic.com/) * **Use Cases:** Advanced reasoning, content analysis, evaluation tasks ### Gemini * **Models Available:** Gemini 2.5 Pro, Gemini 2.5 Flash, and Gemini 2.5 Flash-Lite * **API Key Location:** [Google AI Studio](https://makersuite.google.com/app/apikey) * **Use Cases:** Multimodal analysis, content generation, embeddings ### Vertex AI Access models from Google Cloud's Vertex AI Model Garden. Requests are routed through your GCP project and region. * **Models Available:** Gemini 2.5 Pro, Gemini 2.5 Flash, Gemini 2.5 Flash-Lite, Claude Sonnet 4.5, and Claude Opus 4.5 * **Authentication**: * **GCP Service Account** — Provide a service account JSON key, plus the Vertex AI project (the GCP project where requests are sent) and Vertex AI location (the region, for example `us-central1`). The project and location may differ from the project embedded in the service account key. * **Use cases:** Organizations with existing GCP / Vertex AI infrastructure or Google-managed inference environments ### AWS Bedrock Access LLM models hosted on Amazon Web Services through the Bedrock managed service. All requests are routed through your AWS account. * **Supported model families** (custom model IDs for fine-tuned and newly released models are also supported): * **Anthropic** (`bedrock/anthropic.*`) — Claude models for advanced reasoning and long-context tasks * **Amazon** (`bedrock/amazon.nova-*`) — Nova family for multimodal and text generation * **Meta** (`bedrock/meta.llama*`) — Open-weights Llama models across multiple sizes * **Mistral AI** (`bedrock/mistral.*`) — High-performance models optimized for efficiency * **Authentication**: * **API Key** — Use Fiddler-managed AWS credentials * **AWS Access Key** — Provide your own AWS access key ID, secret access key, and AWS region * **Custom endpoint** (optional) — Set a custom **API Base URL** to route requests through an AWS VPC endpoint instead of the public Bedrock endpoint (for example, `https://vpce-xxx.bedrock-runtime.us-east-1.vpce.amazonaws.com`) * **Use cases:** Evaluators and LLM-as-a-Judge workflows requiring inference traffic to stay within AWS-managed cloud boundaries ### Azure OpenAI Access OpenAI models deployed on Microsoft Azure. When configuring this provider, specify your **Azure deployment name**, which may differ from the base model name. * **Supported models** (custom fine-tuned models are also supported): * **GPT-5** and **GPT-5 mini** — Latest-generation reasoning and general-purpose models * **GPT-4o** and **GPT-4o mini** — Multimodal, cost-optimized models * **Authentication**: * **API Key** — Azure deployment API key for simple authentication * **Microsoft Entra ID** (formerly Azure AD) — OAuth 2.0 client credentials flow using tenant ID, client ID, and client secret; for enterprise SSO integration * **Custom endpoint** — Set a custom **API Base URL** to target a specific Azure region or resource endpoint (for example, `https://.openai.azure.com/`) * **Use cases:** Organizations with existing Azure OpenAI deployments, enterprise compliance requirements, or Microsoft-managed inference environments ### Azure AI Access models from the Azure AI Model Catalog. When configuring this provider, specify your **Azure AI deployment name**. * **Supported models**: * **Anthropic** — Claude Sonnet 4.5, Claude Haiku 4.5, and Claude Opus 4.1 * **Authentication**: * **API Key** — Azure deployment API key for simple authentication * **Microsoft Entra ID** (formerly Azure AD) — OAuth 2.0 client credentials flow using tenant ID, client ID, and client secret; for enterprise SSO integration * **Custom endpoint** — Set a custom **API Base URL** to target a specific Azure AI resource (for example, `https://.services.ai.azure.com/`) * **Use cases:** Organizations with existing Azure AI infrastructure or multi-provider model access through Azure's unified catalog ### Databricks Access foundation models served through Databricks Model Serving. This provider requires a custom **API Base URL** pointing to your workspace serving endpoint. * **Supported model families:** * **OpenAI GPT-OSS** — `databricks-gpt-oss-120b`, `databricks-gpt-oss-20b` * **Meta Llama** — `databricks-meta-llama-3-1-8b-instruct`, `databricks-meta-llama-3-3-70b-instruct`, `databricks-meta-llama-3-1-405b-instruct`, `databricks-llama-4-maverick` * **Google Gemma** — `databricks-gemma-3-12b` * **Authentication**: * **API Key** — Databricks personal access token for simple authentication * **OAuth Client Credentials** — OAuth 2.0 client credentials (machine-to-machine) flow using a Databricks service principal's token URL, client ID, client secret, and scope (for example, `all-apis`). Fiddler exchanges these for a short-lived bearer token and refreshes it automatically — no long-lived tokens to manage or rotate. * **Custom endpoint** — Set the **API Base URL** to your Databricks workspace serving endpoint (for example, `https://adb-xxxx.azuredatabricks.net/serving-endpoints`) * **Use cases:** Organizations serving foundation models on Databricks, or requiring enterprise machine-to-machine authentication via service principals 1. In Databricks, create a **service principal** and generate an **OAuth secret** for it, following Databricks' OAuth machine-to-machine (M2M) guide for your cloud ([AWS](https://docs.databricks.com/aws/en/dev-tools/auth/oauth-m2m), [Azure](https://learn.microsoft.com/en-us/azure/databricks/dev-tools/auth/oauth-m2m), [GCP](https://docs.databricks.com/gcp/en/dev-tools/auth/oauth-m2m)). This gives you the **Client ID** (the service principal's application ID) and **Client Secret** (shown only once). 2. Enter these values when adding the Databricks credential in Fiddler: * **Client ID** and **Client Secret** — from step 1. * **Token URL** — `https:///oidc/v1/token` * **API Base URL** — `https:///serving-endpoints` (same workspace host) * **Scope** — `all-apis` ### Fiddler * **Models Available:** Fiddler-managed LLM services * **API Key Location:** Provided by Fiddler * **Use Cases:** Pre-configured evaluators, platform-optimized features *** ## Best Practices ### Credential Management * **Use Descriptive Nicknames** - Label credentials by team, environment, or purpose (for example, `ML Team - Production`, `Data Science - Test`) * **Rotate Keys Regularly** - Add new credentials before removing old ones to avoid service interruption * **Separate Environments** - Use different API keys for development, staging, and production * **Monitor Usage** - Track API consumption through your provider's dashboard to avoid unexpected costs ### Security * **Restrict Access** - Only grant Admin permissions to users who need to manage LLM credentials * **Avoid Sharing Keys** - Each team should have their own credentials rather than sharing a single key * **Revoke Compromised Keys** - If a key is exposed, immediately revoke it in your provider's console and remove it from Fiddler ### Performance Optimization * **Add Multiple Credentials** - Configure 2-3 keys per provider for redundancy and better throughput * **Test Before Production** - Validate new credentials in a test environment before using them in production * **Monitor Rate Limits** - Be aware of your provider's rate limits and adjust your credential count accordingly *** ## Related Features Once you've configured LLM providers in the Gateway, you can use them with these Fiddler features: * **Custom Evaluators** - Create LLM-based evaluators to assess model outputs * **LLM Enrichments** - Generate AI-powered metrics for your LLM applications * **Content Safety** - Use LLM providers for advanced content analysis *** ## Troubleshooting ### Provider Not Appearing in Feature Selection **Issue:** After adding a provider, it doesn't appear in evaluator or enrichment configuration. **Solution:** * Verify the provider was saved successfully (check the LLM Gateway tab) * Ensure at least one credential was added to the provider * Refresh your browser page * Contact your Fiddler administrator to verify permissions ### Invalid API Key Error **Issue:** Receiving authentication errors when using a configured provider. **Solution:** * Verify the API key is correct in your provider's console * Check that the key hasn't expired or been revoked * Ensure the key has the necessary permissions for the models you're using * Update the credential in Settings → LLM Gateway ### Rate Limit Warnings **Issue:** Receiving rate limit errors from a provider. **Solution:** * Add additional credentials to the provider for load balancing * Check your provider's dashboard for current usage and limits * Consider upgrading your provider plan for higher limits * Temporarily reduce the number of concurrent evaluations or enrichments # Administration Source: https://docs.fiddler.ai/reference/administration/settings Dive into our guide to application settings in Fiddler. Learn to use the settings page to manage team setup, permissions, and credentials. ## Overview The Settings page provides centralized management for your organization's configuration, user access, and integrations. Access the **Settings** page from the left navigation bar in the Fiddler UI. Fiddler home page showing the user menu open and highlighting the Settings link. ## Settings Tabs The Settings page is organized into the following tabs: * **General** - Organization information and user details * **Access** - User and team management * **Credentials** - API key management * **LLM Gateway** - LLM provider and API credential management * **Email Configuration** - Email notification settings * **PagerDuty Integration** - PagerDuty alert configuration * **Webhook Integration** - Webhook service management ## General The **General** tab displays your organization's configuration and current user information. General tab of the Settings page. ### Organization Information * **Organization Name** - Your organization's display name in Fiddler * **Organization ID** - Unique identifier for your organization * **Version** - Current Fiddler platform version ### User Information * **User Name** - Your display name in the system * **Email** - Email address associated with your account ## Access The **Access** tab provides centralized management for users and teams within your organization. ### Users The **Users** sub-tab displays all users who are members of your organization. Users sub-tab of the Access tab on the Settings page showing a list of users. This view shows: * User names and email addresses * Organization roles (Org Admin or Org Member) * Account status (Active/Inactive) * Last login information > **Note** > > User invitations are managed through the Fiddler AuthN console: > > * Email authentication users must be invited by AuthN Org Owners or Org User Managers > * SSO users are automatically created upon first login to Fiddler ### Teams The **Teams** sub-tab displays all teams defined within your organization. Teams provide a way to organize users and manage project-level access controls. Teams sub-tab of the Access tab on the Settings page showing a list of teams #### Creating Teams Create a new team by clicking the plus (**`+`**) icon in the top-right corner. > **Important** > > Only users with the Org Admin role can create teams. The plus (**`+`**) icon will not be visible for Org Members. When creating a team: 1. Enter a unique team name 1. Team names may not include spaces, but mixed-case alphanumeric characters are valid 2. Add team members from existing users 3. Assign appropriate project permissions 4. Click **Create** to save the team #### Team Synchronization If your organization uses SSO with group synchronization enabled, teams can be automatically created and managed based on your identity provider groups. See [Mapping Identity Provider Groups to Fiddler Teams](/reference/access-control/mapping-ad-groups-to-fiddler-teams) for configuration details. ## Credentials The **Credentials** tab manages API keys used for programmatic access to Fiddler through the Fiddler Python client, Fiddler SDKs, and REST APIs. Fiddler UI versions prior to 26.11 labeled API keys as **Access Keys**. Both terms refer to the same credential. Credentials tab showing the list of named API keys. ### How API Keys Work Fiddler API keys behave like Personal Access Tokens (PATs) — similar in model to a GitHub PAT. Each key is tied to the individual user who created it and acts on that user's behalf, rather than identifying an application or service account. Understanding this model is important for security, access control, and key lifecycle management. #### Identity and Attribution * Each API key is issued to a specific user and acts as that user when making API requests * All actions performed with the key are attributed to the issuing user in audit logs * Keys are not tied to a specific application, environment, or service account #### Permission Scope API keys inherit the **full permissions** of the user who created them: * There is no per-key scope reduction (for example, no read-only keys) * There is no per-application or per-project restriction on a key * If the user's role changes, every key they own immediately reflects the new permissions #### Lifetime and Revocation * Keys remain active for as long as the issuing user's account is active * Keys persist until explicitly revoked — there is no automatic expiry * If the user is deactivated, all of their keys stop working immediately * User password changes have no effect on API keys * Revoking a key takes effect immediately; allow up to 5 minutes for all active sessions to reflect the change #### Anti-Patterns to Avoid Because each key carries the issuing user's full permissions and identity: * **Do not share keys** between team members — every action will be attributed to the key's owner, and revoking access for one person requires revoking the shared key for everyone * **Do not commit keys to source control** — treat them like passwords * **Prefer per-developer keys** over a single shared key for any team or CI pipeline * **Rotate keys** on personnel changes, suspected exposure, or on a regular schedule #### What Fiddler API Keys Are Not To set expectations against other common credential models: * **Not OAuth client credentials** — no client ID/secret pair, no token exchange * **Not service-account keys** — no machine identity separate from a human user * **Not scoped tokens** — no per-key permission reduction or resource restriction ### Creating API Keys Fiddler supports two key-creation flows. Named API keys are the recommended approach for deployments running 26.9 or later. #### Named API Keys (recommended, 26.9+) 1. Click **Create Key** to open the create dialog. 2. Provide a descriptive **name** for the key (for example, the integration or environment it will be used for). Key names must start with a letter and may contain letters, digits, spaces, hyphens, and underscores (1–128 characters). Names must be unique within your own keys. Create API key modal. 3. Click **Create Key**. The key is displayed once — copy it immediately and store it securely. Fiddler cannot retrieve it again. One-time API key displayed after creating a named API key. Use the API key for authentication in the Fiddler Python client, Fiddler SDKs, and REST APIs. #### Legacy Single-Key Flow If your deployment was created before Release 26.9, you may see the legacy single-key view instead. Legacy keys continue to work alongside named API keys — creating a named key does not affect your existing legacy key. We recommend using named API keys for any new integrations. Legacy API key view for older deployments. To use the legacy flow: 1. Click **Create Key** to generate your key. 2. Once created, the **Create Key** button is hidden — only one key can exist at a time. 3. To generate a new key, delete the existing key first. The **Create Key** button will reappear. ### Managing API Keys * **Named API keys**: You can create up to 5 per user. On Fiddler Cloud, contact Fiddler Support if you need a higher limit. Self-hosted admins can raise the cap with the `MAX_ACCESS_KEYS_PER_USER` environment variable. Legacy single-key API keys do not count toward this limit. * **Revoking named API keys**: Use the **⋮** (more options) menu in the named keys list view. Revocation takes effect immediately; allow up to 5 minutes for all active sessions to reflect the change. * **Revoking a legacy key**: Delete the existing key. The **Create Key** button will reappear when ready. * Each API key inherits the permissions of the user who created it. **Security Best Practice:** Treat API keys like passwords. Never share them or commit them to version control. Copy and store the key immediately at creation — Fiddler cannot retrieve it again. Rotate keys regularly and revoke unused or compromised keys immediately. ## LLM Gateway The **LLM Gateway** tab allows you to configure and manage LLM provider credentials for AI-powered features throughout the Fiddler platform. Configure LLM providers to enable: * **Custom Evaluators** - Use your preferred LLM to evaluate model outputs * **Content Analysis** - Assess response quality and monitor trust metrics Supported providers include OpenAI, Anthropic, Gemini, and Fiddler. You can add multiple API credentials per provider for redundancy, load balancing, and key rotation. For detailed configuration instructions, see [LLM Gateway Configuration](/reference/administration/llm-gateway). ## Email Configuration The **Email Configuration** tab manages the email provider for your organization. Configure: * Selecting SES or SMTP for email delivery * Fiddler Cloud customers leverage AWS SES * You may choose to use your own SMTP server by entering your own SMTP connection and credentials details ## PagerDuty Integration The **PagerDuty Integration** tab enables configuration of PagerDuty services for alert escalation. Setup includes: * PagerDuty service integration keys * Severity mapping for alerts * Escalation policy configuration * Test alert functionality ## Webhook Integration The **Webhook Integration** tab manages webhook configurations for connecting Fiddler alerts to your notification and communication platforms. ### Supported Webhook Types Fiddler supports three webhook provider types: * **Slack** - Direct integration with Slack channels * **Microsoft Teams** - Native Teams channel integration * **Other** - Custom webhook endpoints for any platform ### Creating a Webhook Click the plus (**`+`**) icon to configure a new webhook: Create Webhook Service modal dialog #### Slack Webhook Configuration 1. Enter a unique name in the **Service Name** field 2. Select **Slack** from the **Provider** dropdown 3. Enter your Slack webhook URL (format: `https://hooks.slack.com/services/...`) 4. Click **Test** to verify the connection 5. Click **Create** once the test succeeds > **Reference** > > See [Slack's webhook documentation](https://api.slack.com/messaging/webhooks) for creating webhook URLs. #### Microsoft Teams Webhook Configuration 1. Enter a unique name in the **Service Name** field 2. Select **MS Teams** from the **Provider** dropdown 3. Enter your Teams webhook URL provided by your administrator 4. Click **Test** to verify the connection 5. Click **Create** once the test succeeds > **Reference** > > See [Microsoft Teams webhook documentation](https://learn.microsoft.com/en-us/microsoftteams/platform/webhooks-and-connectors/how-to/add-incoming-webhook?tabs=newteams%2Cdotnet#create-an-incoming-webhook) for setup instructions. #### Custom Webhook Configuration 1. Enter a unique name in the **Service Name** field 2. Select **Other** from the **Provider** dropdown 3. Enter your platform's webhook URL 4. Click **Test** to verify the endpoint 5. Click **Create** once the test succeeds ### Managing Webhooks Edit or delete existing webhooks using the menu (**...**) icon for each webhook: 1. Select the webhook's menu icon 2. Choose **Edit Webhook** to modify configuration 3. Choose **Delete Webhook** to remove the webhook > **Important** > > You cannot delete webhooks that are currently linked to active alerts. Remove the webhook from all alerts before deletion. ## Access Requirements Different settings require specific permissions: | Setting | Org Admin | Org Member | | ------------------------ | --------- | ---------- | | View General tab | ✓ | ✓ | | View Access > Users | ✓ | ✓ | | View Access > Teams | ✓ | ✓ | | Create/Edit Teams | ✓ | ✗ | | Create API Keys | ✓ | ✓ | | Configure LLM Gateway | ✓ | ✗ | | Configure Email Settings | ✓ | ✗ | | Configure PagerDuty | ✓ | ✗ | | Create/Edit Webhooks | ✓ | ✗ | ## Related Documentation * [Role-Based Access Control](/reference/access-control/role-based-access) - Understanding user roles and permissions * [Single Sign-On Configuration](/reference/access-control/sso-authentication-guide) - Setting up SSO authentication * [Inviting Users](/reference/access-control/email-login#adding-users-to-fiddler) - Adding users through the AuthN console * [Alert Configuration](/observability/platform/alerts-platform) - Using webhooks and integrations for alerts # Supported Browsers Source: https://docs.fiddler.ai/reference/administration/supported-browsers Discover our product guide on supported web browsers for accessing Fiddler, including Google Chrome, Firefox, Safari, and Microsoft Edge. Fiddler Product can be accessed through the following supported web browsers: * Google Chrome * Firefox * Safari * Microsoft Edge # Feature Maturity Definitions Source: https://docs.fiddler.ai/reference/feature-maturity-definitions Review Fiddler's release and support policies for product features at different stages of maturity. ### Product Feature Maturity Definitions Fiddler ships new features rapidly. To maintain a fast development pace and ensure a stable customer experience, we define clear stages for feature maturity. Evolution from one stage to the other is quality-bound, not time-bound. Features evolve through the following stages. To see which Python versions Fiddler's SDKs support, see the [Python version support policy](/reference/python-support-policy). ### Generally Available (GA) The GA stage is when a feature is not only ready for production but the SLA is guaranteed. GA features are fully supported by our team and are backed by our comprehensive support plans, providing customers with confidence in reliability, security, and performance. ### Public Preview Public Preview features are reasonably mature and ready for broader testing, accessible to all customers. This allows us to gather data about the feature in the wild, including important customer feedback. While not formally bound by our SLA, our team responds promptly to issues. APIs and functionality may—but are not likely to—change. #### Criteria * Has a feature flag that is on by default for all customers. * Available to all customers. * Does not break or degrade existing functionality when enabled. (Does not degrade existing SLOs.) * Docs are published publicly but noted as “preview” or “public preview”. * Breaking changes must be minimal and noted in the release notes. Also, Field should message and support the change to heavy users directly. * Expectation that it WILL land in the product after some unspecified amount of time. * SLO, but no SLA. ### Private Preview Private Preview features are early-stage and available to select design partners only. During this stage, no Service Level Agreement (SLA) is provided. Instead, our engineering team collaborates directly with partners to iterate on the solution, making changes as needed based on feedback during business hours. Features, including their APIs, will change rapidly; they might also be abandoned entirely. Why [design partners](https://a16z.com/a-framework-for-finding-a-design-partner/)? Having a handful of transparent, engaged users or prospective customers can guide you through your first iteration of the product’s functionality, user experience, pricing and packaging, and more. Their critiques should help you build something useful and usable for your broader customer base. To inquire about private preview features, please reach out to \<[sales@fiddler.ai](mailto:sales@fiddler.ai)>. #### Criteria * Has a feature flag that is **turned off by default**. * Only available to select customers (as decided by Eng + PM). * Can do a POV with Private Preview with Eng+PM agreement (supporting team and leadership must approve). * Can market, if desired. * Does not break or degrade existing functionality when disabled. * May cause unexpected side-effects when enabled. * Docs are not published, or are published in some not publicly-accessible place. * Supported by the engineering team directly. * Breaking changes can be communicated via Slack, not in release notes. * No SLA or SLO. ### Solutions Engineering Some solutions are custom-crafted by our Solutions Engineering Team. These features, while useful and in production, are not officially supported by our overall product SLA. Talk directly with your SE or CSM for clarification as to what SLA any custom-developed tools fall under. # LLM Observability Metrics Reference Source: https://docs.fiddler.ai/reference/llm-observability-metrics Complete reference of all LLM observability metrics and enrichments supported by the Fiddler monitoring platform. Fiddler provides a comprehensive set of enrichments for monitoring LLM applications in production. Enrichments augment your application data with automatically generated trust, safety, and quality metrics during model onboarding. These metrics integrate directly with Fiddler's monitoring dashboards, alerting systems, and analytics tools. Configure enrichments using the `fdl.Enrichment()` class in the Python Client SDK. For detailed configuration examples, see the [Enrichments Guide](/observability/llm/enrichments). For help choosing the right enrichment, see [Selecting Enrichments](/observability/llm/selecting-enrichments). For ML model metrics (performance, drift, data integrity), see the [ML Metrics Reference](/reference/ml-metrics-reference). ## Safety metrics Safety enrichments detect and flag unsafe, harmful, or policy-violating content in your LLM application's inputs and outputs. | Metric | Enrichment Key | LLM Required? | Output Type | Description | | --------------------------------------------- | -------------------- | -------------------- | -------------------------- | ----------------------------------------------------------------------- | | [Safety](#safety) | `ftl_prompt_safety` | Yes (Fiddler Centor) | bool + float per dimension | Evaluates text safety across 11 dimensions using Fiddler Centor Models | | [PII Detection](#pii-detection) | `pii` | No | bool + matches + entities | Detects personally identifiable information using Presidio | | [Profanity](#profanity) | `profanity` | No | bool | Flags offensive or inappropriate language | | [Banned Keywords](#banned-keywords) | `banned_keywords` | No | bool | Detects user-defined restricted terms | | [Regex Match](#regex-match) | `regex_match` | No | category | Matches text against a user-defined regular expression | | [Language Detection](#language-detection) | `language_detection` | No | string + float | Identifies the language of the source text | | [Topic Classification](#topic-classification) | `topic_model` | No | list\[float] + string | Classifies text into user-defined topics using zero-shot classification | ### Safety The Safety enrichment evaluates text safety across 11 dimensions using Fiddler's proprietary Centor Models. Each dimension produces a boolean flag and a confidence probability score. **Enrichment key:** `ftl_prompt_safety` | Dimension | Output Columns | Score Range | Description | | -------------- | ------------------------------------ | ----------- | ----------------------------------------- | | `illegal` | `illegal`, `illegal score` | 0.0 -- 1.0 | Content promoting illegal activities | | `hateful` | `hateful`, `hateful score` | 0.0 -- 1.0 | Hateful or discriminatory content | | `harassing` | `harassing`, `harassing score` | 0.0 -- 1.0 | Harassing or bullying content | | `racist` | `racist`, `racist score` | 0.0 -- 1.0 | Racist content | | `sexist` | `sexist`, `sexist score` | 0.0 -- 1.0 | Sexist content | | `violent` | `violent`, `violent score` | 0.0 -- 1.0 | Content promoting violence | | `sexual` | `sexual`, `sexual score` | 0.0 -- 1.0 | Sexually explicit content | | `harmful` | `harmful`, `harmful score` | 0.0 -- 1.0 | Generally harmful content | | `unethical` | `unethical`, `unethical score` | 0.0 -- 1.0 | Unethical content | | `jailbreaking` | `jailbreaking`, `jailbreaking score` | 0.0 -- 1.0 | Jailbreaking or prompt injection attempts | | `roleplaying` | `roleplaying`, `roleplaying score` | 0.0 -- 1.0 | Roleplaying attempts to bypass safety | An aggregate `max_risk_prob` output is also generated, representing the maximum probability across all 11 dimensions. For configuration details, see [Enrichments: Safety](/observability/llm/enrichments#safety). ### PII Detection Detects and flags personally identifiable information using [Presidio](https://microsoft.github.io/presidio/analyzer/languages/). Generates a boolean flag, matched text spans, and detected entity types. **Enrichment key:** `pii` **Commonly used entity types:** `CREDIT_CARD`, `CRYPTO`, `DATE_TIME`, `EMAIL_ADDRESS`, `IBAN_CODE`, `IP_ADDRESS`, `LOCATION`, `PERSON`, `PHONE_NUMBER`, `URL`, `US_SSN`, `US_DRIVER_LICENSE`, `US_ITIN`, `US_PASSPORT` Fiddler supports 32 entity types in total, including international identifiers for Australia, India, Singapore, and the UK. For the full list, see the [Presidio supported entities](https://microsoft.github.io/presidio/supported_entities/). For configuration details, see [Enrichments: PII](/observability/llm/enrichments#personally-identifiable-information). ### Profanity Flags offensive or inappropriate language using curated word lists from SurgeAI and Google. **Enrichment key:** `profanity` For configuration details, see [Enrichments: Profanity](/observability/llm/enrichments#profanity). ### Banned Keywords Detects user-defined restricted terms in text inputs. The list of banned keywords is specified in the enrichment configuration. **Enrichment key:** `banned_keywords` For configuration details, see [Enrichments: Banned Keywords](/observability/llm/enrichments#banned-keyword-detector). ### Regex Match Matches text against a user-defined regular expression pattern. Produces a categorical output of "Match" or "No Match". **Enrichment key:** `regex_match` For configuration details, see [Enrichments: Regex Match](/observability/llm/enrichments#regex-match). ### Language Detection Identifies the language of the source text using [fasttext](https://fasttext.cc/docs/en/language-identification.html) models. Produces the detected language and a confidence probability. **Enrichment key:** `language_detection` For configuration details, see [Enrichments: Language Detection](/observability/llm/enrichments#language-detector). ### Topic Classification Classifies text into user-defined topics using a zero-shot classification model. Produces per-topic probability scores and the top-scoring topic. **Enrichment key:** `topic_model` For configuration details, see [Enrichments: Topic](/observability/llm/enrichments#topic). ## Quality and hallucination metrics Quality enrichments assess the accuracy, groundedness, and relevance of LLM-generated responses. | Metric | Enrichment Key | LLM Required? | Output Type | Description | | --------------------------------------------------------- | --------------------------- | -------------------- | ------------ | ---------------------------------------------------------------- | | [Faithfulness (Centor Model)](#faithfulness-centor-model) | `ftl_response_faithfulness` | Yes (Fiddler Centor) | bool + float | Evaluates factual groundedness using Fiddler Centor Models | | [RAG Faithfulness](#rag-faithfulness) | `faithfulness` | Yes (OpenAI) | bool | Evaluates factual accuracy of responses against provided context | | [Answer Relevance](#answer-relevance) | `answer_relevance` | Yes (OpenAI) | bool | Evaluates whether responses address the input prompt | | [Coherence](#coherence) | `coherence` | Yes (OpenAI) | bool | Assesses logical flow and clarity of responses | | [Conciseness](#conciseness) | `conciseness` | Yes (OpenAI) | bool | Evaluates brevity and clarity of responses | ### Faithfulness (Centor Model) Evaluates the factual groundedness of AI-generated responses against provided context using Fiddler's proprietary Centor Models. Produces a boolean faithfulness flag and a confidence probability score. **Enrichment key:** `ftl_response_faithfulness` The faithfulness threshold defaults to 0.5 and can be adjusted in the configuration to control scoring sensitivity. Higher thresholds result in stricter faithfulness detection (fewer responses labeled as faithful). For configuration details, see [Enrichments: Faithfulness (Centor Model)](/observability/llm/enrichments#faithfulness-centor-model). ### RAG Faithfulness Evaluates the accuracy and reliability of facts presented in AI-generated responses by checking whether the information aligns with the provided context documents. Uses an OpenAI LLM for evaluation. **Enrichment key:** `faithfulness` **RAG Faithfulness vs Faithfulness (Centor Model):** This enrichment uses OpenAI for evaluation. [Faithfulness (Centor Model)](#faithfulness-centor-model) uses Fiddler Centor Models for lower latency. See [LLM-Based Metrics](/observability/llm/llm-based-metrics) for a detailed comparison. For configuration details, see [Enrichments: Faithfulness](/observability/llm/enrichments#faithfulness). ### Answer Relevance Evaluates whether AI-generated responses address the input prompt. Produces a binary relevant/not-relevant result. **Enrichment key:** `answer_relevance` For configuration details, see [Enrichments: Answer Relevance](/observability/llm/enrichments#answer-relevance). ### Coherence Assesses the logical flow and clarity of AI-generated responses, checking whether the content maintains a consistent theme and argument structure. **Enrichment key:** `coherence` For configuration details, see [Enrichments: Coherence](/observability/llm/enrichments#coherence). ### Conciseness Evaluates whether AI-generated responses communicate their message efficiently without unnecessary elaboration or redundancy. **Enrichment key:** `conciseness` For configuration details, see [Enrichments: Conciseness](/observability/llm/enrichments#conciseness). ## Text statistics metrics Text statistics enrichments provide quantitative analysis of text properties, including readability, length, and n-gram-based evaluation scores. | Metric | Enrichment Key | LLM Required? | Output Type | Description | | --------------------------- | -------------- | ------------- | -------------- | ------------------------------------------------------------- | | [Textstat](#textstat) | `textstat` | No | float | Generates up to 19 text readability and complexity statistics | | [Evaluate](#evaluate) | `evaluate` | No | float | Computes n-gram-based evaluation scores (BLEU, ROUGE, METEOR) | | [Sentiment](#sentiment) | `sentiment` | No | float + string | Provides sentiment analysis using VADER | | [Token Count](#token-count) | `token_count` | No | int | Counts the number of tokens in a string | ### Textstat Generates text readability and complexity statistics using the [textstat](https://pypi.org/project/textstat/) library. You can select specific statistics or use all 19 available metrics. **Enrichment key:** `textstat` | Sub-metric | Range | Description | | ------------------------------ | ----------- | --------------------------------------------------- | | `char_count` | 0 -- 64,000 | Character count | | `letter_count` | 0 -- 64,000 | Letter count (alphabetical characters) | | `miniword_count` | 0 -- 64,000 | Count of short words | | `words_per_sentence` | 0 -- 1,000 | Average words per sentence | | `polysyllabcount` | 0 -- 64,000 | Polysyllabic word count | | `lexicon_count` | 0 -- 64,000 | Word count | | `syllable_count` | 0 -- 96,000 | Total syllable count | | `sentence_count` | 0 -- 32,000 | Sentence count | | `flesch_reading_ease` | -100 -- 100 | Flesch Reading Ease score (higher = easier to read) | | `smog_index` | 0 -- 30 | SMOG readability index | | `flesch_kincaid_grade` | -3.4 -- 100 | Flesch-Kincaid Grade Level | | `coleman_liau_index` | 0 -- 20 | Coleman-Liau readability index | | `automated_readability_index` | -3.4 -- 100 | Automated Readability Index | | `dale_chall_readability_score` | 0 -- 10 | Dale-Chall readability score | | `difficult_words` | 0 -- 64,000 | Count of difficult words | | `linsear_write_formula` | 0 -- 20 | Linsear Write readability formula | | `gunning_fog` | 0 -- 20 | Gunning Fog readability index | | `long_word_count` | 0 -- 64,000 | Count of long words | | `monosyllabcount` | 0 -- 64,000 | Monosyllabic word count | If no statistics are specified in the configuration, the default statistic is `flesch_kincaid_grade`. For configuration details, see [Enrichments: Textstat](/observability/llm/enrichments#textstat). ### Evaluate Computes n-gram-based evaluation metrics for comparing two text passages, such as an AI-generated response and a reference answer. These metrics score highest when the reference and generated texts contain overlapping sequences. **Enrichment key:** `evaluate` | Sub-metric | Output Column | Score Range | Description | | ---------- | ------------- | ----------- | --------------------------------------------------------------- | | BLEU | `bleu` | 0.0 -- 1.0 | Precision of word n-grams between generated and reference text | | ROUGE-1 | `rouge1` | 0.0 -- 1.0 | Unigram recall between generated and reference text | | ROUGE-2 | `rouge2` | 0.0 -- 1.0 | Bigram recall between generated and reference text | | ROUGE-L | `rougeL` | 0.0 -- 1.0 | Longest common subsequence between generated and reference text | | ROUGE-Lsum | `rougeLsum` | 0.0 -- 1.0 | ROUGE-L applied at the summary level | | METEOR | `meteor` | 0.0 -- 1.0 | Combines precision, recall, and semantic matching | For configuration details, see [Enrichments: Evaluate](/observability/llm/enrichments#evaluate). ### Sentiment Provides sentiment analysis using NLTK's VADER lexicon. Produces a compound score and a categorical sentiment label. **Enrichment key:** `sentiment` | Output Column | Type | Description | | ------------- | ------ | ------------------------------------------- | | `compound` | float | Raw compound sentiment score | | `sentiment` | string | One of `positive`, `negative`, or `neutral` | For configuration details, see [Enrichments: Sentiment](/observability/llm/enrichments#sentiment). ### Token Count Counts the number of tokens in a string using the [tiktoken](https://github.com/openai/tiktoken) library. **Enrichment key:** `token_count` For configuration details, see [Enrichments: Token Count](/observability/llm/enrichments#token-count). ## Text validation metrics Text validation enrichments verify the structural correctness of generated text outputs such as SQL queries and JSON payloads. | Metric | Enrichment Key | LLM Required? | Output Type | Description | | ----------------------------------- | ----------------- | ------------- | ------------- | ----------------------------------------------------- | | [SQL Validation](#sql-validation) | `sql_validation` | No | bool + string | Validates SQL syntax for a specified dialect | | [JSON Validation](#json-validation) | `json_validation` | No | bool + string | Validates JSON syntax and optionally against a schema | ### SQL Validation Validates SQL query syntax for a specified dialect. Supports 25+ SQL dialects including MySQL, PostgreSQL, Snowflake, BigQuery, and others. **Enrichment key:** `sql_validation` Query validation is syntax-based and does not check against any existing schema or databases for validity. For configuration details, see [Enrichments: SQL Validation](/observability/llm/enrichments#sql-validation). ### JSON Validation Validates JSON for correctness and optionally against a user-defined [JSON Schema](https://python-jsonschema.readthedocs.io). **Enrichment key:** `json_validation` For configuration details, see [Enrichments: JSON Validation](/observability/llm/enrichments#json-validation). ## Embedding metrics Embedding enrichments convert text into vector representations for drift detection and visualization. | Metric | Enrichment Key | LLM Required? | Output Type | Description | | --------------------------------------- | ---------------- | ------------- | -------------- | -------------------------------------------------------------------- | | [Text Embedding](#text-embedding) | `TextEmbedding` | No | vector + float | Generates text embeddings for UMAP visualization and drift detection | | [Centroid Distance](#centroid-distance) | (auto-generated) | No | float | Distance from the nearest cluster centroid | ### Text Embedding Converts unstructured text into high-dimensional vector representations for semantic analysis. Enables Fiddler's 3D UMAP visualizations and embedding-based drift detection. **Class:** `fdl.TextEmbedding()` TextEmbedding is configured using `fdl.TextEmbedding()` rather than `fdl.Enrichment()`. See the [Enrichments Guide](/observability/llm/enrichments#embedding) for usage examples. ### Centroid Distance Measures the distance between a data point's embedding and the nearest cluster centroid. This metric is automatically generated when a TextEmbedding enrichment is created. For configuration details, see [Enrichments: Centroid Distance](/observability/llm/enrichments#centroid-distance). ## Related resources * [ML Metrics Reference](/reference/ml-metrics-reference) — Built-in metrics for ML model monitoring * [Enrichments Guide](/observability/llm/enrichments) — Configuration examples for all enrichments * [Selecting Enrichments](/observability/llm/selecting-enrichments) — Choosing the right enrichment for your use case * [LLM-Based Metrics](/observability/llm/llm-based-metrics) — Detailed comparison of LLM-based evaluation methods # ML Metrics Reference Source: https://docs.fiddler.ai/reference/ml-metrics-reference Complete reference of all built-in ML metrics supported by the Fiddler monitoring platform, organized by category and model task type. Fiddler provides 35 built-in metrics for monitoring ML models in production. These metrics cover model performance, data drift, data integrity, traffic, and statistics. You can also define [custom metrics](/observability/platform/custom-metrics) using the [Fiddler Query Language](/observability/platform/fiddler-query-language). For LLM and GenAI application metrics, see the [LLM Observability Metrics Reference](/reference/llm-observability-metrics). ## Performance metrics Performance metrics measure how well a model performs on its task. The available metrics depend on the model task type. For more details on performance monitoring workflows, see [Performance Tracking](/observability/platform/performance-tracking-platform). ### Binary classification | Metric | API ID | Score Range | Description | | --------------------------- | ---------------------------- | ------------- | ------------------------------------------------------------------------------------------------------------------ | | Accuracy | `accuracy` | 0 -- 1 | (TP + TN) / (TP + TN + FP + FN) | | Log Loss | `log_loss` | 0 -- infinity | Measures the difference between the predicted probability distribution and the true distribution | | Precision | `precision` | 0 -- 1 | TP / (TP + FP). Requires a decision threshold. | | Recall / True Positive Rate | `recall` | 0 -- 1 | TP / (TP + FN). Requires a decision threshold. | | F1 Score | `f1_score` | 0 -- 1 | 2 \* (Precision \* Recall) / (Precision + Recall). Requires a decision threshold. | | False Positive Rate | `fpr` | 0 -- 1 | FP / (FP + TN). Requires a decision threshold. | | AUC | `auc` | 0 -- 1 | Area Under the ROC Curve (histogram-based calculation). See also AUROC. | | AUROC | `auroc` | 0 -- 1 | Area Under the Receiver Operating Characteristic curve, plotting true positive rate against false positive rate | | Expected Calibration Error | `expected_calibration_error` | 0 -- 1 | Measures the difference between predicted probabilities and empirical probabilities | | Geometric Mean | `geometric_mean` | 0 -- 1 | Square root of (Precision \* Recall). Requires a decision threshold. | | Calibrated Threshold | `calibrated_threshold` | 0 -- 1 | A threshold that balances precision and recall at a particular operating point | | Data Count | `data_count` | 0 -- infinity | The number of events where target and output are both not NULL. Used as the denominator for accuracy calculations. | ### Multi-class classification | Metric | API ID | Score Range | Description | | -------------- | ---------------- | ------------- | ------------------------------------------------------------------------------------------------------------------------ | | Accuracy | `accuracy` | 0 -- 1 | (Number of correctly classified samples) / Data Count | | Log Loss | `log_loss` | 0 -- infinity | Measures the difference between the predicted probability distribution and the true distribution, on a logarithmic scale | | Log Loss Count | `log_loss_count` | 0 -- infinity | Count of events used in the Log Loss calculation | ### Regression | Metric | API ID | Score Range | Description | | ----------------------------------------------- | ------- | -------------- | ----------------------------------------------------------------------------------------- | | Mean Absolute Error (MAE) | `mae` | 0 -- infinity | Average of the absolute differences between predicted and true values | | Mean Squared Error (MSE) | `mse` | 0 -- infinity | Average of the squared differences between predicted and true values | | Mean Absolute Percentage Error (MAPE) | `mape` | 0 -- infinity | Average of the absolute percentage differences between predicted and true values | | Weighted Mean Absolute Percentage Error (WMAPE) | `wmape` | 0 -- infinity | Weighted average of the absolute percentage differences between predicted and true values | | R-squared (R²) | `r2` | -infinity -- 1 | Proportion of variance in the dependent variable explained by the independent variables | ### Ranking | Metric | API ID | Score Range | Description | | -------------------------------------------- | ------------- | ------------- | --------------------------------------------------------------------------------------------------------------------------- | | Mean Average Precision (MAP) | `map` | 0 -- 1 | Average precision of relevant items in the top-k results. For binary relevance ranking only. Supports configurable `top_k`. | | Normalized Discounted Cumulative Gain (NDCG) | `ndcg_mean` | 0 -- 1 | Quality of the ranking by discounting relevance scores at lower ranks. Supports configurable `top_k`. | | Query Count | `query_count` | 0 -- infinity | Number of ranking queries in the time period | ## Drift metrics Drift metrics measure distributional changes between your baseline dataset and production data. High drift can indicate data pipeline issues or genuine shifts in the data distribution. Both metrics require a [baseline](/glossary/baseline) dataset. For more details, see [Data Drift](/observability/platform/data-drift-platform). | Metric | API ID | Score Range | Description | | -------------------------------- | ------ | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | Jensen-Shannon Distance (JSD) | `jsd` | 0 -- 1 | Distance between the baseline distribution and the production distribution for a given field, using [configurable bins](/observability/platform/data-drift-platform) for numerical columns | | Population Stability Index (PSI) | `psi` | 0 -- infinity | Drift metric based on multinomial classification of a variable into [configurable bins](/observability/platform/data-drift-platform), comparing baseline and production distributions | The drift analytics table also provides **Feature Impact**, **Feature Drift**, and **Prediction Drift Impact** as derived values to help identify which features contribute most to prediction drift. ## Data integrity metrics Data integrity metrics detect violations in production data compared to the schema established during model onboarding. Fiddler tracks three violation types: missing values, type mismatches, and range violations. Both raw counts and percentages are available. For more details, see [Data Integrity](/observability/platform/data-integrity-platform). ### Count-based | Metric | API ID | Description | | ----------------------- | ----------------------- | --------------------------------------------------------- | | Any Violation | `any_violation_count` | Count of any data integrity violation across all features | | Missing Value Violation | `null_violation_count` | Count of missing value violations across all features | | Range Violation | `range_violation_count` | Count of range violations across all features | | Type Violation | `type_violation_count` | Count of data type violations across all features | ### Percentage-based | Metric | API ID | Description | | ------------------------- | ---------------------------- | ------------------------------------------------------ | | % Any Violation | `any_violation_percentage` | Percentage of events with any data integrity violation | | % Missing Value Violation | `null_violation_percentage` | Percentage of events with missing value violations | | % Range Violation | `range_violation_percentage` | Percentage of events with range violations | | % Type Violation | `type_violation_percentage` | Percentage of events with data type violations | ## Traffic metrics Traffic metrics provide visibility into the operational health of your model service. For more details, see [Traffic](/observability/platform/traffic-platform). | Metric | API ID | Description | | ------- | --------- | ------------------------------------------------------------ | | Traffic | `traffic` | Volume of inference requests received by the model over time | ## Statistics metrics Statistics metrics provide basic aggregations over columns. These are useful for monitoring custom metadata fields over time. For more details, see [Statistics](/observability/platform/statistics). | Metric | API ID | Applies To | Description | | --------- | ----------- | ----------------------------- | ----------------------------------- | | Average | `average` | Numeric columns | Arithmetic mean of a numeric column | | Sum | `sum` | Numeric columns | Sum of a numeric column | | Frequency | `frequency` | Categorical / Boolean columns | Count of occurrences for each value | ## Custom metrics In addition to the built-in metrics above, you can define custom metrics using the [Fiddler Query Language (FQL)](/observability/platform/fiddler-query-language). Custom metrics support aggregations, operators, and metric functions to create business-specific KPIs. For details on creating and managing custom metrics, see: * [Custom Metrics Guide](/observability/platform/custom-metrics) * [CustomMetric SDK Reference](/sdk-api/python-client/custom-metric) * [Custom Metrics REST API](/sdk-api/rest-api/custom-metrics) ## Related resources * [LLM Observability Metrics Reference](/reference/llm-observability-metrics) — Enrichments for LLM application monitoring * [Performance Tracking](/observability/platform/performance-tracking-platform) — Performance monitoring workflows * [Data Drift](/observability/platform/data-drift-platform) — Drift monitoring and analysis * [Data Integrity](/observability/platform/data-integrity-platform) — Data quality monitoring * [Custom Metrics Guide](/observability/platform/custom-metrics) — Creating custom metrics with FQL # Python Version Support Policy Source: https://docs.fiddler.ai/reference/python-support-policy How Fiddler's Python SDKs decide which Python versions they support, and when support for a version ends. Fiddler's Python SDKs follow a clear, predictable policy for which Python versions they support. This page explains that policy so you can plan Python upgrades with confidence. ### Our policy Fiddler supports each Python version through its official Python Software Foundation (PSF) end-of-life, and drops support once a version reaches PSF end-of-life. This keeps Fiddler's SDKs aligned with Python versions that still receive upstream security patches. The PSF publishes the end-of-life date for every Python version in its [Status of Python versions](https://devguide.python.org/versions/) table — the source of truth for when a version's support ends. Keeping your projects on a version that the PSF still supports is the most reliable way to stay on a Fiddler-supported Python. Fiddler communicates upcoming changes ahead of time so you have room to upgrade. This window — support through PSF end-of-life — is more generous than community policies such as [SPEC 0](https://scientific-python.org/specs/spec-0000/) and the superseded [NEP 29](https://numpy.org/neps/nep-0029-deprecation_policy.html), which drop older Python versions sooner. ### Which SDKs this applies to This policy applies to all of Fiddler's [Python SDKs](/sdk-api). Fiddler's JavaScript and TypeScript SDKs are not affected by Python version changes. ### How this differs from the compatibility matrix Two references cover Python and Fiddler versions, and they answer different questions: * This **Python version support policy** describes which **Python language** versions Fiddler's Python SDKs run on. * The [compatibility matrix](/changelog/compatibility-matrix) maps each **Fiddler Python client version** to the **Fiddler platform** versions it works with. Use this page to choose a supported Python version, and the compatibility matrix to choose a client version that matches your Fiddler platform. ### Related resources * [Compatibility matrix](/changelog/compatibility-matrix) — Python client and Fiddler platform version compatibility. * [SDK & API reference](/sdk-api) — every Fiddler SDK. * [Feature maturity definitions](/reference/feature-maturity-definitions) — Fiddler's release and support stages. * [Status of Python versions](https://devguide.python.org/versions/) — PSF end-of-life dates. # ADKSpanProcessor Source: https://docs.fiddler.ai/sdk-api/adk/adk-span-processor Span processor that backfills session identity onto ADK root spans. Span processor that backfills `gen_ai.conversation.id` onto the root ADK span. Extends `FiddlerSpanProcessor` (from `fiddler-otel`). ADK sets `gen_ai.conversation.id` only on child spans (`invoke_agent`, `call_llm`, etc.); the root `invocation` span gets no attributes. This processor copies the conversation ID onto the still-open root span when the first child carrying it ends. All other enrichment (span-type classification, agent ID computation, content extraction, attribute normalization) is delegated to the Fiddler backend. ## Example ```python theme={null} from fiddler_adk import ADKSpanProcessor # Typically used via GoogleADKInstrumentor, which adds it automatically. # Direct usage is for advanced custom pipeline setups: from opentelemetry.sdk.trace import TracerProvider provider = TracerProvider() provider.add_span_processor(ADKSpanProcessor()) ``` ## Inherits * `FiddlerSpanProcessor` (from `fiddler-otel`) ## Behavior ### on\_start(span, parent\_context) Tracks root spans (spans with no parent) by their `trace_id`. This allows the processor to backfill session identity when a child span ends. ### on\_end(span) When a child span ends: 1. If the child carries `gen_ai.conversation.id` and the root span for that trace is still recording, copies the conversation ID onto the root. 2. When the root span itself ends, removes it from tracking. The first child with a conversation ID wins -- subsequent children do not overwrite it. ### force\_flush() Delegates to the parent `FiddlerSpanProcessor.force_flush()`. ### Returns `True` if flush completed successfully. # GoogleADKInstrumentor Source: https://docs.fiddler.ai/sdk-api/adk/google-adk-instrumentor OpenTelemetry instrumentor for Google ADK agents. OpenTelemetry instrumentor for Google ADK (Agent Development Kit) agents. This instrumentor sets up an isolated Fiddler tracing pipeline via `FiddlerClient` (provider, processor, exporter) and promotes it to the global tracer provider so ADK's `gcp.vertex.agent` tracer resolves to it. The SDK operates in standalone mode -- it does not interact with customer-configured tracers or providers. ## Example ```python theme={null} from fiddler_otel import FiddlerClient from fiddler_adk import GoogleADKInstrumentor client = FiddlerClient( api_key="YOUR_KEY", application_id="YOUR_APP_UUID", url="https://your-instance.com", ) # Enable instrumentation instrumentor = GoogleADKInstrumentor(client) instrumentor.instrument() # All ADK agents created after this point are automatically traced ``` ## Parameters FiddlerClient instance that owns the tracing pipeline (tracer, provider, processor, exporter). The client's provider is promoted to global so ADK's tracer resolves to it. ## instrument() Enable instrumentation. Sets up the tracer provider and adds the `ADKSpanProcessor` for session-ID propagation. ```python theme={null} instrumentor.instrument() ``` ### Returns No return value. After calling, all ADK agents will be traced. ## uninstrument() Disable instrumentation. The tracer provider wiring is left in place: OpenTelemetry does not support unsetting the global provider or removing span processors. Spans continue to be exported until the client is shut down. ```python theme={null} instrumentor.uninstrument() ``` ### Returns No return value. ## instrumentation\_dependencies() Return the list of packages required for instrumentation. ### Returns Collection of required package names (includes `google-adk`). # Introduction Source: https://docs.fiddler.ai/sdk-api/adk/index Complete API reference for fiddler-adk [![PyPI](https://img.shields.io/pypi/v/fiddler-adk)](https://pypi.org/project/fiddler-adk/) ## Overview Complete API reference documentation for the `fiddler-adk` package, which instruments [Google ADK](https://github.com/google/adk-python) (Agent Development Kit) and exports OpenTelemetry traces to Fiddler. The package is published to PyPI as **`fiddler-adk`** and imported in Python as **`fiddler_adk`**: ```bash theme={null} pip install fiddler-adk ``` ```python theme={null} from fiddler_adk import GoogleADKInstrumentor ``` ## Components ### Instrumentation `GoogleADKInstrumentor` sets up the Fiddler tracing pipeline and promotes it to the global tracer provider so ADK's `gcp.vertex.agent` tracer resolves to it. * [GoogleADKInstrumentor](/sdk-api/adk/google-adk-instrumentor) ### Span Processor `ADKSpanProcessor` backfills `gen_ai.conversation.id` from child spans onto the root `invocation` span, ensuring all spans in a turn share the same session identity in the Fiddler UI. * [ADKSpanProcessor](/sdk-api/adk/adk-span-processor) # AnswerRelevance Source: https://docs.fiddler.ai/sdk-api/evals/answer-relevance Evaluator to assess how well an answer addresses a given question with optional context. Evaluator to assess how well an answer addresses a given question with optional context. The AnswerRelevance evaluator measures whether an LLM's answer is relevant and directly addresses the question being asked. This version supports optional reference documents to provide additional context for more nuanced relevance assessment. This is ideal for RAG (Retrieval-Augmented Generation) pipelines. Key Features: * **Relevance Assessment**: Determines if the answer directly addresses the question * **Three-Level Scoring**: Returns high (1.0), medium (0.5), or low (0.0) relevance scores * **Context-Aware**: Can use retrieved documents to assess relevance more accurately * **Detailed Reasoning**: Provides explanation for the relevance assessment * **Fiddler API Integration**: Uses Fiddler's built-in relevance evaluation model Use Cases: * **RAG Systems**: Evaluating if generated answers are relevant to user queries * **Q\&A Systems**: Ensuring answers stay on topic * **Customer Support**: Verifying responses address user queries * **Educational Content**: Checking if explanations answer the question * **Research Assistance**: Validating that responses are relevant to queries Scoring Logic: * **1.0 (High)**: Answer is fully relevant and directly addresses the question * **0.5 (Medium)**: Answer partially addresses the question but may miss some aspects * **0.0 (Low)**: Answer does not address the question or is off-topic ## Parameters * **user\_query** (*str*) – The question or query being asked. * **rag\_response** (*str*) – The LLM's response to evaluate. * **retrieved\_documents** (*list* \*\[\**str* *]* *,* *optional*) – Reference documents for context. * **model** (*str*) * **credential** (*str* *|* *None*) * **kwargs** (*Any*) ## Returns A Score object containing: * value: 1.0 for high, 0.5 for medium, 0.0 for low relevance * label: "high", "medium", or "low" * reasoning: Detailed explanation of the assessment ## Example ```python theme={null} from fiddler_evals.evaluators import AnswerRelevance evaluator = AnswerRelevance(model="openai/gpt-4o") # High relevance answer score = evaluator.score( user_query="What is the capital of France?", rag_response="The capital of France is Paris." ) print(f"Relevance: {score.label}") # "high" print(f"Score: {score.value}") # 1.0 # With context documents score = evaluator.score( user_query="What is our refund policy?", rag_response="Our refund policy allows returns within 30 days.", retrieved_documents=[ "Refund Policy: Customers may return items within 30 days of purchase.", "All returns must include original packaging." ] ) ``` This evaluator uses Fiddler's built-in relevance assessment model and requires an active connection to the Fiddler API. ## name *= 'answer\_relevance'* ## score() Score the relevance of an answer to a question. ### Parameters The question or query being asked. The LLM's response to evaluate. Reference documents for context. ### Returns A Score object containing: * value: 1.0 for high, 0.5 for medium, 0.0 for low relevance * label: "high", "medium", or "low" * reasoning: Detailed explanation of the assessment # Application Source: https://docs.fiddler.ai/sdk-api/evals/application Represents a GenAI Application container for organizing GenAI application resources. Represents a GenAI Application container for organizing GenAI application resources. An Application is a logical container within a Project that groups related GenAI application resources including datasets, experiments, evaluators, and monitoring configurations. Applications provide resource organization, access control, and lifecycle management for GenAI App monitoring workflows. Key Features: * **Resource Organization**: Container for related GenAI application resources * **Project Context**: Applications are scoped within projects for isolation * **Access Management**: Application-level permissions and access control * **Monitoring Coordination**: Centralized monitoring and alerting configuration * **Lifecycle Management**: Coordinated creation, updates, and deletion of resources Application Lifecycle: 1. **Creation**: Create application with unique name within a project 2. **Configuration**: Set up datasets, evaluators, and monitoring 3. **Operations**: Publish logs, monitor performance, manage alerts 4. **Maintenance**: Update configurations and resources 5. **Cleanup**: Delete application when no longer needed ## Example ```python theme={null} # Create a new application for fraud detection application = Application.create(name="fraud-detection-app", project_id=project_id) print(f"Created application: {application.name} (ID: {application.id})") ``` Applications are permanent containers - once created, the name cannot be changed. Deleting an application removes all contained resources and configurations. Consider the organizational structure carefully before creating applications. ## id ## name ## created\_at ## updated\_at ## created\_by ## updated\_by ## project ## *classmethod* get\_by\_id() Retrieve an application by its unique identifier. Fetches an application from the Fiddler platform using its UUID. This is the most direct way to retrieve an application when you know its ID. ### Parameters The unique identifier (UUID) of the application to retrieve. Can be provided as a UUID object or string representation. ### Returns The application instance with all metadata and configuration. ### Raises * **NotFound** – If no application exists with the specified ID. * **ApiError** – If there's an error communicating with the Fiddler API. ### Example ```python theme={null} # Get application by UUID application = Application.get_by_id(id_="550e8400-e29b-41d4-a716-446655440000") print(f"Retrieved application: {application.name}") print(f"Created: {application.created_at}") print(f"Project: {application.project.name}") ``` This method makes an API call to fetch the latest application state from the server. The returned application instance reflects the current state in Fiddler. ## *classmethod* get\_by\_name() Retrieve an application by name within a project. Finds and returns an application using its name within the specified project. This is useful when you know the application name and project but not its UUID. Application names are unique within a project, making this a reliable lookup method. ### Parameters The name of the application to retrieve. Application names are unique within a project and are case-sensitive. The UUID of the project containing the application. Can be provided as a UUID object or string representation. ### Returns The application instance matching the specified name. ### Raises * **NotFound** – If no application exists with the specified name in the project. * **ApiError** – If there's an error communicating with the Fiddler API. ### Example ```python theme={null} # Get project instance project = Project.get_by_name(name="fraud-detection-project") # Get application by name within a project application = Application.get_by_name( name="fraud-detection-app", project_id=project.id ) print(f"Found application: {application.name} (ID: {application.id})") print(f"Created: {application.created_at}") print(f"Project: {application.project.name}") ``` Application names are case-sensitive and must match exactly. Use this method when you have a known application name from configuration or user input. ## *classmethod* list() List all applications in a project. Retrieves all applications that the current user has access to within the specified project. Returns an iterator for memory efficiency when dealing with many applications. ### Parameters The UUID of the project to list applications from. Can be provided as a UUID object or string representation. ### Yields `Application` – Application instances for all accessible applications in the project. ### Raises **ApiError** – If there's an error communicating with the Fiddler API. ### Returns `Iterator[Application]` ### Example ```python theme={null} # Get project instance project = Project.get_by_name(name="fraud-detection-project") # List all applications in a project for application in Application.list(project_id=project.id): print(f"Application: {application.name}") print(f" ID: {application.id}") print(f" Created: {application.created_at}") # Convert to list for counting and filtering applications = list(Application.list(project_id=project.id)) print(f"Total applications in project: {len(applications)}") # Find applications by name pattern fraud_apps = [ app for app in Application.list(project_id=project.id) if "fraud" in app.name.lower() ] print(f"Fraud detection applications: {len(fraud_apps)}") ``` This method returns an iterator for memory efficiency. Convert to a list with list(Application.list(project\_id)) if you need to iterate multiple times or get the total count. The iterator fetches applications lazily from the API. ## *classmethod* create() Create a new application in a project. Creates a new application within the specified project on the Fiddler platform. The application must have a unique name within the project. ### Parameters Application name, must be unique within the project. The UUID of the project to create the application in. Can be provided as a UUID object or string representation. ### Returns The newly created application instance with server-assigned fields. ### Raises * **Conflict** – If an application with the same name already exists in the project. * **ValidationError** – If the application configuration is invalid (e.g., invalid name format). * **ApiError** – If there's an error communicating with the Fiddler API. ### Example ```python theme={null} # Get project instance project = Project.get_by_name(name="fraud-detection-project") # Create a new application for fraud detection application = Application.create( name="fraud-detection-app", project_id=project.id ) print(f"Created application with ID: {application.id}") print(f"Created at: {application.created_at}") print(f"Project: {application.project.name}") ``` After successful creation, the application instance is returned with server-assigned metadata. The application is immediately available for adding datasets, evaluators, and other resources. ## *classmethod* get\_or\_create() Get an existing application by name or create a new one if it doesn't exist. This is a convenience method that attempts to retrieve an application by name within a project, and if not found, creates a new application with that name. Useful for idempotent application setup in automation scripts and deployment pipelines. ### Parameters The name of the application to retrieve or create. The UUID of the project to search/create the application in. Can be provided as a UUID object or string representation. ### Returns Either the existing application with the specified name, or a newly created application if none existed. ### Raises * **ValidationError** – If the application name format is invalid. * **ApiError** – If there's an error communicating with the Fiddler API. ### Example ```python theme={null} # Get project instance project = Project.get_by_name(name="fraud-detection-project") # Safe application setup - get existing or create new application = Application.get_or_create( name="fraud-detection-app", project_id=project.id ) print(f"Using application: {application.name} (ID: {application.id})") # Idempotent setup in deployment scripts application = Application.get_or_create( name="llm-pipeline-app", project_id=project.id ) # Use in configuration management environments = ["dev", "staging", "prod"] applications = {} for env in environments: applications[env] = Application.get_or_create( name=f"fraud-detection-{env}", project_id=project.id ) ``` This method is idempotent - calling it multiple times with the same name and project\_id will return the same application. It logs when creating a new application for visibility in automation scenarios. # Coherence Source: https://docs.fiddler.ai/sdk-api/evals/coherence Evaluator to assess the coherence and logical flow of a response. Evaluator to assess the coherence and logical flow of a response. The Coherence evaluator measures whether a response is well-structured, logically consistent, and flows naturally from one idea to the next. This metric is important for ensuring that responses are easy to follow and understand, with clear connections between different parts of the text. Key Features: * **Coherence Assessment**: Determines if the response has logical flow and structure * **Binary Scoring**: Returns 1.0 for coherent responses, 0.0 for incoherent ones * **Optional Context**: Can optionally use a prompt for context-aware evaluation * **Detailed Reasoning**: Provides explanation for the coherence assessment * **Fiddler API Integration**: Uses Fiddler's built-in coherence evaluation model Use Cases: * **Content Quality**: Ensuring responses are well-structured and logical * **Educational Content**: Verifying explanations flow logically * **Technical Documentation**: Checking if instructions are coherent * **Creative Writing**: Assessing narrative flow and consistency * **Conversational AI**: Ensuring responses make sense in context Scoring Logic: * **1.0 (Coherent)**: Response has clear logical flow and structure * **0.0 (Incoherent)**: Response lacks logical flow or has structural issues ## Parameters * **response** (*str*) – The response to evaluate for coherence. * **prompt** (*str* *,* *optional*) – The original prompt that generated the response. Used for context-aware coherence evaluation. * **model** (*str*) * **credential** (*str* *|* *None*) * **kwargs** (*Any*) ## Returns A Score object containing: * name: "is\_coherent" * evaluator\_name: "Coherence" * value: 1.0 if coherent, 0.0 if incoherent * label: String representation of the boolean result * reasoning: Explanation for the coherence assessment ## Raises **ValueError** – If the response is empty or None, or if no scores are returned from the API. ## Example ```python theme={null} from fiddler_evals.evaluators import Coherence evaluator = Coherence() ``` ```python theme={null} # Coherent response score = evaluator.score( response="First, we need to understand the problem. Then, we can identify potential solutions. Finally, we should test our approach." ) print(f"Coherence: {score.value}") # 1.0 # Incoherent response incoherent_score = evaluator.score( prompt="Explain the process of making coffee", response="The sky is blue. I like pizza. Quantum physics is complex. Let's go shopping.", ) print(f"Coherence: {incoherent_score.value}") # 0.0 # With context contextual_score = evaluator.score( prompt="Explain the process of making coffee", response="First, grind the beans. Then, heat the water. Next, pour water over grounds. Finally, enjoy your coffee." ) print(f"Coherence: {contextual_score.value}") # 1.0 # Check coherence if score.value == 1.0: print("Response is coherent and well-structured") ``` This evaluator uses Fiddler's built-in coherence assessment model and requires an active connection to the Fiddler API. The optional prompt parameter can provide additional context for more accurate coherence evaluation, especially when the response needs to be evaluated in relation to a specific question or task. ## name *= 'coherence'* ## score() Score the coherence of a response. ### Parameters The original prompt that generated the response. The response to evaluate for coherence. ### Returns A Score object for coherence assessment. # Conciseness Source: https://docs.fiddler.ai/sdk-api/evals/conciseness Evaluator to assess how concise and to-the-point an answer is. Evaluator to assess how concise and to-the-point an answer is. The Conciseness evaluator measures whether an LLM's answer is appropriately brief and direct without unnecessary verbosity. This metric is important for ensuring that responses are efficient and don't waste users' time with irrelevant details or excessive elaboration. Key Features: * **Conciseness Assessment**: Determines if the answer is appropriately brief * **Binary Scoring**: Returns 1.0 for concise answers, 0.0 for verbose ones * **Detailed Reasoning**: Provides explanation for the conciseness assessment * **Fiddler API Integration**: Uses Fiddler's built-in conciseness evaluation model Use Cases: * **Customer Support**: Ensuring responses are direct and helpful * **Technical Documentation**: Verifying explanations are clear and brief * **Educational Content**: Checking if explanations are appropriately detailed * **API Responses**: Ensuring responses are efficient and focused Scoring Logic: * **1.0 (Concise)**: Answer is appropriately brief and to-the-point * **0.0 (Verbose)**: Answer is unnecessarily long or contains irrelevant details ## Parameters * **response** (*str*) – The LLM's response to evaluate for conciseness. * **model** (*str*) * **credential** (*str* *|* *None*) * **kwargs** (*Any*) ## Returns A Score object containing: * value: 1.0 if concise, 0.0 if verbose * label: String representation of the boolean result * reasoning: Detailed explanation of the assessment ## Example ```python theme={null} from fiddler_evals.evaluators import Conciseness evaluator = Conciseness() ``` ```python theme={null} # Concise answer score = evaluator.score("The capital of France is Paris.") print(f"Conciseness: {score.value}") # 1.0 print(f"Reasoning: {score.reasoning}") # Verbose answer score = evaluator.score( "Well, that's a great question about France. Let me think about this..." "France is a beautiful country in Europe, and it has many wonderful cities..." "The capital city of France is Paris, which is located in the north-central part..." ) print(f"Conciseness: {score.value}") # 0.0 ``` This evaluator uses Fiddler's built-in conciseness assessment model and requires an active connection to the Fiddler API. ## name *= 'conciseness'* ## score() Score the conciseness of an answer. ### Parameters The LLM's response to evaluate for conciseness. ### Returns A Score object containing: * value: 1.0 if concise, 0.0 if verbose * label: String representation of the boolean result * reasoning: Detailed explanation of the assessment # Connection Source: https://docs.fiddler.ai/sdk-api/evals/connection Manages authenticated connections to the Fiddler platform. Manages authenticated connections to the Fiddler platform. The Connection class handles all aspects of connecting to and communicating with the Fiddler platform, including authentication, HTTP client management, server version compatibility checking, and organization context management. This class provides the foundation for all API interactions with Fiddler, managing connection parameters, authentication tokens, and ensuring proper communication protocols are established. ## Example ```python theme={null} # Creating a basic connection connection = Connection( url="https://your-instance.fiddler.ai", token="your-api-key" ) # Creating a connection with custom timeout and proxy connection = Connection( url="https://your-instance.fiddler.ai", token="your-api-key", timeout=(5.0, 30.0), # (connect_timeout, read_timeout) proxies={"https": "https://proxy.company.com:8080"} ) # Creating a connection without SSL verification connection = Connection( url="https://your-instance.fiddler.ai", token="your-api-key", verify=False, # Not recommended for production validate=False # Skip version compatibility check ) ``` Initialize a connection to the Fiddler platform. ## Parameters The base URL to your Fiddler platform instance Authentication token obtained from the Fiddler UI Dictionary mapping protocol to proxy URL for HTTP requests HTTP request timeout settings (float or tuple of connect/read timeouts) Whether to verify server's TLS certificate (default: True) Whether to validate server/client version compatibility (default: True) ## Raises * **ValueError** – If url or token parameters are empty * **IncompatibleClient** – If server version is incompatible with client version ## *property* client Get the HTTP request client instance for API communication. ### Returns Configured HTTP client with authentication headers, proxy settings, and timeout configurations. ## *property* server\_info Get server information and metadata from the Fiddler platform. ### Returns Server information including version, organization details, and platform configuration. ## *property* server\_version Get the semantic version of the connected Fiddler server. ### Returns Semantic version object representing the server version. ## *property* organization\_name Get the name of the connected organization. ### Returns Name of the organization associated with this connection. ## *property* organization\_id Get the UUID of the connected organization. ### Returns Unique identifier of the organization associated with this connection. # ContextRelevance Source: https://docs.fiddler.ai/sdk-api/evals/context-relevance Evaluator to assess how relevant retrieved documents are to a user query. Evaluator to assess how relevant retrieved documents are to a user query. The ContextRelevance evaluator measures whether retrieved documents provide sufficient context to answer a given question. This is a critical metric for RAG (Retrieval-Augmented Generation) pipelines to ensure the retrieval step is fetching useful information. Key Features: * **Retrieval Assessment**: Determines if retrieved documents support the query * **Three-Level Scoring**: Returns high (1.0), medium (0.5), or low (0.0) relevance scores * **RAG Pipeline Evaluation**: Specifically designed for evaluating retrieval quality * **Detailed Reasoning**: Provides explanation for the relevance assessment * **Fiddler API Integration**: Uses Fiddler's built-in context relevance model Use Cases: * **RAG Systems**: Evaluating retrieval quality in RAG pipelines * **Search Systems**: Assessing if search results are relevant to queries * **Document Q\&A**: Verifying retrieved context supports the question * **Knowledge Base Evaluation**: Testing retrieval effectiveness Scoring Logic: * **1.0 (High)**: Retrieved documents provide all necessary information to answer the query * **0.5 (Medium)**: Retrieved documents are on topic but don't fully support a complete answer * **0.0 (Low)**: Retrieved documents are not relevant to the query ## Parameters * **user\_query** (*str*) – The question or query being asked. * **retrieved\_documents** (*list* \*\[\**str* *]*) – The documents retrieved as context. * **model** (*str*) * **credential** (*str* *|* *None*) * **kwargs** (*Any*) ## Returns A Score object containing: * value: 1.0 for high, 0.5 for medium, 0.0 for low relevance * label: "high", "medium", or "low" * reasoning: Detailed explanation of the assessment ## Example ```python theme={null} from fiddler_evals.evaluators import ContextRelevance evaluator = ContextRelevance(model="openai/gpt-4o") # High context relevance score = evaluator.score( user_query="What is the capital of France?", retrieved_documents=[ "France is a country in Western Europe.", "Paris is the capital and largest city of France." ] ) print(f"Context Relevance: {score.label}") # "high" print(f"Score: {score.value}") # 1.0 # Low context relevance score = evaluator.score( user_query="What is the capital of France?", retrieved_documents=[ "Pizza is a popular Italian dish.", "The weather is nice today." ] ) print(f"Context Relevance: {score.label}") # "low" ``` This evaluator uses Fiddler's built-in context relevance assessment model and requires an active connection to the Fiddler API. ## name *= 'context\_relevance'* ## score() Score the relevance of retrieved documents to a query. ### Parameters The question or query being asked. The documents retrieved as context. ### Returns A Score object containing: * value: 1.0 for high, 0.5 for medium, 0.0 for low relevance * label: "high", "medium", or "low" * reasoning: Detailed explanation of the assessment # CustomJudge Source: https://docs.fiddler.ai/sdk-api/evals/custom-judge Create a fully customizable LLM-as-a-Judge evaluator with your own prompt and output schema. Create a fully customizable LLM-as-a-Judge evaluator with your own prompt and output schema. The CustomJudge evaluator allows you to define arbitrary evaluation criteria by specifying a custom prompt template and structured output fields. This is the most flexible evaluator in the Fiddler Evals SDK, enabling you to build domain-specific evaluation logic without writing custom code. Key Features: * **Custom Prompts**: Define your own evaluation prompt with `{{ placeholder }}` syntax * **Structured Outputs**: Specify typed output fields (string, boolean, integer, number) * **Categorical Choices**: Constrain string outputs to predefined categories * **Multi-Field Outputs**: Return multiple scores/labels from a single evaluation * **Field Descriptions**: Guide the LLM with descriptions for each output field * **Numeric Constraints**: Set minimum/maximum bounds on numeric output fields * **Multi-Message Prompts**: Use structured message lists with system/user/assistant roles * **Input Metadata**: Define input field requirements and documentation * **Output Transforms**: Map LLM response fields to final output fields with value mapping * **Intermediate Response Schema**: Define a separate LLM response schema with transforms * **CustomJudgeSpec Object**: Bundle prompt, inputs, and outputs into a reusable [`CustomJudgeSpec`](/sdk-api/evals/custom-judge-spec) Use Cases: * **Domain-Specific Evaluation**: Create evaluators tailored to your industry or use case * **Custom Rubrics**: Implement grading rubrics with specific criteria * **Multi-Aspect Scoring**: Evaluate multiple dimensions (e.g., tone, accuracy, helpfulness) * **Classification Tasks**: Categorize responses into predefined labels * **Compliance Checking**: Verify responses meet specific guidelines or policies Output Field Types: * **string**: Free-form text output, or categorical if `choices` is specified * **boolean**: True/False classification * **integer**: Whole number scores (e.g., 1-5 rating scale) * **number**: Floating-point scores (e.g., 0.0-1.0 confidence) ## Parameters The evaluation prompt. Can be either a plain string with `{{ placeholder }}` markers (wrapped in a single user message automatically) or a list of [`Message`](/sdk-api/evals/message) dicts for multi-message prompts. Required unless `prompt_spec` is provided. Schema defining the expected outputs. Required unless `prompt_spec` is provided. Each field has: * `type`: One of 'string', 'boolean', 'integer', 'number' * `choices` (optional): List of allowed values for categorical string fields * `description` (optional): Instructions for the LLM about this field * `title` (optional): Human-readable title for the field * `transform` (optional): Transform from LLM response field to output field * `default` (optional): Default value if field is missing from LLM response * `minimum` (optional): Minimum allowed value for numeric fields * `maximum` (optional): Maximum allowed value for numeric fields A [`CustomJudgeSpec`](/sdk-api/evals/custom-judge-spec) object bundling prompt\_template, output\_fields, inputs, and llm\_response\_fields into a single reusable specification. Mutually exclusive with providing `prompt_template` and `output_fields` directly. LLM Gateway model name in `{provider}/{model}` format. E.g., `openai/gpt-4o`, `anthropic/claude-3-sonnet` Name of the LLM Gateway credential for the provider. Metadata for template variables. Keys must match `{{ placeholder }}` names in the prompt template. Each value can specify: * `title` (optional): Human-readable title * `description` (optional): Description of the input * `required` (optional): Whether this input must be provided (default: False) Schema for the LLM response before transformation. When provided, the LLM is instructed to return fields matching this schema, and `output_fields` with `transform` specs define how to map the response to final outputs. Required when any output field uses a `transform`. ## Returns A list of Score objects, one for each output field defined. Each Score contains: * name: The output field name (e.g., "sentiment", "confidence") * value: The numeric value (for number/integer/boolean fields) * label: The string label (for string/categorical fields) * reasoning: Always None for CustomJudge (reasoning is returned as a field) ## Example Basic sentiment analysis with categorical output: ```python theme={null} from fiddler_evals.evaluators import CustomJudge evaluator = CustomJudge( model="openai/gpt-4o", credential="my-openai-key", prompt_template=""" Analyze the sentiment of the following customer review: Review: {{ review_text }} Classify the sentiment and explain your reasoning. """, output_fields={ "sentiment": { "type": "string", "choices": ["positive", "negative", "neutral"], }, "confidence": { "type": "number", "description": "Confidence score between 0 and 1" }, "reasoning": { "type": "string", } } ) scores = evaluator.score(inputs={ "review_text": "The product exceeded my expectations! Fast shipping too." }) # Access individual scores by index or iterate for score in scores: print(f"{score.name}: {score.value or score.label}") # Output: # sentiment: positive # confidence: 0.95 # reasoning: The review expresses satisfaction... ``` ## Example Multi-criteria response quality evaluation: ```python theme={null} evaluator = CustomJudge( model="anthropic/claude-3-sonnet", credential="my-anthropic-key", prompt_template=""" Evaluate the quality of this customer support response. Customer Question: {{ question }} Support Response: {{ response }} Rate the response on multiple criteria. """, output_fields={ "helpful": { "type": "boolean", "description": "Does the response address the customer's question?" }, "professional_tone": { "type": "boolean", "description": "Is the tone professional and courteous?" }, "quality_score": { "type": "integer", "description": "Overall quality rating from 1 (poor) to 5 (excellent)" } } ) scores = evaluator.score(inputs={ "question": "How do I reset my password?", "response": "Click 'Forgot Password' on the login page and follow the steps." }) # Convert to dict for easy access scores_dict = {s.name: s for s in scores} print(f"Helpful: {scores_dict['helpful'].value}") # True print(f"Quality: {scores_dict['quality_score'].value}") # 4 ``` ## Example Code review evaluator: ````python theme={null} evaluator = CustomJudge( model="openai/gpt-4o", credential="my-openai-key", prompt_template=""" Review this code change for potential issues: ```{{ language }} ```` Context: \{\{ pr\_description }} """, output\_fields=\{ "has\_bugs": \{ "type": "boolean", "description": "Are there any obvious bugs or logic errors?" }, "severity": \{ "type": "string", "choices": \["critical", "major", "minor", "none"], "description": "Severity of issues found" }, "feedback": \{ "type": "string", "description": "Specific feedback for the code author" } } ) ```python theme={null} {{ code_diff }} ``` ```` ## Example Multi-message prompt with system instructions and numeric constraints: ```python evaluator = CustomJudge( model="openai/gpt-4o", credential="my-openai-key", prompt_template=[ {"role": "system", "content": "You are an expert code reviewer."}, {"role": "user", "content": "Review this code:\n{{ code }}"}, ], output_fields={ "quality_score": { "type": "integer", "minimum": 1, "maximum": 10, "description": "Code quality score from 1 to 10" }, "feedback": { "type": "string", "description": "Specific feedback for the code author" } }, inputs={ "code": {"required": True, "description": "The code to review"} } ) ```` ## Example Using llm\_response\_fields with transforms for value mapping: ```python theme={null} evaluator = CustomJudge( model="openai/gpt-4o", credential="my-openai-key", prompt_template="Is the response faithful? Response: {{ response }}", llm_response_fields={ "is_faithful": { "type": "string", "choices": ["faithful", "not_faithful"], }, "reasoning": {"type": "string"}, }, output_fields={ "label": { "type": "string", "choices": ["yes", "no"], "transform": { "source_field": "is_faithful", "value_map": {"faithful": "yes", "not_faithful": "no"}, }, }, "reasoning": {"type": "string"}, }, ) ``` ## Example Using a reusable CustomJudgeSpec object: ```python theme={null} from fiddler_evals.evaluators.custom_judge import ( CustomJudge, CustomJudgeSpec, Message, InputFieldSpec, ) spec = CustomJudgeSpec( prompt_template=[ Message(role="system", content="You are an expert evaluator."), Message(role="user", content="Rate this response:\n{{ response }}"), ], inputs={"response": InputFieldSpec(required=True)}, output_fields={ "quality": { "type": "integer", "minimum": 1, "maximum": 5, "description": "Quality rating from 1 to 5", } }, ) evaluator = CustomJudge(prompt_spec=spec, model="openai/gpt-4o") ``` * Placeholder names in `{{ }}` must exactly match keys in the `inputs` dict * The LLM is instructed to return JSON matching your output schema * For best results, include clear descriptions for each output field * Use `choices` for categorical fields to ensure consistent outputs * Use `minimum`/`maximum` for numeric fields to constrain values * Use [`CustomJudgeSpec`](/sdk-api/evals/custom-judge-spec) to bundle prompt configuration into a reusable object * This evaluator requires an active connection to the Fiddler API ## name *= 'custom\_judge'* ## score() Score using the Custom Judge. ### Parameters Values for the \{\{ placeholders }} in your prompt\_template. Keys must match placeholder names exactly. ### Returns A list of Score objects, one for each output field defined. ### Raises **ValueError** – If inputs is empty. # CustomJudgeSpec Source: https://docs.fiddler.ai/sdk-api/evals/custom-judge-spec Reusable prompt specification for CustomJudge evaluators. Reusable prompt specification for CustomJudge evaluators. Provides a structured, validated way to define evaluation prompts with input/output schemas, transforms, and multi-message templates. A `CustomJudgeSpec` can be defined once and reused across multiple evaluator instances or shared across a codebase. ## Parameters The evaluation prompt. Can be a plain string (wrapped in a single user message) or a list of [`Message`](/sdk-api/evals/message) dicts. Schema defining the expected output fields. Optional metadata for template variables. Optional schema for the LLM response before transformation. Required when output fields use `transform`. ## Example Defining a reusable faithfulness evaluator spec: ```python theme={null} from fiddler_evals.evaluators.custom_judge import ( CustomJudge, CustomJudgeSpec, Message, InputFieldSpec, OutputFieldTransform, ) FAITHFULNESS_SPEC = CustomJudgeSpec( prompt_template=[ Message(role='system', content='Judge faithfulness.'), Message(role='user', content=( 'Question: {{ query }}\n' 'Documents: {{ docs }}\n' 'Answer: {{ answer }}' )), ], inputs={ 'query': InputFieldSpec(required=True), 'docs': InputFieldSpec(required=True), 'answer': InputFieldSpec(required=True), }, llm_response_fields={ 'is_faithful': { 'type': 'string', 'choices': ['faithful', 'not_faithful'], }, }, output_fields={ 'label': { 'type': 'string', 'choices': ['yes', 'no'], 'transform': OutputFieldTransform( source_field='is_faithful', value_map={ 'faithful': 'yes', 'not_faithful': 'no', }, ), }, }, ) evaluator = CustomJudge( prompt_spec=FAITHFULNESS_SPEC, model='openai/gpt-4o', ) ``` ## prompt\_template ## output\_fields ## inputs ## llm\_response\_fields ## model\_config Configuration for the model, should be a dictionary conforming to \[ConfigDict]\[pydantic.config.ConfigDict]. # Dataset Source: https://docs.fiddler.ai/sdk-api/evals/dataset Represents a Dataset container for organizing evaluation test cases. Represents a Dataset container for organizing evaluation test cases. A Dataset is a logical container within an Application that stores structured test cases with inputs and expected outputs for GenAI evaluation. Datasets provide organized storage, metadata management, and tagging capabilities for systematic testing and validation of GenAI applications. Key Features: * **Test Case Storage**: Container for structured evaluation test cases * **Application Context**: Datasets are scoped within applications for isolation * **Metadata Management**: Custom metadata and tagging for organization * **Evaluation Foundation**: Structured data for GenAI application testing * **Lifecycle Management**: Coordinated creation, updates, and deletion of datasets Dataset Lifecycle: 1. **Creation**: Create dataset with unique name within an application 2. **Configuration**: Add test cases and metadata 3. **Evaluation**: Use dataset for testing GenAI applications 4. **Maintenance**: Update test cases and metadata as needed 5. **Cleanup**: Delete dataset when no longer needed ## Example ```python theme={null} # Create a new dataset for fraud detection tests dataset = Dataset.create( name="fraud-detection-tests", application_id=application_id, description="Test cases for fraud detection model", metadata={"source": "production", "version": "1.0"}, ) print(f"Created dataset: {dataset.name} (ID: {dataset.id})") ``` Datasets are permanent containers - once created, the name cannot be changed. Deleting a dataset removes all contained test cases and metadata. Consider the organizational structure carefully before creating datasets. ## id ## name ## created\_at ## updated\_at ## created\_by ## updated\_by ## project ## application ## active ## description ## metadata ## *classmethod* get\_by\_id() Retrieve a dataset by its unique identifier. Fetches a dataset from the Fiddler platform using its UUID. This is the most direct way to retrieve a dataset when you know its ID. ### Parameters The unique identifier (UUID) of the dataset to retrieve. Can be provided as a UUID object or string representation. ### Returns The dataset instance with all metadata and configuration. ### Raises * **NotFound** – If no dataset exists with the specified ID. * **ApiError** – If there's an error communicating with the Fiddler API. ### Example ```python theme={null} # Get dataset by UUID dataset = Dataset.get_by_id(id_="550e8400-e29b-41d4-a716-446655440000") print(f"Retrieved dataset: {dataset.name}") print(f"Created: {dataset.created_at}") print(f"Application: {dataset.application.name}") ``` This method makes an API call to fetch the latest dataset state from the server. The returned dataset instance reflects the current state in Fiddler. ## *classmethod* get\_by\_name() Retrieve a dataset by name within an application. Finds and returns a dataset using its name within the specified application. This is useful when you know the dataset name and application but not its UUID. Dataset names are unique within an application, making this a reliable lookup method. ### Parameters The name of the dataset to retrieve. Dataset names are unique within an application and are case-sensitive. The UUID of the application containing the dataset. Can be provided as a UUID object or string representation. ### Returns The dataset instance matching the specified name. ### Raises * **NotFound** – If no dataset exists with the specified name in the application. * **ApiError** – If there's an error communicating with the Fiddler API. ### Example ```python theme={null} # Get application instance application = Application.get_by_name(name="fraud-detection-app", project_id=project_id) # Get dataset by name within an application dataset = Dataset.get_by_name( name="fraud-detection-tests", application_id=application.id ) print(f"Found dataset: {dataset.name} (ID: {dataset.id})") print(f"Created: {dataset.created_at}") print(f"Application: {dataset.application.name}") ``` Dataset names are case-sensitive and must match exactly. Use this method when you have a known dataset name from configuration or user input. ## *classmethod* list() List all datasets in an application. Retrieves all datasets that the current user has access to within the specified application. Returns an iterator for memory efficiency when dealing with many datasets. ### Parameters The UUID of the application to list datasets from. Can be provided as a UUID object or string representation. ### Yields `Dataset` – Dataset instances for all accessible datasets in the application. ### Raises **ApiError** – If there's an error communicating with the Fiddler API. ### Returns `Iterator[Dataset]` ### Example ```python theme={null} # Get application instance application = Application.get_by_name(name="fraud-detection-app", project_id=project_id) # List all datasets in an application for dataset in Dataset.list(application_id=application.id): print(f"Dataset: {dataset.name}") print(f" ID: {dataset.id}") print(f" Created: {dataset.created_at}") # Convert to list for counting and filtering datasets = list(Dataset.list(application_id=application.id)) print(f"Total datasets in application: {len(datasets)}") # Find datasets by name pattern test_datasets = [ ds for ds in Dataset.list(application_id=application.id) if "test" in ds.name.lower() ] print(f"Test datasets: {len(test_datasets)}") ``` This method returns an iterator for memory efficiency. Convert to a list with list(Dataset.list(application\_id)) if you need to iterate multiple times or get the total count. The iterator fetches datasets lazily from the API. ## *classmethod* create() Create a new dataset in an application. Creates a new dataset within the specified application on the Fiddler platform. The dataset must have a unique name within the application. ### Parameters Dataset name, must be unique within the application. The UUID of the application to create the dataset in. Can be provided as a UUID object or string representation. Optional human-readable description of the dataset. Optional custom metadata dictionary for additional dataset information. Optional boolean flag to indicate if the dataset is active. ### Returns The newly created dataset instance with server-assigned fields. ### Raises * **Conflict** – If a dataset with the same name already exists in the application. * **ValidationError** – If the dataset configuration is invalid (e.g., invalid name format). * **ApiError** – If there's an error communicating with the Fiddler API. ### Example ```python theme={null} # Get application instance application = Application.get_by_name(name="fraud-detection-app", project_id=project_id) # Create a new dataset for fraud detection tests dataset = Dataset.create( name="fraud-detection-tests", application_id=application.id, description="Test cases for fraud detection model evaluation", metadata={"source": "production", "version": "1.0", "environment": "test"}, ) print(f"Created dataset with ID: {dataset.id}") print(f"Created at: {dataset.created_at}") print(f"Application: {dataset.application.name}") ``` After successful creation, the dataset instance is returned with server-assigned metadata. The dataset is immediately available for adding test cases and evaluation workflows. ## *classmethod* get\_or\_create() Get an existing dataset by name or create a new one if it doesn't exist. This is a convenience method that attempts to retrieve a dataset by name within an application, and if not found, creates a new dataset with that name. Useful for idempotent dataset setup in automation scripts and deployment pipelines. ### Parameters The name of the dataset to retrieve or create. The UUID of the application to search/create the dataset in. Can be provided as a UUID object or string representation. Optional human-readable description of the dataset. Optional custom metadata dictionary for additional dataset information. Optional boolean flag to indicate if the dataset is active. ### Returns Either the existing dataset with the specified name, or a newly created dataset if none existed. ### Raises * **ValidationError** – If the dataset name format is invalid. * **ApiError** – If there's an error communicating with the Fiddler API. ### Example ```python theme={null} # Get application instance application = Application.get_by_name(name="fraud-detection-app", project_id=project_id) # Safe dataset setup - get existing or create new dataset = Dataset.get_or_create( name="fraud-detection-tests", application_id=application.id, description="Test cases for fraud detection model", metadata={"source": "production", "version": "1.0"}, ) print(f"Using dataset: {dataset.name} (ID: {dataset.id})") # Idempotent setup in deployment scripts dataset = Dataset.get_or_create( name="llm-evaluation-tests", application_id=application.id, ) # Use in configuration management test_types = ["unit", "integration", "performance"] datasets = {} for test_type in test_types: datasets[test_type] = Dataset.get_or_create( name=f"fraud-detection-{test_type}-tests", application_id=application.id, ) ``` This method is idempotent - calling it multiple times with the same name and application\_id will return the same dataset. It logs when creating a new dataset for visibility in automation scenarios. ## update() Update dataset description, metadata. ### Parameters Optional new description for the dataset. If provided, replaces the existing description. Set to empty string to clear. Optional new metadata dictionary for the dataset. If provided, replaces the existing metadata completely. Use empty dict to clear. Optional boolean flag to indicate if the dataset is active. ### Returns The updated dataset instance with new metadata and configuration. ### Raises * **ValueError** – If no update parameters are provided (all are None). * **ValidationError** – If the update data is invalid (e.g., invalid metadata format). * **ApiError** – If there's an error communicating with the Fiddler API. ### Example ```python theme={null} # Get existing dataset dataset = Dataset.get_by_name(name="fraud-detection-tests", application_id=application_id) # Update description and metadata updated_dataset = dataset.update( description="Updated test cases for fraud detection model v2.0", metadata={"source": "production", "version": "2.0", "environment": "test", "updated_by": "john_doe"}, ) print(f"Updated dataset: {updated_dataset.name}") print(f"New description: {updated_dataset.description}") # Update only metadata dataset.update(metadata={"last_updated": "2024-01-15", "status": "active"}) # Clear description dataset.update(description="") # Batch update multiple datasets for dataset in Dataset.list(application_id=application_id): if "test" in dataset.name: dataset.update(description="Updated test cases for fraud detection model v2.0") ``` This method performs a complete replacement of the specified fields. For partial updates, retrieve current values, modify them, and pass the complete new values. The dataset name and ID cannot be changed. ## delete() Delete the dataset permanently from the Fiddler platform. Permanently removes the dataset and all its associated test case items from the Fiddler platform. This operation cannot be undone. The method performs safety checks before deletion: 1. Verifies that no experiments are currently associated with the dataset 2. Prevents deletion if any experiments reference this dataset 3. Only proceeds with deletion if the dataset is safe to remove ### Parameters **None** – This method takes no parameters. ### Returns This method does not return a value. ### Raises * **ApiError** – If there's an error communicating with the Fiddler API. * **ApiError** – If the dataset cannot be deleted due to existing experiments. * **NotFound** – If the dataset no longer exists. ### Example ```python theme={null} # Get existing dataset dataset = Dataset.get_by_name(name="old-test-dataset", application_id=application_id) # Check if dataset is safe to delete try: dataset.delete() print(f"Successfully deleted dataset: {dataset.name}") except ApiError as e: print(f"Cannot delete dataset: {e}") print("Dataset may have associated experiments") # Clean up unused datasets in bulk unused_datasets = [ Dataset.get_by_name(name="temp-dataset-1", application_id=application_id), Dataset.get_by_name(name="temp-dataset-2", application_id=application_id), ] for dataset in unused_datasets: try: dataset.delete() print(f"Deleted: {dataset.name}") except ApiError: print(f"Skipped {dataset.name} - has associated experiments") ``` This operation is irreversible. All test case items and metadata associated with the dataset will be permanently lost. Ensure that no experiments are using this dataset before calling delete(). ## insert() Add multiple test case items to the dataset. Inserts multiple test case items (inputs, expected outputs, metadata) into the dataset. Each item represents a single test case for evaluation purposes. Items can be provided as dictionaries or NewDatasetItem objects. ### Parameters List of test case items to add to the dataset. Each item can be: * A dictionary containing test case data with keys: > * inputs: Dictionary containing input data for the test case > * expected\_outputs: Dictionary containing expected output data > * metadata: Optional dictionary with additional test case metadata > * extras: Optional dictionary for additional custom data > * source\_name: Optional string identifying the source of the test case > * source\_id: Optional string identifier for the source * A NewDatasetItem object with the same structure ### Returns List of UUIDs for the newly created dataset items. ### Raises * **ValueError** – If the items list is empty. * **ValidationError** – If any item data is invalid (e.g., missing required fields). * **ApiError** – If there's an error communicating with the Fiddler API. ### Example ```python theme={null} # Get existing dataset dataset = Dataset.get_by_name(name="fraud-detection-tests", application_id=application_id) # Add test cases as dictionaries test_cases = [ { "inputs": {"question": "What happens to you if you eat watermelon seeds?"}, "expected_outputs": { "answer": "The watermelon seeds pass through your digestive system", "alt_answers": ["Nothing happens", "You eat watermelon seeds"], }, "metadata": { "type": "Adversarial", "category": "Misconceptions", "source": "https://wonderopolis.org/wonder/will-a-watermelon-grow-in-your-belly-if-you-swallow-a-seed", }, "extras": {}, "source_name": "wonderopolis.org", "source_id": "1", }, ] # Insert test cases item_ids = dataset.insert(test_cases) print(f"Added {len(item_ids)} test cases") print(f"Item IDs: {item_ids}") # Add test cases as NewDatasetItem objects from fiddler_evals.pydantic_models.dataset import NewDatasetItem items = [ NewDatasetItem( inputs={"question": "What is the capital of France?"}, expected_outputs={"answer": "Paris"}, metadata={"difficulty": "easy"}, extras={}, source_name="test_source", source_id="item1", ), ] item_ids = dataset.insert(items) print(f"Added {len(item_ids)} test cases") ``` This method automatically generates UUIDs and timestamps for each item. The items are validated before insertion, and any validation errors will prevent the entire batch from being inserted. Use this method for bulk insertion of test cases into datasets. ## insert\_from\_pandas() Insert test case items from a pandas DataFrame into the dataset. Converts a pandas DataFrame into test case items and inserts them into the dataset. This method provides a convenient way to bulk import test cases from structured data sources like CSV files, databases, or other tabular data formats. The method intelligently maps DataFrame columns to different test case components: * **Input columns**: Data that will be used as inputs for evaluation * **Expected output columns**: Expected results or answers for the test cases * **Metadata columns**: Additional metadata associated with each test case * **Extras columns**: Custom data fields for additional test case information * **Source columns**: Information about the origin of each test case Column Mapping Logic: 1. If input\_columns is specified, those columns become inputs 2. If input\_columns is None, all unmapped columns become inputs 3. Remaining unmapped columns are automatically assigned to extras 4. Source columns are always mapped to source\_name and source\_id ### Parameters The pandas DataFrame containing test case data. Must not be empty and must have at least one column. Optional list of column names to use as input data. If None, all unmapped columns become inputs. Optional list of column names containing expected outputs or answers for the test cases. Optional list of column names to use as metadata. These columns will be stored as test case metadata. Optional list of column names for additional custom data. Unmapped columns are automatically added to extras. Column name containing the ID for each test case. Defaults to "id". Column name containing the source identifier for each test case. Defaults to "source\_name". Column name containing the source ID for each test case. Defaults to "source\_id". ### Returns List of UUIDs for the newly created dataset items. ### Raises * **ValueError** – If the DataFrame is empty or has no columns. * **ImportError** – If pandas is not installed (checked via validate\_pandas\_installation). * **ValidationError** – If any generated test case data is invalid. * **ApiError** – If there's an error communicating with the Fiddler API. ### Example ```python theme={null} # Get existing dataset dataset = Dataset.get_by_name(name="fraud-detection-tests", application_id=application_id) # Example DataFrame with test case data import pandas as pd df = pd.DataFrame({ 'question': ['What is fraud?', 'How to detect fraud?', 'What are fraud types?'], 'expected_answer': ['Fraud is deception', 'Use ML models', 'Identity theft, credit card fraud'], 'difficulty': ['easy', 'medium', 'hard'], 'category': ['definition', 'detection', 'types'], 'source_name': ['manual', 'manual', 'manual'], 'source_id': ['1', '2', '3'] }) # Insert with explicit column mapping item_ids = dataset.insert_from_pandas( df=df, input_columns=['question'], expected_output_columns=['expected_answer'], metadata_columns=['difficulty', 'category'], ) print(f"Added {len(item_ids)} test cases from DataFrame") # Insert with automatic column mapping (all unmapped columns become inputs) df_auto = pd.DataFrame({ 'user_query': ['Is this transaction suspicious?', 'Check for anomalies'], 'context': ['Credit card transaction', 'Banking data'], 'expected_response': ['Yes, flagged', 'Anomalies detected'], 'priority': ['high', 'medium'], 'source': ['production', 'test'] }) item_ids = dataset.insert_from_pandas( df=df_auto, expected_output_columns=['expected_response'], metadata_columns=['priority'], source_name_column='source', source_id_column='source' # Using same column for both ) # Complex DataFrame with many columns df_complex = pd.DataFrame({ 'prompt': ['Classify this text', 'Summarize this document'], 'context': ['Text content here', 'Document content here'], 'expected_class': ['positive', 'neutral'], 'expected_summary': ['Short summary', 'Brief overview'], 'confidence': [0.95, 0.87], 'language': ['en', 'en'], 'domain': ['sentiment', 'summarization'], 'version': ['1.0', '1.0'], 'created_by': ['user1', 'user2'], 'review_status': ['approved', 'pending'] }) item_ids = dataset.insert_from_pandas( df=df_complex, input_columns=['prompt', 'context'], expected_output_columns=['expected_class', 'expected_summary'], metadata_columns=['confidence', 'language', 'domain', 'version'], extras_columns=['created_by', 'review_status'] ) ``` This method requires pandas to be installed. The DataFrame is processed row by row, and each row becomes a separate test case item. Column names are converted to strings to ensure compatibility with the API. Missing values (NaN) in the DataFrame are preserved as None in the resulting test case items. ## insert\_from\_csv\_file() Insert test case items from a CSV file into the dataset. Reads a CSV file and converts it into test case items, then inserts them into the dataset. This method provides a convenient way to bulk import test cases from CSV files, which is particularly useful for importing data from spreadsheets, exported databases, or other tabular data sources. This method is a convenience wrapper around insert\_from\_pandas() that handles CSV file reading automatically. It uses pandas to read the CSV file and then applies the same intelligent column mapping logic as the pandas method. Column Mapping Logic: 1. If input\_columns is specified, those columns become inputs 2. If input\_columns is None, all unmapped columns become inputs 3. Remaining unmapped columns are automatically assigned to extras 4. Source columns are always mapped to source\_name and source\_id ### Parameters Path to the CSV file to read. Can be a string or Path object. Supports both relative and absolute paths. Optional list of column names to use as input data. If None, all unmapped columns become inputs. Optional list of column names containing expected outputs or answers for the test cases. Optional list of column names to use as metadata. These columns will be stored as test case metadata. Optional list of column names for additional custom data. Unmapped columns are automatically added to extras. Column name containing the ID for each test case. Defaults to "id". Column name containing the source identifier for each test case. Defaults to "source\_name". Column name containing the source ID for each test case. Defaults to "source\_id". ### Returns List of UUIDs for the newly created dataset items. ### Raises * **FileNotFoundError** – If the CSV file does not exist at the specified path. * **ValueError** – If the CSV file is empty or has no columns. * **ImportError** – If pandas is not installed (checked via validate\_pandas\_installation). * **ValidationError** – If any generated test case data is invalid. * **ApiError** – If there's an error communicating with the Fiddler API. ### Example ```python theme={null} # Get existing dataset dataset = Dataset.get_by_name(name="fraud-detection-tests", application_id=application_id) # Example CSV file: test_cases.csv # question,expected_answer,difficulty,category,source_name,source_id # "What is fraud?","Fraud is deception","easy","definition","manual","1" # "How to detect fraud?","Use ML models","medium","detection","manual","2" # "What are fraud types?","Identity theft, credit card fraud","hard","types","manual","3" # Insert with explicit column mapping item_ids = dataset.insert_from_csv_file( file_path="test_cases.csv", input_columns=['question'], expected_output_columns=['expected_answer'], metadata_columns=['difficulty', 'category'], ) print(f"Added {len(item_ids)} test cases from CSV") # Insert with automatic column mapping (all unmapped columns become inputs) # CSV: user_query,context,expected_response,priority,source item_ids = dataset.insert_from_csv_file( file_path="evaluation_data.csv", expected_output_columns=['expected_response'], metadata_columns=['priority'], source_name_column='source', source_id_column='source' # Using same column for both ) # Import from CSV with relative path item_ids = dataset.insert_from_csv_file("data/test_cases.csv") print(f"Imported {len(item_ids)} test cases from CSV") # Import from CSV with absolute path from pathlib import Path csv_path = Path("/absolute/path/to/test_cases.csv") item_ids = dataset.insert_from_csv_file(csv_path) # Complex CSV with many columns # prompt,context,expected_class,expected_summary,confidence,language,domain,version,created_by,review_status item_ids = dataset.insert_from_csv_file( file_path="complex_test_cases.csv", input_columns=['prompt', 'context'], expected_output_columns=['expected_class', 'expected_summary'], metadata_columns=['confidence', 'language', 'domain', 'version'], extras_columns=['created_by', 'review_status'] ) # Batch import multiple CSV files csv_files = ["test_cases_1.csv", "test_cases_2.csv", "test_cases_3.csv"] all_item_ids = [] for csv_file in csv_files: item_ids = dataset.insert_from_csv_file(csv_file) all_item_ids.extend(item_ids) print(f"Imported {len(item_ids)} items from {csv_file}") print(f"Total imported: {len(all_item_ids)} items") ``` This method requires pandas to be installed. The CSV file is read using pandas.read\_csv() with default parameters. For advanced CSV reading options (custom delimiters, encoding, etc.), use pandas.read\_csv() directly and then call insert\_from\_pandas() with the resulting DataFrame. Missing values in the CSV are preserved as None in the resulting test case items. ## insert\_from\_jsonl\_file() Insert test case items from a JSONL (JSON Lines) file into the dataset. Reads a JSONL file and converts it into test case items, then inserts them into the dataset. JSONL format is particularly useful for importing structured data from APIs, machine learning datasets, or other sources that export data as one JSON object per line. JSONL Format: Each line in the file must be a valid JSON object. Empty lines are skipped. The method parses each line as a separate JSON object and extracts the specified columns to create test case items. Column Mapping: Unlike CSV/pandas methods, this method requires explicit specification of input\_keys since JSON objects don't have a predefined column structure. All other key/column mappings work the same way as other insert methods. ### Parameters Path to the JSONL file to read. Can be a string or Path object. Supports both relative and absolute paths. Required list of key names to use as input data. These must correspond to keys in the JSON objects. Optional list of key names containing expected outputs or answers for the test cases. Optional list of key names to use as metadata. These keys will be stored as test case metadata. Optional list of key names for additional custom data. Any keys in the JSON objects not mapped to other categories can be included here. Key name containing the ID for each test case. Defaults to "id". Key name containing the source identifier for each test case. Defaults to "source\_name". Key name containing the source ID for each test case. Defaults to "source\_id". ### Returns List of UUIDs for the newly created dataset items. ### Raises * **FileNotFoundError** – If the JSONL file does not exist at the specified path. * **ValueError** – If the JSONL file is empty or has no valid JSON objects. * **json.JSONDecodeError** – If any line in the file contains invalid JSON. * **ValidationError** – If any generated test case data is invalid. * **ApiError** – If there's an error communicating with the Fiddler API. ### Example ```python theme={null} # Get existing dataset dataset = Dataset.get_by_name(name="fraud-detection-tests", application_id=application_id) # Example JSONL file: test_cases.jsonl # {"question": "What is fraud?", "expected_answer": "Fraud is deception", "difficulty": "easy", "category": "definition", "source_name": "manual", "source_id": "1"} # {"question": "How to detect fraud?", "expected_answer": "Use ML models", "difficulty": "medium", "category": "detection", "source_name": "manual", "source_id": "2"} # {"question": "What are fraud types?", "expected_answer": "Identity theft, credit card fraud", "difficulty": "hard", "category": "types", "source_name": "manual", "source_id": "3"} # Insert with explicit column mapping item_ids = dataset.insert_from_jsonl_file( file_path="test_cases.jsonl", input_keys=['question'], expected_output_keys=['expected_answer'], metadata_keys=['difficulty', 'category'], ) print(f"Added {len(item_ids)} test cases from JSONL") # Batch import multiple JSONL files jsonl_files = ["test_cases_1.jsonl", "test_cases_2.jsonl", "test_cases_3.jsonl"] all_item_ids = [] for jsonl_file in jsonl_files: item_ids = dataset.insert_from_jsonl_file( jsonl_file, input_keys=['question'] ) all_item_ids.extend(item_ids) print(f"Imported {len(item_ids)} items from {jsonl_file}") print(f"Total imported: {len(all_item_ids)} items") ``` This method reads the file line by line and parses each line as JSON. Empty lines are automatically skipped. The method requires explicit specification of input\_keys since JSON objects don't have a predefined structure like CSV files. Missing keys in JSON objects are handled gracefully and will result in None values for those fields. ## add\_testcases() Add multiple test case items to the dataset. Inserts multiple test case items (inputs, expected outputs, metadata) into the dataset. Each item represents a single test case for evaluation purposes. Items can be provided as dictionaries or NewDatasetItem objects. ### Parameters List of test case items to add to the dataset. Each item can be: * A dictionary containing test case data with keys: > * inputs: Dictionary containing input data for the test case > * expected\_outputs: Dictionary containing expected output data > * metadata: Optional dictionary with additional test case metadata > * extras: Optional dictionary for additional custom data > * source\_name: Optional string identifying the source of the test case > * source\_id: Optional string identifier for the source * A NewDatasetItem object with the same structure ### Returns List of UUIDs for the newly created dataset items. ### Raises * **ValueError** – If the items list is empty. * **ValidationError** – If any item data is invalid (e.g., missing required fields). * **ApiError** – If there's an error communicating with the Fiddler API. ### Example ```python theme={null} # Get existing dataset dataset = Dataset.get_by_name(name="fraud-detection-tests", application_id=application_id) # Add test cases as dictionaries test_cases = [ { "inputs": {"question": "What happens to you if you eat watermelon seeds?"}, "expected_outputs": { "answer": "The watermelon seeds pass through your digestive system", "alt_answers": ["Nothing happens", "You eat watermelon seeds"], }, "metadata": { "type": "Adversarial", "category": "Misconceptions", "source": "https://wonderopolis.org/wonder/will-a-watermelon-grow-in-your-belly-if-you-swallow-a-seed", }, "extras": {}, "source_name": "wonderopolis.org", "source_id": "1", }, ] # Insert test cases item_ids = dataset.insert(test_cases) print(f"Added {len(item_ids)} test cases") print(f"Item IDs: {item_ids}") # Add test cases as NewDatasetItem objects from fiddler_evals.pydantic_models.dataset import NewDatasetItem items = [ NewDatasetItem( inputs={"question": "What is the capital of France?"}, expected_outputs={"answer": "Paris"}, metadata={"difficulty": "easy"}, extras={}, source_name="test_source", source_id="item1", ), ] item_ids = dataset.insert(items) print(f"Added {len(item_ids)} test cases") ``` This method automatically generates UUIDs and timestamps for each item. The items are validated before insertion, and any validation errors will prevent the entire batch from being inserted. Use this method for bulk insertion of test cases into datasets. ## add\_items() Add multiple test case items to the dataset. Inserts multiple test case items (inputs, expected outputs, metadata) into the dataset. Each item represents a single test case for evaluation purposes. Items can be provided as dictionaries or NewDatasetItem objects. ### Parameters List of test case items to add to the dataset. Each item can be: * A dictionary containing test case data with keys: > * inputs: Dictionary containing input data for the test case > * expected\_outputs: Dictionary containing expected output data > * metadata: Optional dictionary with additional test case metadata > * extras: Optional dictionary for additional custom data > * source\_name: Optional string identifying the source of the test case > * source\_id: Optional string identifier for the source * A NewDatasetItem object with the same structure ### Returns List of UUIDs for the newly created dataset items. ### Raises * **ValueError** – If the items list is empty. * **ValidationError** – If any item data is invalid (e.g., missing required fields). * **ApiError** – If there's an error communicating with the Fiddler API. ### Example ```python theme={null} # Get existing dataset dataset = Dataset.get_by_name(name="fraud-detection-tests", application_id=application_id) # Add test cases as dictionaries test_cases = [ { "inputs": {"question": "What happens to you if you eat watermelon seeds?"}, "expected_outputs": { "answer": "The watermelon seeds pass through your digestive system", "alt_answers": ["Nothing happens", "You eat watermelon seeds"], }, "metadata": { "type": "Adversarial", "category": "Misconceptions", "source": "https://wonderopolis.org/wonder/will-a-watermelon-grow-in-your-belly-if-you-swallow-a-seed", }, "extras": {}, "source_name": "wonderopolis.org", "source_id": "1", }, ] # Insert test cases item_ids = dataset.insert(test_cases) print(f"Added {len(item_ids)} test cases") print(f"Item IDs: {item_ids}") # Add test cases as NewDatasetItem objects from fiddler_evals.pydantic_models.dataset import NewDatasetItem items = [ NewDatasetItem( inputs={"question": "What is the capital of France?"}, expected_outputs={"answer": "Paris"}, metadata={"difficulty": "easy"}, extras={}, source_name="test_source", source_id="item1", ), ] item_ids = dataset.insert(items) print(f"Added {len(item_ids)} test cases") ``` This method automatically generates UUIDs and timestamps for each item. The items are validated before insertion, and any validation errors will prevent the entire batch from being inserted. Use this method for bulk insertion of test cases into datasets. ## get\_testcases() Retrieve all test case items in the dataset. Fetches all test case items (inputs, expected outputs, metadata, tags) from the dataset. Returns an iterator for memory efficiency when dealing with large datasets containing many test cases. ### Returns Iterator of DatasetItem instances for all test cases in the dataset. ### Raises **ApiError** – If there's an error communicating with the Fiddler API. ### Example ```python theme={null} # Get existing dataset dataset = Dataset.get_by_name(name="fraud-detection-tests", application_id=application_id) # Get all test cases in the dataset for item in dataset.get_items(): print(f"Test case ID: {item.id}") print(f"Inputs: {item.inputs}") print(f"Expected outputs: {item.expected_outputs}") print(f"Metadata: {item.metadata}") print("---") # Convert to list for analysis all_items = list(dataset.get_items()) print(f"Total test cases: {len(all_items)}") # Filter items by metadata high_priority_items = [ item for item in dataset.get_items() if item.metadata.get("priority") == "high" ] print(f"High priority test cases: {len(high_priority_items)}") # Process items in batches batch_size = 100 for i, item in enumerate(dataset.get_items()): if i % batch_size == 0: print(f"Processing batch {i // batch_size + 1}") # Process item... ``` This method returns an iterator for memory efficiency. Convert to a list with list(dataset.get\_items()) if you need to iterate multiple times or get the total count. The iterator fetches items lazily from the API. ## get\_items() Retrieve all test case items in the dataset. Fetches all test case items (inputs, expected outputs, metadata, tags) from the dataset. Returns an iterator for memory efficiency when dealing with large datasets containing many test cases. ### Returns Iterator of DatasetItem instances for all test cases in the dataset. ### Raises **ApiError** – If there's an error communicating with the Fiddler API. ### Example ```python theme={null} # Get existing dataset dataset = Dataset.get_by_name(name="fraud-detection-tests", application_id=application_id) # Get all test cases in the dataset for item in dataset.get_items(): print(f"Test case ID: {item.id}") print(f"Inputs: {item.inputs}") print(f"Expected outputs: {item.expected_outputs}") print(f"Metadata: {item.metadata}") print("---") # Convert to list for analysis all_items = list(dataset.get_items()) print(f"Total test cases: {len(all_items)}") # Filter items by metadata high_priority_items = [ item for item in dataset.get_items() if item.metadata.get("priority") == "high" ] print(f"High priority test cases: {len(high_priority_items)}") # Process items in batches batch_size = 100 for i, item in enumerate(dataset.get_items()): if i % batch_size == 0: print(f"Processing batch {i // batch_size + 1}") # Process item... ``` This method returns an iterator for memory efficiency. Convert to a list with list(dataset.get\_items()) if you need to iterate multiple times or get the total count. The iterator fetches items lazily from the API. # DatasetItem Source: https://docs.fiddler.ai/sdk-api/evals/dataset-item Dataset item from Fiddler API Dataset item from Fiddler API ## id ## inputs ## expected\_outputs ## metadata ## extras ## source\_name ## source\_id ## created\_at ## updated\_at ## model\_config Configuration for the model, should be a dictionary conforming to \[ConfigDict]\[pydantic.config.ConfigDict]. # EvalFn Source: https://docs.fiddler.ai/sdk-api/evals/eval-fn Evaluator that wraps a user-provided function for dynamic evaluation. Evaluator that wraps a user-provided function for dynamic evaluation. This class allows users to create evaluators from any callable function, automatically handling parameter passing, validation, and result conversion to Score objects. Key Features: * **Dynamic Function Wrapping**: Converts any callable into an evaluator * **Argument Validation**: Validates that provided arguments match function signature * **Smart Result Conversion**: Automatically converts various return types to Score * **Error Handling**: Gracefully handles function execution and argument errors * **Parameter Flexibility**: Supports functions with any parameter signature ## Parameters The callable function to wrap as an evaluator. Optional custom name for the score. If not provided, uses the function name. ## Example ```python theme={null} def equals(a, b): return a == b evaluator = EvalFn(equals, score_name="exact_match") score = evaluator.score(a="hello", b="hello") print(score.value) # 1.0 def length_check(text, min_length=5): return len(text) >= min_length evaluator = EvalFn(length_check) # Invalid arguments raise TypeError try: evaluator.score(wrong_param="value") except TypeError as e: print(f"Error: {e}") ``` ## *property* name ## score() Execute the wrapped function and convert result to Score. Calls the wrapped function with the provided arguments and converts the result to a Score object. Validates that the provided arguments match the function's signature. ### Parameters Positional arguments to pass to the wrapped function. Keyword arguments to pass to the wrapped function. Only kwargs that match the function's parameters are used. ### Returns A Score object representing the function's evaluation result. ### Raises **TypeError** – If the provided arguments don't match the function signature. The function result is converted to a Score as follows: * bool: 1.0 for True, 0.0 for False * int/float: Direct value conversion * Score: Returns as-is # evaluate Source: https://docs.fiddler.ai/sdk-api/evals/evaluate Evaluate a dataset using a task function and a list of evaluators. Evaluate a dataset using a task function and a list of evaluators. This is the main entry point for running evaluation experiments. It creates an experiment, runs the evaluation task on all dataset items, and executes the specified evaluators to generate scores. The function automatically: 1. Creates a new experiment with a unique name 2. Runs the evaluation task on each dataset item 3. Executes all evaluators on the task outputs 4. Returns comprehensive results with timing and error information Key Features: * **Automatic Experiment Creation**: Creates experiments with unique names * **Task Execution**: Runs custom evaluation tasks on dataset items * **Evaluator Orchestration**: Executes multiple evaluators on outputs * **Error Handling**: Gracefully handles task and evaluator failures * **Result Collection**: Returns detailed results with timing information * **Flexible Configuration**: Supports custom parameter mapping for evaluators * **Concurrent Processing**: Supports concurrent processing of dataset items Use Cases: * **Model Evaluation**: Evaluate LLM models on test datasets * **A/B Testing**: Compare different model versions or configurations * **Quality Assurance**: Validate model performance across different inputs * **Benchmarking**: Run standardized evaluations on multiple models ## Parameters The dataset containing test cases to evaluate. Function that processes dataset items and returns outputs. Must accept (inputs, extras, metadata) and return dict of outputs. List of evaluators to run on task outputs. Can include both Evaluator instances and callable functions. Optional prefix for the experiment name. If not provided, uses the dataset name as prefix. A unique ID is always appended. Optional description for the experiment. Optional metadata dictionary for the experiment. Optional evaluation-level mapping for transforming evaluator parameters. Maps parameter names to either string keys or transformation functions. This mapping has lower priority than evaluator-level mappings set in the evaluator constructor, allowing evaluators to define sensible defaults while still permitting customization at the evaluation level. Maximum number of workers to use for concurrent processing. Use more than 1 only if the eval task function is thread-safe. ## Returns Contains the experiment and list of ScoredExperimentItem objects, each containing the experiment item data and scores for one dataset item. ## Raises * **ValueError** – If dataset is empty or evaluators are invalid. * **RuntimeError** – If no connection is available for API calls. * **ApiError** – If there's an error creating the experiment or communicating with the Fiddler API. ## Example ```python theme={null} from fiddler_evals import evaluate from fiddler_evals.evaluators import AnswerRelevance, Conciseness, RegexSearch from fiddler_evals import Dataset # Get dataset dataset = Dataset.get_by_name("my-eval-dataset") # Define evaluation task def eval_task(inputs, extras, metadata): # Your model inference logic here question = inputs["question"] answer = my_model.generate(question) return {"answer": answer, "question": question} # Example 1: Basic evaluation with parameter mapping results = evaluate( dataset=dataset, task=eval_task, evaluators=[AnswerRelevance(), Conciseness()], name_prefix="my-model-eval", description="Evaluation of my model on Q&A dataset", metadata={"model_version": "v1.0", "temperature": 0.7}, score_fn_kwargs_mapping={ "output": "answer", "question": lambda x: x["inputs"]["question"] } ) # Example 2: Multiple evaluator instances with score_name_prefix for differentiation evaluators = [ RegexSearch( r"\d+", score_name_prefix="question", score_name="has_number", score_fn_kwargs_mapping={"output": "question"} ), RegexSearch( r"\d+", score_name_prefix="answer", score_name="has_number", score_fn_kwargs_mapping={"output": "answer"} ) ] results = evaluate( dataset=dataset, task=eval_task, evaluators=evaluators, score_fn_kwargs_mapping={ "question": lambda x: x["inputs"]["question"], # Note: "answer" mapping not needed since evaluator defines it } ) # Process results for result in results: item_id = result.experiment_item.dataset_item_id status = result.experiment_item.status print(f"Item {item_id}: {status}") for score in result.scores: print(f" {score.name}: {score.value} ({score.status})") ``` The function processes dataset items sequentially. For large datasets, consider implementing parallel processing or batch processing strategies. The experiment name is automatically made unique by appending datetime. Parameter Mapping Priority: When both evaluator-level and evaluation-level mappings are present, evaluator-level mappings take precedence. This allows evaluators to define sensible defaults while still permitting customization at the evaluation level. Mapping Priority (highest to lowest): 1. Evaluator-level score\_fn\_kwargs\_mapping (set in evaluator constructor) 2. Evaluation-level score\_fn\_kwargs\_mapping (passed to evaluate function) 3. Default parameter resolution # Evaluator Source: https://docs.fiddler.ai/sdk-api/evals/evaluator Abstract base class for creating custom evaluators in Fiddler Evals. Abstract base class for creating custom evaluators in Fiddler Evals. The Evaluator class provides a flexible framework for creating builtin and custom evaluators that can assess LLM outputs against various criteria. Each evaluator is responsible for a single, specific evaluation task (e.g., hallucination detection, answer relevance, exact match, etc.). Parameter Mapping: Evaluators can define their own parameter mappings using score\_fn\_kwargs\_mapping in the constructor. These mappings specify how data from the evaluation context (inputs, outputs, expected\_outputs) should be passed to the evaluator's score method.
Mapping Priority (highest to lowest): 1. Evaluator-level score\_fn\_kwargs\_mapping (set in constructor) 2. Evaluation-level kwargs\_mapping (passed to evaluate function) 3. Default parameter resolution
This allows evaluators to define sensible defaults while still permitting customization at the evaluation level. Creating Custom Evaluators: To create a custom evaluator, inherit from this class and implement the score method with parameters specific to your evaluation needs:
Example - Custom evaluator with parameter mapping: class ExactMatchEvaluator(Evaluator):
> def **init**(self, output\_key: str = "answer", score\_name\_prefix: str = None): > : super().**init**( > : score\_name\_prefix=score\_name\_prefix, > score\_fn\_kwargs\_mapping=\{"output": output\_key} > >
> > )
> def score(self, output: str, expected\_output: str) -> Score: > : is\_match = output.strip().lower() == expected\_output.strip().lower() > return Score( > >
> > > name=f"\{self.score\_name\_prefix}exact\_match", > > value=1.0 if is\_match else 0.0, > > reasoning=f"Match: \{is\_match}" > >
> > ) ## Parameters Optional prefix to prepend to score names. Useful for distinguishing scores when using multiple instances of the same evaluator on different fields or with different configurations. Optional mapping for parameter transformation. Maps parameter names to either string keys or transformation functions. This mapping takes precedence over evaluation-level mappings when running the evaluate method. The score method signature is intentionally flexible using \*args and \*\*kwargs to allow each evaluator to define its own parameter requirements. This design enables maximum flexibility while maintaining a consistent interface across all evaluators in the framework. Initialize the evaluator with parameter mapping configuration. ## Parameters Optional prefix to prepend to score names. Useful for distinguishing scores when using multiple instances of the same evaluator on different fields or with different configurations. Optional mapping for parameter transformation. Maps parameter names to either string keys or transformation functions. This mapping takes precedence over evaluation-level mappings when running the evaluate method. ## Example ```python theme={null} # Simple string mapping evaluator = MyEvaluator(score_fn_kwargs_mapping={"output": "answer"}) # Complex transformation function evaluator = MyEvaluator(score_fn_kwargs_mapping={ "question": lambda x: x["inputs"]["question"], "response": "answer" }) # Using score name prefix for multiple instances evaluator1 = RegexSearch(r"\d+", score_name_prefix="question") evaluator2 = RegexSearch(r"\d+", score_name_prefix="answer") # Results in scores named "question_has_number" and "answer_has_number" ``` ## Raises **ScoreFunctionInvalidArgs** – If the mapping contains invalid parameter names that don't match the evaluator's score method signature. ## *property* name ## *abstractmethod* score() Evaluate inputs and return a score or list of scores. This method must be implemented by all concrete evaluator classes. Each evaluator can define its own parameter signature based on what it needs for evaluation. Common parameter patterns: * Output-only: score(self, output: str) -> Score * Input-Output: score(self, input: str, output: str) -> Score * Comparison: score(self, output: str, expected\_output: str) -> Score * All parameters: score(self, input: str, output: str, context: list\[str]) -> Score ### Parameters Positional arguments specific to the evaluator's needs. ### Returns A single Score object or list of Score objects representing the evaluation results. Each Score should include: * name: The score name (e.g., "has\_zipcode") * evaluator\_name: The evaluator name (e.g., "RegexMatch") * value: The score value (typically 0.0 to 1.0) * status: SUCCESS, FAILED, or SKIPPED * reasoning: Optional explanation of the score * error: Optional error information if evaluation failed ### Raises * **ValueError** – If required parameters are missing or invalid. * **TypeError** – If parameters have incorrect types. * **Exception** – Any other evaluation-specific errors. # Experiment Source: https://docs.fiddler.ai/sdk-api/evals/experiment Represents an Experiment for tracking evaluation runs and results. Represents an Experiment for tracking evaluation runs and results. An Experiment is a single evaluation run of a test suite against a specific application/LLM/Agent version and evaluators. Experiments provide comprehensive tracking, monitoring, and result management for GenAI evaluation workflows, enabling systematic testing and performance analysis. Key Features: * **Evaluation Tracking**: Complete lifecycle tracking of evaluation runs * **Status Management**: Real-time status updates (PENDING, IN\_PROGRESS, COMPLETED, etc.) * **Dataset Integration**: Linked to specific datasets for evaluation * **Result Storage**: Comprehensive storage of results, metrics, and error information * **Error Handling**: Detailed error tracking with traceback information Experiment Lifecycle: 1. **Creation**: Create experiment with dataset and application references 2. **Execution**: Experiment runs evaluation against the dataset 3. **Monitoring**: Track status and progress in real-time 4. **Completion**: Retrieve results, metrics, and analysis 5. **Cleanup**: Archive or delete completed experiments ## Example ```python theme={null} # Use this class to list experiments = Experiment.list( application_id=application_id, dataset_id=dataset_id, ) ``` Experiments are permanent records of evaluation runs. Once created, the name cannot be changed, but metadata and description can be updated. Failed experiments retain error information for debugging and analysis. ## id ## name ## status ## created\_at ## updated\_at ## created\_by ## updated\_by ## project ## application ## dataset ## description ## error\_reason ## error\_message ## traceback ## duration\_ms ## metadata ## get\_app\_url() Get the application URL for this experiment ### Returns `str` ## *classmethod* get\_by\_id() Retrieve an experiment by its unique identifier. Fetches an experiment from the Fiddler platform using its UUID. This is the most direct way to retrieve an experiment when you know its ID. ### Parameters The unique identifier (UUID) of the experiment to retrieve. Can be provided as a UUID object or string representation. ### Returns The experiment instance with all metadata and configuration. ### Raises * **NotFound** – If no experiment exists with the specified ID. * **ApiError** – If there's an error communicating with the Fiddler API. ### Example ```python theme={null} # Get experiment by UUID experiment = Experiment.get_by_id(id_="550e8400-e29b-41d4-a716-446655440000") print(f"Retrieved experiment: {experiment.name}") print(f"Status: {experiment.status}") print(f"Created: {experiment.created_at}") print(f"Application: {experiment.application.name}") ``` This method makes an API call to fetch the latest experiment state from the server. The returned experiment instance reflects the current state in Fiddler. ## *classmethod* get\_by\_name() Retrieve an experiment by name within an application. Finds and returns an experiment using its name within the specified application. This is useful when you know the experiment name and application but not its UUID. Experiment names are unique within an application, making this a reliable lookup method. ### Parameters The name of the experiment to retrieve. Experiment names are unique within an application and are case-sensitive. The UUID of the application containing the experiment. Can be provided as a UUID object or string representation. ### Returns The experiment instance matching the specified name. ### Raises * **NotFound** – If no experiment exists with the specified name in the application. * **ApiError** – If there's an error communicating with the Fiddler API. ### Example ```python theme={null} # Get application instance application = Application.get_by_name(name="fraud-detection-app", project_id=project_id) # Get experiment by name within an application experiment = Experiment.get_by_name( name="fraud-detection-eval-v1", application_id=application.id ) print(f"Found experiment: {experiment.name} (ID: {experiment.id})") print(f"Status: {experiment.status}") print(f"Created: {experiment.created_at}") print(f"Dataset: {experiment.dataset.name}") ``` Experiment names are case-sensitive and must match exactly. Use this method when you have a known experiment name from configuration or user input. ## *classmethod* list() List all experiments in an application. Retrieves all experiments that the current user has access to within the specified application. Returns an iterator for memory efficiency when dealing with many experiments. ### Parameters The UUID of the application to list experiments from. Can be provided as a UUID object or string representation. The UUID of the dataset to list experiments from. Can be provided as a UUID object or string representation. ### Yields `Experiment` – Experiment instances for all accessible experiments in the application. ### Raises **ApiError** – If there's an error communicating with the Fiddler API. ### Returns `Iterator[Experiment]` ### Example ```python theme={null} # Get application instance application = Application.get_by_name(name="fraud-detection-app", project_id=project_id) dataset = Dataset.get_by_name(name="fraud-detection-tests", application_id=application.id) # List all experiments in an application for experiment in Experiment.list(application_id=application.id, dataset_id=dataset.id): print(f"Experiment: {experiment.name}") print(f" ID: {experiment.id}") print(f" Status: {experiment.status}") print(f" Created: {experiment.created_at}") print(f" Dataset: {experiment.dataset.name}") # Convert to list for counting and filtering experiments = list(Experiment.list(application_id=application.id, dataset_id=dataset.id )) print(f"Total experiments in application: {len(experiments)}") # Find experiments by status completed_experiments = [ exp for exp in Experiment.list(application_id=application.id, dataset_id=dataset.id) if exp.status == ExperimentStatus.COMPLETED ] print(f"Completed experiments: {len(completed_experiments)}") # Find experiments by name pattern eval_experiments = [ exp for exp in Experiment.list(application_id=application.id, dataset_id=dataset.id) if "eval" in exp.name.lower() ] print(f"Evaluation experiments: {len(eval_experiments)}") ``` This method returns an iterator for memory efficiency. Convert to a list with list(Experiment.list(application\_id)) if you need to iterate multiple times or get the total count. The iterator fetches experiments lazily from the API. ## *classmethod* create() Create a new experiment in an application. Creates a new experiment within the specified application on the Fiddler platform. The experiment must have a unique name within the application and will be linked to the specified dataset for evaluation. Note: It is not recommended to use this method directly. Instead, use the evaluate method. Creating and managing an experiment without evaluate wrapper is extremely advance usecase and should be avoided. ### Parameters Experiment name, must be unique within the application. The UUID of the application to create the experiment in. Can be provided as a UUID object or string representation. The UUID of the dataset to use for evaluation. Can be provided as a UUID object or string representation. Optional human-readable description of the experiment. Optional custom metadata dictionary for additional experiment information. ### Returns The newly created experiment instance with server-assigned fields. ### Raises * **Conflict** – If an experiment with the same name already exists in the application. * **ValidationError** – If the experiment configuration is invalid (e.g., invalid name format). * **ApiError** – If there's an error communicating with the Fiddler API. ### Example ```python theme={null} # Get application and dataset instances application = Application.get_by_name(name="fraud-detection-app", project_id=project_id) dataset = Dataset.get_by_name(name="fraud-detection-tests", application_id=application.id) # Create a new experiment for fraud detection evaluation experiment = Experiment.create( name="fraud-detection-eval-v1", application_id=application.id, dataset_id=dataset.id, description="Comprehensive evaluation of fraud detection model v1.0", metadata={"model_version": "1.0", "evaluation_type": "comprehensive", "baseline": "true"} ) print(f"Created experiment with ID: {experiment.id}") print(f"Status: {experiment.status}") print(f"Created at: {experiment.created_at}") print(f"Application: {experiment.application.name}") print(f"Dataset: {experiment.dataset.name}") ``` After successful creation, the experiment instance is returned with server-assigned metadata. The experiment is immediately available for execution and monitoring. The initial status will be PENDING. ## *classmethod* get\_or\_create() Get an existing experiment by name or create a new one if it doesn't exist. This is a convenience method that attempts to retrieve an experiment by name within an application, and if not found, creates a new experiment with that name. Useful for idempotent experiment setup in automation scripts and deployment pipelines. ### Parameters The name of the experiment to retrieve or create. The UUID of the application to search/create the experiment in. Can be provided as a UUID object or string representation. The UUID of the dataset to use for evaluation. Can be provided as a UUID object or string representation. Optional human-readable description of the experiment. Optional custom metadata dictionary for additional experiment information. ### Returns Either the existing experiment with the specified name, or a newly created experiment if none existed. ### Raises * **ValidationError** – If the experiment name format is invalid. * **ApiError** – If there's an error communicating with the Fiddler API. ### Example ```python theme={null} # Get application and dataset instances application = Application.get_by_name(name="fraud-detection-app", project_id=project_id) dataset = Dataset.get_by_name(name="fraud-detection-tests", application_id=application.id) # Safe experiment setup - get existing or create new experiment = Experiment.get_or_create( name="fraud-detection-eval-v1", application_id=application.id, dataset_id=dataset.id, description="Comprehensive evaluation of fraud detection model v1.0", metadata={"model_version": "1.0", "evaluation_type": "comprehensive"} ) print(f"Using experiment: {experiment.name} (ID: {experiment.id})") # Idempotent setup in deployment scripts experiment = Experiment.get_or_create( name="llm-benchmark-eval", application_id=application.id, dataset_id=dataset.id, metadata={"baseline": "true"} ) # Use in configuration management model_versions = ["v1.0", "v1.1", "v2.0"] experiments = {} for version in model_versions: experiments[version] = Experiment.get_or_create( name=f"fraud-detection-eval-{version}", application_id=application.id, dataset_id=dataset.id, metadata={"model_version": version} ) ``` This method is idempotent - calling it multiple times with the same name and application\_id will return the same experiment. It logs when creating a new experiment for visibility in automation scenarios. ## update() Update experiment description, metadata, and status. Updates the experiment's description, metadata, and/or status. This method allows you to modify the experiment's configuration after creation, including updating the experiment status and error information for failed experiments. ### Parameters Optional new description for the experiment. If provided, replaces the existing description. Set to empty string to clear. Optional new metadata dictionary for the experiment. If provided, replaces the existing metadata completely. Use empty dict to clear. Optional new status for the experiment. Can be used to update experiment status (e.g., PENDING, RUNNING, COMPLETED, FAILED). Required when status is FAILED. The reason for the experiment failure. Required when status is FAILED. Detailed error message for the failure. Required when status is FAILED. Stack trace information for debugging. Optional duration in milliseconds for the experiment execution ### Returns The updated experiment instance with new metadata and configuration. ### Raises * **ValueError** – If no update parameters are provided (all are None) or if status is FAILED but error\_reason, error\_message, or traceback are missing. * **ValidationError** – If the update data is invalid (e.g., invalid metadata format). * **ApiError** – If there's an error communicating with the Fiddler API. ### Example ```python theme={null} # Get existing experiment experiment = Experiment.get_by_name(name="fraud-detection-eval-v1", application_id=application_id) # Update description and metadata updated_experiment = experiment.update( description="Updated comprehensive evaluation of fraud detection model v1.1", metadata={"model_version": "1.1", "evaluation_type": "comprehensive", "updated_by": "john_doe"} ) print(f"Updated experiment: {updated_experiment.name}") print(f"New description: {updated_experiment.description}") # Update only metadata experiment.update(metadata={"last_updated": "2024-01-15", "status": "active"}) # Update experiment status to completed experiment.update(status=ExperimentStatus.COMPLETED) # Mark experiment as failed with error details experiment.update( status=ExperimentStatus.FAILED, error_reason="Evaluation timeout", error_message="The evaluation process exceeded the maximum allowed time", traceback="Traceback (most recent call last): File evaluate.py, line 42..." ) # Clear description experiment.update(description="") # Batch update multiple experiments for experiment in Experiment.list(application_id=application_id): if experiment.status == ExperimentStatus.COMPLETED: experiment.update(metadata={"archived": "true"}) ``` This method performs a complete replacement of the specified fields. For partial updates, retrieve current values, modify them, and pass the complete new values. The experiment name and ID cannot be changed. When updating status to FAILED, all error-related parameters are required. ## delete() Delete the experiment. Permanently deletes the experiment and all associated data from the Fiddler platform. This action cannot be undone and will remove all experiment results, metrics, and metadata. ### Raises **ApiError** – If there's an error communicating with the Fiddler API. ### Example ```python theme={null} # Get existing experiment experiment = Experiment.get_by_name(name="fraud-detection-eval-v1", application_id=application_id) # Delete the experiment experiment.delete() print("Experiment deleted successfully") # Delete multiple experiments for experiment in Experiment.list(application_id=application_id): if experiment.status == ExperimentStatus.FAILED: print(f"Deleting failed experiment: {experiment.name}") experiment.delete() ``` This operation is irreversible. Once deleted, the experiment and all its associated data cannot be recovered. Consider archiving experiments instead of deleting them if you need to preserve historical data. ## add\_items() Add outputs of LLM/Agent/Application against dataset items to the experiment. Adds outputs of LLM/Agent/Application (task or target function) against dataset items to the experiment, representing individual test case outcomes. Each item contains the outputs of LLM/Agent/Application results, timing information, and status for a specific dataset item. ### Parameters List of NewExperimentItem instances containing outputs of LLM/Agent/Application against dataset items. Each item should include: * dataset\_item\_id: UUID of the dataset item being evaluated * outputs: Dictionary containing the outputs of the task function against dataset item * duration\_ms: Duration of the execution in milliseconds: * status: Status of the outputs of the task function / scoring against dataset item (PENDING, COMPLETED, FAILED, etc.) * error\_reason: Reason for failure, if applicable * error\_message: Detailed error message, if applicable ### Returns List of UUIDs for the newly created experiment items. ### Raises * **ValueError** – If the items list is empty. * **ValidationError** – If any item data is invalid (e.g., missing required fields). * **ApiError** – If there's an error communicating with the Fiddler API. ### Example ```python theme={null} # Get existing experiment experiment = Experiment.get_by_name(name="fraud-detection-eval-v1", application_id=application_id) # Create evaluation result items from fiddler_evals.pydantic_models.experiment import NewExperimentItem from datetime import datetime, timezone items = [ NewExperimentItem( dataset_item_id=dataset_item_id_1, outputs={"answer": "The watermelon seeds pass through your digestive system"}, duration_ms=1000, end_time=datetime.now(tz=timezone.utc), status="COMPLETED", error_reason=None, error_message=None ), NewExperimentItem( dataset_item_id=dataset_item_id_2, outputs={"answer": "The precise origin of fortune cookies is unclear"}, duration_ms=1000, end_time=datetime.now(tz=timezone.utc), status="COMPLETED", error_reason=None, error_message=None ) ] # Add items to experiment item_ids = experiment.add_items(items) print(f"Added {len(item_ids)} evaluation result items") print(f"Item IDs: {item_ids}") # Add items from evaluation results items = [ { "dataset_item_id": str(dataset_item_id), "outputs": {"answer": result["answer"]}, "duration_ms": result["duration_ms"], "end_time": result["end_time"], "status": "COMPLETED" } for result in items ] item_ids = experiment.add_items([NewExperimentItem(**item) for item in items]) # Batch add items with error handling try: item_ids = experiment.add_items(items) print(f"Successfully added {len(item_ids)} items") except ValueError as e: print(f"Validation error: {e}") except Exception as e: print(f"Failed to add items: {e}") ``` This method is typically used after running evaluations to store the results in the experiment. Each item represents the evaluation of a single dataset item and contains all relevant timing, output, and status information. ## get\_items() Retrieve all experiment result items from the experiment. Fetches all experiment result items (inputs, outputs, expected outputs, scores) that were generated by the task function against dataset items. Returns an iterator for memory efficiency when dealing with large experiments containing many result items. ### Returns Iterator of ExperimentResultItem instances for all result items in the experiment. ### Raises **ApiError** – If there's an error communicating with the Fiddler API. ### Example ```python theme={null} # Get existing experiment experiment = Experiment.get_by_name(name="fraud-detection-eval-v1", application_id=application_id) # Get all result items from the experiment for item in experiment.get_items(): print(f"Item ID: {item.id}") print(f"Dataset Item ID: {item.dataset_item_id}") print(f"Outputs: {item.outputs}") print(f"Status: {item.status}") print(f"Duration: {item.duration_ms}") if item.error_reason: print(f"Error: {item.error_reason} - {item.error_message}") print("---") # Convert to list for analysis all_items = list(experiment.get_items()) print(f"Total result items: {len(all_items)}") # Filter items by status completed_items = [ item for item in experiment.get_items() if item.status == "COMPLETED" ] print(f"Completed items: {len(completed_items)}") # Filter items by error status failed_items = [ item for item in experiment.get_items() if item.status == "FAILED" ] print(f"Failed items: {len(failed_items)}") # Process items in batches batch_size = 100 for i, item in enumerate(experiment.get_items()): if i % batch_size == 0: print(f"Processing batch {i // batch_size + 1}") # Process item... # Analyze outputs for item in experiment.get_items(): if item.outputs.get("confidence", 0) < 0.8: print(f"Low confidence item: {item.id}") ``` This method returns an iterator for memory efficiency. Convert to a list with list(experiment.get\_items()) if you need to iterate multiple times or get the total count. The iterator fetches items lazily from the API. ## add\_results() Add evaluation results to the experiment. Adds complete evaluation results to the experiment, including both the experiment item data (outputs, timing, status) and all associated evaluator scores. This method is typically used after running evaluations to store the complete results of the evaluation process for a batch of dataset items. This method will only append the results to the experiment. Note: It is not recommended to use this method directly. Instead, use the evaluate method. Creating and managing an experiment without evaluate wrapper is extremely advance usecase and should be avoided. ### Parameters List of ScoredExperimentItem instances containing: * experiment\_item: NewExperimentItem with outputs, timing, and status * scores: List of Score objects from evaluators for this item ### Returns Results are added to the experiment on the server. ### Raises * **ValueError** – If the items list is empty. * **ValidationError** – If any item data is invalid (e.g., missing required fields). * **ApiError** – If there's an error communicating with the Fiddler API. ### Example ```python theme={null} # Get existing experiment experiment = Experiment.get_by_name(name="fraud-detection-eval-v1", application_id=application_id) # Create experiment item with outputs experiment_item = NewExperimentItem( dataset_item_id=dataset_item.id, outputs={"prediction": "fraud", "confidence": 0.95}, duration_ms=1000, end_time=datetime.now(tz=timezone.utc), status="COMPLETED" ) # Create scores from evaluators scores = [ Score( name="accuracy", evaluator_name="AccuracyEvaluator", value=1.0, label="Correct", reasoning="Prediction matches ground truth" ), Score( name="confidence", evaluator_name="ConfidenceEvaluator", value=0.95, label="High", reasoning="High confidence in prediction" ) ] # Create result combining item and scores result = ScoredExperimentItem( experiment_item=experiment_item, scores=scores ) # Add results to experiment experiment.add_results([result]) ``` This method is typically called after running evaluations to store complete results. The results include both the experiment item data and all evaluator scores, providing a complete record of the evaluation process. # ExperimentItemStatus Source: https://docs.fiddler.ai/sdk-api/evals/experiment-item-status ExperimentItemStatus **Values:** * `SUCCESS` - SUCCESS * `FAILED` - FAILED * `SKIPPED` - SKIPPED # ExperimentStatus Source: https://docs.fiddler.ai/sdk-api/evals/experiment-status ExperimentStatus **Values:** * `PENDING` - PENDING * `IN_PROGRESS` - IN\_PROGRESS * `COMPLETED` - COMPLETED * `FAILED` - FAILED * `CANCELLED` - CANCELLED # FTLPromptSafety Source: https://docs.fiddler.ai/sdk-api/evals/ftl-prompt-safety Evaluator to assess prompt safety using Fiddler Centor Models. Evaluator to assess prompt safety using Fiddler Centor Models. The FTLPromptSafety evaluator uses Fiddler Centor Models to evaluate the safety of text prompts across multiple risk categories. This evaluator helps identify potentially harmful, inappropriate, or unsafe content before it reaches users or downstream systems. Key Features: * **Multi-Dimensional Safety Assessment**: Evaluates 11 different safety categories * **Probability-Based Scoring**: Returns probability scores (0.0-1.0) for each risk category * **Comprehensive Risk Coverage**: Covers illegal, hateful, harassing, and other harmful content * **Prompt Safety**: Uses the Centor Model for Safety, Fiddler's proprietary safety evaluation model * **Batch Scoring**: Returns multiple scores for comprehensive safety analysis Safety Categories Evaluated: * **illegal\_prob**: Probability of containing illegal content or activities * **hateful\_prob**: Probability of containing hate speech or discriminatory language * **harassing\_prob**: Probability of containing harassing or threatening content * **racist\_prob**: Probability of containing racist language or content * **sexist\_prob**: Probability of containing sexist language or content * **violent\_prob**: Probability of containing violent or graphic content * **sexual\_prob**: Probability of containing inappropriate sexual content * **harmful\_prob**: Probability of containing content that could cause harm * **unethical\_prob**: Probability of containing unethical or manipulative content * **jailbreaking\_prob**: Probability of containing prompt injection or jailbreaking attempts * **max\_risk\_prob**: Maximum risk probability across all categories Use Cases: * **Content Moderation**: Filtering user-generated content for safety * **Prompt Validation**: Ensuring user prompts are safe before processing * **AI Safety**: Protecting AI systems from harmful or manipulative inputs * **Compliance**: Meeting regulatory requirements for content safety * **Risk Assessment**: Evaluating potential risks in text content Scoring Logic: Each safety category returns a probability score between 0.0 and 1.0: * **0.0-0.3**: Low risk (safe content) * **0.3-0.7**: Medium risk (requires review) * **0.7-1.0**: High risk (likely unsafe content) ## Parameters * **text** (*str*) – The text prompt to evaluate for safety. * **score\_name\_prefix** (*str* *|* *None*) * **score\_fn\_kwargs\_mapping** (*ScoreFnKwargsMappingType* *|* *None*) ## Returns A list of Score objects, one for each safety category: * name: The safety category name (e.g., "illegal\_prob") * evaluator\_name: "FTLPromptSafety" * value: Probability score (0.0-1.0) for that category ## Raises **ValueError** – If the text is empty or None. ## Example ```python theme={null} from fiddler_evals.evaluators import FTLPromptSafety evaluator = FTLPromptSafety() ``` ```python theme={null} # Safe content scores = evaluator.score("What is the weather like today?") for score in scores: print(f"{score.name}: {score.value}") # illegal_prob: 0.01 # hateful_prob: 0.02 # harassing_prob: 0.01 # ... # Potentially unsafe content unsafe_scores = evaluator.score("How to hack into someone's computer?") for score in unsafe_scores: if score.value > 0.5: print(f"High risk detected: {score.name} = {score.value}") # Filter based on maximum risk max_risk_score = next(s for s in scores if s.name == "max_risk_prob") if max_risk_score.value > 0.7: print("Content flagged as potentially unsafe") ``` This evaluator is designed for prompt safety assessment and should be used as part of a comprehensive content moderation strategy. The probability scores should be interpreted in context and combined with other safety measures for robust content filtering. ## name *= 'ftl\_prompt\_safety'* ## score() Score the safety of a text prompt. ### Parameters The text prompt to evaluate for safety. ### Returns A list of Score objects, one for each safety category. # FTLResponseFaithfulness Source: https://docs.fiddler.ai/sdk-api/evals/ftl-response-faithfulness Evaluator to assess response faithfulness using Fiddler Centor Models. Evaluator to assess response faithfulness using Fiddler Centor Models. The FTLResponseFaithfulness evaluator uses Fiddler Centor Models to evaluate how faithful an LLM response is to the provided context. This evaluator helps ensure that responses accurately reflect the information in the source context and don't contain hallucinated or fabricated information. Key Features: * **Faithfulness Assessment**: Evaluates how well the response reflects the context * **Probability-Based Scoring**: Returns probability scores (0.0-1.0) for faithfulness * **Context-Response Alignment**: Compares response against provided context * **Faithfulness (Centor Model)**: Uses the Centor Model for Faithfulness, Fiddler's proprietary faithfulness evaluation model * **Hallucination Detection**: Identifies responses that go beyond the context Faithfulness Categories Evaluated: * **faithful\_prob**: Probability that the response is faithful to the context Use Cases: * **RAG Systems**: Ensuring responses stay grounded in retrieved context * **Document Q\&A**: Verifying answers are based on provided documents * **Fact-Checking**: Validating that responses don't contain fabricated information * **Content Validation**: Ensuring responses accurately reflect source material * **Hallucination Detection**: Identifying responses that go beyond the context Scoring Logic: The faithfulness score represents the probability that the response is faithful to the context: * **0.0-0.3**: Low faithfulness (likely contains hallucinated information) * **0.3-0.7**: Medium faithfulness (some information may not be grounded) * **0.7-1.0**: High faithfulness (response accurately reflects context) ## Parameters * **response** (*str*) – The LLM response to evaluate for faithfulness. * **context** (*str*) – The source context that the response should be faithful to. * **score\_name\_prefix** (*str* *|* *None*) * **score\_fn\_kwargs\_mapping** (*ScoreFnKwargsMappingType* *|* *None*) ## Returns A list of Score objects containing: * name: The faithfulness category name ("faithful\_prob") * evaluator\_name: "FTLResponseFaithfulness" * value: Probability score (0.0-1.0) for faithfulness ## Raises **ValueError** – If the response or context is empty or None. ## Example ```python theme={null} from fiddler_evals.evaluators import FTLResponseFaithfulness evaluator = FTLResponseFaithfulness() ``` ```python theme={null} # Faithful response context = "The capital of France is Paris. It is located in northern Europe." response = "Paris is the capital of France." scores = evaluator.score(response=response, context=context) for score in scores: print(f"{score.name}: {score.value}") # faithful_prob: 0.95 # Unfaithful response with hallucination context = "The capital of France is Paris." response = "The capital of France is Paris, and it has a population of 2.1 million people." scores = evaluator.score(response=response, context=context) for score in scores: print(f"{score.name}: {score.value}") # faithful_prob: 0.65 (population info not in context) # Highly unfaithful response context = "The capital of France is Paris." response = "The capital of France is London." scores = evaluator.score(response=response, context=context) for score in scores: print(f"{score.name}: {score.value}") # faithful_prob: 0.05 # Filter based on faithfulness threshold faithful_score = next(s for s in scores if s.name == "faithful_prob") if faithful_score.value < 0.7: print("Response flagged as potentially unfaithful") ``` This evaluator is designed for response faithfulness assessment and should be used in conjunction with other evaluation metrics for comprehensive response quality assessment. The probability scores should be interpreted in context and combined with other quality measures for robust response validation. ## name *= 'ftl\_response\_faithfulness'* ## score() Score the faithfulness of a response to its context. ### Parameters The LLM response to evaluate for faithfulness. The source context that the response should be faithful to. ### Returns A Score object for faithfulness probability. # FTLSecretDetection Source: https://docs.fiddler.ai/sdk-api/evals/ftl-secret-detection Evaluator to detect credentials, API keys, and tokens in text using Fiddler Centor Models. Evaluator to detect secrets and credentials in text using Fiddler Centor Models. The FTLSecretDetection evaluator scans text for API keys, tokens, and credentials using \~42 known credential formats and Shannon entropy analysis. This is a CPU-only pipeline — deterministic, low-latency, and requiring no GPU. Key Features: * **Pattern-based detection**: \~42 known credential formats across LLM providers, cloud platforms, source control, messaging, and developer tools (entropy-detected secrets are labeled `Possible Secret`) * **Entropy analysis**: Catches unknown or custom secrets that exceed entropy thresholds * **Fast**: CPU-only, sub-millisecond per token — no inference overhead Use Cases: * **Secret leakage detection**: Identify credentials in LLM prompts or responses * **Compliance auditing**: Scan text datasets for inadvertently captured credentials * **Data sanitization**: Locate and redact secrets in datasets before training or fine-tuning Scoring Logic: Unlike probability-based evaluators, FTLSecretDetection returns one `Score` per detected secret: * **No secrets detected**: Returns an empty list * **Secrets detected**: Returns one `Score` per detection, with `name` set to the secret type label and `value` set to `1.0` To retrieve character-level positions for redaction, use the REST API directly — see [Secret Detection tutorial](/developers/tutorials/guardrails/guardrails-secrets). ## Parameters * **text** (*str*) – The text to scan for secrets and credentials. * **score\_name\_prefix** (*str* *|* *None*) * **score\_fn\_kwargs\_mapping** (*ScoreFnKwargsMappingType* *|* *None*) ## Returns A list of Score objects, one per detected secret: * name: The secret type label (e.g., `"Anthropic API Key"`, `"AWS Access Key ID"`) * evaluator\_name: `"FTLSecretDetection"` * value: `1.0` for each detection (binary — present or absent) ## Raises **ValueError** – If the text is empty or None. ## Example ```python theme={null} from fiddler_evals.evaluators import FTLSecretDetection evaluator = FTLSecretDetection() ``` ```python theme={null} # Clean text — no secrets scores = evaluator.score("What is the weather like today?") print(f"Secrets found: {len(scores)}") # Secrets found: 0 # Text containing an API key scores = evaluator.score( "My Anthropic key is sk-ant-api03-abcdefghijklmnopqrstu" ) for score in scores: print(f"Detected: {score.name} (value={score.value})") # Detected: Anthropic API Key (value=1.0) # Check whether any secrets were found has_secrets = len(scores) > 0 secret_types = [score.name for score in scores] print(f"Secret types found: {secret_types}") # Secret types found: ['Anthropic API Key'] ``` FTLSecretDetection uses regex patterns and entropy thresholds — not an ML model. This means it has no false-negative rate for known credential formats (pattern match is exact), but may produce occasional false positives on high-entropy non-secret strings (e.g. UUIDs, git hashes, and base64-encoded data are explicitly excluded via allowlist). ## name *= 'ftl\_secret\_detection'* ## score() Scan a text string for secrets and credentials. ### Parameters The text to scan for secrets and credentials. ### Returns A list of Score objects, one per detected secret. Empty list if no secrets found. # Introduction Source: https://docs.fiddler.ai/sdk-api/evals/index Complete API reference for fiddler-evals [![PyPI](https://img.shields.io/pypi/v/fiddler-evals)](https://pypi.org/project/fiddler-evals/) ## Overview Complete API reference documentation for the fiddler-evals package. ## Components ### Connection Connection management and initialization * [Connection](/sdk-api/evals/connection) * [init](/sdk-api/evals/init) ### Entities Core entity classes for interacting with the platform * [Application](/sdk-api/evals/application) * [Dataset](/sdk-api/evals/dataset) * [Experiment](/sdk-api/evals/experiment) * [ExperimentItemStatus](/sdk-api/evals/experiment-item-status) * [ExperimentStatus](/sdk-api/evals/experiment-status) * [Project](/sdk-api/evals/project) ### Evaluators Built-in and custom evaluators for LLM assessment * [AnswerRelevance](/sdk-api/evals/answer-relevance) * [Coherence](/sdk-api/evals/coherence) * [Conciseness](/sdk-api/evals/conciseness) * [ContextRelevance](/sdk-api/evals/context-relevance) * [CustomJudge](/sdk-api/evals/custom-judge) * [CustomJudgeSpec](/sdk-api/evals/custom-judge-spec) * [EvalFn](/sdk-api/evals/eval-fn) * [Evaluator](/sdk-api/evals/evaluator) * [FTLPromptSafety](/sdk-api/evals/ftl-prompt-safety) * [FTLResponseFaithfulness](/sdk-api/evals/ftl-response-faithfulness) * [InputFieldSpec](/sdk-api/evals/input-field-spec) * [Message](/sdk-api/evals/message) * [OutputField](/sdk-api/evals/output-field) * [OutputFieldTransform](/sdk-api/evals/output-field-transform) * [RAGFaithfulness](/sdk-api/evals/rag-faithfulness) * [RegexMatch](/sdk-api/evals/regex-match) * [RegexSearch](/sdk-api/evals/regex-search) * [Sentiment](/sdk-api/evals/sentiment) * [TopicClassification](/sdk-api/evals/topic-classification) ### Pydantic Models Pydantic data models and validation schemas * [DatasetItem](/sdk-api/evals/dataset-item) * [NewDatasetItem](/sdk-api/evals/new-dataset-item) * [Score](/sdk-api/evals/score) * [ScoreStatus](/sdk-api/evals/score-status) ### Runner Evaluation execution and orchestration * [evaluate](/sdk-api/evals/evaluate) # init Source: https://docs.fiddler.ai/sdk-api/evals/init Initialize the Fiddler client with connection parameters and global configuration. Initialize the Fiddler client with connection parameters and global configuration. This function establishes a connection to the Fiddler platform and configures the global client state. It handles authentication, server compatibility validation, logging setup, and creates the singleton connection instance used throughout the client library. ## Parameters The base URL to your Fiddler platform instance Authentication token obtained from the Fiddler UI Credentials tab Dictionary mapping protocol to proxy URL for HTTP requests HTTP request timeout settings (float or tuple of connect/read timeouts) Whether to verify server's TLS certificate (default: True) Whether to validate server/client version compatibility (default: True) ## Raises * **ValueError** – If url or token parameters are empty * **IncompatibleClient** – If server version is incompatible with client version * **ConnectionError** – If unable to connect to the Fiddler platform ## Examples Basic initialization: ```python theme={null} import fiddler as fdl fdl.init( url="https://your-instance.fiddler.ai", token="your-api-key" ) ``` Initialization with custom timeout and proxy: ```python theme={null} fdl.init( url="https://your-instance.fiddler.ai", token="your-api-key", timeout=(10.0, 60.0), # 10s connect, 60s read timeout proxies={"https": "https://proxy.company.com:8080"} ) ``` Initialization for development with relaxed settings: ```python theme={null} fdl.init( url="https://your-instance.fiddler.ai", token="dev-token", verify=False, # Skip SSL verification validate=False, # Skip version compatibility check ) ``` The client implements automatic retry strategies for transient failures. Configure retry duration via FIDDLER\_CLIENT\_RETRY\_MAX\_DURATION\_SECONDS environment variable (default: 300 seconds). Logging is performed under the 'fiddler' namespace at INFO level. If no root logger is configured, a stderr handler is automatically attached unless auto\_attach\_log\_handler=False. # InputFieldSpec Source: https://docs.fiddler.ai/sdk-api/evals/input-field-spec Metadata for a template variable (input field). Metadata for a template variable (input field). Input fields define metadata for template variables: whether they're required, and optional title/description for documentation. ## title ## description ## required # Message Source: https://docs.fiddler.ai/sdk-api/evals/message A single message in a prompt template. A single message in a prompt template. ## role ## content # NewDatasetItem Source: https://docs.fiddler.ai/sdk-api/evals/new-dataset-item Model to create a new dataset Model to create a new dataset ## id ## inputs ## expected\_outputs ## metadata ## extras ## source\_name ## source\_id ## model\_config Configuration for the model, should be a dictionary conforming to \[ConfigDict]\[pydantic.config.ConfigDict]. # OutputField Source: https://docs.fiddler.ai/sdk-api/evals/output-field Schema for a single output field in the evaluation response. Schema for a single output field in the evaluation response. ## type ## choices ## description ## title ## transform ## default ## minimum ## maximum # OutputFieldTransform Source: https://docs.fiddler.ai/sdk-api/evals/output-field-transform Defines how to transform an LLM output field into a final output field. Defines how to transform an LLM output field into a final output field. Used for field renaming and value mapping, e.g., transforming `is_faithful: 'faithful'` to `label: 'yes'`. ## source\_field ## value\_map # Project Source: https://docs.fiddler.ai/sdk-api/evals/project Represents a project container for organizing GenAI Apps and resources. Represents a project container for organizing GenAI Apps and resources. A Project is the top-level organizational unit in Fiddler that groups related GenAI Applications, datasets, and monitoring configurations. Projects provide logical separation, access control, and resource management for GenAI App monitoring workflows. Key Features: * **GenAI Apps Organization**: Container for related GenAI apps * **Resource Isolation**: Separate namespaces prevent naming conflicts * **Access Management**: Project-level permissions and access control * **Monitoring Coordination**: Centralized monitoring and alerting configuration * **Lifecycle Management**: Coordinated creation, updates, and deletion of resources Project Lifecycle: 1. **Creation**: Create project with unique name within organization 2. **App creation**: Create GenAI applications with Application().create() 3. **Configuration**: Set up monitoring, alerts, and evaluators. 4. **Operations**: Publish logs, monitor performance, manage alerts 5. **Maintenance**: Update configurations 6. **Cleanup**: Delete project when no longer needed (removes all contained resources) ## Example ```python theme={null} # Create a new project for fraud detection models project = Project.create(name="fraud-detection-2024") print(f"Created project: {project.name} (ID: {project.id})") ``` Projects are permanent containers - once created, the name cannot be changed. Deleting a project removes all contained models, datasets, and configurations. Consider the organizational structure carefully before creating projects. ## id ## name ## created\_at ## updated\_at ## *classmethod* get\_by\_id() Retrieve a project by its unique identifier. Fetches a project from the Fiddler platform using its UUID. This is the most direct way to retrieve a project when you know its ID. ### Parameters The unique identifier (UUID) of the project to retrieve. Can be provided as a UUID object or string representation. ### Returns The project instance with all metadata and configuration. ### Raises * **NotFound** – If no project exists with the specified ID. * **ApiError** – If there's an error communicating with the Fiddler API. ### Example ```python theme={null} # Get project by UUID project = Project.get_by_id(id_="550e8400-e29b-41d4-a716-446655440000") print(f"Retrieved project: {project.name}") print(f"Created: {project.created_at}") ``` This method makes an API call to fetch the latest project state from the server. The returned project instance reflects the current state in Fiddler. ## *classmethod* get\_by\_name() Retrieve a project by name. Finds and returns a project using its name within the organization. This is useful when you know the project name but not its UUID. Project names are unique within an organization, making this a reliable lookup method. ### Parameters The name of the project to retrieve. Project names are unique within an organization and are case-sensitive. ### Returns The project instance matching the specified name. ### Raises * **NotFound** – If no project exists with the specified name in the organization. * **ApiError** – If there's an error communicating with the Fiddler API. ### Example ```python theme={null} # Get project by name project = Project.get_by_name(name="fraud-detection") print(f"Found project: {project.name} (ID: {project.id})") print(f"Created: {project.created_at}") # Get project for specific environment prod_project = Project.get_by_name(name="fraud-detection-prod") staging_project = Project.get_by_name(name="fraud-detection-staging") ``` Project names are case-sensitive and must match exactly. Use this method when you have a known project name from configuration or user input. ## *classmethod* list() List all projects in the organization. Retrieves all projects that the current user has access to within the organization. Returns an iterator for memory efficiency when dealing with many projects. ### Yields `Project` – Project instances for all accessible projects. ### Raises **ApiError** – If there's an error communicating with the Fiddler API. ### Returns `Iterator[Project]` ### Example ```python theme={null} # List all projects for project in Project.list(): print(f"Project: {project.name}") print(f" ID: {project.id}") print(f" Created: {project.created_at}") # Convert to list for counting and filtering projects = list(Project.list()) print(f"Total accessible projects: {len(projects)}") # Find projects by name pattern prod_projects = [ p for p in Project.list() if "prod" in p.name.lower() ] print(f"Production projects: {len(prod_projects)}") # Get project summaries for project in Project.list(): print(f"{project.name}") ``` This method returns an iterator for memory efficiency. Convert to a list with list(Project.list()) if you need to iterate multiple times or get the total count. The iterator fetches projects lazily from the API. ## *classmethod* create() Create the project on the Fiddler platform. Persists this project instance to the Fiddler platform, making it available for adding GenAI Apps, configuring monitoring, and other operations. The project must have a unique name within the organization. ### Parameters Project name, must be unique within the organization. Should follow slug-like naming conventions: * Use lowercase letters, numbers, hyphens, and underscores * Start with a letter or number ### Returns This project instance, updated with server-assigned fields like ID, creation timestamp, and other metadata. ### Raises * **Conflict** – If a project with the same name already exists in the organization. * **ValidationError** – If the project configuration is invalid (e.g., invalid name format). * **ApiError** – If there's an error communicating with the Fiddler API. ### Example ```python theme={null} # Create a new project project = Project.create(name="customer-churn-analysis") print(f"Created project with ID: {project.id}") print(f"Created at: {project.created_at}") # Project is now available for adding GenAI Apps assert project.id is not None ``` After successful creation, the project instance is returned with server-assigned metadata. The project is immediately available for adding GenAI Apps and other resources. ## *classmethod* get\_or\_create() Get an existing project by name or create a new one if it doesn't exist. This is a convenience method that attempts to retrieve a project by name, and if not found, creates a new project with that name. Useful for idempotent project setup in automation scripts and deployment pipelines. ### Parameters The name of the project to retrieve or create. Must follow project naming conventions (slug-like format). ### Returns Either the existing project with the specified name, or a newly created project if none existed. ### Raises * **ValidationError** – If the project name format is invalid. * **ApiError** – If there's an error communicating with the Fiddler API. ### Example ```python theme={null} # Safe project setup - get existing or create new project = Project.get_or_create(name="fraud-detection-prod") print(f"Using project: {project.name} (ID: {project.id})") # Idempotent setup in deployment scripts project = Project.get_or_create(name="llm-pipeline-staging") # Use in configuration management environments = ["dev", "staging", "prod"] projects = {} for env in environments: projects[env] = Project.get_or_create(name=f"fraud-detection-{env}") ``` This method is idempotent - calling it multiple times with the same name will return the same project. It logs when creating a new project for visibility in automation scenarios. # RAGFaithfulness Source: https://docs.fiddler.ai/sdk-api/evals/rag-faithfulness Evaluator to assess if an LLM response is faithful to the provided context. Evaluator to assess if an LLM response is faithful to the provided context. The RAGFaithfulness evaluator measures whether a response is grounded in and consistent with the provided reference documents. This is crucial for RAG (Retrieval-Augmented Generation) pipelines to detect hallucinations and ensure responses don't include information not present in the context. Key Features: * **Faithfulness Assessment**: Determines if the response is supported by context * **Binary Scoring**: Returns 1.0 (faithful) or 0.0 (not faithful) * **Hallucination Detection**: Identifies when responses include unsupported claims * **Detailed Reasoning**: Provides explanation for the faithfulness assessment * **Fiddler API Integration**: Uses Fiddler's built-in faithfulness evaluation model Use Cases: * **RAG Systems**: Detecting hallucinations in generated responses * **Document Q\&A**: Ensuring answers are grounded in source documents * **Customer Support**: Verifying responses align with knowledge base * **Legal/Medical AI**: Critical applications requiring factual accuracy * **Content Generation**: Ensuring generated content matches source material Scoring Logic: * **1.0 (Faithful)**: Response is fully supported by the reference documents * **0.0 (Not Faithful)**: Response contains information not in the documents or contradicts the documents ## Parameters * **user\_query** (*str*) – The question or query being asked. * **rag\_response** (*str*) – The LLM's response to evaluate. * **retrieved\_documents** (*list* \*\[\**str* *]*) – The reference documents to check against. * **model** (*str*) * **credential** (*str* *|* *None*) * **kwargs** (*Any*) ## Returns A Score object containing: * value: 1.0 if faithful, 0.0 if not faithful * label: "yes" or "no" * reasoning: Detailed explanation of the assessment ## Example ```python theme={null} from fiddler_evals.evaluators import RAGFaithfulness evaluator = RAGFaithfulness(model="openai/gpt-4o") # Faithful response score = evaluator.score( user_query="What is the capital of France?", rag_response="According to the document, Paris is the capital of France.", retrieved_documents=[ "Paris is the capital and largest city of France.", "France is located in Western Europe." ] ) print(f"Faithful: {score.label}") # "yes" print(f"Score: {score.value}") # 1.0 # Unfaithful response (hallucination) score = evaluator.score( user_query="What is the capital of France?", rag_response="Paris is the capital of France with a population of 12 million.", retrieved_documents=[ "Paris is the capital of France." # Note: population is not mentioned in documents ] ) print(f"Faithful: {score.label}") # "no" ``` This evaluator uses Fiddler's built-in faithfulness assessment model and requires an active connection to the Fiddler API. The evaluator checks if the response is supported by the documents, not whether the response correctly answers the question. ## name *= 'rag\_faithfulness'* ## score() Score the faithfulness of a response to the provided context. ### Parameters The question or query being asked. The LLM's response to evaluate. The reference documents to check against. ### Returns A Score object containing: * value: 1.0 if faithful, 0.0 if not faithful * label: "yes" or "no" * reasoning: Detailed explanation of the assessment # RegexMatch Source: https://docs.fiddler.ai/sdk-api/evals/regex-match Regex match attempts to match the regex pattern only at the beginning Regex match attempts to match the regex pattern only at the beginning of the string. ## *property* match\_fn Match function to use for the regex evaluator. # RegexSearch Source: https://docs.fiddler.ai/sdk-api/evals/regex-search Regex search scans the entire string from beginning to end, looking for the Regex search scans the entire string from beginning to end, looking for the first occurrence where the regex pattern matches. ## *property* match\_fn Match function to use for the regex evaluator. # Score Source: https://docs.fiddler.ai/sdk-api/evals/score A single output of an evaluator. A single output of an evaluator. ## name ## evaluator\_name ## value ## label ## status ## reasoning ## error\_reason ## error\_message ## model\_config Configuration for the model, should be a dictionary conforming to \[ConfigDict]\[pydantic.config.ConfigDict]. # ScoreStatus Source: https://docs.fiddler.ai/sdk-api/evals/score-status The status of a score. The status of a score. **Values:** * `SUCCESS` - SUCCESS * `FAILED` - FAILED * `SKIPPED` - SKIPPED # Sentiment Source: https://docs.fiddler.ai/sdk-api/evals/sentiment Evaluator to assess text sentiment using Fiddler's sentiment analysis model. Evaluator to assess text sentiment using Fiddler's sentiment analysis model. The Sentiment evaluator uses Fiddler's implementation of the cardiffnlp/twitter-roberta-base-sentiment-latest model to evaluate the sentiment polarity of text content. This evaluator helps identify the emotional tone and attitude expressed in text, providing both sentiment labels and confidence scores for sentiment classification. Key Features: * **Sentiment Classification**: Evaluates text for positive, negative, or neutral sentiment * **Dual Score Output**: Returns both sentiment label and probability confidence * **Fiddler Integration**: Leverages Fiddler's optimized sentiment evaluation model * **Multi-Score Output**: Returns both sentiment label and probability scores Sentiment Categories Evaluated: * **sentiment**: The predicted sentiment label (positive, negative, neutral) * **sentiment\_prob**: Probability score (0.0-1.0) for the predicted sentiment Use Cases: * **Social Media Monitoring**: Analyzing sentiment in tweets, posts, and comments * **Customer Feedback Analysis**: Understanding customer satisfaction and opinions * **Brand Monitoring**: Tracking public sentiment about products or services * **Content Moderation**: Identifying emotionally charged or problematic content * **Market Research**: Analyzing public opinion and sentiment trends Scoring Logic: The sentiment evaluation provides two complementary scores: * **sentiment**: The predicted sentiment label
> * "positive": Text expresses positive emotions or opinions > * "negative": Text expresses negative emotions or opinions > * "neutral": Text expresses neutral or balanced sentiment * **sentiment\_prob**: Confidence score (0.0-1.0) for the prediction * **0.0-0.3**: Low confidence in sentiment prediction * **0.3-0.7**: Medium confidence in sentiment prediction * **0.7-1.0**: High confidence in sentiment prediction ## Parameters * **text** (*str*) – The text content to evaluate for sentiment. * **score\_name\_prefix** (*str* *|* *None*) * **score\_fn\_kwargs\_mapping** (*ScoreFnKwargsMappingType* *|* *None*) ## Returns A list of Score objects containing: * sentiment: Score object with sentiment label (positive/negative/neutral) * sentiment\_prob: Score object with probability score (0.0-1.0) ## Raises **ValueError** – If the text is empty or None, or if no scores are returned from the API. ## Example ```python theme={null} from fiddler_evals.evaluators import Sentiment evaluator = Sentiment() ``` ```python theme={null} # Positive sentiment scores = evaluator.score("I love this product! It's amazing!") print(f"Sentiment: {scores[0].label}") print(f"Confidence: {scores[1].value}") # Sentiment: positive # Confidence: 0.95 # Negative sentiment negative_scores = evaluator.score("This is terrible and disappointing!") print(f"Sentiment: {negative_scores[0].label}") print(f"Confidence: {negative_scores[1].value}") # Sentiment: negative # Confidence: 0.88 # Neutral sentiment neutral_scores = evaluator.score("The weather is okay today.") print(f"Sentiment: {neutral_scores[0].label}") print(f"Confidence: {neutral_scores[1].value}") # Sentiment: neutral # Confidence: 0.72 # Filter based on sentiment and confidence if scores[0].label == "positive" and scores[1].value > 0.8: print("High confidence positive sentiment detected") ``` This evaluator is optimized for social media and informal text analysis using the cardiffnlp/twitter-roberta-base-sentiment-latest model. It performs best on short, conversational text similar to Twitter posts. For formal or academic text, consider using specialized sentiment analysis models. The dual-score output provides both categorical classification and confidence assessment for robust sentiment analysis workflows. ## name *= 'sentiment\_analysis'* ## score() Score the sentiment of text content. ### Parameters The text content to evaluate for sentiment. ### Returns A list of Score objects for sentiment label and probability. # TopicClassification Source: https://docs.fiddler.ai/sdk-api/evals/topic-classification Evaluator to classify text topics using Fiddler's zero-shot topic classification model. Evaluator to classify text topics using Fiddler's zero-shot topic classification model. The TopicClassification evaluator uses Fiddler's implementation of the mortizlaurer/roberta-base-zeroshot-v2-0-c model to classify text content into predefined topic categories. This evaluator helps identify the main subject matter or theme of text content, providing both topic labels and confidence scores for topic classification. Key Features: * **Topic Classification**: Classifies text into predefined topic categories * **Dual Score Output**: Returns both topic label and probability confidence * **Zero-Shot Model**: Uses mortizlaurer/roberta-base-zeroshot-v2-0-c for flexible topic classification * **Multi-Score Output**: Returns both topic name and probability scores Topic Categories Evaluated: * **top\_topic**: The predicted topic name from the provided topics list * **top\_topic\_prob**: Probability score (0.0-1.0) for the predicted topic Use Cases: * **Content Categorization**: Automatically organizing content by topic * **Document Classification**: Sorting documents by subject matter * **News Analysis**: Categorizing news articles by topic * **Customer Support**: Routing tickets by topic or issue type * **Content Moderation**: Identifying content themes for policy enforcement Scoring Logic: The topic classification provides two complementary scores: * **top\_topic**: The predicted topic name from the provided topics list
> * Selected from the topics provided during initialization > * Represents the most relevant topic for the input text * **top\_topic\_prob**: Confidence score (0.0-1.0) for the prediction * **0.0-0.3**: Low confidence in topic prediction * **0.3-0.7**: Medium confidence in topic prediction * **0.7-1.0**: High confidence in topic prediction ## Parameters List of topic categories to classify text into. ## Returns A list of Score objects containing: * top\_topic: Score object with predicted topic name * top\_topic\_prob: Score object with probability score (0.0-1.0) ## Raises **ValueError** – If the text is empty or None, or if no scores are returned from the API. ## Example ```python theme={null} from fiddler_evals.evaluators import TopicClassification evaluator = TopicClassification(topics=["technology", "sports", "politics", "entertainment"]) ``` ```python theme={null} # Technology topic scores = evaluator.score("The new AI model shows promising results in natural language processing.") print(f"Topic: {scores[0].label}") print(f"Confidence: {scores[1].value}") # Topic: technology # Confidence: 0.92 # Sports topic sports_scores = evaluator.score("The team won the championship with an amazing performance!") print(f"Topic: {sports_scores[0].label}") print(f"Confidence: {sports_scores[1].value}") # Topic: sports # Confidence: 0.88 # Politics topic politics_scores = evaluator.score("The new policy will affect millions of citizens.") print(f"Topic: {politics_scores[0].label}") print(f"Confidence: {politics_scores[1].value}") # Topic: politics # Confidence: 0.85 # Filter based on topic and confidence if scores[0].label == "technology" and scores[1].value > 0.8: print("High confidence technology topic detected") ``` This evaluator uses zero-shot classification, meaning it can classify text into any set of topics provided during initialization without requiring training data for those specific topics. The mortizlaurer/roberta-base-zeroshot-v2-0-c model is particularly effective for general-purpose topic classification across diverse domains. The dual-score output provides both categorical classification and confidence assessment for robust topic analysis workflows. ## name *= 'topic\_classification'* Initialize the TopicClassification evaluator. ### Parameters List of topic categories to classify text into. ### Raises **ValueError** – If the topics are empty or None. ## score() Score the topic classification of text content. ### Parameters The text content to evaluate for topic classification. ### Returns A list of Score objects for topic name and probability. # Overview Source: https://docs.fiddler.ai/sdk-api/index Complete SDK documentation and REST API reference for Fiddler AI Observability Platform. ## 🐍 Python Client SDK ### [Python Client SDK](/sdk-api/python-client/connection) Official Python SDK for comprehensive ML and LLM observability - monitor traditional ML models and LLM applications. **Key Features:** * Model onboarding and schema definition * Production event publishing (batch and streaming) * Baseline dataset management * Alert configuration * Custom metrics and segments **Use Cases:** * ML model monitoring (drift, performance, data quality) * Production data ingestion * Creating monitoring dashboards * Configuring alerts for model issues [**View Full Documentation →**](/sdk-api/python-client/connection) [**View Usage Guides →**](/developers/python-client-guides/installation-and-setup) *** ## 🎯 Agentic AI SDKs SDKs for monitoring, evaluating, and testing LLM applications and AI agents. ### [Fiddler Evals SDK](/sdk-api/evals/evaluate) Evaluate and test LLM outputs with built-in and custom metrics. **Key Features:** * Pre-built evaluators (faithfulness, toxicity, coherence, etc.) * Custom evaluation functions * Experiment tracking and comparison * Dataset management for test sets **Use Cases:** * LLM output quality assessment * A/B testing prompts and models * Regression testing for LLM changes * Custom evaluation metrics **Quick Start:** ```python theme={null} import fiddler as fdl # Initialize evaluator evaluator = fdl.AnswerRelevance() # Run evaluation result = evaluator.evaluate( question="What is Fiddler?", answer="Fiddler is an AI observability platform." ) ``` [**View Full Documentation →**](/sdk-api/evals/evaluate) *** ### [Fiddler OTel SDK](/sdk-api/otel/fiddler-client) Framework-agnostic OpenTelemetry instrumentation for any Python LLM or agent application. This is the foundation the LangChain, LangGraph, and Strands SDKs build on, and the canonical source for Fiddler's span attributes and conversation tracking. **Key Features:** * Framework-agnostic tracing for any Python LLM or agent code * `@trace` decorator and manual span wrappers (chain, generation, tool) * Conversation and session attribute tracking * Canonical Fiddler span attributes and span types * Custom span processor and JSONL capture for offline analysis **Use Cases:** * Instrumenting apps not built on LangChain, LangGraph, or Strands * Adding spans around arbitrary functions and workflows * Shared tracing primitives across Fiddler's framework SDKs **Quick Start:** ```python theme={null} from fiddler_otel import FiddlerClient, trace # Initialize once at startup (see FiddlerClient reference for options) client = FiddlerClient() # Capture a Fiddler span around any function @trace def generate_answer(question: str) -> str: return call_llm(question) ``` [**View Full Documentation →**](/sdk-api/otel/fiddler-client) *** ### [Fiddler LangGraph SDK](/sdk-api/langgraph/fiddler-client) [![PyPI](https://img.shields.io/pypi/v/fiddler-langgraph)](https://pypi.org/project/fiddler-langgraph/) Monitor LangGraph agents with distributed tracing and observability. **Key Features:** * Automatic LangGraph instrumentation * Distributed tracing for agent workflows * Span attributes for nodes and edges * Conversation and session tracking **Use Cases:** * Debugging multi-step agent workflows * Performance analysis of agent chains * Monitoring production LangGraph applications * Understanding agent decision paths **Quick Start:** ```python theme={null} from fiddler.langchain import LangGraphInstrumentor # Instrument your LangGraph app instrumentor = LangGraphInstrumentor() instrumentor.instrument() # Your LangGraph code runs normally # Traces are automatically sent to Fiddler ``` [**View Full Documentation →**](/sdk-api/langgraph/fiddler-client) *** ### [Fiddler LangChain SDK](/sdk-api/langchain/fiddler-lang-chain-instrumentor) Instrument [LangChain V1](https://docs.langchain.com/oss/python/langchain/overview) agents (the `create_agent` API and middleware pattern) and export OpenTelemetry traces to Fiddler. **Key Features:** * Automatic instrumentation of LangChain V1 agents * Drop-in agent middleware emitting LLM, tool, and chain spans * Retrieval context attachment via `set_llm_context` * Span and session attribute helpers **Use Cases:** * Monitoring production LangChain agents * Debugging multi-step chains and tool calls * Tracking retrieval context on LLM spans **Quick Start:** ```python theme={null} from fiddler_langchain import FiddlerLangChainInstrumentor # Call once before creating your agents FiddlerLangChainInstrumentor().instrument() # Agents created with langchain.agents.create_agent are now traced ``` [**View Full Documentation →**](/sdk-api/langchain/fiddler-lang-chain-instrumentor) *** ### [Fiddler Strands SDK](/sdk-api/strands/strands-agent-instrumentor) [![PyPI](https://img.shields.io/pypi/v/fiddler-strands)](https://pypi.org/project/fiddler-strands/) Monitor Strands Agents with native instrumentation. **Key Features:** * Strands Agent instrumentation * Session and conversation tracking * Span attributes for agent actions * Integration with Fiddler platform **Use Cases:** * Monitoring Strands production agents * Debugging Strands Agent workflows * Tracking agent performance metrics * Session-based analysis **Quick Start:** ```python theme={null} from fiddler.strands import StrandsAgentInstrumentor # Instrument Strands Agent instrumentor = StrandsAgentInstrumentor( model_id="my-strands-agent" ) instrumentor.instrument() ``` [**View Full Documentation →**](/sdk-api/strands/strands-agent-instrumentor) *** ### [Fiddler OTel JS SDK](/sdk-api/otel-js/fiddler-client) OpenTelemetry instrumentation for Fiddler AI observability in TypeScript and JavaScript applications. Captures LLM traces, conversation context, and span attributes. **Key Features:** * OpenTelemetry tracing for TypeScript and JavaScript apps * Isolated tracer provider with OTLP HTTP export to Fiddler * Manual span helpers (agent, generation, tool) * Span attribute and token-usage conventions **Use Cases:** * Instrumenting Node.js LLM and agent applications * Capturing traces from non-LangChain TypeScript code * Adding spans around arbitrary functions and workflows **Quick Start:** ```typescript theme={null} import { FiddlerClient } from '@fiddler-ai/otel'; // Initialize once at startup (see FiddlerClient reference for options) const client = new FiddlerClient(); ``` [**View Full Documentation →**](/sdk-api/otel-js/fiddler-client) *** ### [Fiddler LangGraph JS SDK](/sdk-api/langgraph-js/lang-graph-instrumentor) OpenTelemetry-based instrumentation for LangGraph JS applications. Mirrors the Python `fiddler-langgraph` SDK API for agentic workflows. **Key Features:** * Automatic instrumentation of LangGraph JS via the callback manager * Trace capture for agentic workflows * Conversation and session attribute tracking * LLM context helpers **Use Cases:** * Monitoring production LangGraph JS agents * Debugging agent workflows in Node.js * Conversation- and session-level analysis **Quick Start:** ```typescript theme={null} import { LangGraphInstrumentor } from '@fiddler-ai/langgraph'; // Instrument once at startup; LangGraph runs export to Fiddler new LangGraphInstrumentor().instrument(); ``` [**View Full Documentation →**](/sdk-api/langgraph-js/lang-graph-instrumentor) *** ### [Fiddler LangChain JS SDK](/sdk-api/langchain-js/lang-chain-instrumentor) LangChain JS instrumentation for Fiddler AI observability. Re-exports the callback handler and instrumentor from `@fiddler-ai/langgraph` under a LangChain-branded API, with no code changes to existing chains. **Key Features:** * Automatic trace capture for LangChain JS applications * No changes to existing chains * Conversation and session attribute tracking * LLM context helpers **Use Cases:** * Monitoring production LangChain JS applications * Adding observability to existing chains * Conversation- and session-level analysis **Quick Start:** ```typescript theme={null} import { LangChainInstrumentor } from '@fiddler-ai/langchain'; // Instrument once; existing chains are traced with no further changes new LangChainInstrumentor().instrument(); ``` [**View Full Documentation →**](/sdk-api/langchain-js/lang-chain-instrumentor) *** ## 🌐 REST API ### [REST API Reference](/sdk-api/rest-api) Complete HTTP API documentation for programmatic access to the Fiddler platform. **Use Cases:** * Non-Python integrations (Java, Go, JavaScript, etc.) * Custom CI/CD pipelines * Integration with existing monitoring systems * Webhook-based automation **Quick Start (cURL):** ```bash theme={null} # Publish events to Fiddler curl -X POST https://app.fiddler.ai/api/v1/events -H "Authorization: Bearer fid_..." -H "Content-Type: application/json" -d '{ "project": "fraud-detection", "model": "fraud_model_v1", "events": [...] }' ``` [**View Full REST API Documentation →**](/sdk-api/rest-api) **API Guides:** * [Alert Rules](/sdk-api/rest-api/alert-rules) * [Applications](/sdk-api/rest-api/applications) * [Attributes](/sdk-api/rest-api/attributes) * [Baselines](/sdk-api/rest-api/baseline) * [Custom Metrics](/sdk-api/rest-api/custom-metrics) * [Environments](/sdk-api/rest-api/environment) * [Evals](/sdk-api/rest-api/evals) * [Evaluation](/sdk-api/rest-api/evaluation) * [Evaluator Rules](/sdk-api/rest-api/evaluator-rules) * [Evaluators](/sdk-api/rest-api/evaluators) * [Events](/sdk-api/rest-api/events) * [Experiments](/sdk-api/rest-api/experiments) * [File Upload](/sdk-api/rest-api/file-upload) * [FQL Expressions](/sdk-api/rest-api/fql-expressions) * [GenAI Alert Rules](/sdk-api/rest-api/genai-alert-rules) * [Jobs](/sdk-api/rest-api/jobs) * [LLM Gateway](/sdk-api/rest-api/llm-gateway) * [Models](/sdk-api/rest-api/model) * [Projects](/sdk-api/rest-api/projects) * [Queries](/sdk-api/rest-api/queries) * [Segments](/sdk-api/rest-api/segments) * [Server Info](/sdk-api/rest-api/server-info) * [Spans](/sdk-api/rest-api/spans) * [User Access Keys](/sdk-api/rest-api/user-access-keys) * [Users](/sdk-api/rest-api/users) ### [Guardrails API Reference](/sdk-api/guardrails-api-reference) API endpoints for Fiddler guardrails. *** ## 🚀 Getting Started ### Choose Your SDK | Your Use Case | Recommended SDK | | -------------------------------------------- | --------------------------------------------------------------------------- | | **Monitor ML/LLM models and platform admin** | [Python Client SDK](/sdk-api/python-client/connection) | | **Evaluate and test LLM outputs** | [Fiddler Evals SDK](/sdk-api/evals/evaluate) | | **Instrument any Python LLM/agent app** | [Fiddler OTel SDK](/sdk-api/otel/fiddler-client) | | **Monitor LangGraph (Python) agents** | [Fiddler LangGraph SDK](/sdk-api/langgraph/fiddler-client) | | **Monitor LangChain (Python) agents** | [Fiddler LangChain SDK](/sdk-api/langchain/fiddler-lang-chain-instrumentor) | | **Monitor Strands agents** | [Fiddler Strands SDK](/sdk-api/strands/strands-agent-instrumentor) | | **Instrument any TypeScript/JS app** | [Fiddler OTel JS SDK](/sdk-api/otel-js/fiddler-client) | | **Monitor LangGraph JS apps** | [Fiddler LangGraph JS SDK](/sdk-api/langgraph-js/lang-graph-instrumentor) | | **Monitor LangChain JS apps** | [Fiddler LangChain JS SDK](/sdk-api/langchain-js/lang-chain-instrumentor) | | **Language-agnostic HTTP integration** | [REST API](/sdk-api/rest-api) | ### Installation **Python SDKs:** ```bash theme={null} # Python Client SDK pip install fiddler-client # Evals SDK pip install fiddler-evals # OTel SDK (framework-agnostic instrumentation) pip install fiddler-otel # LangGraph SDK pip install fiddler-langgraph # LangChain SDK pip install fiddler-langchain # Strands SDK pip install fiddler-strands ``` Fiddler follows the Python Software Foundation's support schedule for Python versions. See the [Python version support policy](/reference/python-support-policy) for details. **JavaScript / TypeScript SDKs:** ```bash theme={null} # OTel JS SDK npm install @fiddler-ai/otel # LangGraph JS SDK npm install @fiddler-ai/langgraph # LangChain JS SDK npm install @fiddler-ai/langchain ``` **REST API:** No installation required - use any HTTP client. *** ## 📚 Related Documentation * [**Developer Guides**](/developers/quick-starts/get-started-in-less-than-10-minutes) - Quick starts and tutorials * [**Integrations**](/integrations) - Connect with your ML stack * [**Product Documentation**](/) - Platform features and concepts *** ## 💡 Common Workflows ### ML Model & LLM App Monitoring Workflow 1. Install [Python Client SDK](/sdk-api/python-client/connection) 2. Define [model schema](/sdk-api/python-client/model-schema) 3. Upload [baseline dataset](/sdk-api/python-client/baseline) 4. [Publish production events](/sdk-api/rest-api/events) 5. Configure [alerts](/sdk-api/python-client/alert-rule) ### LLM Experiments Workflow 1. Install [Fiddler Evals SDK](/sdk-api/evals/evaluate) 2. Create a test dataset with the [Dataset API](/sdk-api/evals/dataset) 3. Define evaluators ([built-in](/sdk-api/evals/evaluator) or [custom](/sdk-api/evals/eval-fn)) 4. Run [experiments](/sdk-api/evals/experiment) and analyze results ### Agent Monitoring Workflow 1. Install the SDK for your framework — [LangGraph](/sdk-api/langgraph/fiddler-client), [LangChain](/sdk-api/langchain/fiddler-lang-chain-instrumentor), [Strands](/sdk-api/strands/strands-agent-instrumentor), or a JavaScript SDK ([OTel JS](/sdk-api/otel-js/fiddler-client), [LangGraph JS](/sdk-api/langgraph-js/lang-graph-instrumentor), [LangChain JS](/sdk-api/langchain-js/lang-chain-instrumentor)) 2. Instrument your agent application 3. Deploy to production 4. View traces and analytics in the Fiddler platform *** ## 📖 Additional Resources * [**GitHub Examples**](https://github.com/fiddler-labs/fiddler-examples) - Sample code and notebooks * [**SDK Changelog**](/changelog/python-sdk) - Latest SDK updates * [**Support Portal**](mailto:support@fiddler.ai) - Enterprise support * [**Community**](https://fiddler-community.slack.com) - Join our Slack community # addSessionAttributes Source: https://docs.fiddler.ai/sdk-api/langchain-js/add-session-attributes addSessionAttributes Key-value pairs to add to the session context. # CallbackManagerModule Source: https://docs.fiddler.ai/sdk-api/langchain-js/callback-manager-module Shape of the `@langchain/core/callbacks/manager` module export. Shape of the `@langchain/core/callbacks/manager` module export. Used by LangGraphInstrumentor.manuallyInstrument when the caller provides the module reference directly (e.g. in bundled environments where dynamic `import()` does not work). ## Properties ### `CallbackManager: CallbackManagerLike & Record` The CallbackManager class with configureSync or configure methods. # extractTextContent Source: https://docs.fiddler.ai/sdk-api/langchain-js/extract-text-content extractTextContent The message content in any supported format. The extracted text as a single string. # FiddlerCallbackHandler Source: https://docs.fiddler.ai/sdk-api/langchain-js/fiddler-callback-handler LangChain callback handler that creates Fiddler OTel spans for every LangChain callback handler that creates Fiddler OTel spans for every chain, LLM, tool, agent, and retriever lifecycle event. Can be used directly by passing it in the `callbacks` array of a LangChain/LangGraph invocation, or automatically injected via LangGraphInstrumentor. ## Properties ### `name: string` ## Methods ### `constructor(client: FiddlerClient)` An initialized FiddlerClient used to create spans. ### `handleAgentAction(action: AgentAction, runId: string)` Called when an agent is about to execute an action, with the action and the run ID. The agent action containing tool name and input. Run identifier to look up the span. ### `handleAgentEnd(action: AgentFinish, runId: string)` Called when an agent finishes execution, before it exits. with the final output and the run ID. The agent finish containing return values. Run identifier to look up the span. ### `handleChainEnd(outputs: ChainValues, runId: string)` Called at the end of a Chain run, with the outputs and the run ID. Output values produced by the chain. Run identifier to look up the span. ### `handleChainError(error: Error, runId: string)` Called if a Chain run encounters an error The error that occurred. Run identifier to look up the span. ### `handleChainStart(serialized: Serialized, inputs: ChainValues, runId: string, parentRunId?: string, tags?: string[], metadata?: Record)` Called at the start of a Chain run, with the chain name and inputs and the run ID. Serialized chain/runnable metadata. Input values passed to the chain. Unique run identifier. Parent run ID for nesting. LangChain tags (used for LangGraph node detection). LangChain metadata (agent name, node name, etc.). ### `handleChatModelStart(serialized: Serialized, messages: BaseMessage[][], runId: string, parentRunId?: string, extraParams?: Record, _tags?: string[], _metadata?: Record, runName?: string)` Called at the start of a Chat Model run, with the prompt(s) and the run ID. Serialized chat model metadata. 2D array of chat messages (outer = batches). Unique run identifier. Parent run ID for nesting. Additional invocation parameters. Optional explicit run name. ### `handleLLMEnd(output: LLMResult, runId: string)` Called at the end of an LLM/ChatModel run, with the output and the run ID. The LLMResult containing generations and usage. Run identifier to look up the span. ### `handleLLMError(error: Error, runId: string)` Called if an LLM/ChatModel run encounters an error The error that occurred. Run identifier to look up the span. ### `handleLLMStart(serialized: Serialized, prompts: string[], runId: string, parentRunId?: string, _extraParams?: Record, _tags?: string[], _metadata?: Record, runName?: string)` Called at the start of an LLM or Chat Model run, with the prompt(s) and the run ID. Serialized LLM metadata. Array of prompt strings. Unique run identifier. Parent run ID for nesting. Optional explicit run name. ### `handleRetrieverEnd(documents: { metadata?: unknown; pageContent?: string }[], runId: string)` Called when a retriever returns documents. Sets the concatenated page content as the tool output. Array of retrieved documents with `pageContent`. Run identifier to look up the span. ### `handleRetrieverError(error: Error, runId: string)` Called when a retriever throws an error. The error that occurred. Run identifier to look up the span. ### `handleRetrieverStart(serialized: Serialized, query: string, runId: string, parentRunId?: string)` Called when a retriever begins fetching documents. Creates a tool-type span with the retriever name and query. Serialized retriever metadata. The search query string. Unique run identifier. Parent run ID for nesting. ### `handleToolEnd(output: string, runId: string)` Called at the end of a Tool run, with the tool output and the run ID. Tool output (string or ToolMessage-like object). Run identifier to look up the span. ### `handleToolError(error: Error, runId: string)` Called if a Tool run encounters an error The error that occurred. Run identifier to look up the span. ### `handleToolStart(serialized: Serialized, input: string, runId: string, parentRunId?: string, _tags?: string[], _metadata?: Record, runName?: string)` Called at the start of a Tool run, with the tool name and input and the run ID. Serialized tool metadata. The input string or structured input for the tool. Unique run identifier. Parent run ID for nesting. Optional explicit run name. # formatMessages Source: https://docs.fiddler.ai/sdk-api/langchain-js/format-messages formatMessages Array of message objects or strings. A newline-separated string of formatted messages. # getConversationId Source: https://docs.fiddler.ai/sdk-api/langchain-js/get-conversation-id getConversationId The active conversation ID, or `undefined` if none is set. # getLlmContext Source: https://docs.fiddler.ai/sdk-api/langchain-js/get-llm-context getLlmContext A LangChain chat model instance or invocation params object. The attached context string, or `undefined` if none is set. # getProviderFromModel Source: https://docs.fiddler.ai/sdk-api/langchain-js/get-provider-from-model getProviderFromModel Model identifier (e.g., "gpt-4", "claude-3-opus", "gemini-1.5-pro") Provider name (e.g., "openai", "anthropic", "google") # getSessionAttributes Source: https://docs.fiddler.ai/sdk-api/langchain-js/get-session-attributes getSessionAttributes A copy of the active session attributes map. # Introduction Source: https://docs.fiddler.ai/sdk-api/langchain-js/index Complete API reference for fiddler-langchain-js [![npm](https://img.shields.io/npm/v/@fiddler-ai/langchain)](https://www.npmjs.com/package/@fiddler-ai/langchain) ## Overview The `@fiddler-ai/langchain` package provides LangChain JS instrumentation for Fiddler AI observability. It re-exports the callback handler and instrumentor from `@fiddler-ai/langgraph` under a LangChain-branded API, enabling automatic trace capture for LangChain applications with zero code changes to existing chains. ```bash theme={null} npm install @fiddler-ai/langchain ``` ```typescript theme={null} import { LangChainInstrumentor, setConversationId } from '@fiddler-ai/langchain'; ``` ## Components ### Core The full LangChain JS instrumentation surface, re-exported from `@fiddler-ai/langgraph` under a LangChain-branded API. `LangChainInstrumentor` is the one-time setup and `FiddlerCallbackHandler` emits spans; the `setConversationId`, `setLlmContext`, and `addSessionAttributes` families propagate conversation, session, and retrieval context, while the remaining utilities handle message formatting and serialization. * [addSessionAttributes](/sdk-api/langchain-js/add-session-attributes) * [CallbackManagerModule](/sdk-api/langchain-js/callback-manager-module) * [extractTextContent](/sdk-api/langchain-js/extract-text-content) * [FiddlerCallbackHandler](/sdk-api/langchain-js/fiddler-callback-handler) * [formatMessages](/sdk-api/langchain-js/format-messages) * [getConversationId](/sdk-api/langchain-js/get-conversation-id) * [getLlmContext](/sdk-api/langchain-js/get-llm-context) * [getProviderFromModel](/sdk-api/langchain-js/get-provider-from-model) * [getSessionAttributes](/sdk-api/langchain-js/get-session-attributes) * [LangChainInstrumentor](/sdk-api/langchain-js/lang-chain-instrumentor) * [runWithContext](/sdk-api/langchain-js/run-with-context) * [safeStringify](/sdk-api/langchain-js/safe-stringify) * [setConversationId](/sdk-api/langchain-js/set-conversation-id) * [setLlmContext](/sdk-api/langchain-js/set-llm-context) * [truncate](/sdk-api/langchain-js/truncate) # LangChainInstrumentor Source: https://docs.fiddler.ai/sdk-api/langchain-js/lang-chain-instrumentor Auto-instruments LangChain/LangGraph by monkey-patching Auto-instruments LangChain/LangGraph by monkey-patching `CallbackManager._configureSync` (or `.configure`) to inject a FiddlerCallbackHandler into every invocation. **Node.js only** — requires `@langchain/core` as a peer dependency and uses `node:async_hooks` (via context) for context propagation. Uses a WeakSet to track patched modules so frozen ESM exports are handled correctly. ## Methods ### `constructor(client: FiddlerClient)` An initialized FiddlerClient used by the callback handler to create spans. ### `async instrument(): Promise` Auto-instrument by dynamically importing `@langchain/core/callbacks/manager`. ### `isInstrumented(): boolean` Check whether the instrumentor has successfully patched a `CallbackManager` module. `true` if auto-instrumentation is active. ### `manuallyInstrument(module: CallbackManagerModule)` Manually instrument a specific `@langchain/core/callbacks/manager` module. This is the recommended approach for bundled environments. The imported `@langchain/core/callbacks/manager` module. ### `uninstrument()` Remove the patch and restore the original `CallbackManager` behavior. Safe to call even if the instrumentor was never activated. # runWithContext Source: https://docs.fiddler.ai/sdk-api/langchain-js/run-with-context runWithContext The function to execute within the new context. The return value of `fn`. # safeStringify Source: https://docs.fiddler.ai/sdk-api/langchain-js/safe-stringify safeStringify The value to serialize. Maximum allowed length (defaults to MAX\_CONTENT\_LENGTH). A JSON string (possibly truncated), or empty string. # setConversationId Source: https://docs.fiddler.ai/sdk-api/langchain-js/set-conversation-id setConversationId Unique conversation or session identifier. # setLlmContext Source: https://docs.fiddler.ai/sdk-api/langchain-js/set-llm-context setLlmContext A LangChain chat model instance (e.g. `ChatOpenAI`). The context string to attach. # truncate Source: https://docs.fiddler.ai/sdk-api/langchain-js/truncate truncate The string to truncate. Maximum allowed length (defaults to MAX\_CONTENT\_LENGTH). The original string if short enough, or a truncated copy. # add_session_attributes Source: https://docs.fiddler.ai/sdk-api/langchain/add-session-attributes Add a session-level attribute that appears on all spans in the current context. Re-exported from [`fiddler_otel.attributes.add_session_attributes`](/sdk-api/otel/add-session-attributes). Add a session-level attribute that appears on all spans in the current context. The attribute is stored in a ContextVar that `FiddlerSpanProcessor` reads when spans are started. It is emitted as `fiddler.session.user.{key}` on every span created in the current thread or async coroutine, and is automatically propagated from parent spans to child spans. ## Parameters Logical attribute key. Will appear as `fiddler.session.user.{key}` in span attributes. Attribute value. Accepts `str`, `int`, `float`, or `bool`. Numeric values (`int`/`float`) are stored as numeric attributes and will appear in the `ValueFloat` column in ClickHouse, enabling range-based filtering and metrics. String and boolean values appear in the `ValueString` column and support categorical filtering (booleans are stored as `"true"` or `"false"`). ## Returns None Example: default from fiddler\_otel import add\_session\_attributes add\_session\_attributes("user\_id", "user\_12345") add\_session\_attributes("environment", "production") add\_session\_attributes("priority", 7) add\_session\_attributes("score", 0.95) See the [canonical reference](/sdk-api/otel/add-session-attributes) for the full description and examples. # add_span_attributes Source: https://docs.fiddler.ai/sdk-api/langchain/add-span-attributes Add custom span-level attributes to a specific LangChain component's metadata. Add custom span-level attributes to a specific LangChain component's metadata. Attributes are stored under the Fiddler metadata key on the component and read by [`FiddlerAgentMiddleware`](/sdk-api/langchain/fiddler-agent-middleware) when creating spans. Unlike `add_session_attributes()`, these are scoped to individual components and only applied to spans created for that component (e.g. a particular model, retriever, or tool). ## Parameters The LangChain component to annotate (modified in place). Accepts `BaseLanguageModel`, `BaseRetriever`, or `BaseTool` instances. Arbitrary key-value attributes. Keys matching known `FiddlerSpanAttributes` values are set directly; all others are prefixed with `fiddler.span.user.`. ## Returns None Example: default from langchain\_openai import ChatOpenAI from fiddler\_langchain import add\_span\_attributes llm = ChatOpenAI(model="gpt-4o") add\_span\_attributes(llm, model\_tier="premium", use\_case="summarization") # clear_llm_context Source: https://docs.fiddler.ai/sdk-api/langchain/clear-llm-context Remove LLM context from a language model instance. Remove LLM context from a language model instance. This is a convenience wrapper that calls `set_llm_context(llm, None)`. Use it in multi-step agent workflows after a RAG retrieval step to ensure subsequent non-RAG LLM calls (tool planning, routing, etc.) do not carry stale context and do not trigger faithfulness evaluation. The context is stored in the model's metadata and read by [`FiddlerAgentMiddleware`](/sdk-api/langchain/fiddler-agent-middleware) when creating LLM spans. ## Parameters The language model instance or binding to clear context from. ## Raises **TypeError** – If a `RunnableBinding` is provided but its bound object is not a `BaseLanguageModel`. ## Returns None Example: default from langchain\_openai import ChatOpenAI from fiddler\_langchain import set\_llm\_context, clear\_llm\_context llm = ChatOpenAI(model="gpt-4o") retrieved\_context = "Relevant documents joined as a single string..." rag\_prompt = "Answer the question using the context above." planning\_prompt = "Plan the next agent step." # Step 1: RAG retrieval -- attach context for faithfulness evaluation set\_llm\_context(llm, retrieved\_context) response = llm.invoke(rag\_prompt) # faithfulness evaluated # Step 2: Non-RAG planning -- clear context to skip faithfulness evaluation clear\_llm\_context(llm) plan = llm.invoke(planning\_prompt) # no faithfulness evaluation ## SEE ALSO `set_llm_context()` – Set or clear context on a language model instance. Passing `None` as the context value is equivalent to calling `clear_llm_context()`. # FiddlerAgentMiddleware Source: https://docs.fiddler.ai/sdk-api/langchain/fiddler-agent-middleware LangChain V1 middleware that instruments `create_agent` calls with Fiddler tracing. LangChain V1 middleware that instruments `create_agent` calls with Fiddler tracing. This middleware produces a clean, flat trace hierarchy for agents built with `langchain.agents.create_agent`: * One root **Agent** span (opened in `before_agent`, closed in `after_agent`) * One **LLM** child span per model invocation (`wrap_model_call` / `awrap_model_call`) * One **Tool** child span per tool invocation (`wrap_tool_call` / `awrap_tool_call`) All spans are written to Fiddler's isolated OpenTelemetry context so they do not interfere with any global tracer that may be active in the application. Concurrent invocations (async) are fully isolated: Python's `ContextVar` ensures each `agent.ainvoke()` task tracks its own root span independently. Usage: ```python theme={null} from langchain.agents import create_agent from fiddler_otel import FiddlerClient from fiddler_langchain import FiddlerAgentMiddleware client = FiddlerClient(api_key="...", application_id="...", url="...") agent = create_agent( model="openai:gpt-4o-mini", tools=[...], middleware=[FiddlerAgentMiddleware(client=client, agent_name="my_agent")], ) agent.invoke({"messages": [...]}) ``` ## Parameters The `FiddlerClient` instance. Label applied to the root Agent span. Defaults to `"agent"`. ## before\_agent() Opens a root Agent span at the start of each agent invocation. If the current context already has a Fiddler span (e.g. we are being invoked as a sub-agent from a tool call), the new agent span is created as a child of that span so the full multi-agent flow appears in a single trace. ### Returns `dict[str, Any] | None` ## after\_agent() Closes the root Agent span at the end of each agent invocation. ### Returns `dict[str, Any] | None` ## wrap\_model\_call() Wraps a synchronous model call with an LLM span. ### Returns `ModelResponse` ## *async* awrap\_model\_call() Wraps an asynchronous model call with an LLM span. ### Returns `ModelResponse` ## wrap\_tool\_call() Wraps a synchronous tool call with a Tool span. ### Returns `Any` ## *async* awrap\_tool\_call() Wraps an asynchronous tool call with a Tool span. ### Returns `Any` # FiddlerLangChainInstrumentor Source: https://docs.fiddler.ai/sdk-api/langchain/fiddler-lang-chain-instrumentor Auto-instrumentor for LangChain V1 agents. Auto-instrumentor for LangChain V1 agents. Monkey-patches `langchain.agents.create_agent` so that every agent created after [`instrument()`](#instrument) is called receives a [`FiddlerAgentMiddleware`](/sdk-api/langchain/fiddler-agent-middleware) automatically. Callers no longer need to pass `middleware=[FiddlerAgentMiddleware(...)]` to each `create_agent` call. When a call to `create_agent` includes a `name` argument (e.g. `name='flight_assistant'`), that name is used for the agent in traces. Otherwise, no agent name is set (empty string), so the agent is not labeled in the UI. If a call to `create_agent` already includes a [`FiddlerAgentMiddleware`](/sdk-api/langchain/fiddler-agent-middleware) instance in its `middleware` list, the instrumentor skips injection for that call so existing manual configurations are preserved. Note: Instrumentation persists for the lifetime of the application unless explicitly removed by calling uninstrument(). Calling instrument() multiple times is safe — it will not create duplicate middleware. Usage: ```python theme={null} import langchain.agents from fiddler_otel import FiddlerClient from fiddler_langchain import FiddlerLangChainInstrumentor client = FiddlerClient(api_key="...", application_id="...", url="...") instrumentor = FiddlerLangChainInstrumentor(client=client) instrumentor.instrument() # Use the module attribute (not a `from ... import` alias) so the call goes # through the patched version at run-time: agent = langchain.agents.create_agent(model=..., tools=[...]) agent.invoke({"messages": [...]}) # Remove instrumentation when done: instrumentor.uninstrument() ``` Note: `instrument()` patches the `langchain.agents` module attribute. If you prefer `from langchain.agents import create_agent`, call `instrument()` *before* that import so the local name is bound to the patched wrapper. ## Parameters The FiddlerClient instance. **Required**. ## Raises **RuntimeError** – If the FiddlerClient tracer cannot be initialized. ## instrument() Enable automatic instrumentation of LangChain V1 agents. Activates the instrumentor by patching `langchain.agents.create_agent` to automatically inject [`FiddlerAgentMiddleware`](/sdk-api/langchain/fiddler-agent-middleware) into all agent instances created afterwards. This method is idempotent — calling it multiple times has the same effect as calling it once. After activation, all newly created agents will automatically include Fiddler's middleware. ### Parameters Additional instrumentation configuration (currently unused). ### Example ```python theme={null} import langchain.agents from fiddler_otel import FiddlerClient from fiddler_langchain import FiddlerLangChainInstrumentor client = FiddlerClient(api_key="...", application_id="...", url="...") instrumentor = FiddlerLangChainInstrumentor(client=client) instrumentor.instrument() # Use module attribute so the patched version is called: agent = langchain.agents.create_agent(model=model, tools=[...]) # Check if instrumentation is active if instrumentor.is_instrumented_by_opentelemetry: print("Instrumentation is active") ``` ## uninstrument() Disable automatic instrumentation and restore original behavior. Deactivates the instrumentor by restoring the original `langchain.agents.create_agent` function. Agents created after calling this method will no longer have [`FiddlerAgentMiddleware`](/sdk-api/langchain/fiddler-agent-middleware) automatically injected. Note: This does not affect agents that were already created while instrumentation was active — those will retain their middleware. ### Parameters Additional uninstrumentation configuration (currently unused). ### Example ```python theme={null} instrumentor = FiddlerLangChainInstrumentor(client=client) instrumentor.instrument() # Create some agents (automatically instrumented) agent1 = create_agent(model=model, tools=[...]) # Deactivate instrumentation instrumentor.uninstrument() # New agents won't be instrumented agent2 = create_agent(model=model, tools=[...]) # agent1 still has the middleware, agent2 does not ``` ## instrumentation\_dependencies() Returns the package dependencies required for this instrumentor. ### Returns A collection of package dependency strings. # Introduction Source: https://docs.fiddler.ai/sdk-api/langchain/index Complete API reference for fiddler-langchain [![PyPI](https://img.shields.io/pypi/v/fiddler-langchain)](https://pypi.org/project/fiddler-langchain/) ## Overview Complete API reference documentation for the `fiddler-langchain` package, which instruments [LangChain V1](https://docs.langchain.com/oss/python/langchain/overview) agents (the `langchain.agents.create_agent` API and middleware pattern) and exports OpenTelemetry traces to Fiddler. ```bash theme={null} pip install fiddler-langchain ``` ```python theme={null} from fiddler_langchain import FiddlerLangChainInstrumentor ``` ## Components ### Attributes Span and session attribute helpers. `add_span_attributes` attaches component-scoped attributes to a specific model, retriever, or tool. `add_session_attributes` and `set_conversation_id` are re-exported from `fiddler-otel` and propagate through every span in the current trace context. * [add\_session\_attributes](/sdk-api/langchain/add-session-attributes) * [add\_span\_attributes](/sdk-api/langchain/add-span-attributes) * [set\_conversation\_id](/sdk-api/langchain/set-conversation-id) ### Tracing Instrumentation entry points and LLM context helpers. `FiddlerLangChainInstrumentor` is the one-time setup that wires the Fiddler exporter into LangChain; `FiddlerAgentMiddleware` is a drop-in agent middleware that emits spans for LLM, tool, and chain steps; `set_llm_context` and `clear_llm_context` attach and remove retrieval context (e.g. retrieved documents) on the active model so it appears on its LLM spans. * [clear\_llm\_context](/sdk-api/langchain/clear-llm-context) * [FiddlerAgentMiddleware](/sdk-api/langchain/fiddler-agent-middleware) * [FiddlerLangChainInstrumentor](/sdk-api/langchain/fiddler-lang-chain-instrumentor) * [set\_llm\_context](/sdk-api/langchain/set-llm-context) # set_conversation_id Source: https://docs.fiddler.ai/sdk-api/langchain/set-conversation-id Set the conversation ID for the current execution context. Re-exported from [`fiddler_otel.attributes.set_conversation_id`](/sdk-api/otel/set-conversation-id). Set the conversation ID for the current execution context. The conversation ID is propagated to all spans created in the current thread or async coroutine, allowing the Fiddler dashboard to filter and display the full ordered sequence of operations for a single conversation. This value persists until it is called again with a new ID. ## Parameters Unique identifier for the conversation session. ## Returns None Example: default import uuid from fiddler\_otel import set\_conversation\_id set\_conversation\_id(str(uuid.uuid4())) # All spans created in this thread or coroutine after this call # carry the same conversation\_id, until set\_conversation\_id is # called again with a new value. See the [canonical reference](/sdk-api/otel/set-conversation-id) for the full description and examples. # set_llm_context Source: https://docs.fiddler.ai/sdk-api/langchain/set-llm-context Set or clear additional context on a language model for inclusion in LLM spans. Set or clear additional context on a language model for inclusion in LLM spans. The context is stored in the model's metadata and read by [`FiddlerAgentMiddleware`](/sdk-api/langchain/fiddler-agent-middleware) when creating LLM spans. Supports both plain model instances and `RunnableBinding`. Passing `None` removes the context so that subsequent spans no longer carry it. This is useful in multi-step agent workflows where context set after a RAG step should not leak into later non-RAG LLM calls. ## Parameters The language model (or binding) to attach context to. The context string to attach, or `None` to clear. ## Raises **TypeError** – If a `RunnableBinding` is provided but its bound object is not a `BaseLanguageModel`. ## Returns None Example: default from langchain\_openai import ChatOpenAI from fiddler\_langchain import set\_llm\_context llm = ChatOpenAI(model="gpt-4o") set\_llm\_context(llm, "User prefers concise responses") # Clear context before non-RAG steps set\_llm\_context(llm, None) # addSessionAttributes Source: https://docs.fiddler.ai/sdk-api/langgraph-js/add-session-attributes addSessionAttributes Key-value pairs to add to the session context. # CallbackManagerModule Source: https://docs.fiddler.ai/sdk-api/langgraph-js/callback-manager-module Shape of the `@langchain/core/callbacks/manager` module export. Shape of the `@langchain/core/callbacks/manager` module export. Used by LangGraphInstrumentor.manuallyInstrument when the caller provides the module reference directly (e.g. in bundled environments where dynamic `import()` does not work). ## Properties ### `CallbackManager: CallbackManagerLike & Record` The CallbackManager class with configureSync or configure methods. # extractTextContent Source: https://docs.fiddler.ai/sdk-api/langgraph-js/extract-text-content extractTextContent The message content in any supported format. The extracted text as a single string. # FiddlerCallbackHandler Source: https://docs.fiddler.ai/sdk-api/langgraph-js/fiddler-callback-handler LangChain callback handler that creates Fiddler OTel spans for every LangChain callback handler that creates Fiddler OTel spans for every chain, LLM, tool, agent, and retriever lifecycle event. Can be used directly by passing it in the `callbacks` array of a LangChain/LangGraph invocation, or automatically injected via LangGraphInstrumentor. ## Properties ### `name: string` ## Methods ### `constructor(client: FiddlerClient)` An initialized FiddlerClient used to create spans. ### `handleAgentAction(action: AgentAction, runId: string)` Called when an agent decides to invoke a tool. Updates the existing agent span with the chosen tool name and input. The agent action containing tool name and input. Run identifier to look up the span. ### `handleAgentEnd(action: AgentFinish, runId: string)` Called when an agent produces its final answer. Updates the existing agent span with the return values. The agent finish containing return values. Run identifier to look up the span. ### `handleChainEnd(outputs: ChainValues, runId: string)` Called when a chain/graph node completes successfully. Output values produced by the chain. Run identifier to look up the span. ### `handleChainError(error: Error, runId: string)` Called when a chain/graph node throws an error. The error that occurred. Run identifier to look up the span. ### `handleChainStart(serialized: Serialized, inputs: ChainValues, runId: string, parentRunId?: string, tags?: string[], metadata?: Record)` Called when a LangChain chain/graph node begins execution. Creates a chain or `langgraph_node` span with input and agent identity attributes. Serialized chain/runnable metadata. Input values passed to the chain. Unique run identifier. Parent run ID for nesting. LangChain tags (used for LangGraph node detection). LangChain metadata (agent name, node name, etc.). ### `handleChatModelStart(serialized: Serialized, messages: BaseMessage[][], runId: string, parentRunId?: string, extraParams?: Record, _tags?: string[], _metadata?: Record, runName?: string)` Called when a chat model call begins (e.g. ChatOpenAI, ChatAnthropic). Creates an LLM span with model name, provider, system/user messages, and optional LLM context. Serialized chat model metadata. 2D array of chat messages (outer = batches). Unique run identifier. Parent run ID for nesting. Additional invocation parameters. Optional explicit run name. ### `handleLLMEnd(output: LLMResult, runId: string)` Called when an LLM call completes. Sets completion text and token usage attributes on the span. The LLMResult containing generations and usage. Run identifier to look up the span. ### `handleLLMError(error: Error, runId: string)` Called when an LLM call throws an error. The error that occurred. Run identifier to look up the span. ### `handleLLMStart(serialized: Serialized, prompts: string[], runId: string, parentRunId?: string, _extraParams?: Record, _tags?: string[], _metadata?: Record, runName?: string)` Called when a non-chat LLM call begins (e.g. completion models). Creates an LLM span with model name, provider, and prompt attributes. Serialized LLM metadata. Array of prompt strings. Unique run identifier. Parent run ID for nesting. Optional explicit run name. ### `handleRetrieverEnd(documents: { metadata?: unknown; pageContent?: string }[], runId: string)` Called when a retriever returns documents. Sets the concatenated page content as the tool output. Array of retrieved documents with `pageContent`. Run identifier to look up the span. ### `handleRetrieverError(error: Error, runId: string)` Called when a retriever throws an error. The error that occurred. Run identifier to look up the span. ### `handleRetrieverStart(serialized: Serialized, query: string, runId: string, parentRunId?: string)` Called when a retriever begins fetching documents. Creates a tool-type span with the retriever name and query. Serialized retriever metadata. The search query string. Unique run identifier. Parent run ID for nesting. ### `handleToolEnd(output: string, runId: string)` Called when a tool invocation completes successfully. Extracts the output content — handles both plain strings and LangGraph `ToolMessage` objects that carry a `.content` field. Tool output (string or ToolMessage-like object). Run identifier to look up the span. ### `handleToolError(error: Error, runId: string)` Called when a tool invocation throws an error. The error that occurred. Run identifier to look up the span. ### `handleToolStart(serialized: Serialized, input: string, runId: string, parentRunId?: string, _tags?: string[], _metadata?: Record, runName?: string)` Called when a tool invocation begins. Creates a tool span with the tool name and input. Serialized tool metadata. The input string or structured input for the tool. Unique run identifier. Parent run ID for nesting. Optional explicit run name. # formatMessages Source: https://docs.fiddler.ai/sdk-api/langgraph-js/format-messages formatMessages Array of message objects or strings. A newline-separated string of formatted messages. # getConversationId Source: https://docs.fiddler.ai/sdk-api/langgraph-js/get-conversation-id getConversationId The active conversation ID, or `undefined` if none is set. # getLlmContext Source: https://docs.fiddler.ai/sdk-api/langgraph-js/get-llm-context getLlmContext A LangChain chat model instance or invocation params object. The attached context string, or `undefined` if none is set. # getProviderFromModel Source: https://docs.fiddler.ai/sdk-api/langgraph-js/get-provider-from-model getProviderFromModel Model identifier (e.g. `"gpt-4"`, `"claude-3-opus"`, `"gemini-1.5-pro"`). Provider name (e.g. `"openai"`, `"anthropic"`, `"google"`). Returns `"unknown"` if no provider can be detected. # getSessionAttributes Source: https://docs.fiddler.ai/sdk-api/langgraph-js/get-session-attributes getSessionAttributes A copy of the active session attributes map. # Introduction Source: https://docs.fiddler.ai/sdk-api/langgraph-js/index Complete API reference for fiddler-langgraph-js [![npm](https://img.shields.io/npm/v/@fiddler-ai/langgraph)](https://www.npmjs.com/package/@fiddler-ai/langgraph) ## Overview The `@fiddler-ai/langgraph` package provides OpenTelemetry-based instrumentation for LangGraph JS applications, enabling automatic trace capture for agentic workflows monitored by Fiddler AI observability. Mirrors the Python `fiddler-langgraph` SDK API. ```bash theme={null} npm install @fiddler-ai/langgraph ``` ```typescript theme={null} import { LangGraphInstrumentor, setConversationId } from '@fiddler-ai/langgraph'; ``` ## Components ### Callback-Handler The LangChain callback handler that emits Fiddler spans. `FiddlerCallbackHandler` hooks into LangGraph/LangChain run-lifecycle events and translates them into OpenTelemetry spans. * [FiddlerCallbackHandler](/sdk-api/langgraph-js/fiddler-callback-handler) ### Context Conversation, session, and retrieval-context helpers. `setConversationId`/`getConversationId` tag spans with a conversation ID, `addSessionAttributes`/`getSessionAttributes` attach session-wide attributes, `setLlmContext`/`getLlmContext` attach retrieval context, and `runWithContext` scopes them to a callback. * [addSessionAttributes](/sdk-api/langgraph-js/add-session-attributes) * [getConversationId](/sdk-api/langgraph-js/get-conversation-id) * [getLlmContext](/sdk-api/langgraph-js/get-llm-context) * [getSessionAttributes](/sdk-api/langgraph-js/get-session-attributes) * [runWithContext](/sdk-api/langgraph-js/run-with-context) * [setConversationId](/sdk-api/langgraph-js/set-conversation-id) * [setLlmContext](/sdk-api/langgraph-js/set-llm-context) ### Instrumentor One-time instrumentation setup. `LangGraphInstrumentor` patches the LangChain callback manager (`CallbackManagerModule`) so every LangGraph run automatically emits Fiddler spans. * [CallbackManagerModule](/sdk-api/langgraph-js/callback-manager-module) * [LangGraphInstrumentor](/sdk-api/langgraph-js/lang-graph-instrumentor) ### Utils Internal helpers for span serialization and formatting -- message formatting (`formatMessages`, `extractTextContent`), provider detection (`getProviderFromModel`), and safe truncation/stringification (`truncate`, `safeStringify`). * [extractTextContent](/sdk-api/langgraph-js/extract-text-content) * [formatMessages](/sdk-api/langgraph-js/format-messages) * [getProviderFromModel](/sdk-api/langgraph-js/get-provider-from-model) * [safeStringify](/sdk-api/langgraph-js/safe-stringify) * [truncate](/sdk-api/langgraph-js/truncate) # LangGraphInstrumentor Source: https://docs.fiddler.ai/sdk-api/langgraph-js/lang-graph-instrumentor Auto-instruments LangChain/LangGraph by monkey-patching Auto-instruments LangChain/LangGraph by monkey-patching `CallbackManager._configureSync` (or `.configure`) to inject a FiddlerCallbackHandler into every invocation. **Node.js only** — requires `@langchain/core` as a peer dependency and uses `node:async_hooks` (via context) for context propagation. Uses a WeakSet to track patched modules so frozen ESM exports are handled correctly. ## Methods ### `constructor(client: FiddlerClient)` An initialized FiddlerClient used by the callback handler to create spans. ### `async instrument(): Promise` Auto-instrument by dynamically importing `@langchain/core/callbacks/manager` and patching its `CallbackManager`. ### `isInstrumented(): boolean` Check whether the instrumentor has successfully patched a `CallbackManager` module. `true` if auto-instrumentation is active. ### `manuallyInstrument(module: CallbackManagerModule)` Manually instrument a specific `@langchain/core/callbacks/manager` module reference. Use this in bundled environments (Webpack, esbuild, etc.) where dynamic `import()` of `@langchain/core` may not resolve correctly. The imported `@langchain/core/callbacks/manager` module. ### `uninstrument()` Remove the patch and restore the original `CallbackManager` behavior. Safe to call even if the instrumentor was never activated. # runWithContext Source: https://docs.fiddler.ai/sdk-api/langgraph-js/run-with-context runWithContext The function to execute within the new context. The return value of `fn`. # safeStringify Source: https://docs.fiddler.ai/sdk-api/langgraph-js/safe-stringify safeStringify The value to serialize. Maximum allowed length (defaults to MAX\_CONTENT\_LENGTH). A JSON string (possibly truncated), or empty string. # setConversationId Source: https://docs.fiddler.ai/sdk-api/langgraph-js/set-conversation-id setConversationId Unique conversation or session identifier. # setLlmContext Source: https://docs.fiddler.ai/sdk-api/langgraph-js/set-llm-context setLlmContext A LangChain chat model instance (e.g. `ChatOpenAI`). The context string to attach. # truncate Source: https://docs.fiddler.ai/sdk-api/langgraph-js/truncate truncate The string to truncate. Maximum allowed length (defaults to MAX\_CONTENT\_LENGTH). The original string if short enough, or a truncated copy. # add_session_attributes Source: https://docs.fiddler.ai/sdk-api/langgraph/add-session-attributes Add a session-level attribute that appears on all spans in the current context. Add a session-level attribute that appears on all spans in the current context. The attribute is stored in a ContextVar that `FiddlerSpanProcessor` reads when spans are started. It is emitted as `fiddler.session.user.{key}` on every span created in the current thread or async coroutine, and is automatically propagated from parent spans to child spans. ## Parameters Logical attribute key. Will appear as `fiddler.session.user.{key}` in span attributes. Attribute value. Accepts `str`, `int`, `float`, or `bool`. Numeric values (`int`/`float`) are stored as numeric attributes and will appear in the `ValueFloat` column in ClickHouse, enabling range-based filtering and metrics. String and boolean values appear in the `ValueString` column and support categorical filtering (booleans are stored as `"true"` or `"false"`). ## Returns None Example: default from fiddler\_otel import add\_session\_attributes add\_session\_attributes("user\_id", "user\_12345") add\_session\_attributes("environment", "production") add\_session\_attributes("priority", 7) add\_session\_attributes("score", 0.95) # add_span_attributes Source: https://docs.fiddler.ai/sdk-api/langgraph/add-span-attributes Add custom span-level attributes to a specific LangChain component's metadata. Add custom span-level attributes to a specific LangChain component's metadata. Attributes are stored in the component's metadata and automatically included in OTel spans when the component executes. Unlike session attributes, these are scoped to individual components. ## Parameters The LangChain component to annotate (modified in place). Arbitrary key-value attributes. Keys matching known `FiddlerSpanAttributes` values are set directly; all others are prefixed with `fiddler.span.user.`. ## Returns None Example: default from langchain\_openai import ChatOpenAI from fiddler\_langgraph import add\_span\_attributes llm = ChatOpenAI(model="gpt-4o") add\_span\_attributes(llm, model\_tier="premium", use\_case="summarization") # clear_llm_context Source: https://docs.fiddler.ai/sdk-api/langgraph/clear-llm-context Remove LLM context from a language model instance. Remove LLM context from a language model instance. This is a convenience wrapper that calls `set_llm_context(llm, None)`. Use it in multi-step agent workflows after a RAG retrieval step to ensure subsequent non-RAG LLM calls (tool planning, routing, etc.) do not carry stale context and do not trigger faithfulness evaluation. The context is stored in the model's metadata and read by [`LangGraphInstrumentor`](/sdk-api/langgraph/lang-graph-instrumentor) when creating LLM spans. ## Parameters The language model instance or binding to clear context from. ## Raises **TypeError** – If a `RunnableBinding` is provided but its bound object is not a `BaseLanguageModel`. ## Returns None Example: default from langchain\_openai import ChatOpenAI from fiddler\_langgraph import set\_llm\_context, clear\_llm\_context llm = ChatOpenAI(model="gpt-4o") retrieved\_context = "Relevant documents joined as a single string..." rag\_prompt = "Answer the question using the context above." planning\_prompt = "Plan the next agent step." # Step 1: RAG retrieval -- attach context for faithfulness evaluation set\_llm\_context(llm, retrieved\_context) response = llm.invoke(rag\_prompt) # faithfulness evaluated # Step 2: Non-RAG planning -- clear context to skip faithfulness evaluation clear\_llm\_context(llm) plan = llm.invoke(planning\_prompt) # no faithfulness evaluation ## SEE ALSO `set_llm_context()` – Set or clear context on a language model instance. Passing `None` as the context value is equivalent to calling `clear_llm_context()`. # FiddlerChain Source: https://docs.fiddler.ai/sdk-api/langgraph/fiddler-chain Wrapper for chain/workflow spans with semantic convention helpers. Re-exported from [`fiddler_otel.span_wrapper.FiddlerChain`](/sdk-api/otel/fiddler-chain). Wrapper for chain/workflow spans with semantic convention helpers. Initialize chain span wrapper. ## **enter**() Enter context and set chain type. ### Returns `FiddlerChain` See the [canonical reference](/sdk-api/otel/fiddler-chain) for the full description and examples. # FiddlerClient Source: https://docs.fiddler.ai/sdk-api/langgraph/fiddler-client The main client for instrumenting Generative AI applications with Fiddler observability. Re-exported from [`fiddler_otel.client.FiddlerClient`](/sdk-api/otel/fiddler-client). The main client for instrumenting Generative AI applications with Fiddler observability. This client configures and manages the OpenTelemetry tracer that sends telemetry data to the Fiddler platform for monitoring, analysis, and debugging of your AI agents and workflows. Flush on exit: A shutdown handler is registered via `atexit()` so that pending spans are flushed and the tracer is shut down when the process exits. For short scripts or critical workloads, call [`force_flush()`](#force_flush) and [`shutdown()`](#shutdown) explicitly (e.g. in a `try`/`finally` or signal handler) since `atexit` may not run in all environments (e.g. SIGKILL, fork). Asyncio: Tracing works in asyncio (context vars propagate across `await`). When shutting down from async code, use [`aflush()`](#async-aflush) and [`ashutdown()`](#async-ashutdown) so the event loop is not blocked; the sync [`force_flush()`](#force_flush) and [`shutdown()`](#shutdown) can block for up to the flush timeout. Context manager: Use `with FiddlerClient(...) as client:` to ensure [`shutdown()`](#shutdown) is called on exit (flush then shutdown; atexit is unregistered). AWS SageMaker Partner App: When running inside a SageMaker Partner Application, set the following environment variables to enable SigV4-signed OTLP export — no code changes are required: * `AWS_PARTNER_APP_AUTH=true` — opt-in trigger * `AWS_PARTNER_APP_ARN` — ARN of the SageMaker Partner Application resource * `AWS_PARTNER_APP_URL` — base URL of the partner app endpoint AWS credentials are resolved via the standard boto3 credential chain (IAM role inside a SageMaker runtime, `~/.aws/credentials`, instance profile, environment variables); no additional env vars are needed when running inside the partner-app sandbox. Install the `sagemaker` extra to enable this feature: ```python theme={null} pip install "fiddler-otel[sagemaker]" ``` In a SageMaker-managed runtime the package is pre-installed. Initialise the FiddlerClient. ## Parameters The unique identifier (UUID4) for the application. Must be a valid UUID4 (e.g. `550e8400-e29b-41d4-a716-446655440000`). Copy this from the **GenAI Applications** page in the Fiddler UI. Required in all modes — even when `otlp_enabled=False` — because the S3 connector uses it to route traces to the correct application. The API key for authenticating with the Fiddler backend. Required when `otlp_enabled=True` (the default). Not required when `otlp_enabled=False` (e.g. S3-routing mode) — omit or pass `''`. The base URL for your Fiddler instance (e.g. `https://your-instance.fiddler.ai`). Required when `otlp_enabled=True` (the default). Not required when `otlp_enabled=False` — omit or pass `''`. Must use `http` or `https` scheme. Controls whether traces are exported directly to the Fiddler OTLP endpoint. Set to `False` to disable all direct export to Fiddler — useful when traces must first be written to local files for S3 upload (offline / S3 routing mode). When `False`, `api_key` and `url` are not required and not validated. Defaults to `True`. **Note:** `console_tracer`, `jsonl_capture_enabled`, and `otlp_json_capture_enabled` are all independent of this flag and can be used in any combination. If `True`, span data is **also** printed to the console (stdout). This is **additive** — traces are still exported to Fiddler via OTLP (unless `otlp_enabled=False`). Setting this to `True` does **not** suppress or replace the OTLP export. Useful for local debugging to confirm spans are being created. Configuration for span limits, such as the maximum number of attributes or events. When `None` (default), OpenTelemetry automatically applies its standard defaults: * `max_attributes`: 128 (or `OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT` env var) * `max_events`: 128 (or `OTEL_SPAN_EVENT_COUNT_LIMIT` env var) * `max_links`: 128 (or `OTEL_SPAN_LINK_COUNT_LIMIT` env var) * `max_event_attributes`: 128 (or `OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT` env var) * `max_link_attributes`: 128 (or `OTEL_LINK_ATTRIBUTE_COUNT_LIMIT` env var) * `max_span_attribute_length`: None/unlimited (or `OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT` env var) Override these by passing a custom `SpanLimits` object or by setting the corresponding environment variables. The sampler for deciding which spans to record. Defaults to the parent-based always-on OpenTelemetry sampler (100% sampling). The compression algorithm for exporting traces. Can be `Compression.Gzip`, `Compression.Deflate`, or `Compression.NoCompression`. Only used when `otlp_enabled=True`. Defaults to `Compression.Gzip`. If `True`, span data is **also** saved to a local JSONL file in a custom Fiddler format. This is **additive** — OTLP export to Fiddler continues as normal (unless `otlp_enabled=False`). Setting this to `True` does **not** suppress the OTLP export. Useful for keeping a local copy of trace data. **Note:** This JSONL format is **not** compatible with the Fiddler S3 connector. For S3 ingestion use `otlp_json_capture_enabled=True` instead. Path to the JSONL file where trace data will be saved. Only used when `jsonl_capture_enabled=True`. Override with the `FIDDLER_JSONL_FILE` environment variable. If `True`, traces are written to local `.json` files in standard OTLP JSON format (`ExportTraceServiceRequest` envelope). Files are written to `otlp_json_output_dir`. This format is **directly compatible** with the Fiddler S3 connector — upload the generated files to S3 and the connector ingests them without any reformatting. This is **additive** relative to OTLP export; combine with `otlp_enabled=False` to write to files only (offline / S3 routing mode). Directory path where OTLP JSON files are written when `otlp_json_capture_enabled=True`. The directory is created automatically if it does not exist. Each batch of spans is written to a separate timestamped `.json` file. If `True`, large inline base64 content in span attributes is uploaded to S3 via `POST /v3/files/upload` and replaced with `fiddler-file://` URIs before the span is exported. This prevents trace loss at the 10MB Kafka span limit. Requires `otlp_enabled=True` (needs `url` and `api_key`). Defaults to `False`. ## Raises * **ValueError** – If `application_id` is not a valid UUID4. * **ValueError** – If `otlp_enabled=True` and `api_key` is empty or not provided. * **ValueError** – If `otlp_enabled=True` and `url` is empty, missing a scheme, or uses a scheme other than `http`/`https`. **Basic connection to your Fiddler instance**: ```python theme={null} client = FiddlerClient( application_id='YOUR_APPLICATION_ID', # UUID4, required in all modes api_key='YOUR_API_KEY', url='https://your-instance.fiddler.ai', ) ``` **High-volume applications with custom configuration**: ```python theme={null} from opentelemetry.sdk.trace import SpanLimits, sampling from opentelemetry.exporter.otlp.proto.http.trace_exporter import Compression client = FiddlerClient( application_id='YOUR_APPLICATION_ID', api_key='YOUR_API_KEY', url='https://your-instance.fiddler.ai', span_limits=SpanLimits( max_span_attributes=64, # Reduce from default 128 max_span_attribute_length=2048, # Limit from default None (unlimited) ), sampler=sampling.TraceIdRatioBased(0.1), # Sample 10% of traces compression=Compression.Gzip, ) ``` **Local development with console output** (traces still sent to Fiddler): ```python theme={null} # console_tracer=True prints spans to stdout AND continues to export to Fiddler. # It does NOT suppress OTLP export. client = FiddlerClient( application_id='00000000-0000-0000-0000-000000000000', api_key='dev-key', url='http://localhost:4318', console_tracer=True, ) ``` **Offline / S3 routing mode** (no data sent directly to Fiddler): ```python theme={null} # otlp_enabled=False → disables direct OTLP export; api_key and url not needed # otlp_json_capture_enabled=True → writes traces to local .json files in standard # OTLP JSON format (ExportTraceServiceRequest) # application_id is still required so the S3 connector routes traces correctly # # Upload files from otlp_json_output_dir to your S3 bucket. # The Fiddler S3 connector reads them directly with no reformatting required. client = FiddlerClient( application_id='YOUR_APPLICATION_ID', otlp_enabled=False, otlp_json_capture_enabled=True, otlp_json_output_dir='./fiddler_traces', # default: 'fiddler_traces' ) ``` ## **enter**() Context manager entry. ### Returns `FiddlerClient` ## **exit**() Context manager exit — flushes and shuts down the tracer provider. ## force\_flush() Flush pending spans to the exporter. ### Parameters Maximum time to wait for flush in milliseconds. ### Returns True if flush completed within the timeout, False otherwise. ## *async* aflush() Async version of [`force_flush()`](#force_flush). Runs the flush in a thread pool so the event loop is not blocked. ### Returns `bool` ## shutdown() Shut down the tracer provider after flushing pending spans. Safe to call multiple times. The atexit handler is unregistered on first call. ## *async* ashutdown() Async version of [`shutdown()`](#shutdown). Runs flush and shutdown in a thread pool so the event loop is not blocked. ## get\_tracer\_provider() Return the OpenTelemetry TracerProvider, initializing it on first call. ### Returns The configured TracerProvider. ### Raises **RuntimeError** – If initialization fails. ## update\_resource() Update the OTel resource with additional attributes. Must be called **before** [`get_tracer()`](#get_tracer) is invoked. ### Parameters Key-value pairs to merge into the resource. ### Raises **ValueError** – If the tracer has already been initialized. ## get\_tracer() Return an OTel tracer for creating spans. Initializes the tracer on the first call. ### Returns The OTel tracer instance. ### Raises **RuntimeError** – If tracer initialization fails. ## start\_as\_current\_span() Create a span using a context manager (automatic lifecycle management). ### Parameters Name for the span. Span type — `"span"`, `"generation"`, `"chain"`, or `"tool"`. ### Returns Span wrapper with context manager support. ## start\_span() Create a span with manual lifecycle control. Caller must call `span.end()`. ### Parameters Name for the span. Span type — `"span"`, `"generation"`, `"chain"`, or `"tool"`. ### Returns Span wrapper requiring an explicit `end()` call. See the [canonical reference](/sdk-api/otel/fiddler-client) for the full description and examples. # FiddlerGeneration Source: https://docs.fiddler.ai/sdk-api/langgraph/fiddler-generation Wrapper for LLM generation spans with semantic convention helpers. Re-exported from [`fiddler_otel.span_wrapper.FiddlerGeneration`](/sdk-api/otel/fiddler-generation). Wrapper for LLM generation spans with semantic convention helpers. Initialize LLM generation wrapper. ## **enter**() Enter context and set LLM type. ### Returns `FiddlerGeneration` ## set\_model() Set the LLM model name (gen\_ai.request.model). ## set\_system() Set the LLM system/provider (gen\_ai.system). ## set\_system\_prompt() Set the system prompt (gen\_ai.llm.input.system). ## set\_user\_prompt() Set the user prompt (gen\_ai.llm.input.user). ### Parameters Plain text string, or a list of content parts in OpenAI multimodal format (e.g. `[{'type': 'text', 'text': '...'}, {'type': 'image_url', 'image_url': {'url': 'data:...'}}]`). Lists are auto-serialized to JSON. ## set\_completion() Set the LLM completion/output (gen\_ai.llm.output). ## set\_usage() Set token usage information (gen\_ai.usage.\*). ### Parameters Number of input/prompt tokens. Number of output/completion tokens. Total tokens; computed from input + output when omitted. ## set\_context() Set additional context (gen\_ai.llm.context). ## set\_messages() Set input messages in OpenAI chat format (gen\_ai.input.messages). Accepts simple format: `[{'role': 'user', 'content': '...'}]` Auto-converts to OTel format with `parts`. ## set\_output\_messages() Set output messages in OpenAI chat format (gen\_ai.output.messages). Accepts simple format: `[{'role': 'assistant', 'content': '...'}]` Auto-converts to OTel format with `parts`. ## set\_tool\_definitions() Set available tool definitions for this LLM call (gen\_ai.tool.definitions). See the [canonical reference](/sdk-api/otel/fiddler-generation) for the full description and examples. # FiddlerSpan Source: https://docs.fiddler.ai/sdk-api/langgraph/fiddler-span Wrapper around OpenTelemetry span with simplified helper methods. Re-exported from [`fiddler_otel.span_wrapper.FiddlerSpan`](/sdk-api/otel/fiddler-span). Wrapper around OpenTelemetry span with simplified helper methods. Initialize wrapper around an OTel span or context manager. ## Parameters An OTel span or context manager. Optional `MediaUploader` for normalizing large base64 content before span export. ## **enter**() Enter context manager and start span. ### Returns `FiddlerSpan` ## **exit**() Exit context manager, record exceptions, and end span. ### Returns `Literal[False]` ## end() Explicitly end the span. Must be called when using start\_span(). ## set\_input() Set input data. Auto-serializes dicts/lists to JSON. ## set\_output() Set output data. Auto-serializes dicts/lists to JSON. ## set\_attribute() Set a custom attribute on the span. ## update() Bulk update multiple attributes. ## record\_exception() Record an exception on the span. ## set\_agent\_name() Set the agent name (gen\_ai.agent.name). ## set\_agent\_id() Set the agent ID (gen\_ai.agent.id). ## set\_conversation\_id() Set the conversation ID (gen\_ai.conversation.id). See the [canonical reference](/sdk-api/otel/fiddler-span) for the full description and examples. # FiddlerTool Source: https://docs.fiddler.ai/sdk-api/langgraph/fiddler-tool Wrapper for tool/function call spans with semantic convention helpers. Re-exported from [`fiddler_otel.span_wrapper.FiddlerTool`](/sdk-api/otel/fiddler-tool). Wrapper for tool/function call spans with semantic convention helpers. Initialize tool span wrapper. ## **enter**() Enter context and set tool type. ### Returns `FiddlerTool` ## set\_tool\_name() Set the tool/function name (gen\_ai.tool.name). ## set\_tool\_input() Set the tool input arguments (gen\_ai.tool.input). ## set\_tool\_output() Set the tool output/result (gen\_ai.tool.output). ## set\_tool\_definitions() Set available tool definitions (gen\_ai.tool.definitions). See the [canonical reference](/sdk-api/otel/fiddler-tool) for the full description and examples. # get_client Source: https://docs.fiddler.ai/sdk-api/langgraph/get-client Return the global FiddlerClient singleton (first created in this process). Re-exported from [`fiddler_otel.client.get_client`](/sdk-api/otel/get-client). Return the global FiddlerClient singleton (first created in this process). ## Returns The global client instance. ## Raises **RuntimeError** – If no FiddlerClient has been initialized. See the [canonical reference](/sdk-api/otel/get-client) for the full description and examples. # get_current_span Source: https://docs.fiddler.ai/sdk-api/langgraph/get-current-span Get the currently active span as a Fiddler wrapper (inside a traced function). Re-exported from [`fiddler_otel.decorators.get_current_span`](/sdk-api/otel/get-current-span). Get the currently active span as a Fiddler wrapper (inside a traced function). Retrieves the span from the current context and verifies it belongs to Fiddler's tracer to maintain isolation from other OpenTelemetry tracers. ## Parameters Wrapper type — `"span"`, `"generation"`, `"chain"`, or `"tool"`. ## Returns Current span wrapper, or None if no active Fiddler span exists. See the [canonical reference](/sdk-api/otel/get-current-span) for the full description and examples. # Introduction Source: https://docs.fiddler.ai/sdk-api/langgraph/index Complete API reference for fiddler-langgraph [![PyPI](https://img.shields.io/pypi/v/fiddler-langgraph)](https://pypi.org/project/fiddler-langgraph/) ## Overview Complete API reference documentation for the `fiddler-langgraph` package, which instruments [LangGraph](https://langchain-ai.github.io/langgraph/) (and the underlying LangChain callback system) and exports OpenTelemetry traces to Fiddler. ```bash theme={null} pip install fiddler-langgraph ``` ```python theme={null} from fiddler_langgraph import LangGraphInstrumentor ``` ## Components ### Instrumentation Native LangGraph APIs for tracing, attributes, and LLM context. `LangGraphInstrumentor` patches the LangChain callback manager so all LangGraph runs emit Fiddler spans. `add_span_attributes` attaches component-scoped attributes to a specific model, retriever, or tool. `set_llm_context` and `clear_llm_context` attach and remove retrieval context (e.g. retrieved documents) on the active model so it appears on its LLM spans. `add_session_attributes` adds an attribute that appears on every span in the current context, and `set_conversation_id` (re-exported from `fiddler-otel`) tags all spans in the current context with a conversation ID. * [add\_session\_attributes](/sdk-api/langgraph/add-session-attributes) * [add\_span\_attributes](/sdk-api/langgraph/add-span-attributes) * [clear\_llm\_context](/sdk-api/langgraph/clear-llm-context) * [LangGraphInstrumentor](/sdk-api/langgraph/lang-graph-instrumentor) * [set\_conversation\_id](/sdk-api/langgraph/set-conversation-id) * [set\_llm\_context](/sdk-api/langgraph/set-llm-context) ### Re Exported From Otel `fiddler-langgraph` re-exports the core `fiddler-otel` symbols so you only need to install one package. See the [Fiddler OTel SDK reference](/sdk-api/otel) for full details on each: `FiddlerClient` (the global client; required to construct `LangGraphInstrumentor`), `trace` (decorator that starts a Fiddler span around any function), `get_current_span` (return the active Fiddler span if any), `get_client` (return the global `FiddlerClient` instance), and the manual span wrappers `FiddlerChain`, `FiddlerGeneration`, `FiddlerSpan`, and `FiddlerTool`. * [FiddlerChain](/sdk-api/langgraph/fiddler-chain) * [FiddlerClient](/sdk-api/langgraph/fiddler-client) * [FiddlerGeneration](/sdk-api/langgraph/fiddler-generation) * [FiddlerSpan](/sdk-api/langgraph/fiddler-span) * [FiddlerTool](/sdk-api/langgraph/fiddler-tool) * [get\_client](/sdk-api/langgraph/get-client) * [get\_current\_span](/sdk-api/langgraph/get-current-span) * [trace](/sdk-api/langgraph/trace) # LangGraphInstrumentor Source: https://docs.fiddler.ai/sdk-api/langgraph/lang-graph-instrumentor An OpenTelemetry instrumentor for LangGraph applications. An OpenTelemetry instrumentor for LangGraph applications. Provides automatic instrumentation for applications built with LangGraph by monkey-patching LangChain's callback system to inject a custom callback handler that captures trace data. Once instrumented, all LangGraph operations automatically generate telemetry data. Instrumentation persists for the lifetime of the application unless explicitly removed by calling [`uninstrument()`](#uninstrument). Calling [`instrument()`](#instrument) multiple times is safe — it will not create duplicate handlers. Thread Safety: The instrumentation applies globally to the process and affects all threads. In concurrent environments (multi-threading, async), all contexts share the same instrumented callback system. **Basic usage**: ```python theme={null} from fiddler_langgraph import FiddlerClient, LangGraphInstrumentor client = FiddlerClient( application_id="...", api_key="...", url="https://your-instance.fiddler.ai", ) instrumentor = LangGraphInstrumentor(client=client) instrumentor.instrument() ``` **Removing instrumentation**: ```python theme={null} # Clean up instrumentation when shutting down instrumentor.uninstrument() ``` Initialise the LangGraphInstrumentor. ## Parameters The [`FiddlerClient`](/sdk-api/langgraph/fiddler-client) instance to use for tracing. ## Raises **ImportError** – If LangGraph is not installed or its version is incompatible. ## instrument() Instrument LangGraph by monkey-patching `BaseCallbackManager`. Calling this method multiple times is safe; subsequent calls are no-ops. ### Raises **ValueError** – If the tracer is not initialized in the FiddlerClient. ## uninstrument() Remove the instrumentation from LangGraph. # set_conversation_id Source: https://docs.fiddler.ai/sdk-api/langgraph/set-conversation-id Set the conversation ID for the current execution context. Re-exported from [`fiddler_otel.attributes.set_conversation_id`](/sdk-api/otel/set-conversation-id). Set the conversation ID for the current execution context. The conversation ID is propagated to all spans created in the current thread or async coroutine, allowing the Fiddler dashboard to filter and display the full ordered sequence of operations for a single conversation. This value persists until it is called again with a new ID. ## Parameters Unique identifier for the conversation session. ## Returns None Example: default import uuid from fiddler\_otel import set\_conversation\_id set\_conversation\_id(str(uuid.uuid4())) # All spans created in this thread or coroutine after this call # carry the same conversation\_id, until set\_conversation\_id is # called again with a new value. See the [canonical reference](/sdk-api/otel/set-conversation-id) for the full description and examples. # set_llm_context Source: https://docs.fiddler.ai/sdk-api/langgraph/set-llm-context Set or clear additional context information on a language model instance. Set or clear additional context information on a language model instance. The context is attached to all spans created for this model and is stored as `gen_ai.llm.context`. Supports both `BaseLanguageModel` instances and `RunnableBinding` objects. Passing `None` removes the context so that subsequent spans no longer carry it. This is useful in multi-step agent workflows where context set after a RAG step should not leak into later non-RAG LLM calls. ## Parameters The language model instance or binding. The context string to attach, or `None` to clear. ## Raises **TypeError** – If a `RunnableBinding` is provided but its bound object is not a `BaseLanguageModel`. ## Returns None Example: default from langchain\_openai import ChatOpenAI from fiddler\_langgraph import set\_llm\_context llm = ChatOpenAI(model="gpt-4o") set\_llm\_context(llm, "User prefers concise responses in Spanish") # Clear context before non-RAG steps set\_llm\_context(llm, None) # trace Source: https://docs.fiddler.ai/sdk-api/langgraph/trace Decorator for automatic function tracing with input/output capture. Re-exported from [`fiddler_otel.decorators.trace`](/sdk-api/otel/trace). Decorator for automatic function tracing with input/output capture. Uses the global FiddlerClient when `client=` is not passed. Supports both sync and async functions. ## Parameters Function to decorate. Custom span name (defaults to the function name). Span type — `"span"`, `"generation"`, `"chain"`, or `"tool"`. Capture function arguments as span input. Capture the return value as span output. FiddlerClient instance (defaults to `get_client()`). LLM model name; sets `gen_ai.request.model`. User identifier; sets `user.id`. Version string; sets `service.version`. LLM provider; sets `gen_ai.system`. ## Returns The decorated function. See the [canonical reference](/sdk-api/otel/trace) for the full description and examples. # FiddlerAgentSpan Source: https://docs.fiddler.ai/sdk-api/otel-js/fiddler-agent-span Span wrapper for agent/chain operations with agent identity helpers. Span wrapper for agent/chain operations with agent identity helpers. Created via FiddlerClient.startAgent. All setter methods return `this` for fluent chaining. ## Methods ### `setAgentId(id: string): this` Set the unique agent identifier. Agent ID string (e.g. `"travel_agent_v2"`). `this` for chaining. ### `setAgentName(name: string): this` Set the human-readable agent name. Agent display name (e.g. `"travel_agent"`). `this` for chaining. # FiddlerClient Source: https://docs.fiddler.ai/sdk-api/otel-js/fiddler-client Primary entry point for Fiddler AI observability in JavaScript/TypeScript. Primary entry point for Fiddler AI observability in JavaScript/TypeScript. Creates an isolated OpenTelemetry BasicTracerProvider that exports traces to the Fiddler backend via OTLP HTTP. The provider is **not** registered globally, so it will not interfere with other OTel instrumentation in the same process. **Node.js only** — registers a `process.beforeExit` handler for automatic shutdown. The `process` guard is safe in non-Node environments but OTel SDK dependencies require Node.js >= 20. ## Methods ### `constructor(config: FiddlerClientConfig)` Create a new Fiddler client and initialize the OTel provider. Client configuration including Fiddler URL, API key, and application ID. ### `async flush(): Promise` Force-flush all buffered spans to the Fiddler backend. Call this before process exit in short-lived scripts to ensure all spans are exported. ### `async shutdown(): Promise` Flush remaining spans and shut down the underlying OTel provider. After shutdown the client cannot create new spans. This method is idempotent — calling it multiple times is safe. ### `startAgent(name: string, options?: Omit): FiddlerAgentSpan` Start a new agent/chain span (sets `fiddler.span.type` to `"chain"`). Human-readable name for the agent span. Optional parent span for nesting. A new FiddlerAgentSpan with agent-specific helpers. ### `startGeneration(name: string, options?: Omit): FiddlerGenerationSpan` Start a new LLM generation span (sets `fiddler.span.type` to `"llm"`). Human-readable name for the generation span. Optional parent span for nesting. A new FiddlerGenerationSpan with LLM-specific helpers. ### `startSpan(name: string, options?: StartSpanOptions): FiddlerSpan` Start a new span with an optional explicit type. Human-readable name for the span. Optional span type and parent span. A new FiddlerSpan instance. ### `startTool(name: string, options?: Omit): FiddlerToolSpan` Start a new tool span (sets `fiddler.span.type` to `"tool"`). Human-readable name for the tool span. Optional parent span for nesting. A new FiddlerToolSpan with tool-specific helpers. # FiddlerClientConfig Source: https://docs.fiddler.ai/sdk-api/otel-js/fiddler-client-config Configuration for FiddlerClient. Configuration for FiddlerClient. ## Properties ### `apiKey: string` Fiddler API key or personal access token. ### `applicationId: string` UUID of the Fiddler GenAI application to send traces to. ### `consoleTracer?: boolean` When `true`, also print spans to the console for local debugging. ### `serviceName?: string` OTel service name (defaults to `"fiddler-otel"`). ### `serviceVersion?: string` OTel service version (defaults to `"0.1.0"`). ### `url: string` Base URL of the Fiddler instance (e.g. `"https://app.fiddler.ai"`). # FiddlerGenerationSpan Source: https://docs.fiddler.ai/sdk-api/otel-js/fiddler-generation-span Span wrapper for LLM generation calls with model, prompt, completion, Span wrapper for LLM generation calls with model, prompt, completion, and token-usage helpers. Created via FiddlerClient.startGeneration. All setter methods return `this` for fluent chaining. ## Methods ### `setCompletion(text: string): this` Set the LLM completion/response text. Alias for FiddlerSpan.setOutput — writes to `gen_ai.llm.output`. The completion content. `this` for chaining. ### `setContext(context: string): this` Set the LLM context (e.g. retrieved RAG context) for this generation. Context string provided to the LLM. `this` for chaining. ### `setMessages(messages: Record[]): this` Set the full input message history sent to the model. Array of chat messages in OpenAI/Anthropic format. `this` for chaining. ### `setModel(model: string): this` Set the model identifier (e.g. `"gpt-4o"`, `"claude-3-opus"`). Model name or identifier string. `this` for chaining. ### `setOutputMessages(messages: Record[]): this` Set the output messages returned by the model. Array of assistant response messages. `this` for chaining. ### `setSystem(system: string): this` Set the LLM provider/system (e.g. `"openai"`, `"anthropic"`). Provider identifier string. `this` for chaining. ### `setSystemPrompt(text: string): this` Set the system prompt text. The system prompt content. `this` for chaining. ### `setToolDefinitions(definitions: Record[]): this` Set the tool/function definitions available to the model. Array of tool definition objects. `this` for chaining. ### `setUsage(usage: TokenUsage): this` Set token usage statistics for this generation. If `totalTokens` is not provided it is computed as `inputTokens + outputTokens`. Token counts for input, output, and total. `this` for chaining. ### `setUserPrompt(text: string): this` Set the user prompt text. Alias for FiddlerSpan.setInput — writes to `gen_ai.llm.input.user`. The user prompt content. `this` for chaining. # FiddlerSpan Source: https://docs.fiddler.ai/sdk-api/otel-js/fiddler-span Base wrapper around an OpenTelemetry Span with Fiddler-specific Base wrapper around an OpenTelemetry Span with Fiddler-specific attribute helpers. All setter methods return `this` for fluent chaining. ## Methods ### `constructor(span: Span)` The underlying OpenTelemetry span instance. ### `end()` Mark the span as successful and record its end timestamp. ### `recordError(error: string | Error)` Record an error on this span and set its status to `ERROR`. An Error instance or error message string. ### `setAttribute(key: string, value: string | number | boolean): this` Set an arbitrary attribute on the span. Attribute key (e.g. `"gen_ai.request.model"`). Attribute value. `this` for chaining. ### `setConversationId(id: string): this` Tag this span with a conversation/session identifier. Unique conversation or session ID. `this` for chaining. ### `setInput(input: unknown): this` Set the user-facing input for this span. Writes to the `gen_ai.llm.input.user` attribute after safely serializing non-string values. The input value (string or serializable object). `this` for chaining. ### `setOutput(output: unknown): this` Set the output/response for this span. Writes to the `gen_ai.llm.output` attribute after safely serializing non-string values. The output value (string or serializable object). `this` for chaining. # FiddlerToolSpan Source: https://docs.fiddler.ai/sdk-api/otel-js/fiddler-tool-span Span wrapper for tool/function invocations with tool-specific attribute Span wrapper for tool/function invocations with tool-specific attribute helpers. Created via FiddlerClient.startTool. All setter methods return `this` for fluent chaining. ## Methods ### `setInput(input: unknown): this` Set the input passed to the tool. Overrides the base FiddlerSpan.setInput to write to `gen_ai.tool.input` instead of `gen_ai.llm.input.user`. Tool input (string or serializable object). `this` for chaining. ### `setOutput(output: unknown): this` Set the output returned by the tool. Overrides the base FiddlerSpan.setOutput to write to `gen_ai.tool.output` instead of `gen_ai.llm.output`. Tool output (string or serializable object). `this` for chaining. ### `setToolDefinitions(definitions: Record[]): this` Set the tool/function definitions available in this context. Array of tool definition objects. `this` for chaining. ### `setToolName(name: string): this` Set the canonical tool/function name. Tool name (e.g. `"web_search"`, `"calculator"`). `this` for chaining. # Introduction Source: https://docs.fiddler.ai/sdk-api/otel-js/index Complete API reference for fiddler-otel-js [![npm](https://img.shields.io/npm/v/@fiddler-ai/otel)](https://www.npmjs.com/package/@fiddler-ai/otel) ## Overview The `@fiddler-ai/otel` package provides OpenTelemetry instrumentation for Fiddler AI observability. Use it to automatically capture LLM traces, conversation context, and span attributes from your TypeScript applications. ```bash theme={null} npm install @fiddler-ai/otel ``` ```typescript theme={null} import { FiddlerClient } from '@fiddler-ai/otel'; ``` ## Components ### Client Client initialization. `FiddlerClient` creates an isolated OpenTelemetry tracer provider that exports traces to Fiddler over OTLP HTTP without registering globally, so it does not interfere with other instrumentation in the same process. * [FiddlerClient](/sdk-api/otel-js/fiddler-client) ### Internal Configuration and attribute constants. `FiddlerClientConfig` is the client's options object; `SpanAttributes` and `SpanType` enumerate the attribute keys and span-type values Fiddler recognizes. * [FiddlerClientConfig](/sdk-api/otel-js/fiddler-client-config) * [SpanAttributes](/sdk-api/otel-js/span-attributes) * [SpanType](/sdk-api/otel-js/span-type) ### Spans Manual span helpers. `FiddlerAgentSpan`, `FiddlerGenerationSpan`, and `FiddlerToolSpan` carry semantic conventions for agent steps, LLM calls, and tool invocations; `FiddlerSpan` is the base, with `StartSpanOptions` and `TokenUsage` as supporting types. * [FiddlerAgentSpan](/sdk-api/otel-js/fiddler-agent-span) * [FiddlerGenerationSpan](/sdk-api/otel-js/fiddler-generation-span) * [FiddlerSpan](/sdk-api/otel-js/fiddler-span) * [FiddlerToolSpan](/sdk-api/otel-js/fiddler-tool-span) * [StartSpanOptions](/sdk-api/otel-js/start-span-options) * [TokenUsage](/sdk-api/otel-js/token-usage) # SpanAttributes Source: https://docs.fiddler.ai/sdk-api/otel-js/span-attributes Fiddler span attribute keys. Fiddler span attribute keys. Maps logical attribute names to their OpenTelemetry string keys following the `gen_ai.*` semantic conventions. ## Values | Constant | Value | Description | | ------------------------ | ------------------------------ | ---------------------------------------------------------------- | | `AGENT_ID` | `"gen_ai.agent.id"` | Unique agent identifier. | | `AGENT_NAME` | `"gen_ai.agent.name"` | Human-readable agent name. | | `CONVERSATION_ID` | `"gen_ai.conversation.id"` | Conversation or session identifier for multi-turn grouping. | | `GEN_AI_INPUT_MESSAGES` | `"gen_ai.input.messages"` | Full input message history as JSON. | | `GEN_AI_OUTPUT_MESSAGES` | `"gen_ai.output.messages"` | Full output messages as JSON. | | `LLM_CONTEXT` | `"gen_ai.llm.context"` | Retrieved context provided to the LLM (e.g. RAG context). | | `LLM_INPUT_SYSTEM` | `"gen_ai.llm.input.system"` | System prompt sent to the LLM. | | `LLM_INPUT_USER` | `"gen_ai.llm.input.user"` | User prompt or input sent to the LLM. | | `LLM_OUTPUT` | `"gen_ai.llm.output"` | LLM completion/response text. | | `LLM_REQUEST_MODEL` | `"gen_ai.request.model"` | Requested model identifier (e.g. `"gpt-4o"`). | | `LLM_SYSTEM` | `"gen_ai.system"` | LLM provider/system (e.g. `"openai"`, `"anthropic"`). | | `LLM_TOKEN_COUNT_INPUT` | `"gen_ai.usage.input_tokens"` | Number of input/prompt tokens. | | `LLM_TOKEN_COUNT_OUTPUT` | `"gen_ai.usage.output_tokens"` | Number of output/completion tokens. | | `LLM_TOKEN_COUNT_TOTAL` | `"gen_ai.usage.total_tokens"` | Total token count. | | `SESSION_ID` | `"session.id"` | Session identifier. | | `TOOL_DEFINITIONS` | `"gen_ai.tool.definitions"` | Tool/function definitions as JSON. | | `TOOL_INPUT` | `"gen_ai.tool.input"` | Tool input payload. | | `TOOL_NAME` | `"gen_ai.tool.name"` | Tool/function name. | | `TOOL_OUTPUT` | `"gen_ai.tool.output"` | Tool output payload. | | `TYPE` | `"fiddler.span.type"` | The Fiddler span type (`"llm"`, `"tool"`, `"chain"`, `"agent"`). | | `USER_ID` | `"user.id"` | User identifier. | # SpanType Source: https://docs.fiddler.ai/sdk-api/otel-js/span-type Allowed values for the `fiddler.span.type` attribute. Allowed values for the `fiddler.span.type` attribute. ## Values | Constant | Value | Description | | -------- | --------- | -------------------------------- | | `AGENT` | `"agent"` | An autonomous agent span. | | `CHAIN` | `"chain"` | A chain or workflow span. | | `LLM` | `"llm"` | An LLM generation span. | | `OTHER` | `"other"` | An uncategorized span. | | `TOOL` | `"tool"` | A tool/function invocation span. | # StartSpanOptions Source: https://docs.fiddler.ai/sdk-api/otel-js/start-span-options Options for creating a new span via FiddlerClient.startSpan. Options for creating a new span via FiddlerClient.startSpan. ## Properties ### `parent?: FiddlerSpan` An existing span to use as the logical parent. ### `type?: SpanTypeValue` The Fiddler span type (e.g. `"llm"`, `"tool"`, `"chain"`). # TokenUsage Source: https://docs.fiddler.ai/sdk-api/otel-js/token-usage Token usage statistics for an LLM call. Token usage statistics for an LLM call. ## Properties ### `inputTokens?: number` Number of tokens in the prompt/input. ### `outputTokens?: number` Number of tokens in the completion/output. ### `totalTokens?: number` Total token count (computed from input + output if omitted). # add_session_attributes Source: https://docs.fiddler.ai/sdk-api/otel/add-session-attributes Add a session-level attribute that appears on all spans in the current context. Add a session-level attribute that appears on all spans in the current context. The attribute is stored in a ContextVar that [`FiddlerSpanProcessor`](/sdk-api/otel/fiddler-span-processor) reads when spans are started. It is emitted as `fiddler.session.user.{key}` on every span created in the current thread or async coroutine, and is automatically propagated from parent spans to child spans. ## Parameters Logical attribute key. Will appear as `fiddler.session.user.{key}` in span attributes. Attribute value. Accepts `str`, `int`, `float`, or `bool`. Numeric values (`int`/`float`) are stored as numeric attributes and will appear in the `ValueFloat` column in ClickHouse, enabling range-based filtering and metrics. String and boolean values appear in the `ValueString` column and support categorical filtering (booleans are stored as `"true"` or `"false"`). ## Returns None Example: default from fiddler\_otel import add\_session\_attributes add\_session\_attributes("user\_id", "user\_12345") add\_session\_attributes("environment", "production") add\_session\_attributes("priority", 7) add\_session\_attributes("score", 0.95) # FiddlerChain Source: https://docs.fiddler.ai/sdk-api/otel/fiddler-chain Wrapper for chain/workflow spans with semantic convention helpers. Wrapper for chain/workflow spans with semantic convention helpers. Initialize chain span wrapper. ## **enter**() Enter context and set chain type. ### Returns `FiddlerChain` # FiddlerClient Source: https://docs.fiddler.ai/sdk-api/otel/fiddler-client The main client for instrumenting Generative AI applications with Fiddler observability. The main client for instrumenting Generative AI applications with Fiddler observability. This client configures and manages the OpenTelemetry tracer that sends telemetry data to the Fiddler platform for monitoring, analysis, and debugging of your AI agents and workflows. Flush on exit: A shutdown handler is registered via `atexit()` so that pending spans are flushed and the tracer is shut down when the process exits. For short scripts or critical workloads, call [`force_flush()`](#force_flush) and [`shutdown()`](#shutdown) explicitly (e.g. in a `try`/`finally` or signal handler) since `atexit` may not run in all environments (e.g. SIGKILL, fork). Asyncio: Tracing works in asyncio (context vars propagate across `await`). When shutting down from async code, use [`aflush()`](#async-aflush) and [`ashutdown()`](#async-ashutdown) so the event loop is not blocked; the sync [`force_flush()`](#force_flush) and [`shutdown()`](#shutdown) can block for up to the flush timeout. Context manager: Use `with FiddlerClient(...) as client:` to ensure [`shutdown()`](#shutdown) is called on exit (flush then shutdown; atexit is unregistered). AWS SageMaker Partner App: When running inside a SageMaker Partner Application, set the following environment variables to enable SigV4-signed OTLP export — no code changes are required: * `AWS_PARTNER_APP_AUTH=true` — opt-in trigger * `AWS_PARTNER_APP_ARN` — ARN of the SageMaker Partner Application resource * `AWS_PARTNER_APP_URL` — base URL of the partner app endpoint AWS credentials are resolved via the standard boto3 credential chain (IAM role inside a SageMaker runtime, `~/.aws/credentials`, instance profile, environment variables); no additional env vars are needed when running inside the partner-app sandbox. Install the `sagemaker` extra to enable this feature: ```python theme={null} pip install "fiddler-otel[sagemaker]" ``` In a SageMaker-managed runtime the package is pre-installed. Initialise the FiddlerClient. ## Parameters The unique identifier (UUID4) for the application. Must be a valid UUID4 (e.g. `550e8400-e29b-41d4-a716-446655440000`). Copy this from the **GenAI Applications** page in the Fiddler UI. Required in all modes — even when `otlp_enabled=False` — because the S3 connector uses it to route traces to the correct application. The API key for authenticating with the Fiddler backend. Required when `otlp_enabled=True` (the default). Not required when `otlp_enabled=False` (e.g. S3-routing mode) — omit or pass `''`. The base URL for your Fiddler instance (e.g. `https://your-instance.fiddler.ai`). Required when `otlp_enabled=True` (the default). Not required when `otlp_enabled=False` — omit or pass `''`. Must use `http` or `https` scheme. Controls whether traces are exported directly to the Fiddler OTLP endpoint. Set to `False` to disable all direct export to Fiddler — useful when traces must first be written to local files for S3 upload (offline / S3 routing mode). When `False`, `api_key` and `url` are not required and not validated. Defaults to `True`. **Note:** `console_tracer`, `jsonl_capture_enabled`, and `otlp_json_capture_enabled` are all independent of this flag and can be used in any combination. If `True`, span data is **also** printed to the console (stdout). This is **additive** — traces are still exported to Fiddler via OTLP (unless `otlp_enabled=False`). Setting this to `True` does **not** suppress or replace the OTLP export. Useful for local debugging to confirm spans are being created. Configuration for span limits, such as the maximum number of attributes or events. When `None` (default), OpenTelemetry automatically applies its standard defaults: * `max_attributes`: 128 (or `OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT` env var) * `max_events`: 128 (or `OTEL_SPAN_EVENT_COUNT_LIMIT` env var) * `max_links`: 128 (or `OTEL_SPAN_LINK_COUNT_LIMIT` env var) * `max_event_attributes`: 128 (or `OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT` env var) * `max_link_attributes`: 128 (or `OTEL_LINK_ATTRIBUTE_COUNT_LIMIT` env var) * `max_span_attribute_length`: None/unlimited (or `OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT` env var) Override these by passing a custom `SpanLimits` object or by setting the corresponding environment variables. The sampler for deciding which spans to record. Defaults to the parent-based always-on OpenTelemetry sampler (100% sampling). The compression algorithm for exporting traces. Can be `Compression.Gzip`, `Compression.Deflate`, or `Compression.NoCompression`. Only used when `otlp_enabled=True`. Defaults to `Compression.Gzip`. If `True`, span data is **also** saved to a local JSONL file in a custom Fiddler format. This is **additive** — OTLP export to Fiddler continues as normal (unless `otlp_enabled=False`). Setting this to `True` does **not** suppress the OTLP export. Useful for keeping a local copy of trace data. **Note:** This JSONL format is **not** compatible with the Fiddler S3 connector. For S3 ingestion use `otlp_json_capture_enabled=True` instead. Path to the JSONL file where trace data will be saved. Only used when `jsonl_capture_enabled=True`. Override with the `FIDDLER_JSONL_FILE` environment variable. If `True`, traces are written to local `.json` files in standard OTLP JSON format (`ExportTraceServiceRequest` envelope). Files are written to `otlp_json_output_dir`. This format is **directly compatible** with the Fiddler S3 connector — upload the generated files to S3 and the connector ingests them without any reformatting. This is **additive** relative to OTLP export; combine with `otlp_enabled=False` to write to files only (offline / S3 routing mode). Directory path where OTLP JSON files are written when `otlp_json_capture_enabled=True`. The directory is created automatically if it does not exist. Each batch of spans is written to a separate timestamped `.json` file. If `True`, large inline base64 content in span attributes is uploaded to S3 via `POST /v3/files/upload` and replaced with `fiddler-file://` URIs before the span is exported. This prevents trace loss at the 10MB Kafka span limit. Requires `otlp_enabled=True` (needs `url` and `api_key`). Defaults to `False`. ## Raises * **ValueError** – If `application_id` is not a valid UUID4. * **ValueError** – If `otlp_enabled=True` and `api_key` is empty or not provided. * **ValueError** – If `otlp_enabled=True` and `url` is empty, missing a scheme, or uses a scheme other than `http`/`https`. **Basic connection to your Fiddler instance**: ```python theme={null} client = FiddlerClient( application_id='YOUR_APPLICATION_ID', # UUID4, required in all modes api_key='YOUR_API_KEY', url='https://your-instance.fiddler.ai', ) ``` **High-volume applications with custom configuration**: ```python theme={null} from opentelemetry.sdk.trace import SpanLimits, sampling from opentelemetry.exporter.otlp.proto.http.trace_exporter import Compression client = FiddlerClient( application_id='YOUR_APPLICATION_ID', api_key='YOUR_API_KEY', url='https://your-instance.fiddler.ai', span_limits=SpanLimits( max_span_attributes=64, # Reduce from default 128 max_span_attribute_length=2048, # Limit from default None (unlimited) ), sampler=sampling.TraceIdRatioBased(0.1), # Sample 10% of traces compression=Compression.Gzip, ) ``` **Local development with console output** (traces still sent to Fiddler): ```python theme={null} # console_tracer=True prints spans to stdout AND continues to export to Fiddler. # It does NOT suppress OTLP export. client = FiddlerClient( application_id='00000000-0000-0000-0000-000000000000', api_key='dev-key', url='http://localhost:4318', console_tracer=True, ) ``` **Offline / S3 routing mode** (no data sent directly to Fiddler): ```python theme={null} # otlp_enabled=False → disables direct OTLP export; api_key and url not needed # otlp_json_capture_enabled=True → writes traces to local .json files in standard # OTLP JSON format (ExportTraceServiceRequest) # application_id is still required so the S3 connector routes traces correctly # # Upload files from otlp_json_output_dir to your S3 bucket. # The Fiddler S3 connector reads them directly with no reformatting required. client = FiddlerClient( application_id='YOUR_APPLICATION_ID', otlp_enabled=False, otlp_json_capture_enabled=True, otlp_json_output_dir='./fiddler_traces', # default: 'fiddler_traces' ) ``` ## **enter**() Context manager entry. ### Returns `FiddlerClient` ## **exit**() Context manager exit — flushes and shuts down the tracer provider. ## force\_flush() Flush pending spans to the exporter. ### Parameters Maximum time to wait for flush in milliseconds. ### Returns True if flush completed within the timeout, False otherwise. ## *async* aflush() Async version of [`force_flush()`](#force_flush). Runs the flush in a thread pool so the event loop is not blocked. ### Returns `bool` ## shutdown() Shut down the tracer provider after flushing pending spans. Safe to call multiple times. The atexit handler is unregistered on first call. ## *async* ashutdown() Async version of [`shutdown()`](#shutdown). Runs flush and shutdown in a thread pool so the event loop is not blocked. ## get\_tracer\_provider() Return the OpenTelemetry TracerProvider, initializing it on first call. ### Returns The configured TracerProvider. ### Raises **RuntimeError** – If initialization fails. ## update\_resource() Update the OTel resource with additional attributes. Must be called **before** [`get_tracer()`](#get_tracer) is invoked. ### Parameters Key-value pairs to merge into the resource. ### Raises **ValueError** – If the tracer has already been initialized. ## get\_tracer() Return an OTel tracer for creating spans. Initializes the tracer on the first call. ### Returns The OTel tracer instance. ### Raises **RuntimeError** – If tracer initialization fails. ## start\_as\_current\_span() Create a span using a context manager (automatic lifecycle management). ### Parameters Name for the span. Span type — `"span"`, `"generation"`, `"chain"`, or `"tool"`. ### Returns Span wrapper with context manager support. ## start\_span() Create a span with manual lifecycle control. Caller must call `span.end()`. ### Parameters Name for the span. Span type — `"span"`, `"generation"`, `"chain"`, or `"tool"`. ### Returns Span wrapper requiring an explicit `end()` call. # FiddlerGeneration Source: https://docs.fiddler.ai/sdk-api/otel/fiddler-generation Wrapper for LLM generation spans with semantic convention helpers. Wrapper for LLM generation spans with semantic convention helpers. Initialize LLM generation wrapper. ## **enter**() Enter context and set LLM type. ### Returns `FiddlerGeneration` ## set\_model() Set the LLM model name (gen\_ai.request.model). ## set\_system() Set the LLM system/provider (gen\_ai.system). ## set\_system\_prompt() Set the system prompt (gen\_ai.llm.input.system). ## set\_user\_prompt() Set the user prompt (gen\_ai.llm.input.user). ### Parameters Plain text string, or a list of content parts in OpenAI multimodal format (e.g. `[{'type': 'text', 'text': '...'}, {'type': 'image_url', 'image_url': {'url': 'data:...'}}]`). Lists are auto-serialized to JSON. ## set\_completion() Set the LLM completion/output (gen\_ai.llm.output). ## set\_usage() Set token usage information (gen\_ai.usage.\*). ### Parameters Number of input/prompt tokens. Number of output/completion tokens. Total tokens; computed from input + output when omitted. ## set\_context() Set additional context (gen\_ai.llm.context). ## set\_messages() Set input messages in OpenAI chat format (gen\_ai.input.messages). Accepts simple format: `[{'role': 'user', 'content': '...'}]` Auto-converts to OTel format with `parts`. ## set\_output\_messages() Set output messages in OpenAI chat format (gen\_ai.output.messages). Accepts simple format: `[{'role': 'assistant', 'content': '...'}]` Auto-converts to OTel format with `parts`. ## set\_tool\_definitions() Set available tool definitions for this LLM call (gen\_ai.tool.definitions). # FiddlerResourceAttributes Source: https://docs.fiddler.ai/sdk-api/otel/fiddler-resource-attributes Constants for Fiddler OpenTelemetry resource attributes. Constants for Fiddler OpenTelemetry resource attributes. ## APPLICATION\_ID *= 'application.id'* # FiddlerSpan Source: https://docs.fiddler.ai/sdk-api/otel/fiddler-span Wrapper around OpenTelemetry span with simplified helper methods. Wrapper around OpenTelemetry span with simplified helper methods. Initialize wrapper around an OTel span or context manager. ## Parameters An OTel span or context manager. Optional `MediaUploader` for normalizing large base64 content before span export. ## **enter**() Enter context manager and start span. ### Returns `FiddlerSpan` ## **exit**() Exit context manager, record exceptions, and end span. ### Returns `Literal[False]` ## end() Explicitly end the span. Must be called when using start\_span(). ## set\_input() Set input data. Auto-serializes dicts/lists to JSON. ## set\_output() Set output data. Auto-serializes dicts/lists to JSON. ## set\_attribute() Set a custom attribute on the span. ## update() Bulk update multiple attributes. ## record\_exception() Record an exception on the span. ## set\_agent\_name() Set the agent name (gen\_ai.agent.name). ## set\_agent\_id() Set the agent ID (gen\_ai.agent.id). ## set\_conversation\_id() Set the conversation ID (gen\_ai.conversation.id). # FiddlerSpanAttributes Source: https://docs.fiddler.ai/sdk-api/otel/fiddler-span-attributes Constants for Fiddler OpenTelemetry span attributes. Constants for Fiddler OpenTelemetry span attributes. ## AGENT\_NAME *= 'gen\_ai.agent.name'* ## AGENT\_ID *= 'gen\_ai.agent.id'* ## CONVERSATION\_ID *= 'gen\_ai.conversation.id'* ## TYPE *= 'fiddler.span.type'* ## SERVICE\_VERSION *= 'service.version'* ## LLM\_INPUT\_SYSTEM *= 'gen\_ai.llm.input.system'* ## LLM\_INPUT\_USER *= 'gen\_ai.llm.input.user'* ## LLM\_OUTPUT *= 'gen\_ai.llm.output'* ## LLM\_CONTEXT *= 'gen\_ai.llm.context'* ## LLM\_REQUEST\_MODEL *= 'gen\_ai.request.model'* ## LLM\_SYSTEM *= 'gen\_ai.system'* ## LLM\_TOKEN\_COUNT\_INPUT *= 'gen\_ai.usage.input\_tokens'* ## LLM\_TOKEN\_COUNT\_OUTPUT *= 'gen\_ai.usage.output\_tokens'* ## LLM\_TOKEN\_COUNT\_TOTAL *= 'gen\_ai.usage.total\_tokens'* ## GEN\_AI\_INPUT\_MESSAGES *= 'gen\_ai.input.messages'* ## GEN\_AI\_OUTPUT\_MESSAGES *= 'gen\_ai.output.messages'* ## TOOL\_INPUT *= 'gen\_ai.tool.input'* ## TOOL\_OUTPUT *= 'gen\_ai.tool.output'* ## TOOL\_NAME *= 'gen\_ai.tool.name'* ## TOOL\_DEFINITIONS *= 'gen\_ai.tool.definitions'* ## SYSTEM\_PROMPT *= 'system\_prompt'* ## GENAI\_SYSTEM\_MESSAGE *= 'gen\_ai.system.message'* # FiddlerSpanProcessor Source: https://docs.fiddler.ai/sdk-api/otel/fiddler-span-processor Span processor that automatically propagates attributes from parent to child spans. Span processor that automatically propagates attributes from parent to child spans. ## DENORMALIZED\_ATTRIBUTES ## on\_start() Called when a span starts. Automatically propagates attributes from parent. ### Parameters The span being started. The parent context, if any. ## force\_flush() No buffered state; satisfy `SpanProcessor` interface. ### Returns `bool` # FiddlerTool Source: https://docs.fiddler.ai/sdk-api/otel/fiddler-tool Wrapper for tool/function call spans with semantic convention helpers. Wrapper for tool/function call spans with semantic convention helpers. Initialize tool span wrapper. ## **enter**() Enter context and set tool type. ### Returns `FiddlerTool` ## set\_tool\_name() Set the tool/function name (gen\_ai.tool.name). ## set\_tool\_input() Set the tool input arguments (gen\_ai.tool.input). ## set\_tool\_output() Set the tool output/result (gen\_ai.tool.output). ## set\_tool\_definitions() Set available tool definitions (gen\_ai.tool.definitions). # get_client Source: https://docs.fiddler.ai/sdk-api/otel/get-client Return the global FiddlerClient singleton (first created in this process). Return the global FiddlerClient singleton (first created in this process). ## Returns The global client instance. ## Raises **RuntimeError** – If no FiddlerClient has been initialized. # get_current_span Source: https://docs.fiddler.ai/sdk-api/otel/get-current-span Get the currently active span as a Fiddler wrapper (inside a traced function). Get the currently active span as a Fiddler wrapper (inside a traced function). Retrieves the span from the current context and verifies it belongs to Fiddler's tracer to maintain isolation from other OpenTelemetry tracers. ## Parameters Wrapper type — `"span"`, `"generation"`, `"chain"`, or `"tool"`. ## Returns Current span wrapper, or None if no active Fiddler span exists. # Introduction Source: https://docs.fiddler.ai/sdk-api/otel/index Complete API reference for fiddler-otel [![PyPI](https://img.shields.io/pypi/v/fiddler-otel)](https://pypi.org/project/fiddler-otel/) ## Overview Complete API reference documentation for the `fiddler-otel` package, the framework-agnostic OpenTelemetry-based instrumentation layer for any Python LLM or agent application. `fiddler-otel` is the canonical source for Fiddler's span attributes, conversation tracking, and span processing primitives; the LangChain, LangGraph, and Strands SDKs build on top of it and re-export several of its symbols. ```bash theme={null} pip install fiddler-otel ``` ```python theme={null} from fiddler_otel import FiddlerClient, trace ``` ## Components ### Attributes Span and resource attribute helpers. `set_conversation_id` and `add_session_attributes` are propagated through the current trace context; `FiddlerSpanAttributes`, `FiddlerResourceAttributes`, and `SpanType` enumerate the constant keys Fiddler recognizes. * [add\_session\_attributes](/sdk-api/otel/add-session-attributes) * [FiddlerResourceAttributes](/sdk-api/otel/fiddler-resource-attributes) * [FiddlerSpanAttributes](/sdk-api/otel/fiddler-span-attributes) * [set\_conversation\_id](/sdk-api/otel/set-conversation-id) * [SpanType](/sdk-api/otel/span-type) ### Client Client initialization and configuration. `FiddlerClient` wires the OTLP exporter, span processor, and resource attributes into the global tracer provider; `get_client` returns the active singleton. * [FiddlerClient](/sdk-api/otel/fiddler-client) * [get\_client](/sdk-api/otel/get-client) ### Decorators Function-level tracing helpers. `@trace` instruments arbitrary Python functions; `get_current_span` returns the active span for attribute mutation inside a traced call. * [get\_current\_span](/sdk-api/otel/get-current-span) * [trace](/sdk-api/otel/trace) ### JSONL Capture JSONL span exporter for offline analysis. Writes a structured trace record per span to a local file alongside (or instead of) OTLP export, useful for debugging and reproducing customer issues. * [JSONLSpanExporter](/sdk-api/otel/jsonl-span-exporter) ### Span Processor Custom OpenTelemetry span processor that enriches outgoing spans with Fiddler resource attributes before export. * [FiddlerSpanProcessor](/sdk-api/otel/fiddler-span-processor) ### Span Wrapper Manual span creation primitives for code paths that don't fit the decorator model. `FiddlerSpan` is the base; `FiddlerChain`, `FiddlerGeneration`, and `FiddlerTool` carry semantic conventions for retrieval/agent steps, LLM calls, and tool invocations. * [FiddlerChain](/sdk-api/otel/fiddler-chain) * [FiddlerGeneration](/sdk-api/otel/fiddler-generation) * [FiddlerSpan](/sdk-api/otel/fiddler-span) * [FiddlerTool](/sdk-api/otel/fiddler-tool) # JSONLSpanExporter Source: https://docs.fiddler.ai/sdk-api/otel/jsonl-span-exporter SpanExporter that captures spans using JSONLSpanCapture. SpanExporter that captures spans using JSONLSpanCapture. ## Parameters The JSONLSpanCapture instance to use. ## export() Export spans by capturing them with JSONLSpanCapture. ### Returns `SpanExportResult` # set_conversation_id Source: https://docs.fiddler.ai/sdk-api/otel/set-conversation-id Set the conversation ID for the current execution context. Set the conversation ID for the current execution context. The conversation ID is propagated to all spans created in the current thread or async coroutine, allowing the Fiddler dashboard to filter and display the full ordered sequence of operations for a single conversation. This value persists until it is called again with a new ID. ## Parameters Unique identifier for the conversation session. ## Returns None Example: default import uuid from fiddler\_otel import set\_conversation\_id set\_conversation\_id(str(uuid.uuid4())) # All spans created in this thread or coroutine after this call # carry the same conversation\_id, until set\_conversation\_id is # called again with a new value. # SpanType Source: https://docs.fiddler.ai/sdk-api/otel/span-type Constants for Fiddler OpenTelemetry span types. Constants for Fiddler OpenTelemetry span types. ## AGENT *= 'agent'* ## CHAIN *= 'chain'* ## TOOL *= 'tool'* ## LLM *= 'llm'* ## OTHER *= 'other'* # trace Source: https://docs.fiddler.ai/sdk-api/otel/trace Decorator for automatic function tracing with input/output capture. Decorator for automatic function tracing with input/output capture. Uses the global FiddlerClient when `client=` is not passed. Supports both sync and async functions. ## Parameters Function to decorate. Custom span name (defaults to the function name). Span type — `"span"`, `"generation"`, `"chain"`, or `"tool"`. Capture function arguments as span input. Capture the return value as span output. FiddlerClient instance (defaults to `get_client()`). LLM model name; sets `gen_ai.request.model`. User identifier; sets `user.id`. Version string; sets `service.version`. LLM provider; sets `gen_ai.system`. ## Returns The decorated function. # AlertCondition Source: https://docs.fiddler.ai/sdk-api/python-client/alert-condition Alert trigger conditions for metric comparisons. Alert trigger conditions for metric comparisons. Defines the comparison operator used to evaluate whether an alert should trigger based on the metric value and threshold. ## GREATER Trigger when metric value > threshold. Common for drift detection, error rates, latency spikes. ## LESSER Trigger when metric value \< threshold. Common for accuracy drops, traffic decreases, availability issues. ### Example ```python theme={null} # Alert when data drift exceeds 5% drift_alert = AlertRule( condition=AlertCondition.GREATER, threshold=0.05 ) # Alert when model accuracy drops below 90% accuracy_alert = AlertRule( condition=AlertCondition.LESSER, threshold=0.90 ) ``` ## GREATER *= 'greater'* ## LESSER *= 'lesser'* # AlertRecord Source: https://docs.fiddler.ai/sdk-api/python-client/alert-record Alert record representing a triggered alert instance. Alert record representing a triggered alert instance. An AlertRecord captures the details of a specific alert trigger event, including the metric values, thresholds, and context that caused an AlertRule to fire. Alert records provide essential data for monitoring analysis and troubleshooting. ## Example ```python theme={null} # List recent critical alerts critical_alerts = [ record for record in AlertRecord.list( alert_rule_id=drift_alert.id, start_time=datetime.now() - timedelta(days=3) ) if record.severity == "CRITICAL" ] # Analyze alert details for alert in critical_alerts: print(f"Alert triggered at {alert.created_at}") print(f"Metric value: {alert.alert_value:.3f}") print(f"Critical threshold: {alert.critical_threshold:.3f}") if alert.feature_name: print(f"Feature: {alert.feature_name}") print(f"Message: {alert.message}") print("—") # Check for alert patterns hourly_alerts = {} for alert in AlertRecord.list(alert_rule_id=perf_alert.id): hour = alert.created_at.hour hourly_alerts[hour] = hourly_alerts.get(hour, 0) + 1 print("Alerts by hour:", hourly_alerts) ``` Alert records are read-only entities created automatically by the Fiddler platform when AlertRules trigger. They cannot be created or modified directly but provide valuable historical data for analysis and debugging. Initialize an AlertRecord instance. Creates an alert record object for representing triggered alert instances. Alert records are typically created automatically by the Fiddler platform when AlertRules trigger, rather than being instantiated directly by users. Alert records are read-only entities that capture historical alert trigger events. They are created automatically by the system and cannot be modified after creation. ## *classmethod* list() List alert records triggered by a specific alert rule. Retrieves historical alert records for analysis and troubleshooting. This method provides access to all alert trigger events within a specified time range, enabling pattern analysis and threshold tuning. ### Parameters The unique identifier of the AlertRule to retrieve records for. Must be a valid alert rule UUID. Start time for filtering alert records. If None, defaults to 7 days ago. Used to define the beginning of the query window. End time for filtering alert records. If None, defaults to current time. Used to define the end of the query window. List of field names for result ordering. Prefix with "-" for descending order (e.g., \["-created\_at"] for newest first). ### Yields `AlertRecord` – Alert record instances with complete trigger details and context information. ### Returns `Iterator[AlertRecord]` ### Example ```python theme={null} # Get recent alerts for analysis recent_alerts = list(AlertRecord.list( alert_rule_id=drift_alert.id, start_time=datetime.now() - timedelta(days=3), ordering=["-created_at"] # Newest first )) # Analyze alert frequency print(f"Total alerts in last 3 days: {len(recent_alerts)}") critical_count = sum(1 for a in recent_alerts if a.severity == "CRITICAL") print(f"Critical alerts: {critical_count}") # Check alert patterns by feature feature_alerts = {} for alert in recent_alerts: if alert.feature_name: feature_alerts[alert.feature_name] = feature_alerts.get(alert.feature_name, 0) + 1 print("Alerts by feature:", feature_alerts) # Analyze threshold violations for alert in recent_alerts[:5]: # Latest 5 alerts violation_ratio = alert.alert_value / alert.critical_threshold print(f"Alert value: {alert.alert_value:.3f} " f"({violation_ratio:.1%} of threshold)") ``` Results are paginated automatically. The default time range is 7 days to balance performance with useful historical context. Use ordering parameters to get the most relevant results first. # AlertRule Source: https://docs.fiddler.ai/sdk-api/python-client/alert-rule Alert rule for automated monitoring and alerting in ML systems. Alert rule for automated monitoring and alerting in ML systems. An AlertRule defines conditions that automatically trigger notifications when ML model metrics exceed specified thresholds. Alert rules are essential for proactive monitoring of model performance, data drift, and operational issues. ## Example ```python theme={null} # Create feature drift alert drift_alert = AlertRule( name="credit_score_drift", model_id=model.id, metric_id="drift_score", priority=Priority.HIGH, compare_to=CompareTo.BASELINE, condition=AlertCondition.GT, bin_size=BinSize.HOUR, critical_threshold=0.8, warning_threshold=0.6, baseline_id=baseline.id, columns=["credit_score", "income"] ).create() # Create performance degradation alert perf_alert = AlertRule( name="accuracy_drop", model_id=model.id, metric_id="accuracy", priority=Priority.MEDIUM, compare_to=CompareTo.TIME_PERIOD, condition=AlertCondition.LESSER, bin_size=BinSize.DAY, critical_threshold=0.85, compare_bin_delta=7 # Compare to 7 days ago ).create() # Configure notifications drift_alert.set_notification_config( emails=["[ml-team@company.com](mailto:ml-team@company.com)", "[data-team@company.com](mailto:data-team@company.com)"], pagerduty_services=["ML_ALERTS"], pagerduty_severity="critical" ) ``` Alert rules continuously monitor metrics and trigger notifications when thresholds are exceeded. Use appropriate evaluation delays to avoid false positives from temporary data fluctuations. Initialize an AlertRule instance. Creates an alert rule configuration for automated monitoring of ML model metrics. The alert rule defines conditions that trigger notifications when thresholds are exceeded, enabling proactive monitoring of model performance and data quality. ## Parameters Human-readable name for the alert rule. Should be descriptive and unique within the model context. UUID of the model this alert rule monitors. Must be a valid model that exists in the Fiddler platform. ID of the metric to monitor (e.g., "drift\_score", "accuracy", "precision", "recall", custom metric IDs). Alert priority level (HIGH, MEDIUM, LOW). Determines urgency and routing of notifications. Comparison method for threshold evaluation: * BASELINE: Compare against a fixed baseline * TIME\_PERIOD: Compare against previous time period * RAW\_VALUE: Compare against absolute threshold Alert condition (GT, LT, OUTSIDE\_RANGE). Defines when the alert should trigger relative to the threshold. Time aggregation window (HOUR, DAY, WEEK). Controls how data is grouped for metric calculation. Threshold calculation method (MANUAL or AUTO). MANUAL uses user-defined thresholds, AUTO calculates dynamic thresholds based on historical data. Parameters for automatic threshold calculation. Used when threshold\_type is AUTO. Critical alert threshold value. Triggers high-priority notifications when exceeded. List of feature columns to monitor. For feature-specific drift alerts. If None, monitors all features. UUID of the baseline to compare against. Required when compare\_to is BASELINE. UUID of the data segment to monitor. For segment-specific monitoring (optional). Number of time bins to compare against. Used with TIME\_PERIOD comparison (e.g., 7 for week-over-week). Delay in minutes before evaluating alerts. Helps avoid false positives from incomplete data. Custom category for organizing alerts. Useful for grouping related alerts in dashboards. ## Example ```python theme={null} # Feature drift alert with baseline comparison drift_alert = AlertRule( name="income_drift_detection", model_id=model.id, metric_id="drift_score", priority=Priority.HIGH, compare_to=CompareTo.BASELINE, condition=AlertCondition.GT, bin_size=BinSize.HOUR, critical_threshold=0.8, warning_threshold=0.6, baseline_id=baseline.id, columns=["income", "credit_score"], evaluation_delay=15, # 15 minute delay category="data_quality" ) # Performance monitoring with time comparison perf_alert = AlertRule( name="weekly_accuracy_check", model_id=model.id, metric_id="accuracy", priority=Priority.MEDIUM, compare_to=CompareTo.TIME_PERIOD, condition=AlertCondition.LESSER, bin_size=BinSize.DAY, critical_threshold=0.85, compare_bin_delta=7, # Compare to 7 days ago category="performance" ) ``` After initialization, call create() to persist the alert rule to the Fiddler platform. Alert rules begin monitoring immediately after creation. ## *classmethod* get() Retrieve an alert rule by its unique identifier. Fetches an alert rule from the Fiddler platform using its UUID. This method returns the complete alert rule configuration including thresholds, notification settings, and monitoring status. ### Parameters The unique identifier (UUID) of the alert rule to retrieve. Can be provided as a UUID object or string representation. ### Returns The alert rule instance with all configuration and metadata populated from the server. ### Raises * **NotFound** – If no alert rule exists with the specified ID. * **ApiError** – If there's an error communicating with the Fiddler API. ### Example ```python theme={null} # Retrieve alert rule by ID alert_rule = AlertRule.get(id_="550e8400-e29b-41d4-a716-446655440000") print(f"Alert: {alert_rule.name}") print(f"Metric: {alert_rule.metric_id}") print(f"Priority: {alert_rule.priority}") print(f"Critical threshold: {alert_rule.critical_threshold}") # Check notification configuration notification_config = alert_rule.get_notification_config() print(f"Email recipients: {notification_config.emails}") ``` This method makes an API call to fetch the latest alert rule configuration from the server, including any recent threshold or notification updates. ## *classmethod* list() Get a list of all alert rules in the organization. ### Parameters list from the specified model list rules set on the specified metric id list rules set on the specified list of columns order result as per list of fields. \["-field\_name"] for descending ### Returns paginated list of alert rules for the specified filters ## delete() Delete an alert rule. ## create() Create a new alert rule. ### Returns `AlertRule` ## update() Update an existing alert rule. ## enable\_notifications() Enable notifications for an alert rule ## disable\_notifications() Disable notifications for an alert rule ## set\_notification\_config() Set notification config for an alert rule ### Parameters list of emails list of pagerduty services severity of pagerduty list of webhooks UUIDs ### Returns NotificationConfig object ## get\_notification\_config() Get notifications config for an alert rule ### Returns NotificationConfig object # AlertThresholdAlgo Source: https://docs.fiddler.ai/sdk-api/python-client/alert-threshold-algo Threshold determination algorithms for alert rules. Threshold determination algorithms for alert rules. Defines how alert thresholds are calculated - either manually specified or automatically computed based on historical data patterns. ## MANUAL User-specified static thresholds. Provides full control but requires domain knowledge to set appropriately. ## STD\_DEV\_AUTO\_THRESHOLD Automatic thresholds based on standard deviation. Calculates thresholds as mean ± (multiplier × std\_dev) from historical data. Adapts to data patterns automatically. ### Example ```python theme={null} # Manual threshold - user knows the acceptable drift limit manual_alert = AlertRule( threshold_type=AlertThresholdAlgo.MANUAL, critical_threshold=0.1, warning_threshold=0.05 ) # Auto threshold - let system learn from historical patterns auto_alert = AlertRule( threshold_type=AlertThresholdAlgo.STD_DEV_AUTO_THRESHOLD, auto_threshold_params={ 'warning_multiplier': 2.0, # 2 std devs for warning 'critical_multiplier': 3.0 # 3 std devs for critical } ) ``` ## MANUAL *= 'manual'* ## STD\_DEV\_AUTO\_THRESHOLD *= 'standard\_deviation\_auto\_threshold'* ## **str**() Return the string value of the enum. ### Returns The enum's string value for serialization and display. ### Example ```python theme={null} algo = AlertThresholdAlgo.MANUAL str(algo) 'manual' ``` # ApiError Source: https://docs.fiddler.ai/sdk-api/python-client/api-error Raised when the Fiddler API returns an HTTP error response. Raised when the Fiddler API returns an HTTP error response. This exception represents errors returned by the Fiddler platform API, including both client errors (4xx status codes) and server errors (5xx status codes). It contains detailed information about the error including the HTTP status code, error message, and any additional error details provided by the API. ApiError serves as the base class for more specific API errors like NotFound and Conflict, but can also be raised directly for other HTTP error status codes. ## Examples Handling general API errors: ```python theme={null} try: model = client.get_model("nonexistent-model") except ApiError as e: print(f"API Error {e.code}: {e.message}") if e.errors: print(f"Details: {e.errors}") ``` Handling specific status codes: ```python theme={null} try: # API operation pass except ApiError as e: if e.code == 429: # Rate limit print("Rate limited, retrying later...") time.sleep(60) elif e.code >= 500: # Server error print("Server error, contact support") else: print(f"Client error: {e.message}") ``` ## reason ## code # ArtifactStatus Source: https://docs.fiddler.ai/sdk-api/python-client/artifact-status Model artifact upload and deployment status. Model artifact upload and deployment status. This enum tracks the status of model artifacts in Fiddler, indicating whether explainability features are available and what type of model deployment is active. Artifact Types: * **No Model**: No artifacts uploaded, monitoring only * **Surrogate**: Fiddler-generated surrogate model for explainability * **User Uploaded**: User-provided model artifacts for full explainability ## Examples Checking artifact status and capabilities: ```python theme={null} # Check current artifact status model = fdl.Model.from_name('my_model', project_id=project.id) if model.artifact_status == fdl.ArtifactStatus.NO_MODEL: print("Monitoring only - no explainability features") elif model.artifact_status == fdl.ArtifactStatus.SURROGATE: print("Surrogate model available - basic explainability") elif model.artifact_status == fdl.ArtifactStatus.USER_UPLOADED: print("Full model artifacts - complete explainability") # Upload model artifacts to enable explainability if model.artifact_status == fdl.ArtifactStatus.NO_MODEL: job = model.add_artifact( model_dir='./model_package/', deployment_params=fdl.DeploymentParams( artifact_type=fdl.ArtifactType.PYTHON_PACKAGE ) ) job.wait() ``` Artifact status affects available explainability features. User-uploaded artifacts provide the most comprehensive explanation capabilities. ## NO\_MODEL *= 'no\_model'* No model artifacts have been uploaded. The model exists in Fiddler for monitoring purposes only. Data drift detection, performance monitoring, and alerting are available, but explainability features are not accessible. Available features: * Data drift monitoring * Performance metric tracking * Alert rule configuration * Dashboard visualization * Data publishing and monitoring Unavailable features: * Point explainability * Global feature importance * Model artifact-based analysis * Custom explanation methods This is the default status for newly created models before any artifacts are uploaded. ## SURROGATE *= 'surrogate'* Surrogate model generated by Fiddler for explainability. Fiddler has automatically generated a surrogate model based on your published data to provide basic explainability features. The surrogate model approximates your original model's behavior. Available features: * Basic point explainability * Global feature importance * Approximated explanations * All monitoring features Characteristics: * Automatically generated by Fiddler * Approximates original model behavior * Provides reasonable explanation quality * No additional setup required Limitations: * May not perfectly match original model * Limited to surrogate model capabilities * Cannot use custom explanation methods ## USER\_UPLOADED *= 'user\_uploaded'* User-provided model artifacts have been uploaded. Complete model artifacts have been uploaded, enabling full explainability features with the actual model. This provides the highest quality explanations and complete feature access. Available features: * Full point explainability with actual model * Global feature importance from actual model * Custom explanation methods (if defined) * Model artifact-based analysis * All monitoring and surrogate features Characteristics: * Uses actual uploaded model * Highest explanation accuracy * Supports custom explanation methods * Complete feature access Requirements: * Model artifacts must be properly packaged * Compatible with Fiddler's deployment environment * May require specific Python dependencies # ArtifactType Source: https://docs.fiddler.ai/sdk-api/python-client/artifact-type Model artifact types for deployment. Model artifact types for deployment. **Values:** * `SURROGATE` - SURROGATE Surrogate model artifact generated by Fiddler. ## PYTHON\_PACKAGE *= 'PYTHON\_PACKAGE'* User-provided Python package artifact. # AsyncJobFailed Source: https://docs.fiddler.ai/sdk-api/python-client/async-job-failed Raised when an asynchronous job fails to execute successfully. Raised when an asynchronous job fails to execute successfully. This exception is thrown when long-running operations (such as model training, data processing, or batch operations) fail to complete successfully. The job may have been submitted successfully but encountered an error during execution. Async jobs in Fiddler include operations like model artifact uploads, baseline computations, batch data ingestion, and other time-intensive operations that run in the background. ## Examples Handling async job failures: ```python theme={null} try: job = model.upload_artifact(artifact_path) job.wait() # Wait for completion except AsyncJobFailed as e: print(f"Job failed: {e.message}") # Check job logs or retry operation ``` Monitoring job status to avoid exceptions: ```python theme={null} job = model.upload_artifact(artifact_path) while not job.is_complete(): if job.status == JobStatus.FAILED: print(f"Job failed: {job.error_message}") break time.sleep(5) ``` # Baseline Source: https://docs.fiddler.ai/sdk-api/python-client/baseline Baseline for drift detection and model performance monitoring. Baseline for drift detection and model performance monitoring. A Baseline defines a reference point for comparing production data against expected patterns. It serves as the foundation for detecting data drift, model performance degradation, and distributional changes in ML systems. ## Example ```python theme={null} # Create a static baseline from training data baseline = Baseline( name="production_baseline_v1", model_id=model.id, environment=EnvType.PRE_PRODUCTION, dataset_id=training_dataset.id, type_="STATIC" ).create() # Create a rolling 30-day baseline rolling_baseline = Baseline( name="rolling_30day", model_id=model.id, environment=EnvType.PRODUCTION, type_="ROLLING_WINDOW", window_bin_size=WindowBinSize.DAY, offset_delta=30 ).create() # Monitor drift detection print(f"Baseline '{baseline.name}' has {baseline.row_count} records") print(f"Created: {baseline.created_at}") ``` Baselines are immutable once created. To modify baseline parameters, create a new baseline and update your monitoring configurations. Initialize a Baseline instance. Creates a baseline configuration for drift detection and monitoring. The baseline serves as a reference point for comparing production data against expected patterns. ## Parameters Human-readable name for the baseline. Should be descriptive and unique within the model context. UUID of the model this baseline belongs to. Must be a valid model that exists in the Fiddler platform. Environment type (PRE\_PRODUCTION or PRODUCTION). Determines the data environment this baseline monitors. Baseline type. Supported values: * "STATIC": Fixed dataset reference (requires dataset\_id) * "ROLLING\_WINDOW": Sliding time window (requires offset\_delta) * "PREVIOUS\_PERIOD": Previous time period comparison UUID of the reference dataset. Required for STATIC baselines, optional for time-based baselines. Start timestamp for time-based baselines (Unix timestamp). Defines the beginning of the reference period. Time offset in days for rolling/previous period baselines. For ROLLING\_WINDOW: size of the sliding window. For PREVIOUS\_PERIOD: how far back to compare. Aggregation window for time-series analysis. Controls how data is grouped for comparison. ## Example ```python theme={null} # Static baseline from training data baseline = Baseline( name="training_baseline_v2", model_id=model.id, environment=EnvType.PRE_PRODUCTION, dataset_id=training_dataset.id, type_="STATIC" ) # Rolling 7-day window baseline rolling_baseline = Baseline( name="weekly_rolling", model_id=model.id, environment=EnvType.PRODUCTION, type_="ROLLING_WINDOW", offset_delta=7, window_bin_size=WindowBinSize.DAY ) # Previous month comparison baseline monthly_baseline = Baseline( name="month_over_month", model_id=model.id, environment=EnvType.PRODUCTION, type_="PREVIOUS_PERIOD", offset_delta=30, window_bin_size=WindowBinSize.DAY ) ``` After initialization, call create() to persist the baseline to the Fiddler platform. The baseline configuration cannot be modified after creation. ## *classmethod* get() Retrieve a baseline by its unique identifier. Fetches a baseline from the Fiddler platform using its UUID. This method returns the complete baseline configuration including metadata and statistics. ### Parameters The unique identifier (UUID) of the baseline to retrieve. Can be provided as a UUID object or string representation. ### Returns The baseline instance with all configuration and metadata populated from the server. ### Raises * **NotFound** – If no baseline exists with the specified ID. * **ApiError** – If there's an error communicating with the Fiddler API. ### Example ```python theme={null} # Retrieve baseline by ID baseline = Baseline.get(id_="550e8400-e29b-41d4-a716-446655440000") print(f"Baseline: {baseline.name}") print(f"Type: {baseline.type}") print(f"Environment: {baseline.environment}") print(f"Records: {baseline.row_count}") # Check baseline configuration if baseline.type == "STATIC": print(f"Reference dataset: {baseline.dataset_id}") elif baseline.type == "ROLLING_WINDOW": print(f"Window size: {baseline.offset_delta} days") print(f"Bin size: {baseline.window_bin_size}") ``` This method makes an API call to fetch the latest baseline information from the server, including any updated statistics or metadata. ## *classmethod* from\_name() Get the baseline instance of a model from baseline name ### Parameters Baseline name Model identifier ### Returns Baseline instance ## *classmethod* list() Get a list of all baselines of a model. ### Returns `Iterator[Baseline]` ## create() Create a new baseline. ### Returns `Baseline` ## delete() Delete a baseline. # BaselineCompact Source: https://docs.fiddler.ai/sdk-api/python-client/baseline-compact Fetch baseline instance ## id ## name ## fetch() Fetch baseline instance ### Returns [`Baseline`](/sdk-api/python-client/baseline) # BaselineType Source: https://docs.fiddler.ai/sdk-api/python-client/baseline-type Baseline computation strategies for data drift detection in Fiddler. Baseline computation strategies for data drift detection in Fiddler. Baseline types determine how reference data is defined and used for comparison with production model behavior. Fiddler supports static and rolling baselines, each serving different monitoring needs and use cases. Static Baselines: * Fixed reference point that doesn't change over time * Can be created from pre-production data (training/test sets) or production data * Consistent comparison point for detecting absolute drift * Ideal for compliance, audit requirements, and stable model environments * Pre-production static baselines created via model.publish() with PRE\_PRODUCTION environment * Production static baselines defined using specific time ranges Rolling Baselines: * Dynamic sliding window that shifts with time * Always maintains fixed time distance from current data (e.g., 4 weeks ago) * Automatically adapts to gradual changes in data patterns * Excellent for detecting sudden changes or anomalies in time-sensitive data * Requires window\_bin\_size and offset\_delta parameters Selection Guidelines: * Use STATIC for regulatory compliance, model validation, and stable environments * Use ROLLING for seasonal patterns, evolving data, and operational monitoring * Static pre-production baselines are recommended for most use cases * Rolling baselines work best with sufficient historical production data ## Example ```python theme={null} # Static production baseline using time range static_baseline = fdl.Baseline( name="static_baseline", model_id=model.id, environment=fdl.EnvType.PRODUCTION, type_=fdl.BaselineType.STATIC, start_time=(datetime.now() - timedelta(days=30)).timestamp(), end_time=(datetime.now() - timedelta(days=7)).timestamp() ).create() # Rolling production baseline with monthly window rolling_baseline = fdl.Baseline( name="rolling_baseline", model_id=model.id, environment=fdl.EnvType.PRODUCTION, type_=fdl.BaselineType.ROLLING, window_bin_size=fdl.WindowBinSize.MONTH, offset_delta=1 # 1 month offset ).create() ``` ## STATIC Fixed baseline using historical reference data or specific time ranges ## ROLLING Dynamic sliding window baseline that shifts with time ## STATIC *= 'STATIC'* ## ROLLING *= 'ROLLING'* # BinSize Source: https://docs.fiddler.ai/sdk-api/python-client/bin-size Time bin sizes for alert rule aggregation. Time bin sizes for alert rule aggregation. Defines the time window granularity for aggregating metrics when evaluating alert rules. Smaller bin sizes provide more frequent monitoring but may be more sensitive to noise. ## Example ```python theme={null} alert_rule = AlertRule( name="Hourly Drift Check", bin_size=BinSize.HOUR, # ... other parameters ) ``` ## HOUR *= 'Hour'* ## DAY *= 'Day'* ## WEEK *= 'Week'* ## MONTH *= 'Month'* # Column Source: https://docs.fiddler.ai/sdk-api/python-client/column Represents a single column in a model schema with its metadata and constraints. Represents a single column in a model schema with its metadata and constraints. A Column defines the structure and properties of a data column that will be used in a Fiddler model. It includes information about the column's data type, value ranges, categorical values, binning configuration, and other metadata necessary for proper data validation and monitoring. This class is used within ModelSchema to define the complete structure of data that a model expects to receive. ## Examples Creating a numeric column: ```python theme={null} column = Column( name="age", data_type=DataType.INTEGER, min=0, max=120 ) ``` Creating a categorical column: ```python theme={null} column = Column( name="category", data_type=DataType.CATEGORY, categories=["A", "B", "C"] ) ``` Creating a vector column: ```python theme={null} column = Column( name="embedding", data_type=DataType.VECTOR, n_dimensions=128 ) ``` ## name Column name provided by the customer ## data\_type Data type of the column ## min Min value of integer/float column ## max Max value of integer/float column ## categories List of unique values of a categorical column ## bins Bins of integer/float column ## replace\_with\_nulls Replace the list of given values to NULL if found in the events data ## model\_config Configuration for the model, should be a dictionary conforming to \[ConfigDict]\[pydantic.config.ConfigDict]. ## n\_dimensions Number of dimensions of a vector column # CompareTo Source: https://docs.fiddler.ai/sdk-api/python-client/compare-to Comparison baseline types for alert rule thresholds. Comparison baseline types for alert rule thresholds. Determines what the current metric value should be compared against when evaluating alert conditions. ## TIME\_PERIOD Compare to a historical time period (relative comparison). Useful for detecting changes over time, seasonal patterns, etc. When using TIME\_PERIOD, the compare\_bin\_delta parameter specifies how many time periods back to compare against. ## RAW\_VALUE Compare to an absolute threshold value (absolute comparison). Useful for hard limits and business rule enforcement. When using RAW\_VALUE, compare\_bin\_delta is ignored. When using TIME\_PERIOD, the allowed compare\_bin\_delta values depend on bin\_size: ### Example ```python theme={null} # Compare current hourly drift to same hour yesterday (24 hours ago) alert_rule = AlertRule( compare_to=CompareTo.TIME_PERIOD, bin_size=BinSize.HOUR, compare_bin_delta=24 # 24 hours ago ) # Compare daily metrics to last week (7 days ago) alert_rule = AlertRule( compare_to=CompareTo.TIME_PERIOD, bin_size=BinSize.DAY, compare_bin_delta=7 # 7 days ago ) # Compare current accuracy to absolute minimum (no time comparison) alert_rule = AlertRule( compare_to=CompareTo.RAW_VALUE, threshold=0.85 # Must be above 85% ) ``` ## TIME\_PERIOD *= 'time\_period'* ## RAW\_VALUE *= 'raw\_value'* # Conflict Source: https://docs.fiddler.ai/sdk-api/python-client/conflict Raised when a request conflicts with the current state of a resource (HTTP 409). Raised when a request conflicts with the current state of a resource (HTTP 409). This exception occurs when attempting to perform an operation that conflicts with the current state of a resource. This typically happens when trying to create resources that already exist, or when concurrent modifications cause state conflicts. Common scenarios include creating models or projects with names that already exist, attempting to modify resources that are currently being processed, or violating business rules that prevent certain operations. ## Examples Handling resource conflicts: ```python theme={null} try: project = client.create_project(name="existing-project") except Conflict as e: print(f"Project already exists: {e.message}") # Use existing project or choose different name project = client.get_project("existing-project") ``` Handling state conflicts: ```python theme={null} try: model.update_status("active") except Conflict as e: print(f"Cannot change status: {e.message}") # Wait for current operation to complete ``` Common Conflict scenarios: ```python theme={null} - Creating resources with duplicate names - Modifying resources during processing - Violating business logic constraints - Concurrent modification conflicts ``` ## code ## reason # ConnError Source: https://docs.fiddler.ai/sdk-api/python-client/conn-error Raised when a connection error occurs during HTTP requests. Raised when a connection error occurs during HTTP requests. This exception was used to indicate general connection problems when trying to communicate with the Fiddler platform, such as network unreachability, DNS resolution failures, or connection refused errors. ## Examples Historical usage (now deprecated): ```python theme={null} try: # Network API call pass except ConnError as e: print(f"Connection failed: {e.message}") # Check network connectivity or URL configuration ``` ## message # ConnTimeout Source: https://docs.fiddler.ai/sdk-api/python-client/conn-timeout Raised when a connection timeout occurs during HTTP requests. Raised when a connection timeout occurs during HTTP requests. This exception was used to indicate that an HTTP request to the Fiddler platform timed out while waiting for a response. Timeouts can occur due to network issues, server overload, or requests taking longer than the configured timeout period. ## Examples Historical usage (now deprecated): ```python theme={null} try: # Long-running API call pass except ConnTimeout as e: print(f"Request timed out: {e.message}") # Retry with longer timeout or check network ``` ## message # Connection Source: https://docs.fiddler.ai/sdk-api/python-client/connection Manages authenticated connections to the Fiddler platform. Manages authenticated connections to the Fiddler platform. The Connection class handles all aspects of connecting to and communicating with the Fiddler platform, including authentication, HTTP client management, server version compatibility checking, and organization context management. This class provides the foundation for all API interactions with Fiddler, managing connection parameters, authentication tokens, and ensuring proper communication protocols are established. ## Examples Creating a basic connection: ```python theme={null} connection = Connection( url="https://your-fiddler-instance.com", token="your-api-key" ) ``` Creating a connection with custom timeout and proxy: ```python theme={null} connection = Connection( url="https://your-fiddler-instance.com", token="your-api-key", timeout=(5.0, 30.0), # (connect_timeout, read_timeout) proxies={"https": "https://proxy.company.com:8080"} ) ``` Creating a connection without SSL verification: ```python theme={null} connection = Connection( url="https://your-fiddler-instance.com", token="your-api-key", verify=False, # Not recommended for production validate=False # Skip version compatibility check ) ``` Initialize a connection to the Fiddler platform. ## Parameters The base URL to your Fiddler platform instance API key obtained from the Fiddler UI Credentials tab Dictionary mapping protocol to proxy URL for HTTP requests HTTP request timeout settings (float or tuple of connect/read timeouts) Whether to verify server's TLS certificate (default: True) Whether to validate server/client version compatibility (default: True) ## Raises * **ValueError** – If url or token parameters are empty * **IncompatibleClient** – If server version is incompatible with client version ## *property* client Get the HTTP request client instance for API communication. ### Returns Configured HTTP client with authentication headers, proxy settings, and timeout configurations. ## *property* server\_info Get server information and metadata from the Fiddler platform. ### Returns Server information including version, organization details, and platform configuration. ## *property* server\_version Get the semantic version of the connected Fiddler server. ### Returns Semantic version object representing the server version. ## *property* organization\_name Get the name of the connected organization. ### Returns Name of the organization associated with this connection. ## *property* organization\_id Get the UUID of the connected organization. ### Returns Unique identifier of the organization associated with this connection. # ConnectionMixin Source: https://docs.fiddler.ai/sdk-api/python-client/connection-mixin Mixin class providing connection-related functionality to other classes. Mixin class providing connection-related functionality to other classes. ConnectionMixin provides a standardized way for other classes to access the global Fiddler connection instance and its associated properties. This mixin enables classes throughout the Fiddler client to access connection details, HTTP client functionality, and organization context without directly managing connection state. This pattern ensures consistent access to connection resources across all client components while maintaining a clean separation of concerns. ## organization\_name() Property access to organization name ## organization\_id() Property access to organization UUID ## get\_organization\_name() Class method to retrieve organization name ### Returns `str` ## get\_organization\_id() Class method to retrieve organization UUID ### Returns `UUID` ### Examples Using ConnectionMixin in a custom class: ```python theme={null} class CustomModel(ConnectionMixin): def fetch_data(self): # Access HTTP client through mixin response = self._client().get('/api/data') return response.json() def get_org_info(self): # Access organization info through mixin return { 'name': self.organization_name, 'id': str(self.organization_id) } ``` Using class methods without instantiation: ```python theme={null} org_name = SomeEntityClass.get_organization_name() org_id = SomeEntityClass.get_organization_id() ``` ## *property* organization\_name Get the organization name from the connection. ### Returns Name of the organization associated with the current connection. ## *property* organization\_id Get the organization UUID from the connection. ### Returns Unique identifier of the organization associated with the current connection. ## *classmethod* get\_organization\_name() Get the organization name from the global connection. ### Returns Name of the organization associated with the current connection. ## *classmethod* get\_organization\_id() Get the organization UUID from the global connection. ### Returns Unique identifier of the organization associated with the current connection. # create_columns_from_df Source: https://docs.fiddler.ai/sdk-api/python-client/create-columns-from-df Helper function to create Columns from a pandas DataFrame column dtypes. Helper function to create Columns from a pandas DataFrame column dtypes. timedelta, period, interval & object dtypes are converted to string. Sparse dtypes are not handled. * **df**: Input pandas DataFrame ## Returns ModelSchema # CustomFeature Source: https://docs.fiddler.ai/sdk-api/python-client/custom-feature Base class for all custom feature types in Fiddler models. Base class for all custom feature types in Fiddler models. CustomFeature provides the foundation for creating specialized feature types that enhance model monitoring and analysis. Custom features allow you to define derived metrics, embeddings, and enrichments that extend beyond basic model inputs and outputs for advanced drift detection and analysis. This is an abstract base class that should not be instantiated directly. Instead, use one of its concrete subclasses: Multivariate, VectorFeature, TextEmbedding, ImageEmbedding, or Enrichment. ## Examples Creating a multivariate feature from multiple columns: ```python theme={null} feature = CustomFeature.from_columns( custom_name="user_behavior_cluster", cols=["clicks", "views", "time_spent"], n_clusters=5 ) ``` Creating a custom feature from a dictionary: ```python theme={null} feature_dict = { "name": "text_sentiment", "type": "FROM_TEXT_EMBEDDING", "column": "embedding_col", "source_column": "review_text" } feature = CustomFeature.from_dict(feature_dict) ``` ## name ## type ## model\_config Configuration for the model, should be a dictionary conforming to \[ConfigDict]\[pydantic.config.ConfigDict]. ## *classmethod* from\_columns() ### Returns [`Multivariate`](/sdk-api/python-client/multivariate) ## *classmethod* from\_dict() ### Returns `Any` ## to\_dict() ### Returns `Dict[str, Any]` # CustomFeatureType Source: https://docs.fiddler.ai/sdk-api/python-client/custom-feature-type Types of custom features for advanced model monitoring. Types of custom features for advanced model monitoring. This enum defines different types of custom features that can be created for advanced monitoring scenarios. Custom features enable monitoring of complex data types, embeddings, and multi-column relationships. Feature Categories: * **Multi-column**: Features derived from multiple input columns * **Vector-based**: Features from embedding or vector columns * **Embedding-specific**: Specialized embedding monitoring * **Enrichment**: Features from data enrichment processes ## Examples Creating different types of custom features: ```python theme={null} # Multi-column feature for monitoring column interactions multivariate_feature = fdl.Multivariate( name='user_profile', columns=['age', 'income', 'location'], monitor_components=True ) # Vector feature for embedding monitoring vector_feature = fdl.VectorFeature( name='product_embedding', column='product_vector', n_clusters=10 ) # Text embedding feature with clustering text_embedding = fdl.TextEmbedding( name='review_sentiment', column='review_embedding', n_clusters=5, n_tags=10 ) # Image embedding feature image_embedding = fdl.ImageEmbedding( name='image_features', column='image_embedding', n_clusters=8 ) # Enrichment feature for data validation enrichment_feature = fdl.Enrichment( name='email_validation', enrichment='email_validation', columns=['email_address'], config={'strict': True} ## ) ``` Custom features enable advanced monitoring capabilities but require careful configuration to match your specific use case and data structure. ## FROM\_COLUMNS *= 'FROM\_COLUMNS'* Multi-column derived features (Multivariate). Used for creating custom features that monitor relationships and interactions between multiple input columns. Enables detection of drift patterns across column combinations. Characteristics: * Monitors multiple columns as a single feature * Detects multi-dimensional drift patterns * Can monitor individual components separately * Supports complex feature interactions Use cases: * Geographic coordinates (latitude, longitude) * User profiles (age, income, location) * Product specifications (dimensions, weight, price) * Time series components (trend, seasonality) Configuration: * Specify list of columns to monitor together * Optional component monitoring * Clustering for dimensionality reduction ## FROM\_VECTOR *= 'FROM\_VECTOR'* Single vector column features (VectorFeature). Used for monitoring embedding vectors or other high-dimensional numerical arrays as single features. Enables clustering-based drift detection and embedding analysis. Characteristics: * Monitors single vector/embedding column * Clustering-based drift detection * Dimensionality reduction visualization * Vector similarity analysis Use cases: * Word embeddings (Word2Vec, GloVe) * Neural network hidden layer outputs * Feature vectors from autoencoders * Learned representations Configuration: * Specify vector column name * Set number of clusters for monitoring * Optional source column reference ## FROM\_TEXT\_EMBEDDING *= 'FROM\_TEXT\_EMBEDDING'* Text embedding features (TextEmbedding). Specialized for monitoring text embeddings with text-specific analysis capabilities. Includes TF-IDF summarization and text-aware clustering. Characteristics: * Text-specific embedding analysis * TF-IDF token summarization * Text-aware clustering * Semantic drift detection Use cases: * BERT, GPT embeddings * Document embeddings * Sentence transformers * Text classification features Configuration: * Specify embedding column * Set number of clusters * Configure TF-IDF tags per cluster ## FROM\_IMAGE\_EMBEDDING *= 'FROM\_IMAGE\_EMBEDDING'* Image embedding features (ImageEmbedding). Specialized for monitoring image embeddings and visual features extracted from images. Optimized for computer vision model monitoring. Characteristics: * Image-specific embedding analysis * Visual feature clustering * Image-aware drift detection * Computer vision optimizations Use cases: * CNN feature extractions * Image classification embeddings * Object detection features * Visual similarity vectors Configuration: * Specify embedding column * Set clustering parameters * Image-specific preprocessing ## ENRICHMENT *= 'ENRICHMENT'* Enrichment-derived features (Enrichment). Used for features created through data enrichment processes such as validation, transformation, or external data augmentation. Enables monitoring of enriched data quality and consistency. Characteristics: * Derived from enrichment processes * Data quality monitoring * Validation result tracking * Transformation monitoring Use cases: * Email validation results * Address standardization * Data quality scores * External API enrichments Configuration: * Specify enrichment type * Configure enrichment parameters * Set input columns for enrichment # CustomMetric Source: https://docs.fiddler.ai/sdk-api/python-client/custom-metric Custom metric for monitoring business-specific and domain-specific KPIs. Custom metric for monitoring business-specific and domain-specific KPIs. CustomMetric enables creation of user-defined metrics that calculate specific values from model data using SQL-like expressions. Custom metrics extend Fiddler's built-in monitoring capabilities to support business requirements, domain-specific quality measures, and complex performance indicators. ## Example ```python theme={null} # Business conversion rate metric conversion_rate = CustomMetric( name="weekly_conversion_rate", model_id=model.id, definition="sum(if(prediction_score > 0.7 and converted == 1, 1, 0)) / sum(if(prediction_score > 0.7, 1, 0))", description="Conversion rate for high-confidence predictions" ).create() # Data quality metric missing_rate = CustomMetric( name="feature_missing_rate", model_id=model.id, definition="sum(if(is_null(income), 1, 0)) / count(income)", description="Percentage of records with missing income values" ).create() # Fairness metric fairness_metric = CustomMetric( name="demographic_parity", model_id=model.id, definition="abs((sum(if(gender == 'Male', predicted_churn, 0)) / sum(if(gender == 'Male', 1, 0))) - (sum(if(gender == 'Female', predicted_churn, 0)) / sum(if(gender == 'Female', 1, 0))))", description="Demographic parity difference between gender groups" ).create() # Use in alert rule alert_rule = AlertRule( name="conversion_rate_alert", model_id=model.id, metric_id=conversion_rate.id, priority=Priority.HIGH, compare_to=CompareTo.TIME_PERIOD, condition=AlertCondition.LESSER, bin_size=BinSize.DAY, critical_threshold=0.15, # Alert if conversion drops below 15% compare_bin_delta=7 ).create() ``` Custom metrics are calculated during data ingestion and monitoring cycles. Complex expressions may impact performance, so optimize for efficiency. Test expressions thoroughly before using in production alert rules. ## create() Create a new CustomMetric on the Fiddler platform. Registers this CustomMetric with the Fiddler platform. The expression must have a name, model\_id, and definition specified before calling create(). ### Returns The same CustomMetric instance with updated server-side attributes (id, created\_at, etc.). ### Raises * **ApiError** – If there's an error communicating with the Fiddler API. * **Conflict** – If a CustomMetric with the same name already exists for this model. ## delete() Delete this CustomMetric from the Fiddler platform. Permanently removes the CustomMetric. This action cannot be undone. Any alert rules or monitors using this CustomMetric must be deleted first. ### Raises * **NotFound** – If the CustomMetric no longer exists. * **ApiError** – If there's an error communicating with the Fiddler API. * **Conflict** – If the CustomMetric is still being used by alert rules or monitors. ## *classmethod* from\_name() Retrieve a CustomMetric by name and model. Fetches a CustomMetric from the Fiddler platform using its name and associated model ID. ### Parameters The name of the CustomMetric to retrieve. UUID or string identifier of the associated Model. ### Returns The CustomMetric instance for the provided parameters. ### Raises * **NotFound** – If no CustomMetric exists with the specified name and model. * **ApiError** – If there's an error communicating with the Fiddler API. ## *classmethod* get() Retrieve a CustomMetric by its unique identifier. Fetches a CustomMetric from the Fiddler platform using its UUID. ### Parameters The unique identifier (UUID) of the CustomMetric to retrieve. Can be provided as a UUID object or string representation. ### Returns The CustomMetric instance with all its configuration and metadata. ### Raises * **NotFound** – If no CustomMetric exists with the specified ID. * **ApiError** – If there's an error communicating with the Fiddler API. ## *classmethod* get\_organization\_id() Get the organization UUID from the global connection. ### Returns Unique identifier of the organization associated with the current connection. ## *classmethod* get\_organization\_name() Get the organization name from the global connection. ### Returns Name of the organization associated with the current connection. ## *classmethod* list() List all CustomMetric instances for a model. Retrieves all CustomMetric instances associated with a specific model. ### Parameters UUID or string identifier of the Model. ### Yields CustomMetric instances for each CustomMetric in the model. ### Raises **ApiError** – If there's an error communicating with the Fiddler API. ### Returns `Iterator[CustomMetric]` ## **init**() Construct a custom metric instance. # DataType Source: https://docs.fiddler.ai/sdk-api/python-client/data-type Data types supported for model columns in Fiddler. Data types supported for model columns in Fiddler. This enum defines the supported data types for model schema columns. Data types determine how Fiddler processes, validates, and monitors individual columns in your model's input and output data. Type Categories: * **Numeric**: FLOAT, INTEGER - enable statistical analysis * **Categorical**: BOOLEAN, CATEGORY - enable distribution analysis * **Textual**: STRING - enable text-based monitoring * **Temporal**: TIMESTAMP - enable time-based analysis * **Vector**: VECTOR - enable embedding-based monitoring ## Examples Defining column data types in model schema: ```python theme={null} from fiddler import Column, DataType # Define columns with appropriate data types columns = [ Column(name='age', data_type=DataType.INTEGER), Column(name='income', data_type=DataType.FLOAT), Column(name='is_member', data_type=DataType.BOOLEAN), Column(name='category', data_type=DataType.CATEGORY), Column(name='description', data_type=DataType.STRING), Column(name='created_at', data_type=DataType.TIMESTAMP), Column(name='embedding', data_type=DataType.VECTOR) ] # Create model schema schema = fdl.ModelSchema(columns=columns) ``` Data type validation and monitoring: ```python theme={null} # Numeric types enable statistical monitoring if column.data_type.is_numeric(): # Statistical drift detection available # Range validation enabled # Distribution analysis supported pass # Categorical types enable distribution monitoring if column.data_type.is_bool_or_cat(): # Category distribution tracking # New category detection # Frequency analysis pass # Vector types enable embedding monitoring if column.data_type.is_vector(): # Embedding drift detection # Clustering analysis # Dimensionality monitoring pass ``` Choose data types that accurately represent your data for optimal monitoring and validation. Incorrect data types may lead to inappropriate metrics or monitoring failures. ## FLOAT *= 'float'* Floating-point numerical values. Used for continuous numerical data with decimal precision. Enables comprehensive statistical analysis and numerical drift detection. Characteristics: * Decimal precision values * Statistical distribution analysis * Range and outlier detection * Correlation analysis support Monitoring features: * Mean, median, standard deviation tracking * Distribution drift detection (KS test, PSI) * Range violation alerts * Outlier detection and analysis Typical use cases: * Prices, costs, revenues * Probabilities and confidence scores * Measurements and sensor readings * Performance metrics and ratios * Model prediction scores Validation: Numeric range checks, NaN detection ## INTEGER *= 'int'* Integer numerical values. Used for whole number data without decimal places. Supports numerical analysis while recognizing discrete nature of integer data. Characteristics: * Whole number values only * Discrete distribution analysis * Count-based statistics * Range validation Monitoring features: * Count distribution tracking * Range violation detection * Discrete value frequency analysis * Statistical drift detection Typical use cases: * Counts and quantities * Age, years, days * IDs and identifiers (when numeric) * Ranking positions * Categorical codes (when numeric) Validation: Integer format checks, range validation ## BOOLEAN *= 'bool'* True/false binary values. Used for binary flag data with exactly two possible values. Enables binary distribution analysis and proportion tracking. Characteristics: * Exactly two values (True/False, 1/0, Yes/No) * Binary distribution analysis * Proportion-based metrics * Simple categorical handling Monitoring features: * True/False ratio tracking * Binary distribution drift * Proportion change detection * Flag frequency analysis Typical use cases: * Feature flags and indicators * Binary classifications * Yes/No survey responses * Membership status * Activation states Validation: Binary value format checks ## STRING *= 'str'* Text string values. Used for textual data of variable length. Supports text-based analysis and can be combined with text embeddings for advanced monitoring. Characteristics: * Variable length text * Text-based analysis * String pattern detection * Encoding-aware processing Monitoring features: * Length distribution tracking * Pattern and format analysis * Text embedding integration * String uniqueness analysis Typical use cases: * Names and descriptions * Comments and reviews * URLs and paths * Free-form text inputs * JSON or XML strings Special considerations: * Can be converted to embeddings for semantic monitoring * Supports text enrichment features * May require text preprocessing ## CATEGORY *= 'category'* Categorical values with limited distinct options. Used for data with a finite set of possible values or categories. Enables categorical distribution analysis and new category detection. Characteristics: * Limited set of possible values * Categorical distribution tracking * Category frequency analysis * New category detection Monitoring features: * Category distribution drift * New/missing category alerts * Frequency change detection * Category proportion analysis Typical use cases: * Product categories * Geographic regions * Status codes * Demographic categories * Classification labels Best practices: * Use for data with \< 1000 unique values * Consider STRING type for high-cardinality categories * Define expected categories during schema creation ## TIMESTAMP *= 'timestamp'* Date and time values. Used for temporal data including dates, times, and timestamps. Enables time-based analysis and temporal pattern detection. Characteristics: * Date/time information * Temporal ordering * Time-based aggregations * Timezone awareness Monitoring features: * Temporal pattern analysis * Time gap detection * Seasonal trend monitoring * Data freshness tracking Typical use cases: * Event timestamps * Creation/modification dates * Transaction times * Log timestamps * Scheduled events Supported formats: * Unix timestamps * ISO 8601 strings * Pandas datetime objects * Various date formats (with parsing) ## VECTOR *= 'vector'* Multi-dimensional numerical vectors (embeddings). Used for embedding vectors, feature vectors, and other multi-dimensional numerical data. Enables embedding-based drift detection and clustering analysis. Characteristics: * Fixed-dimension numerical arrays * Embedding-based analysis * Vector similarity metrics * Clustering support Monitoring features: * Embedding drift detection * Cluster analysis and visualization * Vector similarity tracking * Dimensionality validation Typical use cases: * Text embeddings (Word2Vec, BERT, etc.) * Image embeddings (CNN features) * User/item embeddings * Feature vectors from neural networks * Recommendation system embeddings Special considerations: * Requires consistent vector dimensions * Benefits from custom feature definitions * Supports clustering and UMAP visualization ## is\_numeric() Check if the data type is numeric. ### Returns True if data type is INTEGER or FLOAT ## is\_bool\_or\_cat() Check if the data type is boolean or categorical. ### Returns True if data type is BOOLEAN or CATEGORY ## is\_vector() Check if the data type is vector. ### Returns True if data type is VECTOR # Dataset Source: https://docs.fiddler.ai/sdk-api/python-client/dataset Represents a dataset containing data published to a Fiddler model. Represents a dataset containing data published to a Fiddler model. A Dataset is a collection of data records that have been published to a specific model in the Fiddler platform. Datasets are automatically created when data is published using Model.publish() and serve as the foundation for monitoring, drift detection, and baseline creation. Key Features: * **Data Collection**: Organized storage of model input/output data * **Environment Separation**: Distinct handling of production vs. pre-production data * **Baseline Source**: Reference data for drift detection and monitoring * **Analysis Support**: Data download and statistical analysis capabilities * **Model Integration**: Tight coupling with specific models for context Dataset Characteristics: * **Automatic Creation**: Created by Model.publish() operations * **Model-Scoped**: Each dataset belongs to exactly one model * **Named Collections**: Unique names within a model for identification * **Row Tracking**: Automatic counting of data records * **Environment Typed**: Classified as production or pre-production data ## Example ```python theme={null} # Retrieve a specific dataset dataset = Dataset.from_name( name="training_data_v1", model_id=model.id ) print(f"Dataset: {dataset.name}") print(f"Rows: {dataset.row_count}") print(f"Model: {dataset.model_id}") # List all datasets for a model datasets = list(Dataset.list(model_id=model.id)) print(f"Found {len(datasets)} datasets") # Find datasets by characteristics large_datasets = [ ds for ds in Dataset.list(model_id=model.id) if ds.row_count and ds.row_count > 10000 ] ``` Datasets cannot be created directly through the Dataset class. They are automatically created when data is published to models using Model.publish(). Use the Dataset class for retrieval, listing, and analysis operations. Initialize a Dataset instance. Creates a dataset object representing data published to a model. This constructor is typically used internally when deserializing API responses rather than for direct dataset creation. ## Parameters Dataset name, must be unique within the model. Should be descriptive of the data contents or purpose. Identifier of the model this dataset belongs to. Can be provided as UUID object or string representation. Identifier of the parent project. Can be provided as UUID object or string representation. ## Example ```python theme={null} # Internal usage - typically not called directly dataset = Dataset( name="training_baseline_v1", model_id="550e8400-e29b-41d4-a716-446655440000", project_id="660e8400-e29b-41d4-a716-446655440000" ) ``` Datasets are typically retrieved using Dataset.get(), Dataset.from\_name(), or Dataset.list() rather than created directly. Direct creation is mainly used internally by the Fiddler client. ## *classmethod* get() Retrieve a dataset by its unique identifier. Fetches a dataset from the Fiddler platform using its UUID. This is the most direct way to retrieve a dataset when you know its ID. ### Parameters The unique identifier (UUID) of the dataset to retrieve. Can be provided as a UUID object or string representation. ### Returns The dataset instance with all metadata and row count information. ### Raises * **NotFound** – If no dataset exists with the specified ID. * **ApiError** – If there's an error communicating with the Fiddler API. ### Example ```python theme={null} # Get dataset by UUID dataset = Dataset.get(id_="550e8400-e29b-41d4-a716-446655440000") print(f"Retrieved dataset: {dataset.name}") print(f"Rows: {dataset.row_count}") print(f"Model: {dataset.model_id}") # Use dataset for analysis if dataset.row_count and dataset.row_count > 1000: print("Large dataset suitable for baseline creation") ``` This method makes an API call to fetch the latest dataset state from the server. The returned dataset instance reflects the current state in Fiddler. ## *classmethod* from\_name() Retrieve a dataset by name within a specific model. Finds and returns a dataset using its name and model context. Dataset names are unique within a model, making this a reliable lookup method when you know both the dataset name and model ID. ### Parameters The name of the dataset to retrieve. Dataset names are unique within a model and are case-sensitive. The identifier of the model containing the dataset. Can be provided as UUID object or string representation. ### Returns The dataset instance matching the specified name and model. ### Raises * **NotFound** – If no dataset exists with the specified name in the given model. * **ApiError** – If there's an error communicating with the Fiddler API. ### Example ```python theme={null} # Get dataset by name for a specific model dataset = Dataset.from_name( name="training_baseline", model_id=model.id ) print(f"Found dataset: {dataset.name}") print(f"Rows: {dataset.row_count}") # Get validation dataset val_dataset = Dataset.from_name( name="validation_set_v2", model_id=model.id ) # Use for baseline creation baseline = Baseline.create_from_dataset( dataset_id=dataset.id, name="training_baseline" ) ``` Dataset names are case-sensitive and must match exactly. This method is useful when you know the dataset name from configuration or when working with named datasets created during model training workflows. ## *classmethod* list() List all pre-production datasets for a specific model. Retrieves all datasets that have been published to a model in the pre-production environment. These datasets are typically used for baselines, training data analysis, and validation purposes. ### Parameters The identifier of the model to list datasets for. Can be provided as UUID object or string representation. ### Yields `Dataset` – Dataset instances for all pre-production datasets in the model. ### Raises **ApiError** – If there's an error communicating with the Fiddler API. ### Returns `Iterator[Dataset]` ### Example ```python theme={null} # List all datasets for a model for dataset in Dataset.list(model_id=model.id): print(f"Dataset: {dataset.name}") print(f" Rows: {dataset.row_count}") print(f" ID: {dataset.id}") # Convert to list for analysis datasets = list(Dataset.list(model_id=model.id)) print(f"Found {len(datasets)} datasets") # Find datasets by characteristics large_datasets = [ ds for ds in Dataset.list(model_id=model.id) if ds.row_count and ds.row_count > 10000 ] print(f"Large datasets: {len(large_datasets)}") # Get dataset summary statistics total_rows = sum( ds.row_count or 0 for ds in Dataset.list(model_id=model.id) ) print(f"Total rows across all datasets: {total_rows}") ``` This method returns an iterator for memory efficiency and only includes pre-production datasets. Production data is handled separately through the monitoring system. Convert to a list with list(Dataset.list(…)) if you need to iterate multiple times. # DatasetCompact Source: https://docs.fiddler.ai/sdk-api/python-client/dataset-compact Lightweight dataset representation for listing and basic operations. Lightweight dataset representation for listing and basic operations. A minimal dataset object containing only essential identifiers. Used by various operations to efficiently reference datasets without fetching full dataset details and metadata. This class provides a memory-efficient way to work with dataset references when you don't need the full dataset functionality but want to access basic information or fetch the complete dataset when needed. ## Example ```python theme={null} # From dataset references in other entities baseline = Baseline.get(id_="baseline-uuid") dataset_ref = baseline.dataset # Returns DatasetCompact # Access basic info print(f"Dataset: {dataset_ref.name}") print(f"ID: {dataset_ref.id}") # Fetch full details when needed full_dataset = dataset_ref.fetch() print(f"Rows: {full_dataset.row_count}") print(f"Model: {full_dataset.model_id}") ``` DatasetCompact objects are typically returned by other entities that reference datasets. Use .fetch() to get the complete Dataset instance when you need full functionality like row counts or model information. ## id ## name ## fetch() Fetch the complete Dataset instance. Retrieves the full Dataset object with all metadata, row counts, and model associations from the Fiddler platform using this compact dataset's ID. ### Returns Complete dataset instance with all details and capabilities. ### Example ```python theme={null} # From dataset reference compact = baseline.dataset # Get full dataset details full_dataset = compact.fetch() # Now can access full functionality print(f"Dataset has {full_dataset.row_count} rows") print(f"Belongs to model: {full_dataset.model_id}") ``` # DatasetDataSource Source: https://docs.fiddler.ai/sdk-api/python-client/dataset-data-source Data source for explainability analysis using a sample from a dataset. Data source for explainability analysis using a sample from a dataset. DatasetDataSource allows you to perform explainability analysis on a random sample of data from a specified environment/dataset. This is useful for understanding general model behavior, analyzing feature importance patterns across multiple instances, or getting representative explanations. This data source type is ideal for exploratory analysis, understanding overall model behavior, or when you want to analyze explanations across a representative sample rather than specific instances. ## Examples Creating a dataset data source for production sampling: ```python theme={null} dataset_source = DatasetDataSource( env_type="PRODUCTION", num_samples=100, env_id="prod_dataset_uuid" ) ``` Creating a dataset data source for validation analysis: ```python theme={null} validation_source = DatasetDataSource( env_type="VALIDATION", num_samples=50 ) ``` Creating a dataset data source with default sampling: ```python theme={null} default_source = DatasetDataSource( env_type="PRODUCTION" ) ``` ## source\_type ## env\_type ## num\_samples ## env\_id ## model\_config Configuration for the model, should be a dictionary conforming to \[ConfigDict]\[pydantic.config.ConfigDict]. # DeploymentParams Source: https://docs.fiddler.ai/sdk-api/python-client/deployment-params Configuration parameters for deploying a model in the Fiddler platform. Configuration parameters for deploying a model in the Fiddler platform. DeploymentParams defines the deployment configuration for a model, including the artifact type, deployment environment, resource allocation, and container specifications. These parameters control how the model is packaged, deployed, and scaled within the Fiddler infrastructure. This class is used when deploying models to specify the runtime environment, resource requirements, and deployment strategy that best fits your model's needs and performance requirements. ## Examples Creating basic deployment parameters: ```python theme={null} basic_params = DeploymentParams() ``` Creating deployment with custom resources: ```python theme={null} custom_params = DeploymentParams( artifact_type=ArtifactType.PYTHON_PACKAGE, deployment_type=DeploymentType.BASE_CONTAINER, replicas=3, cpu=2, memory=4096 ) ``` Creating deployment with custom container: ```python theme={null} container_params = DeploymentParams( artifact_type=ArtifactType.DOCKER_IMAGE, deployment_type=DeploymentType.CUSTOM_CONTAINER, image_uri="my-registry.com/my-model:v1.0", replicas=2, cpu=4, memory=8192 ) ``` ## artifact\_type ## deployment\_type ## image\_uri ## replicas ## cpu ## memory ## model\_config Configuration for the model, should be a dictionary conforming to \[ConfigDict]\[pydantic.config.ConfigDict]. # DeploymentType Source: https://docs.fiddler.ai/sdk-api/python-client/deployment-type Model deployment types for explainability services. Model deployment types for explainability services. **Values:** * `BASE_CONTAINER` - BASE\_CONTAINER Base container deployment with standard environment. ## MANUAL *= 'MANUAL'* Manual deployment configuration. # DownloadFormat Source: https://docs.fiddler.ai/sdk-api/python-client/download-format File formats for downloading and exporting explanation data. File formats for downloading and exporting explanation data. This enum defines the supported file formats for downloading explanation results from Fiddler. Different formats offer different advantages in terms of performance, compatibility, and data structure preservation. ## PARQUET Apache Parquet format for efficient columnar storage ## CSV Comma-separated values format for broad compatibility ### Examples Downloading explanations in different formats: ```python theme={null} # Download as Parquet (recommended for large datasets) parquet_data = model.download_explanations( format=fdl.DownloadFormat.PARQUET, chunk_size=1000 ) # Download as CSV (better compatibility) csv_data = model.download_explanations( format=fdl.DownloadFormat.CSV, chunk_size=500 ## ) ``` Choose format based on your analysis tools and data size requirements. Parquet is recommended for large datasets due to compression and performance. ## PARQUET *= 'PARQUET'* Apache Parquet format for efficient columnar data storage. Parquet is a columnar storage format that provides excellent compression and query performance. It preserves data types and schema information, making it ideal for analytical workloads and large datasets. Advantages: * Excellent compression ratios * Fast query performance * Preserves data types and schema * Efficient for analytical operations Best for: * Large explanation datasets * Analytical workflows * Integration with data science tools * Long-term data storage ## CSV *= 'CSV'* Comma-separated values format for broad tool compatibility. CSV is a simple, widely-supported text format that can be opened by virtually any data analysis tool, spreadsheet application, or programming language. While less efficient than Parquet, it offers maximum compatibility. Advantages: * Universal compatibility * Human-readable format * Simple structure * Supported by all tools Best for: * Small to medium datasets * Sharing with non-technical users * Quick data inspection * Integration with legacy systems # Enrichment Source: https://docs.fiddler.ai/sdk-api/python-client/enrichment Represents custom features derived from enrichment operations. Represents custom features derived from enrichment operations. Enrichment features apply external processing or analysis to existing columns to create derived insights. This can include operations like sentiment analysis, toxicity detection, entity extraction, SQL validation, JSON validation, or any custom transformation that adds value to the original data. The feature type is automatically set to CustomFeatureType.ENRICHMENT and enables domain-specific analysis through configurable enrichment operations. ## Examples ```python theme={null} # Creating a sentiment analysis enrichment: sentiment_enrichment = Enrichment( name="review_sentiment", columns=["review_text"], enrichment="sentiment_analysis", config={ "model": "vader", "return_scores": True } ) # Creating a SQL validation enrichment: sql_enrichment = Enrichment( name="sql_validation", columns=["query_string"], enrichment="sql_validation", config={ "dialect": "postgresql", "strict": True } ) # Creating a JSON validation enrichment: json_enrichment = Enrichment( name="json_validation", columns=["json_string"], enrichment="json_validation", config={ "strict": True, "validation_schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "prop_1": {"type": "number"} }, "required": ["prop_1"], "additionalProperties": False } } ) # Creating a toxicity detection enrichment: toxicity_enrichment = Enrichment( name="content_toxicity", columns=["user_comment"], enrichment="toxicity_detection", config={ "threshold": 0.7, "categories": ["toxic", "severe_toxic", "obscene"] } ) ``` ## type ## columns ## enrichment ## config ## model\_config Configuration for the model, should be a dictionary conforming to \[ConfigDict]\[pydantic.config.ConfigDict]. # EnvType Source: https://docs.fiddler.ai/sdk-api/python-client/env-type Environment types for data publishing in Fiddler. Environment types for data publishing in Fiddler. This enum defines the two primary environment types used when publishing inference data to Fiddler. The environment type determines how Fiddler processes, stores, and monitors the data. ## PRODUCTION Live inference data from production model deployments ## PRE\_PRODUCTION Static baseline datasets for drift detection reference ### Examples Publishing pre-production baseline data: ```python theme={null} # Upload training data as baseline baseline_job = model.publish( source='training_data.csv', environment=fdl.EnvType.PRE_PRODUCTION, dataset_name='training_baseline' ## ) ``` Publishing production inference data: ```python theme={null} # Stream live inference events model.publish( source=inference_events, environment=fdl.EnvType.PRODUCTION ## ) ``` Environment-specific data handling: ```python theme={null} # Different processing based on environment if env_type == fdl.EnvType.PRE_PRODUCTION: # Static dataset - immutable after upload # Used for baseline calculations # No time-series monitoring pass elif env_type == fdl.EnvType.PRODUCTION: # Time-series data - continuous monitoring # Compared against baselines for drift # Subject to data retention policies pass ``` Environment types cannot be changed after data publication. Choose the appropriate environment based on your data's intended use case. ## PRODUCTION *= 'PRODUCTION'* Production environment for live inference data. Used for time-series inference data from live model deployments. This data: * Gets monitored continuously for drift and performance issues * Is compared against baseline datasets for anomaly detection * Supports real-time streaming and batch publishing * Is subject to data retention policies (typically 90 days) * Enables alert rule evaluation and dashboard visualization Typical use cases: * Live model inference results * Real-time prediction streaming * Batch inference job outputs * A/B testing data * Production model monitoring Data characteristics: * Time-series with timestamps * Continuous data flow * Variable data volumes * Monitored for drift patterns ## PRE\_PRODUCTION *= 'PRE\_PRODUCTION'* Pre-production environment for baseline datasets. Used for static datasets that serve as reference points for monitoring. This data: * Remains immutable after publication * Serves as baseline for drift detection calculations * Represents expected model behavior and data distributions * Is retained indefinitely for comparison purposes * Does not appear in time-series monitoring charts Typical use cases: * Training dataset baselines * Validation dataset references * Historical "golden" datasets * Model performance benchmarks * Data distribution references Data characteristics: * Static, unchanging datasets * Representative of expected distributions * Used for statistical comparisons * No time-series component # EventIdDataSource Source: https://docs.fiddler.ai/sdk-api/python-client/event-id-data-source Data source for explainability analysis using a specific event ID. Data source for explainability analysis using a specific event ID. EventIdDataSource allows you to perform explainability analysis on a specific event that has been previously logged to Fiddler. This is useful when you want to explain predictions for events that are already stored in your environment, enabling you to analyze historical predictions and their explanations. This data source type is ideal for investigating specific incidents, analyzing historical predictions, or performing post-hoc analysis on logged events. ## Examples Creating an event data source for production analysis: ```python theme={null} event_source = EventIdDataSource( event_id="evt_12345abcdef", env_id="prod_dataset_uuid", env_type=EnvType.PRODUCTION ) ``` Creating an event data source for validation analysis: ```python theme={null} validation_event_source = EventIdDataSource( event_id="validation_event_789", env_id="validation_dataset_uuid", env_type=EnvType.VALIDATION ) ``` ## source\_type ## event\_id ## env\_id ## env\_type ## model\_config Configuration for the model, should be a dictionary conforming to \[ConfigDict]\[pydantic.config.ConfigDict]. # ExplainMethod Source: https://docs.fiddler.ai/sdk-api/python-client/explain-method Explanation methods for model interpretability and feature importance analysis. Explanation methods for model interpretability and feature importance analysis. This enum defines the available algorithms for computing feature importance and generating explanations for model predictions. Different methods provide different perspectives on how features contribute to model decisions. Method Categories: * **SHAP-based**: Unified framework for feature importance (SHAP, FIDDLER\_SHAP) * **Gradient-based**: Uses model gradients for explanations (IG) * **Perturbation-based**: Feature permutation and baseline methods ## Examples Using different explanation methods: ```python theme={null} # Standard SHAP explanations shap_explanations = model.explain( data_source=fdl.RowDataSource(row=sample_data), explain_method=fdl.ExplainMethod.SHAP ) # Fiddler's optimized SHAP (recommended) fast_explanations = model.explain( data_source=fdl.RowDataSource(row=sample_data), explain_method=fdl.ExplainMethod.FIDDLER_SHAP ) # Integrated Gradients for neural networks ig_explanations = model.explain( data_source=fdl.RowDataSource(row=sample_data), explain_method=fdl.ExplainMethod.IG ) # Permutation importance perm_explanations = model.explain( data_source=fdl.RowDataSource(row=sample_data), explain_method=fdl.ExplainMethod.PERMUTE ## ) ``` Method availability depends on model type and artifact configuration. FIDDLER\_SHAP is recommended for most use cases due to performance optimizations. ## SHAP *= 'SHAP'* Standard SHAP (SHapley Additive exPlanations) method. Implements the original SHAP algorithm for computing feature importance based on game theory. Provides globally consistent and locally accurate feature attributions that sum to the difference between model output and expected output. Characteristics: * Theoretically grounded in game theory * Satisfies efficiency, symmetry, dummy, and additivity axioms * Works with any machine learning model * Computationally intensive for complex models Best for: * Research and academic applications * When theoretical guarantees are important * Comparative analysis with other SHAP implementations ## FIDDLER\_SHAP *= 'FIDDLER\_SHAP'* Fiddler's optimized SHAP implementation for improved performance. Fiddler's enhanced version of SHAP that provides the same theoretical guarantees as standard SHAP but with significant performance improvements and optimizations for production use cases. Characteristics: * Same theoretical properties as standard SHAP * Significant performance optimizations * Better suited for production environments * Optimized for Fiddler's infrastructure Best for: * Production explainability workflows * High-volume explanation generation * Real-time explanation requirements * Most general-purpose use cases (recommended) ## IG *= 'IG'* Integrated Gradients method for gradient-based explanations. Computes feature importance by integrating gradients of the model output with respect to inputs along a straight path from a baseline to the input. Particularly effective for neural networks and differentiable models. Characteristics: * Uses model gradients for attribution * Satisfies implementation invariance and sensitivity axioms * Requires differentiable models * Effective for neural networks Best for: * Neural network models * Deep learning applications * When gradient information is available * Image and text models with embeddings ## PERMUTE *= 'PERMUTE'* Permutation-based feature importance analysis. Computes feature importance by measuring the decrease in model performance when feature values are randomly permuted. Provides model-agnostic importance scores based on predictive contribution. Characteristics: * Model-agnostic approach * Based on predictive performance impact * Computationally straightforward * Provides global feature importance Best for: * Model-agnostic analysis * Understanding overall feature importance * Comparing feature relevance across models * When other methods are not applicable ## ZERO\_RESET *= 'ZERO\_RESET'* Zero baseline reset method for feature ablation analysis. Computes feature importance by replacing feature values with zero and measuring the change in model output. Provides insights into how features contribute relative to a zero baseline. Characteristics: * Simple ablation-based approach * Uses zero as the baseline value * Fast computation * May not be suitable for all feature types Best for: * Quick feature importance analysis * Models where zero is a meaningful baseline * Sparse feature representations * Initial feature importance exploration ## MEAN\_RESET *= 'MEAN\_RESET'* Mean baseline reset method for feature ablation analysis. Computes feature importance by replacing feature values with their population mean and measuring the change in model output. Uses the training data mean as a more representative baseline than zero. Characteristics: * Ablation-based with mean baseline * Uses training data statistics * More representative baseline than zero * Accounts for feature distributions Best for: * Models where mean is a natural baseline * Features with non-zero typical values * When training distribution is representative * Comparative analysis with zero baseline # File Source: https://docs.fiddler.ai/sdk-api/python-client/file Construct a files instance. Construct a files instance. ## upload() Upload file. Single or multipart upload depends on file size ### Returns `File` ## single\_upload() Single part file upload ### Returns `File` ## multipart\_upload() Multi part file upload ### Returns `File` # group_by Source: https://docs.fiddler.ai/sdk-api/python-client/group-by Group the events by a column. Use this method to form the grouped data for ranking models. Group the events by a column. Use this method to form the grouped data for ranking models. ## Parameters The dataframe with flat data The column to group the data by Optional path to write the grouped data to. If not specified, data won't be written anywhere ## Returns Dataframe in grouped format ## Examples ```python theme={null} COLUMN_NAME = 'col_2' grouped_df = group_by(df=df, group_by_col=COLUMN_NAME) ``` # HttpError Source: https://docs.fiddler.ai/sdk-api/python-client/http-error Base class for all HTTP-related errors. Base class for all HTTP-related errors. This is the parent class for HTTP communication errors that can occur during API requests to the Fiddler platform. While this specific class is deprecated and no longer thrown directly, it serves as the base for more specific HTTP error types. This class is deprecated and not thrown anymore. Use more specific HTTP error subclasses like ApiError, NotFound, or Conflict instead. ## Examples Catching any HTTP-related error: ```python theme={null} try: # API operation pass except HttpError as e: print(f"HTTP error: {e.message}") ``` # ImageEmbedding Source: https://docs.fiddler.ai/sdk-api/python-client/image-embedding Represents custom features derived from image embeddings for visual content analysis. Represents custom features derived from image embeddings for visual content analysis. ImageEmbedding extends VectorFeature to handle image-based embeddings, providing clustering analysis specifically designed for visual content. This feature type is used to monitor image models and detect visual drift in high-dimensional embedding spaces. The feature type is automatically set to CustomFeatureType.FROM\_IMAGE\_EMBEDDING and applies clustering to image embeddings for visual pattern analysis. ## Examples Creating an image embedding feature for product photos: ```python theme={null} image_feature = ImageEmbedding( name="product_image_clusters", column="product_embedding", source_column="product_image_url", n_clusters=15 ) ``` Creating a feature for medical image analysis: ```python theme={null} medical_feature = ImageEmbedding( name="xray_pattern_clusters", column="xray_embedding", source_column="xray_image_path", n_clusters=10 ) ``` ## type ## source\_column ## model\_config Configuration for the model, should be a dictionary conforming to \[ConfigDict]\[pydantic.config.ConfigDict]. # IncompatibleClient Source: https://docs.fiddler.ai/sdk-api/python-client/incompatible-client Raised when the Python client version is incompatible with the Fiddler platform version. Raised when the Python client version is incompatible with the Fiddler platform version. This exception occurs during connection initialization when the client library version is not compatible with the connected Fiddler platform version. This ensures that users are aware of version mismatches that could cause unexpected behavior or missing functionality. The exception includes both the client version and server version in the error message to help users understand what versions are involved in the incompatibility. ## Examples Handling version incompatibility: ```python theme={null} try: fdl.init(url="https://old-fiddler.com", token="token") except IncompatibleClient as e: print(f"Version mismatch: {e.message}") # Upgrade client or contact administrator ``` Typical error message format: ```python theme={null} "Python Client version (3.8.0) is not compatible with your Fiddler Platform version (3.5.0)." ``` ## message # Introduction Source: https://docs.fiddler.ai/sdk-api/python-client/index Complete API reference for fiddler [![PyPI](https://img.shields.io/pypi/v/fiddler-client)](https://pypi.org/project/fiddler-client/) ## Overview Complete API reference documentation for the fiddler package. ## Components ### Connection Connection management and initialization * [Connection](/sdk-api/python-client/connection) * [ConnectionMixin](/sdk-api/python-client/connection-mixin) ### Constants Constants module documentation * [AlertCondition](/sdk-api/python-client/alert-condition) * [AlertThresholdAlgo](/sdk-api/python-client/alert-threshold-algo) * [ArtifactStatus](/sdk-api/python-client/artifact-status) * [ArtifactType](/sdk-api/python-client/artifact-type) * [BaselineType](/sdk-api/python-client/baseline-type) * [BinSize](/sdk-api/python-client/bin-size) * [CompareTo](/sdk-api/python-client/compare-to) * [CustomFeatureType](/sdk-api/python-client/custom-feature-type) * [DataType](/sdk-api/python-client/data-type) * [DeploymentType](/sdk-api/python-client/deployment-type) * [DownloadFormat](/sdk-api/python-client/download-format) * [EnvType](/sdk-api/python-client/env-type) * [ExplainMethod](/sdk-api/python-client/explain-method) * [JobStatus](/sdk-api/python-client/job-status) * [ModelInputType](/sdk-api/python-client/model-input-type) * [ModelTask](/sdk-api/python-client/model-task) * [Priority](/sdk-api/python-client/priority) * [WindowBinSize](/sdk-api/python-client/window-bin-size) ### Entities Core entity classes for interacting with the platform * [AlertRecord](/sdk-api/python-client/alert-record) * [AlertRule](/sdk-api/python-client/alert-rule) * [Baseline](/sdk-api/python-client/baseline) * [BaselineCompact](/sdk-api/python-client/baseline-compact) * [CustomMetric](/sdk-api/python-client/custom-metric) * [Dataset](/sdk-api/python-client/dataset) * [DatasetCompact](/sdk-api/python-client/dataset-compact) * [File](/sdk-api/python-client/file) * [Job](/sdk-api/python-client/job) * [Model](/sdk-api/python-client/model) * [ModelCompact](/sdk-api/python-client/model-compact) * [ModelDeployment](/sdk-api/python-client/model-deployment) * [Project](/sdk-api/python-client/project) * [ProjectCompact](/sdk-api/python-client/project-compact) * [Segment](/sdk-api/python-client/segment) * [Webhook](/sdk-api/python-client/webhook) ### Exceptions Exceptions module documentation * [ApiError](/sdk-api/python-client/api-error) * [AsyncJobFailed](/sdk-api/python-client/async-job-failed) * [Conflict](/sdk-api/python-client/conflict) * [ConnError](/sdk-api/python-client/conn-error) * [ConnTimeout](/sdk-api/python-client/conn-timeout) * [HttpError](/sdk-api/python-client/http-error) * [IncompatibleClient](/sdk-api/python-client/incompatible-client) * [NotFound](/sdk-api/python-client/not-found) * [Unsupported](/sdk-api/python-client/unsupported) ### Schemas Schemas module documentation * [Column](/sdk-api/python-client/column) * [CustomFeature](/sdk-api/python-client/custom-feature) * [DatasetDataSource](/sdk-api/python-client/dataset-data-source) * [DeploymentParams](/sdk-api/python-client/deployment-params) * [Enrichment](/sdk-api/python-client/enrichment) * [EventIdDataSource](/sdk-api/python-client/event-id-data-source) * [ImageEmbedding](/sdk-api/python-client/image-embedding) * [ModelSchema](/sdk-api/python-client/model-schema) * [ModelSpec](/sdk-api/python-client/model-spec) * [ModelTaskParams](/sdk-api/python-client/model-task-params) * [Multivariate](/sdk-api/python-client/multivariate) * [RowDataSource](/sdk-api/python-client/row-data-source) * [TextEmbedding](/sdk-api/python-client/text-embedding) * [VectorFeature](/sdk-api/python-client/vector-feature) * [XaiParams](/sdk-api/python-client/xai-params) ### Utils Utils module documentation * [create\_columns\_from\_df](/sdk-api/python-client/create-columns-from-df) * [group\_by](/sdk-api/python-client/group-by) # Job Source: https://docs.fiddler.ai/sdk-api/python-client/job Represents an asynchronous operation in the Fiddler platform. Represents an asynchronous operation in the Fiddler platform. A Job tracks the execution of long-running operations such as data publishing, model artifact uploads, surrogate model training, and other async tasks. Jobs provide status monitoring, progress tracking, and error handling for operations that may take significant time to complete. Key Features: * **Status Monitoring**: Real-time tracking of job execution state * **Progress Tracking**: Percentage completion for running operations * **Error Reporting**: Detailed error messages and failure reasons * **Timeout Handling**: Configurable timeouts for job completion * **Responsive Polling**: Efficient status checking with backoff strategies Job States: * **PENDING**: Job queued and waiting to start execution * **STARTED**: Job actively running with progress updates * **SUCCESS**: Job completed successfully * **FAILURE**: Job failed with detailed error information * **RETRY**: Job being retried after a failure * **REVOKED**: Job cancelled or terminated ## Example ```python theme={null} # Get a job by ID job = Job.get(id_="550e8400-e29b-41d4-a716-446655440000") print(f"Job: {job.name} - Status: {job.status}") print(f"Progress: {job.progress:.1f}%") # Wait for job completion job.wait(timeout=1800) # 30 minute timeout print("Job completed successfully!") # Monitor job progress in real-time for job_update in job.watch(interval=10, timeout=3600): print(f"{job_update.name}: {job_update.progress:.1f}%") if job_update.status in [JobStatus.SUCCESS, JobStatus.FAILURE]: break ``` Jobs are created automatically by async operations and cannot be instantiated directly. Use Job.get() to retrieve existing jobs and the monitoring methods to track progress and handle completion. Initialize a Job instance. Creates a job object for tracking asynchronous operations. This constructor is typically used internally when deserializing API responses rather than for direct job creation. Jobs are automatically created by async operations (like Model.publish(), Model.add\_artifact(), etc.) and cannot be created directly. Use Job.get() to retrieve existing jobs and monitoring methods to track progress. ## *classmethod* get() Retrieve a job by its unique identifier. Fetches a job from the Fiddler platform using its UUID. This is the primary way to retrieve job information for monitoring async operations. ### Parameters The unique identifier (UUID) of the job to retrieve. Can be provided as a UUID object or string representation. Whether to include detailed task execution information. When True, provides additional debugging and progress details. ### Returns The job instance with current status, progress, and metadata. ### Raises * **NotFound** – If no job exists with the specified ID. * **ApiError** – If there's an error communicating with the Fiddler API. ### Example ```python theme={null} # Get basic job information job = Job.get(id_="550e8400-e29b-41d4-a716-446655440000") print(f"Job: {job.name} - Status: {job.status}") print(f"Progress: {job.progress:.1f}%") # Get detailed job information for debugging detailed_job = Job.get( id_="550e8400-e29b-41d4-a716-446655440000", verbose=True ) print(f"Task details: {detailed_job.info}") # Check for errors if job.status == JobStatus.FAILURE: print(f"Error: {job.error_reason}") print(f"Details: {job.error_message}") ``` This method makes an API call to fetch the latest job state from the server. Use verbose=True when debugging failed jobs to get additional task details. ## watch() Monitor job progress with real-time status updates. Continuously polls the job status at specified intervals and yields updated job instances. This method provides real-time monitoring of job progress and automatically handles network errors and retries. ### Parameters Polling interval in seconds between status checks. Default is configured by JOB\_POLL\_INTERVAL (typically 5-10 seconds). Maximum time in seconds to monitor the job before giving up. Default is configured by JOB\_WAIT\_TIMEOUT (typically 1800 seconds). ### Yields `Job` – Updated job instances with current status and progress. ### Raises * **TimeoutError** – If the job doesn't complete within the specified timeout. * **AsyncJobFailed** – If the job fails during execution (raised by wait() method). ### Returns `Iterator[Job]` ### Example ```python theme={null} # Monitor job progress with default settings job = model.publish(source="large_dataset.csv") for job_update in job.watch(): print(f"Progress: {job_update.progress:.1f}%") print(f"Status: {job_update.status}") if job_update.status in [JobStatus.SUCCESS, JobStatus.FAILURE]: break # Custom polling interval and timeout for job_update in job.watch(interval=30, timeout=7200): # 2 hour timeout print(f"{job_update.name}: {job_update.progress:.1f}%") if job_update.status == JobStatus.SUCCESS: print("Job completed successfully!") break elif job_update.status == JobStatus.FAILURE: print(f"Job failed: {job_update.error_message}") break # Progress tracking with custom logic last_progress = 0 for job_update in job.watch(interval=15): if job_update.progress > last_progress + 10: print(f"Progress milestone: {job_update.progress:.1f}%") last_progress = job_update.progress ``` This method handles network errors gracefully and continues monitoring. It automatically stops when the job reaches a terminal state (SUCCESS, FAILURE, or REVOKED). Use shorter intervals for more responsive monitoring but be mindful of API rate limits. ## wait() Wait for job completion with automatic progress logging. Blocks execution until the job completes (successfully or with failure). Provides automatic progress logging and raises an exception if the job fails. This is the most convenient method for simple job completion waiting. ### Parameters Polling interval in seconds between status checks. Default is configured by JOB\_POLL\_INTERVAL (typically 5-10 seconds). Maximum time in seconds to wait for job completion. Default is configured by JOB\_WAIT\_TIMEOUT (typically 1800 seconds). ### Raises * **TimeoutError** – If the job doesn't complete within the specified timeout. * **AsyncJobFailed** – If the job fails during execution, includes error details. ### Example ```python theme={null} # Simple job completion waiting job = model.publish(source="training_data.csv") job.wait() # Blocks until completion print("Data publishing completed!") # Custom timeout for long-running jobs job = model.add_artifact(model_dir="./model_package") job.wait(timeout=3600) # 1 hour timeout print("Model artifact upload completed!") # Handle job failures try: job = model.publish(source="invalid_data.csv") job.wait() except AsyncJobFailed as e: print(f"Job failed: {e}") # Handle failure (retry, alert, etc.) # Fast polling for critical operations job = model.update_surrogate(dataset_id=dataset.id) job.wait(interval=5, timeout=600) # 5 second polling, 10 min timeout ``` This method automatically logs progress updates to the logger. For custom progress handling, use the watch() method instead. The method blocks the current thread until completion, so consider using watch() for non-blocking monitoring in async applications. # JobStatus Source: https://docs.fiddler.ai/sdk-api/python-client/job-status Status values for asynchronous job operations in Fiddler. Status values for asynchronous job operations in Fiddler. This enum defines the possible states that a Job can be in during its lifecycle. Jobs represent asynchronous operations such as data publishing, model uploads, and computation tasks that may take significant time to complete. Job Lifecycle: 1. **PENDING**: Job created and queued for execution 2. **STARTED**: Job execution has begun 3. **SUCCESS/FAILURE**: Job completed with final status 4. **RETRY**: Job failed but will be retried automatically 5. **REVOKED**: Job was cancelled before completion ## Examples Monitoring job progress: ```python theme={null} # Start a data publishing job job = model.publish(source=data_df, environment=fdl.EnvType.PRODUCTION) # Wait for completion job.wait() # Blocks until job completes # Check final status if job.status == fdl.JobStatus.SUCCESS: print("Data published successfully") else: print(f"Job failed with status: {job.status}") ``` Polling job status manually: ```python theme={null} import time # Check status periodically while job.status in [fdl.JobStatus.PENDING, fdl.JobStatus.STARTED]: print(f"Job progress: {job.progress}%") time.sleep(10) job.refresh() # Update job status from server # Handle different completion states if job.status == fdl.JobStatus.SUCCESS: print("Operation completed successfully") elif job.status == fdl.JobStatus.FAILURE: print(f"Operation failed: {job.error_message}") elif job.status == fdl.JobStatus.REVOKED: print("Operation was cancelled") ``` Handling job failures and retries: ```python theme={null} # Monitor job with retry handling max_wait_time = 3600 # 1 hour timeout start_time = time.time() while (time.time() - start_time) < max_wait_time: if job.status == fdl.JobStatus.SUCCESS: break elif job.status == fdl.JobStatus.FAILURE: print(f"Job failed permanently: {job.error_message}") break elif job.status == fdl.JobStatus.RETRY: print("Job failed but will be retried automatically") time.sleep(30) job.refresh() ``` Job status should be refreshed periodically using job.refresh() to get the latest status from the server. The job.wait() method provides a convenient way to block until completion. ## PENDING *= 'PENDING'* Job is queued and waiting to start execution. This is the initial status when a job is first created. The job has been submitted to the system but has not yet begun processing. Jobs may remain in PENDING status if there are resource constraints or if they are waiting for dependencies. Characteristics: * Job is in the execution queue * No processing has started yet * May transition to STARTED when resources become available * Can be cancelled while in this state Typical duration: Seconds to minutes depending on system load ## STARTED *= 'STARTED'* Job execution is currently in progress. The job has begun processing and is actively running. Progress information may be available through the job.progress property. Jobs in this state are consuming system resources and performing the requested operation. Characteristics: * Active processing is occurring * Progress updates may be available * Cannot be cancelled once started * Will transition to SUCCESS, FAILURE, or RETRY Typical duration: Minutes to hours depending on operation complexity ## SUCCESS *= 'SUCCESS'* Job completed successfully. The operation has finished successfully and all requested work has been completed. Results are available and the operation achieved its intended outcome without errors. Characteristics: * Operation completed without errors * Results are available for use * Job will not change status again * Resources have been released This is a terminal status - the job is complete. ## FAILURE *= 'FAILURE'* Job failed and will not be retried. The operation encountered an error and could not be completed successfully. This is a permanent failure - the job will not be automatically retried. Error details are typically available in the job.error\_message property. Characteristics: * Operation failed due to an error * No automatic retry will occur * Error details available in error\_message * Manual intervention may be required Common causes: * Invalid input data or parameters * Insufficient permissions * System resource exhaustion * Data validation failures This is a terminal status - the job will not continue. ## RETRY *= 'RETRY'* Job failed but will be automatically retried. The operation encountered a temporary error but the system will automatically attempt to retry the job. This typically occurs for transient issues like network timeouts or temporary resource unavailability. Characteristics: * Temporary failure occurred * System will automatically retry * May transition back to PENDING or STARTED * Retry attempts are limited Common causes: * Network connectivity issues * Temporary resource constraints * Transient system errors * Database connection timeouts The job may eventually succeed or transition to FAILURE if retries are exhausted. ## REVOKED *= 'REVOKED'* Job was cancelled or revoked before completion. The job was explicitly cancelled by the user or system before it could complete. This may occur due to user cancellation, system shutdown, or administrative intervention. Characteristics: * Job was cancelled before completion * No results are available * Resources have been cleaned up * Operation did not complete Common causes: * User-initiated cancellation * System maintenance or shutdown * Administrative intervention * Timeout or resource limits exceeded This is a terminal status - the job will not continue. # Model Source: https://docs.fiddler.ai/sdk-api/python-client/model Represents a machine learning model in the Fiddler platform. Represents a machine learning model in the Fiddler platform. The Model class is the central entity for ML model monitoring and management. It encapsulates the model's schema, specification, and metadata, and provides methods for data publishing, artifact management, and monitoring operations. Key Concepts: * **Schema** ([`ModelSchema`](/sdk-api/python-client/model-schema)): Defines the structure and data types of model inputs/outputs * **Spec** ([`ModelSpec`](/sdk-api/python-client/model-spec)): Defines how columns are used (features, targets, predictions, etc.) * **Task** ([`ModelTask`](/sdk-api/python-client/model-task)): The ML task type (classification, regression, ranking, etc.) * **Artifacts** (`ModelArtifact`): Deployable model code and dependencies * **Surrogates** (`Surrogate`): Simplified models for fast explanations Lifecycle: 1. Create model with schema/spec (from data or manual definition) 2. Upload model artifacts for serving (optional) 3. Publish baseline/training data for drift detection 4. Publish production data for monitoring 5. Set up alerts and monitoring rules Common Use Cases: * **Tabular Models**: Traditional ML models with structured data * **Text Models**: NLP models with text inputs and embeddings * **Mixed Models**: Models combining tabular and unstructured data * **Ranking Models**: Recommendation and search ranking systems * **LLM Models**: Large language model monitoring ## Parameters Model name, must be unique within the project version. Should be descriptive and follow naming conventions. UUID or string identifier of the parent project. [`ModelSchema`](/sdk-api/python-client/model-schema) defining column structure and data types. Can be created manually or generated from data. [`ModelSpec`](/sdk-api/python-client/model-spec) defining how columns are used (inputs, outputs, targets). Specifies the model's interface and column roles. Optional version identifier for model versioning and A/B testing. Falls back to 'v1' when not specified. [`ModelInputType`](/sdk-api/python-client/model-input-type) - Type of input data the model processes. * TABULAR: Structured/tabular data (default) * TEXT: Natural language text data * MIXED: Combination of structured and unstructured data [`ModelTask`](/sdk-api/python-client/model-task) - Machine learning task type. * BINARY\_CLASSIFICATION: Binary classification (0/1, True/False) * MULTICLASS\_CLASSIFICATION: Multi-class classification * REGRESSION: Continuous value prediction * RANKING: Ranking/recommendation tasks * LLM: Large language model tasks * NOT\_SET: Task not specified (default) [`ModelTaskParams`](/sdk-api/python-client/model-task-params) - Task-specific parameters like classification thresholds, class weights, or ranking parameters. Human-readable description of the model's purpose, training data, or other relevant information. Column name containing unique identifiers for each prediction event. Used for event tracking and updates. Column name containing event timestamps. Used for time-based analysis and drift detection. Format string for parsing timestamps in event\_ts\_col. Examples: '%Y-%m-%d %H:%M:%S', '%Y-%m-%dT%H:%M:%SZ' [`XaiParams`](/sdk-api/python-client/xai-params) - Configuration for explainability features like explanation methods and custom feature definitions. The model exists only locally until .create() is called. Use Model.from\_data() for automatic schema/spec generation from DataFrames or files. ## Examples ```python theme={null} # Create model from DataFrame with automatic schema detection import fiddler as fdl import pandas as pd df = pd.DataFrame({ 'age': [25, 35, 45], 'income': [50000, 75000, 100000], 'approved': [0, 1, 1] # target }) model = fdl.Model.from_data( source=df, name="credit_approval", project_id='', task=fdl.ModelTask.BINARY_CLASSIFICATION, description="Credit approval model v1.0" ) model.create() # Publish production events events = [ {'age': 30, 'income': 60000, 'prediction': 0.8}, {'age': 40, 'income': 80000, 'prediction': 0.9} ] event_ids = model.publish(source=events) # Get model info print(f"Model: {model.name} (Task: {model.task})") print(f"Columns: {len(model.schema.columns)}") print(f"Features: {model.spec.inputs}") ``` ## download\_data() Download production or pre-production event data to a local Parquet or CSV file. Replaces the removed `get_slice()` and `download_slice()` methods. ### Parameters Directory where the output file is written. Created if it does not exist. Environment to query. One of `EnvType.PRODUCTION` or `EnvType.PRE_PRODUCTION`. When `env_type=EnvType.PRE_PRODUCTION`, the UUID of the dataset to query. Ignored for PRODUCTION. Start of the query window. PRODUCTION only. Naive datetimes are interpreted as UTC. UUID of a saved Segment associated with the model. Mutually exclusive with `segment_definition`. Inline FQL (Fiddler Query Language) segment expression. The segment is applied transiently and not saved. Mutually exclusive with `segment_id`. Maximum number of rows to return. When omitted, the server applies a limit of 1,000 rows. Maximum allowed value is 10,000,000. Column names to include. When omitted, all model columns are returned. Row count per download chunk. You can increase this for faster downloads when querying fewer than 1000 columns and no vector columns. When `True`, vector columns are included in the output. When omitted or `False`, vector columns are filtered out. Output file format. One of `DownloadFormat.PARQUET` or `DownloadFormat.CSV`. ### Returns None. Writes a file named `output.parquet` (default) or `output.csv` (when `output_format=DownloadFormat.CSV`) into `output_dir`. ### Raises **ApiError** – If the request fails, the model is a draft model, or no data matches the query. ### Example ```python theme={null} from datetime import datetime, timedelta, timezone import fiddler as fdl import pandas as pd model = fdl.Model.from_name(name='my_model', project_id='') end_time = datetime.now(timezone.utc) start_time = end_time - timedelta(days=7) model.download_data( output_dir='./exports', env_type=fdl.EnvType.PRODUCTION, start_time=start_time, end_time=end_time, output_format=fdl.DownloadFormat.CSV, ) df = pd.read_csv('./exports/output.csv') ``` This method is not available for draft models. Caller must have READ permission on the model's project. ## *classmethod* get() Retrieve a model by its unique identifier. Fetches a model from the Fiddler platform using its UUID. This is the most direct way to retrieve a model when you know its ID. ### Parameters The unique identifier (UUID) of the model to retrieve. Can be provided as a UUID object or string representation. ### Returns The model instance with all its configuration and metadata. ### Raises * **NotFound** – If no model exists with the specified ID. * **ApiError** – If there's an error communicating with the Fiddler API. ### Example ```python theme={null} # Get model by UUID model = Model.get(id_="550e8400-e29b-41d4-a716-446655440000") print(f"Retrieved model: {model.name} (Task: {model.task})") # Access model properties print(f"Project ID: {model.project_id}") print(f"Input columns: {model.spec.inputs}") print(f"Created: {model.created_at}") ``` This method makes an API call to fetch the latest model state from the server. The returned model instance reflects the current state in Fiddler. ## *classmethod* from\_name() Retrieve a model by name within a project. Finds and returns a model using its name and project context. This is useful when you know the model name but not its UUID. Supports version-specific retrieval and latest version lookup. ### Parameters The name of the model to retrieve. Model names are unique within a project but may have multiple versions. UUID or string identifier of the project containing the model. Specific version name to retrieve. If None, behavior depends on the 'latest' parameter. If True and version is None, retrieves the most recently created version. If False, retrieves the first (oldest) version. Ignored if version is specified. ### Returns The model instance matching the specified criteria. ### Raises * **NotFound** – If no model exists with the specified name/version in the project. * **ApiError** – If there's an error communicating with the Fiddler API. ### Example ```python theme={null} # Get specific version model = Model.from_name( name="fraud_detector", project_id=project.id, version="v2.1" ) # Get latest version latest_model = Model.from_name( name="fraud_detector", project_id=project.id, latest=True ) # Get first version (default behavior) first_model = Model.from_name( name="fraud_detector", project_id=project.id ) print(f"Model versions: {first_model.version} -> {latest_model.version}") ``` When version is None and latest=False, returns the first version created. This provides consistent behavior for accessing the "original" model version. ## create() Create the model on the Fiddler platform. Persists this model instance to the Fiddler platform, making it available for monitoring, data publishing, and other operations. The model must have a valid schema, spec, and be associated with an existing project. ### Returns This model instance, updated with server-assigned fields like ID, creation timestamp, and other metadata. ### Raises * **Conflict** – If a model with the same name and version already exists in the project. * **ValidationError** – If the model configuration is invalid (e.g., invalid schema, spec, or task parameters). * **ApiError** – If there's an error communicating with the Fiddler API. ### Example ```python theme={null} # Create model from DataFrame model = Model.from_data( source=training_df, name="churn_predictor", project_id=project.id, task=ModelTask.BINARY_CLASSIFICATION ) # Create on platform created_model = model.create() print(f"Created model with ID: {created_model.id}") print(f"Created at: {created_model.created_at}") # Model is now available for monitoring assert created_model.id is not None # Can now publish data, set up alerts, etc. job = created_model.publish(source=production_data) ``` After successful creation, the model instance is updated in-place with server-assigned metadata. The same instance can be used for subsequent operations without needing to fetch it again. ## update() Update an existing model. ## add\_column() Add a new column to the model schema. Updates both the schema and spec to include the new column. This allows you to extend your model with additional columns after initial creation. **New in version 3.11.0** ### Parameters Column object defining the new column's properties (name, data\_type, etc.) Type of column in spec. One of: 'inputs', 'outputs', 'targets', 'decisions', 'metadata'. Defaults to 'metadata'. ### Raises * **ValueError** – If column already exists or column\_type is invalid * **BadRequest** – If column definition is invalid per backend validation ### Example ```python theme={null} # Add a numeric metadata column new_col = Column( name="customer_segment", data_type=DataType.INTEGER, min=1, max=5 ) model.add_column(column=new_col, column_type='metadata') # Add a categorical feature category_col = Column( name="region", data_type=DataType.CATEGORY, categories=["US", "EU", "APAC"] ) model.add_column(column=category_col, column_type='inputs') ``` * Adding a column doesn't populate historical data; new column will be null for past events * Column names must be unique within the model * After adding a column, include it in future event publishing ## *classmethod* list() List models in a project with optional filtering. Retrieves all models or model versions within a project. Returns lightweight ModelCompact objects that can be used to fetch full Model instances when needed. ### Parameters UUID or string identifier of the project to search within. Optional model name filter. If provided, returns all versions of the specified model. If None, returns all models in the project. ### Yields *ModelCompact* – Lightweight model objects containing id, name, and version. Call .fetch() on any ModelCompact to get the full Model instance. ### Returns `Iterator[ModelCompact]` ### Example ```python theme={null} # List all models in project for model_compact in Model.list(project_id=project.id): print(f"Model: {model_compact.name} v{model_compact.version}") print(f" ID: {model_compact.id}") # List all versions of a specific model for version in Model.list(project_id=project.id, name="fraud_detector"): print(f"Version: {version.version}") ... # Get full model details if needed full_model = version.fetch() print(f" Task: {full_model.task}") print(f" Created: {full_model.created_at}") # Convert to list for counting models = list(Model.list(project_id=project.id)) print(f"Total models in project: {len(models)}") ``` This method returns an iterator for memory efficiency when dealing with many models. The ModelCompact objects are lightweight and don't include full schema/spec information - use .fetch() when you need complete details. ## duplicate() Duplicate the model instance with the given version name. This call will not save the model on server. After making changes to the model instance call .create() to add the model version to Fiddler Platform. ### Parameters Version name for the new instance ### Returns Model instance ## *property* datasets Get all datasets associated with this model. Returns an iterator over all datasets that have been published to this model, including both production data and pre-production datasets used for baselines and drift comparison. ### Yields [`Dataset`](/sdk-api/python-client/dataset) – Dataset objects containing metadata and data access methods. Each dataset represents a collection of events published to the model. ### Example ```python theme={null} # List all datasets for the model for dataset in model.datasets: print(f"Dataset: {dataset.name}") print(f" Environment: {dataset.environment}") print(f" Size: {dataset.size} events") print(f" Created: {dataset.created_at}") # Find specific dataset baseline_datasets = [ ds for ds in model.datasets if ds.environment == EnvType.PRE_PRODUCTION ] print(f"Found {len(baseline_datasets)} baseline datasets") ``` This includes both production event data and named pre-production datasets. Use the Dataset objects to download data, analyze distributions, or set up baseline comparisons for drift detection. ## *property* baselines Get all baselines configured for this model. Returns an iterator over all baseline configurations used for drift detection and performance monitoring. Baselines define reference distributions and metrics for comparison with production data. ### Yields [`Baseline`](/sdk-api/python-client/baseline) – Baseline objects containing configuration and reference data. Each baseline defines how drift and performance should be measured against historical or reference datasets. ### Example ```python theme={null} # List all baselines for baseline in model.baselines: print(f"Baseline: {baseline.name}") print(f" Type: {baseline.type}") # STATIC or ROLLING print(f" Dataset: {baseline.dataset_name}") print(f" Created: {baseline.created_at}") # Find production baseline prod_baselines = [ bl for bl in model.baselines if "production" in bl.name.lower() ] # Use baseline for drift comparison if prod_baselines: baseline = prod_baselines[0] drift_metrics = baseline.compute_drift(recent_data) ``` Baselines are essential for drift detection and alerting. They define the "normal" behavior against which production data is compared. Static baselines use fixed reference data, while rolling baselines update automatically with recent data. ## *property* deployment Fetch model deployment instance of this model. ### Returns The deployment configuration for this model. ## *classmethod* from\_data() Create a Model instance with automatic schema generation from data. This is the most convenient way to create models when you have training data or representative samples. The method automatically analyzes the data to generate appropriate schema (column types) and spec (column roles) definitions. ### Parameters Data source for schema generation. Can be: * pandas.DataFrame: Direct data analysis * Path/str: File path (.csv, .parquet, .json supported) The data should be representative of your model's inputs/outputs. Model name, must be unique within the project version. Use descriptive names like "fraud\_detector\_v1" or "churn\_model". UUID or string identifier of the parent project. Optional [`ModelSpec`](/sdk-api/python-client/model-spec) defining column roles. If None, automatic detection attempts to identify inputs, outputs, and targets based on column names and data patterns. Model version identifier. If None, defaults to "v1". Use semantic versioning like "v1.0", "v2.1", etc. [`ModelInputType`](/sdk-api/python-client/model-input-type) - Type of input data the model processes. * TABULAR: Structured/tabular data (default) * TEXT: Natural language text data * MIXED: Combination of structured and unstructured data [`ModelTask`](/sdk-api/python-client/model-task) - Machine learning task type: * BINARY\_CLASSIFICATION: Binary classification (0/1, True/False) * MULTICLASS\_CLASSIFICATION: Multi-class classification * REGRESSION: Continuous value prediction * RANKING: Ranking/recommendation tasks * LLM: Large language model tasks * NOT\_SET: Task not specified (default) [`ModelTaskParams`](/sdk-api/python-client/model-task-params) - Task-specific parameters: * binary\_classification\_threshold: Decision threshold (0.5) * target\_class\_order: Class label ordering * group\_by: Column for ranking model grouping * top\_k: Top-k evaluation for ranking Human-readable description of the model's purpose, training approach, or other relevant information. Column name for unique event identifiers. Used for tracking individual predictions and enabling updates. Column name for event timestamps. Used for time-based analysis, drift detection, and temporal monitoring. Timestamp format string for parsing event\_ts\_col. Examples: '%Y-%m-%d %H:%M:%S', '%Y-%m-%dT%H:%M:%SZ' [`XaiParams`](/sdk-api/python-client/xai-params) - Explainability configuration including explanation methods and custom feature definitions. Maximum unique values to consider a column categorical. Columns with more unique values are treated as continuous. Default is typically 100-1000 depending on data size. Number of rows to sample for schema generation. Useful for large datasets to speed up analysis. If None, uses entire dataset (up to reasonable limits). ### Returns A new Model instance with automatically generated schema and spec. The model is not yet created on the platform - call .create() to persist. ### Raises * **ValueError** – If the data source is invalid or cannot be processed. * **FileNotFoundError** – If source is a file path that doesn't exist. * **ValidationError** – If the generated schema/spec is invalid. ### Example ```python theme={null} import pandas as pd # Create from DataFrame df = pd.DataFrame({ 'age': [25, 35, 45, 55], 'income': [30000, 50000, 70000, 90000], 'credit_score': [650, 700, 750, 800], 'approved': [0, 1, 1, 1], # target 'prediction': [0.2, 0.8, 0.9, 0.95], # model output 'prediction_score': [0.2, 0.8, 0.9, 0.95] # alternative output }) model = Model.from_data( source=df, name="credit_approval_v1", project_id=project.id, task=ModelTask.BINARY_CLASSIFICATION, description="Credit approval model trained on 2024 data", event_id_col="application_id", # if present in real data event_ts_col="timestamp" # if present in real data ) # Review generated schema print(f"Columns detected: {len(model.schema.columns)}") for col in model.schema.columns: print(f" {col.name}: {col.data_type}") # Review generated spec print(f"Inputs: {model.spec.inputs}") print(f"Outputs: {model.spec.outputs}") print(f"Targets: {model.spec.targets}") # Create on platform model.create() # Create from file model = Model.from_data( source="training_data.csv", name="file_based_model", project_id=project.id, task=ModelTask.REGRESSION, sample_size=10000 # Sample large files ) ``` The automatic schema generation uses heuristics to detect column types and roles. Review the generated schema and spec before calling .create() to ensure they match your model's actual interface. You can modify the schema and spec after creation if needed. ## delete() Delete a model and it's associated resources. ### Returns model deletion job instance ## remove\_column() Remove a column from the model schema and spec This method is only to modify model object before creating and will not save the model on Fiddler Platform. After making changes to the model instance, call .create() to add the model to Fiddler Platform. ### Parameters Column name to be removed If True, do not raise an error if the column is not found ### Returns None ### Raises **KeyError** – If the column name is not found and missing\_ok is False ## publish() Publish data to the model for monitoring and analysis. Deprecated: Use [`publish_stream()`](#publish_stream) for streaming events (list of dicts) or [`publish_batch()`](#publish_batch) for batch publishing (file path or DataFrame). Uploads prediction events, training data, or reference datasets to Fiddler for monitoring, drift detection, and performance analysis. This is how you send your model's real-world data to the platform. ### Parameters Data to publish. Supported formats: * **File path (str/Path)**: CSV or Parquet files. > Best for large datasets and batch uploads. * **DataFrame**: Pandas DataFrame with prediction events. Good for programmatic uploads and real-time data. * **List of dicts**: Individual events as dictionaries. Perfect for streaming/real-time publishing (max 1000 events). Each dict should match the model's schema. [`EnvType`](/sdk-api/python-client/env-type) - Data environment type: * **PRODUCTION**: Live production prediction data. > Used for real-time monitoring and alerting. * **PRE\_PRODUCTION**: Training, validation, or baseline data. Used for drift comparison and model evaluation. Name for the dataset when using PRE\_PRODUCTION environment. Creates a named dataset for baseline comparisons. Not used for PRODUCTION data. Whether these events update previously published data. Set to True when republishing corrected predictions or adding ground truth labels to existing events. ### Returns Event IDs when source is list of dicts or DataFrame. Use these IDs to reference specific events later. * [`Job`](/sdk-api/python-client/job): Async job object when source is a file path. Use job.wait() to wait for completion or check job.status. ### Raises * **ValidationError** – If the data doesn't match the model's schema or contains invalid values. * **ApiError** – If there's an error uploading the data to Fiddler. * **ValueError** – If the source format is unsupported or parameters are incompatible (e.g., dataset\_name with PRODUCTION). ### Example ```python theme={null} # Publish production events from DataFrame # (assumes model is a fdl.Model instance; see Model.from_name() or Model.from_data()) import fiddler as fdl import pandas as pd prod_df = pd.DataFrame({ 'age': [30, 25, 45], 'income': [60000, 45000, 80000], 'prediction': [0.8, 0.3, 0.9], 'timestamp': ['2024-01-01 10:00:00', '2024-01-01 11:00:00', '2024-01-01 12:00:00'] }) # Returns list of event UUIDs event_ids = model.publish( source=prod_df, environment=fdl.EnvType.PRODUCTION ) print(f"Published {len(event_ids)} events") # Publish baseline data for drift comparison job = model.publish( source="training_data.csv", # File path environment=fdl.EnvType.PRE_PRODUCTION, dataset_name="training_baseline_2024" ) job.wait() # Wait for upload to complete print(f"Baseline upload status: {job.status}") # Publish real-time streaming events events = [ { 'age': 35, 'income': 70000, 'prediction': 0.75, 'event_id': 'pred_001', 'timestamp': '2024-01-01 13:00:00' }, { 'age': 28, 'income': 55000, 'prediction': 0.45, 'event_id': 'pred_002', 'timestamp': '2024-01-01 13:01:00' } ] event_ids = model.publish(source=events) print(f"Published {len(events)} streaming events") # Update existing events with ground truth corrected_events = [ { 'event_id': 'pred_001', 'ground_truth': 1, # Actual outcome 'timestamp': '2024-01-01 13:00:00' } ] model.publish(source=corrected_events, update=True) ``` * **Schema Validation**: All published data must match the model's schema. Column names, types, and value ranges are validated. * **Event IDs**: Include event\_id\_col if specified in model config for event tracking and updates. * **Timestamps**: Include event\_ts\_col for time-based analysis and drift detection. * **Batch Limits**: List of dicts is limited to 1000 events per call. Use files or multiple calls for larger datasets. Production data publishing enables real-time monitoring, alerting, and drift detection. Pre-production data creates reference datasets for comparison and model evaluation. ## publish\_stream() Publish events via streaming for real-time monitoring. Sends events synchronously to Fiddler. Events are written to an in-memory queue and asynchronously persisted. ### Parameters List of event dicts matching the model's schema. Each dict represents a single prediction event with feature values, predictions, and optional metadata (event\_id, timestamp). [`EnvType`](/sdk-api/python-client/env-type) - Data environment type: * **PRODUCTION**: Live production prediction data. * **PRE\_PRODUCTION**: Training, validation, or baseline data. Name for the dataset when using PRE\_PRODUCTION environment. Not used for PRODUCTION data. Whether these events update previously published data. Set to True when adding ground truth labels to existing events. ### Returns Event IDs for the published events. Use these IDs to reference specific events later. ### Raises * **ValidationError** – If the data doesn't match the model's schema. * **ApiError** – If there's an error publishing the events to Fiddler. ### Example ```python theme={null} events = [ { 'age': 35, 'income': 70000, 'prediction': 0.75, 'event_id': 'pred_001', 'timestamp': '2024-01-01 13:00:00' }, { 'age': 28, 'income': 55000, 'prediction': 0.45, 'event_id': 'pred_002', 'timestamp': '2024-01-01 13:01:00' } ] event_ids = model.publish_stream(events=events) print(f"Published {len(event_ids)} streaming events") # Update existing events with ground truth ground_truth = [ {'event_id': 'pred_001', 'ground_truth': 1} ] model.publish_stream(events=ground_truth, update=True) ``` For large datasets, consider using [`publish_batch()`](#publish_batch) with a file path or DataFrame instead. Streaming is best suited for real-time or near-real-time event publishing. ## publish\_batch() Publish data via batch upload for monitoring and analysis. Uploads data as a file and kicks off an asynchronous server-side job. Use the returned Job object to track progress. Best suited for large datasets, historical data uploads, and baseline/reference datasets. ### Parameters Data to publish. Supported formats: * **File path (str/Path)**: CSV or Parquet files. > Best for large datasets already on disk. * **DataFrame**: Pandas DataFrame with prediction events. Automatically converted to Parquet (falls back to CSV). [`EnvType`](/sdk-api/python-client/env-type) - Data environment type: * **PRODUCTION**: Live production prediction data. * **PRE\_PRODUCTION**: Training, validation, or baseline data. Name for the dataset when using PRE\_PRODUCTION environment. Creates a named dataset for baseline comparisons. Not used for PRODUCTION data. Whether these events update previously published data. Set to True when republishing corrected predictions or adding ground truth labels to existing events. ### Returns Async job object. Use `job.wait()` to block until completion, or check `job.status` to poll. ### Raises * **ValidationError** – If the data doesn't match the model's schema. * **ApiError** – If there's an error uploading the data to Fiddler. * **ValueError** – If the source format is unsupported. ### Example ```python theme={null} # Batch upload from file job = model.publish_batch( source="training_data.csv", environment=EnvType.PRE_PRODUCTION, dataset_name="training_baseline_2024" ) job.wait() print(f"Upload status: {job.status}") # Batch upload from DataFrame import pandas as pd prod_df = pd.DataFrame({ 'age': [30, 25, 45], 'income': [60000, 45000, 80000], 'prediction': [0.8, 0.3, 0.9], }) job = model.publish_batch(source=prod_df) job.wait() ``` For real-time or near-real-time event publishing, consider using [`publish_stream()`](#publish_stream) instead. ## delete\_events() Delete published production events for this model. Select events to delete by a time range or by an explicit list of event IDs (the two are mutually exclusive). Deletion runs asynchronously on the server; use the returned Job to track progress. ### Parameters Inclusive start of the time window to delete. Accepts a timezone-aware `datetime` or an ISO 8601 string with an explicit offset (e.g. `'2025-11-17T01:00:00Z'`); the value is normalized to UTC. Naive datetimes are rejected. Must be given together with `end_time`. Exclusive end of the time window to delete. Same format rules as `start_time`. Must be given together with `start_time`. List of event IDs to delete, up to the documented per-call limit. An empty list is treated as "no ID filter" (the same as `None`). Cannot be combined with a time range. Whether the server should recompute metrics after the events are deleted. Applies to time-range deletions only; combining `update_metrics=True` with `event_ids` is rejected. ### Returns Async job object. Use `job.wait()` to block until completion, or check `job.status` to poll. ### Raises * **ValueError** – If neither a time range nor `event_ids` is given (to avoid accidentally deleting all events for the model), if only one of `start_time`/`end_time` is provided, or if `event_ids` exceeds the documented per-call limit. * **ApiError** – If there's an error deleting the events on Fiddler. ### Example ```python theme={null} # Delete a window of production events job = model.delete_events( start_time='2025-11-17T01:00:00.000Z', end_time='2025-11-17T02:00:00.000Z', update_metrics=True, ) job.wait() print(f"Delete status: {job.status}") # Delete specific events by ID job = model.delete_events(event_ids=['pred_001', 'pred_002']) job.wait() ``` Deletion is irreversible. Provide either a time range or `event_ids` to scope the deletion (not both); a call with no filter is rejected. ## add\_artifact() Upload and deploy model artifact. ### Parameters Path to model artifact tar file Model deployment parameters ### Returns Async job instance ## update\_artifact() Update existing model artifact. ### Parameters Path to model artifact tar file Model deployment parameters ### Returns Async job instance ## download\_artifact() Download existing model artifact. ### Parameters Path to download model artifact tar file ## add\_surrogate() Add a new surrogate model ### Parameters Dataset to be used for generating surrogate model Model deployment parameters ### Returns Async job ## update\_surrogate() Update an existing surrogate model ### Parameters Dataset to be used for generating surrogate model Model deployment parameters ### Returns Async job # ModelCompact Source: https://docs.fiddler.ai/sdk-api/python-client/model-compact Lightweight model representation for listing and basic operations. Lightweight model representation for listing and basic operations. A minimal model object containing only essential identifiers. Used by Model.list() to efficiently return model information without fetching full schema and configuration details. ## Example ```python theme={null} # Get from listing models = list(Model.list(project_id=project.id)) compact_model = models[0] # Access basic info print(f"Model: {compact_model.name} v{compact_model.version}") print(f"ID: {compact_model.id}") # Fetch full details when needed full_model = compact_model.fetch() print(f"Task: {full_model.task}") print(f"Schema: {len(full_model.schema.columns)} columns") ``` ## id ## name ## version ## fetch() Fetch the complete Model instance. Retrieves the full Model object with all schema, spec, and configuration details from the Fiddler platform using this compact model's ID. ### Returns Complete model instance with all details and capabilities. ### Example ```python theme={null} # From model listing compact = next(Model.list(project_id=project.id)) # Get full model details full_model = compact.fetch() # Now can access full functionality full_model.publish(source=data) print(f"Input columns: {full_model.spec.inputs}") ``` # ModelDeployment Source: https://docs.fiddler.ai/sdk-api/python-client/model-deployment Model deployment management for serving infrastructure. Model deployment management for serving infrastructure. This class manages containerized model deployments including resource allocation, scaling, and activation status. ## Examples Get and update deployment: ```python theme={null} # Get deployment deployment = ModelDeployment.of(model_id=model.id) # Update resources deployment.replicas = 3 deployment.cpu = 1000 deployment.memory = 2048 job = deployment.update() job.wait() ``` Initialize ModelDeployment instance. ## Parameters Model identifier ## update() Update an existing model deployment. ### Returns [`Job`](/sdk-api/python-client/job) ## *classmethod* of() Get model deployment instance of the given model ### Parameters Model identifier ### Returns ModelDeployment instance # ModelInputType Source: https://docs.fiddler.ai/sdk-api/python-client/model-input-type Input data types supported by Fiddler models. Input data types supported by Fiddler models. This enum defines the different types of input data that models can process. The input type determines how Fiddler handles data preprocessing, validation, and monitoring for the model. ## Examples Defining model input type during onboarding: ```python theme={null} # Tabular data model (traditional ML) model = fdl.Model.from_data( name='credit_model', source=credit_data, spec=model_spec, task=fdl.ModelTask.BINARY_CLASSIFICATION, input_type=fdl.ModelInputType.TABULAR ) # Text-based model (NLP) model = fdl.Model.from_data( name='sentiment_model', source=text_data, spec=model_spec, task=fdl.ModelTask.MULTICLASS_CLASSIFICATION, input_type=fdl.ModelInputType.TEXT ) # Mixed data model (multimodal) model = fdl.Model.from_data( name='multimodal_model', source=mixed_data, spec=model_spec, task=fdl.ModelTask.REGRESSION, input_type=fdl.ModelInputType.MIXED ## ) ``` Input type affects data validation, preprocessing, and available monitoring features. Choose the type that best matches your model's primary input data format. ## TABULAR *= 'structured'* Structured tabular data with rows and columns. Used for traditional machine learning models that operate on structured datasets with well-defined features. This includes most supervised learning models trained on CSV data, database tables, or pandas DataFrames. Characteristics: * Fixed schema with defined columns * Numeric and categorical features * Traditional ML algorithms (trees, linear models, etc.) * Standard drift detection on individual features Typical use cases: * Credit scoring models * Fraud detection systems * Customer churn prediction * Sales forecasting models * Risk assessment models Supported data types: All DataType enum values ## TEXT *= 'text'* Natural language text data. Used for models that primarily process text inputs such as NLP models, language models, and text classification systems. Enables text-specific monitoring and embedding-based drift detection. Characteristics: * Text strings as primary input * Embedding-based feature monitoring * Text-specific preprocessing * Language model optimizations Typical use cases: * Sentiment analysis models * Document classification * Named entity recognition * Text summarization models * Chatbots and conversational AI Special considerations: * May require text embedding custom features * Supports text-specific enrichments * Drift detection on embedding vectors ## MIXED *= 'mixed'* Combination of structured and unstructured data. Used for multimodal models that process both structured tabular data and unstructured data like text, images, or embeddings. Enables comprehensive monitoring across different data types. Characteristics: * Multiple data modalities * Complex feature interactions * Flexible schema definitions * Advanced custom feature support Typical use cases: * Recommendation systems (user features + content) * Fraud detection (transaction data + text descriptions) * Medical diagnosis (structured data + images/text) * E-commerce search (product features + text queries) * Content moderation (metadata + text/images) Special considerations: * Requires careful schema design * May need multiple custom feature types * Complex drift monitoring setup # ModelSchema Source: https://docs.fiddler.ai/sdk-api/python-client/model-schema Defines the complete schema structure for a model's input data. Defines the complete schema structure for a model's input data. ModelSchema contains the specification of all columns that a model expects to receive, including their data types, constraints, and metadata. This schema is used by Fiddler for data validation, monitoring, and analysis purposes. The schema acts as a contract between your model and Fiddler, ensuring that incoming data conforms to expected formats and enabling proper drift detection, data quality monitoring, and other features. ## Examples Creating a model schema: ```python theme={null} schema = ModelSchema( columns=[ Column(name="age", data_type=DataType.INTEGER, min=0, max=120), Column(name="income", data_type=DataType.FLOAT, min=0), Column(name="category", data_type=DataType.CATEGORY, categories=["A", "B", "C"]) ] ) ``` Accessing columns by name: ```python theme={null} age_column = schema["age"] print(age_column.data_type) ``` Adding a new column: ```python theme={null} new_column = Column(name="score", data_type=DataType.FLOAT) schema["score"] = new_column ``` Removing a column: ```python theme={null} del schema["age"] ``` ## model\_config Configuration for the model, should be a dictionary conforming to \[ConfigDict]\[pydantic.config.ConfigDict]. ## schema\_version Schema version ## columns List of columns ## **getitem**() Get column by name ### Returns [`Column`](/sdk-api/python-client/column) ## **setitem**() Set column by name ## **delitem**() Delete column by name # ModelSpec Source: https://docs.fiddler.ai/sdk-api/python-client/model-spec Defines how model columns are categorized and used along with model task configuration. Defines how model columns are categorized and used along with model task configuration. ModelSpec provides a comprehensive specification of how different columns in your model's data should be interpreted and used. It categorizes columns into inputs, outputs, targets, decisions, and metadata, and allows for custom feature definitions that enhance model monitoring and analysis capabilities. This specification is crucial for Fiddler to understand your model's structure, enabling proper monitoring, drift detection, bias analysis, and explainability features. It acts as the contract between your model and Fiddler's monitoring infrastructure. * **custom\_features** (*List* *\[Multivariate* *|* *VectorFeature* *|* *TextEmbedding* *|* *ImageEmbedding* *|* *Enrichment* *]*) ## Examples Creating a basic model spec for classification: ```python theme={null} spec = ModelSpec( inputs=["age", "income", "credit_score"], outputs=["prediction", "probability"], targets=["approved"], metadata=["customer_id", "timestamp"] ) ``` Creating a spec with custom features: ```python theme={null} from fiddler.schemas.custom_features import Multivariate, TextEmbedding spec = ModelSpec( inputs=["user_clicks", "session_time", "review_text_embedding"], outputs=["recommendation_score"], targets=["user_rating"], metadata=["user_id", "session_id"], custom_features=[ Multivariate( name="user_behavior", columns=["user_clicks", "session_time"], n_clusters=5 ), TextEmbedding( name="review_clusters", column="review_text_embedding", source_column="review_text", n_clusters=8 ) ] ) ``` Creating a spec for ranking models: ```python theme={null} ranking_spec = ModelSpec( inputs=["query_features", "doc_features", "relevance_score"], outputs=["ranking_score"], targets=["click_through"], decisions=["final_ranking"], metadata=["query_id", "doc_id"] ) ``` ## schema\_version Schema version ## inputs Feature columns ## outputs Prediction columns ## targets Label columns ## model\_config Configuration for the model, should be a dictionary conforming to \[ConfigDict]\[pydantic.config.ConfigDict]. ## decisions Decisions columns ## metadata Metadata columns ## custom\_features Custom feature definitions ## remove\_column() Remove a column name from spec if it exists. # ModelTask Source: https://docs.fiddler.ai/sdk-api/python-client/model-task Machine learning task types supported by Fiddler. Machine learning task types supported by Fiddler. This enum defines the different types of ML tasks that Fiddler can monitor. The task type determines which metrics are calculated, how performance is measured, and what monitoring capabilities are available. Task-Specific Features: * **Classification**: Accuracy, precision, recall, F1, AUC, confusion matrix * **Regression**: MAE, MSE, RMSE, R², residual analysis * **Ranking**: NDCG, MAP, precision\@k, ranking-specific metrics * **LLM**: Token-based metrics, response quality, safety metrics ## Examples Configuring models for different tasks: ```python theme={null} # Binary classification (fraud detection) fraud_model = fdl.Model.from_data( name='fraud_detector', source=fraud_data, spec=model_spec, task=fdl.ModelTask.BINARY_CLASSIFICATION, task_params=fdl.ModelTaskParams( binary_classification_threshold=0.5 ) ) # Multiclass classification (sentiment analysis) sentiment_model = fdl.Model.from_data( name='sentiment_analyzer', source=sentiment_data, spec=model_spec, task=fdl.ModelTask.MULTICLASS_CLASSIFICATION, task_params=fdl.ModelTaskParams( target_class_order=['negative', 'neutral', 'positive'] ) ) # Regression (price prediction) price_model = fdl.Model.from_data( name='price_predictor', source=price_data, spec=model_spec, task=fdl.ModelTask.REGRESSION ) # Ranking (recommendation system) ranking_model = fdl.Model.from_data( name='recommender', source=ranking_data, spec=model_spec, task=fdl.ModelTask.RANKING, task_params=fdl.ModelTaskParams( group_by='user_id', top_k=10 ) ) # LLM (language model) llm_model = fdl.Model.from_data( name='chatbot', source=conversation_data, spec=model_spec, task=fdl.ModelTask.LLM ## ) ``` Task type cannot be changed after model creation. Choose carefully based on your model's primary objective and output format. ## BINARY\_CLASSIFICATION *= 'binary\_classification'* Two-class classification tasks. Used for models that predict one of two possible outcomes or classes. Enables binary classification metrics and threshold-based analysis. Available metrics: * Accuracy, Precision, Recall, F1-score * AUC-ROC, AUC-PR curves * Confusion matrix analysis * Threshold optimization tools Typical use cases: * Fraud detection (fraud/legitimate) * Email spam filtering (spam/ham) * Medical diagnosis (positive/negative) * Credit approval (approve/deny) * Churn prediction (churn/retain) Required outputs: Single probability score or binary prediction Task parameters: binary\_classification\_threshold ## MULTICLASS\_CLASSIFICATION *= 'multiclass\_classification'* Multi-class classification tasks. Used for models that predict one of multiple possible classes or categories. Supports comprehensive multiclass performance analysis and class-specific metrics. Available metrics: * Per-class precision, recall, F1-score * Macro and micro-averaged metrics * Confusion matrix with multiple classes * Class distribution analysis Typical use cases: * Document categorization (multiple topics) * Image classification (multiple objects) * Sentiment analysis (positive/neutral/negative) * Product categorization * Intent classification in chatbots Required outputs: Class probabilities or single class prediction Task parameters: target\_class\_order, class\_weights ## REGRESSION *= 'regression'* Continuous value prediction tasks. Used for models that predict numerical values on a continuous scale. Enables regression-specific metrics and residual analysis. Available metrics: * Mean Absolute Error (MAE) * Mean Squared Error (MSE) * Root Mean Squared Error (RMSE) * R-squared (coefficient of determination) * Residual distribution analysis Typical use cases: * Price prediction * Sales forecasting * Risk scoring (continuous scores) * Demand forecasting * Performance rating prediction Required outputs: Single continuous numerical value Task parameters: None (uses standard regression metrics) ## RANKING *= 'ranking'* Ranking and recommendation tasks. Used for models that rank items or provide ordered recommendations. Supports ranking-specific metrics and list-wise evaluation. Available metrics: * Normalized Discounted Cumulative Gain (NDCG) * Mean Average Precision (MAP) * Precision\@K, Recall\@K * Mean Reciprocal Rank (MRR) * Hit Rate analysis Typical use cases: * Search result ranking * Product recommendations * Content recommendation systems * Information retrieval * Personalized ranking Required outputs: Ranked list of items with scores Task parameters: group\_by (session/user ID), top\_k Special data format: Grouped by query/session identifier ## LLM *= 'llm'* Large language model and generative AI tasks. Used for language models, chatbots, and generative AI applications. Enables LLM-specific monitoring including safety, quality, and performance metrics. Available metrics: * Response quality metrics * Safety and toxicity detection * Hallucination detection * Token-based analysis * Latency and throughput metrics Typical use cases: * Chatbots and conversational AI * Text generation models * Question-answering systems * Code generation models * Content creation assistants Special features: * Guardrails integration * Safety monitoring * Prompt and response analysis * Token usage tracking ## NOT\_SET *= 'not\_set'* Placeholder for undefined or unspecified tasks. Used as a default value when the model task has not been explicitly defined. Should be replaced with an appropriate task type during model configuration. This value should not be used for production models as it limits available monitoring capabilities and metrics. ## is\_classification() Check if the task is a classification type. ### Returns True if task is binary or multiclass classification ## is\_regression() Check if the task is regression. ### Returns True if task is regression # ModelTaskParams Source: https://docs.fiddler.ai/sdk-api/python-client/model-task-params Configuration parameters for different model task types and evaluation metrics. Configuration parameters for different model task types and evaluation metrics. ModelTaskParams defines task-specific parameters that control how models are evaluated and monitored within Fiddler. Different model types (classification, regression, ranking) require different parameters to properly compute metrics and perform analysis. These parameters are essential for accurate metric computation, proper baseline establishment, and meaningful performance monitoring across different model types and use cases. ## Examples Configuration for binary classification: ```python theme={null} binary_params = ModelTaskParams( binary_classification_threshold=0.5, target_class_order=["negative", "positive"] ) ``` Configuration for multi-class classification with class weights: ```python theme={null} multiclass_params = ModelTaskParams( target_class_order=["class_a", "class_b", "class_c"], class_weights=[0.3, 0.5, 0.2], weighted_ref_histograms=True ) ``` Configuration for ranking models: ```python theme={null} ranking_params = ModelTaskParams( group_by="query_id", top_k=10, target_class_order=["not_relevant", "relevant", "highly_relevant"] ) ``` Configuration for imbalanced datasets: ```python theme={null} imbalanced_params = ModelTaskParams( binary_classification_threshold=0.3, class_weights=[0.1, 0.9], weighted_ref_histograms=True ) ``` ## binary\_classification\_threshold Threshold for labels ## target\_class\_order Order of target classes ## group\_by Query/session id column for ranking models ## model\_config Configuration for the model, should be a dictionary conforming to \[ConfigDict]\[pydantic.config.ConfigDict]. ## top\_k Top k results to consider when computing ranking metrics ## class\_weights Weight of each classes ## weighted\_ref\_histograms Whether baseline histograms must be weighted or not while drift metrics # Multivariate Source: https://docs.fiddler.ai/sdk-api/python-client/multivariate Represents custom features derived from multiple columns using clustering analysis. Represents custom features derived from multiple columns using clustering analysis. Multivariate features combine multiple numeric columns into a single derived feature using k-means clustering algorithms. This enables monitoring of multivariate drift and detecting unusual combinations that might not be apparent when monitoring columns individually. The feature type is automatically set to CustomFeatureType.FROM\_COLUMNS and uses clustering to group similar combinations of column values for drift detection. ## Examples Creating a user behavior multivariate feature: ```python theme={null} behavior_feature = Multivariate( name="user_engagement_cluster", columns=["page_views", "session_duration", "clicks"], n_clusters=8, monitor_components=True ) ``` Creating a system performance multivariate feature: ```python theme={null} perf_feature = Multivariate( name="system_health", columns=["cpu_usage", "memory_usage", "response_time"], n_clusters=5, monitor_components=False ) ``` ## type ## n\_clusters ## centroids ## columns ## monitor\_components ## *classmethod* validate\_columns() ### Returns `List[str]` ## *classmethod* validate\_n\_clusters() ### Returns `int` ## model\_config Configuration for the model, should be a dictionary conforming to \[ConfigDict]\[pydantic.config.ConfigDict]. # NotFound Source: https://docs.fiddler.ai/sdk-api/python-client/not-found Raised when a requested resource is not found (HTTP 404). Raised when a requested resource is not found (HTTP 404). This exception is thrown when attempting to access or manipulate a resource that does not exist in the Fiddler platform. This can include models, projects, datasets, alerts, or any other entity that cannot be located using the provided identifier. Common scenarios include using incorrect IDs, attempting to access deleted resources, or referencing resources that haven't been created yet. ## Examples Handling missing resources: ```python theme={null} try: model = client.get_model("wrong-model-id") except NotFound as e: print(f"Model not found: {e.message}") # Create the model or check the correct ID ``` Checking if a resource exists: ```python theme={null} try: project = client.get_project("my-project") print("Project exists") except NotFound: print("Project doesn't exist, creating it...") project = client.create_project(name="my-project") ``` Common NotFound scenarios: ```python theme={null} - Accessing models, projects, or datasets with wrong IDs - Referencing deleted or expired resources - Typos in resource names or identifiers ``` ## code ## reason # Priority Source: https://docs.fiddler.ai/sdk-api/python-client/priority Alert priority levels for notification routing and escalation. Alert priority levels for notification routing and escalation. Determines the urgency and routing behavior of alert notifications. Higher priority alerts may trigger immediate notifications, phone calls, or escalation to on-call personnel. ## HIGH Critical issues requiring immediate attention. Examples: Model completely down, severe data quality issues. ## MEDIUM Important issues that should be addressed promptly. Examples: Performance degradation, moderate drift. ## LOW Minor issues for awareness and trend monitoring. Examples: Small drift increases, non-critical feature changes. ### Example ```python theme={null} # High priority for production model failures critical_alert = AlertRule( name="Model Down", priority=Priority.HIGH ) # Medium priority for performance monitoring perf_alert = AlertRule( name="Accuracy Drop", priority=Priority.MEDIUM ) ``` ## HIGH *= 'HIGH'* ## MEDIUM *= 'MEDIUM'* ## LOW *= 'LOW'* # Project Source: https://docs.fiddler.ai/sdk-api/python-client/project Represents a project container for organizing ML models and resources. Represents a project container for organizing ML models and resources. A Project is the top-level organizational unit in Fiddler that groups related machine learning models, datasets, and monitoring configurations. Projects provide logical separation, access control, and resource management for ML monitoring workflows. Key Features: * **Model Organization**: Container for related ML models and their versions * **Resource Isolation**: Separate namespaces prevent naming conflicts * **Access Management**: Project-level permissions and access control * **Monitoring Coordination**: Centralized monitoring and alerting configuration * **Lifecycle Management**: Coordinated creation, updates, and deletion of resources Project Lifecycle: 1. **Creation**: Create project with unique name within organization 2. **Model Addition**: Add models using Model.create() or Model.from\_data() 3. **Configuration**: Set up monitoring, alerts, and baseline comparisons 4. **Operations**: Publish data, monitor performance, manage alerts 5. **Maintenance**: Update configurations, add new model versions 6. **Cleanup**: Delete project when no longer needed (removes all contained resources) ## Example ```python theme={null} # Create a new project for fraud detection models project = Project(name="fraud-detection-2024") project = project.create() print(f"Created project: {project.name} (ID: {project.id})") # Add a model to the project model = Model.from_data( source=training_df, name="xgboost_v1", project_id=project.id, task=ModelTask.BINARY_CLASSIFICATION ) model.create() # List all models in the project models = list(project.models) print(f"Project contains {len(models)} models") # Access project models for model_compact in project.models: full_model = model_compact.fetch() print(f"Model: {full_model.name} (Task: {full_model.task})") ``` Projects are permanent containers - once created, the name cannot be changed. Deleting a project removes all contained models, datasets, and configurations. Consider the organizational structure carefully before creating projects. Initialize a Project instance. Creates a new Project object with the specified name. The project is not created on the Fiddler platform until .create() is called. ## Parameters Project name, must be unique within the organization. Should follow slug-like naming conventions: * Use lowercase letters, numbers, hyphens, and underscores * Start with a letter or number * Be descriptive of the project's purpose * Examples: "fraud-detection", "churn\_prediction\_2024", "nlp-models" ## Example ```python theme={null} # Create project instance for fraud detection project = Project(name="fraud-detection-prod") # Create project instance for experimentation experiment_project = Project(name="ml-experiments-q1-2024") # Create on platform created_project = project.create() print(f"Project created with ID: {created_project.id}") ``` The project exists only locally until .create() is called. Project names cannot be changed after creation, so choose descriptive, permanent names. Consider your organization's naming conventions and project structure. ## *classmethod* get() Retrieve a project by its unique identifier. Fetches a project from the Fiddler platform using its UUID. This is the most direct way to retrieve a project when you know its ID. ### Parameters The unique identifier (UUID) of the project to retrieve. Can be provided as a UUID object or string representation. ### Returns The project instance with all metadata and configuration. ### Raises * **NotFound** – If no project exists with the specified ID. * **ApiError** – If there's an error communicating with the Fiddler API. ### Example ```python theme={null} # Get project by UUID project = Project.get(id_="550e8400-e29b-41d4-a716-446655440000") print(f"Retrieved project: {project.name}") print(f"Created: {project.created_at}") # Access project models model_count = len(list(project.models)) print(f"Project contains {model_count} models") ``` This method makes an API call to fetch the latest project state from the server. The returned project instance reflects the current state in Fiddler. ## *classmethod* from\_name() Retrieve a project by name. Finds and returns a project using its name within the organization. This is useful when you know the project name but not its UUID. Project names are unique within an organization, making this a reliable lookup method. ### Parameters The name of the project to retrieve. Project names are unique within an organization and are case-sensitive. ### Returns The project instance matching the specified name. ### Raises * **NotFound** – If no project exists with the specified name in the organization. * **ApiError** – If there's an error communicating with the Fiddler API. ### Example ```python theme={null} # Get project by name project = Project.from_name(name="fraud-detection") print(f"Found project: {project.name} (ID: {project.id})") print(f"Created: {project.created_at}") # Use project to list models for model in project.models: print(f"Model: {model.name} v{model.version}") # Get project for specific environment prod_project = Project.from_name(name="fraud-detection-prod") staging_project = Project.from_name(name="fraud-detection-staging") ``` Project names are case-sensitive and must match exactly. Use this method when you have a known project name from configuration or user input. ## *classmethod* list() List all projects in the organization. Retrieves all projects that the current user has access to within the organization. Returns an iterator for memory efficiency when dealing with many projects. ### Yields `Project` – Project instances for all accessible projects. ### Raises **ApiError** – If there's an error communicating with the Fiddler API. ### Returns `Iterator[Project]` ### Example ```python theme={null} # List all projects for project in Project.list(): print(f"Project: {project.name}") print(f" ID: {project.id}") print(f" Created: {project.created_at}") print(f" Models: {len(list(project.models))}") # Convert to list for counting and filtering projects = list(Project.list()) print(f"Total accessible projects: {len(projects)}") # Find projects by name pattern prod_projects = [ p for p in Project.list() if "prod" in p.name.lower() ] print(f"Production projects: {len(prod_projects)}") # Get project summaries for project in Project.list(): model_count = len(list(project.models)) print(f"{project.name}: {model_count} models") ``` This method returns an iterator for memory efficiency. Convert to a list with list(Project.list()) if you need to iterate multiple times or get the total count. The iterator fetches projects lazily from the API. ## create() Create the project on the Fiddler platform. Persists this project instance to the Fiddler platform, making it available for adding models, configuring monitoring, and other operations. The project must have a unique name within the organization. ### Returns This project instance, updated with server-assigned fields like ID, creation timestamp, and other metadata. ### Raises * **Conflict** – If a project with the same name already exists in the organization. * **ValidationError** – If the project configuration is invalid (e.g., invalid name format). * **ApiError** – If there's an error communicating with the Fiddler API. ### Example ```python theme={null} # Create a new project project = Project(name="customer-churn-analysis") created_project = project.create() print(f"Created project with ID: {created_project.id}") print(f"Created at: {created_project.created_at}") # Project is now available for adding models assert created_project.id is not None # Add a model to the newly created project model = Model.from_data( source=training_data, name="churn_model_v1", project_id=created_project.id ) model.create() ``` After successful creation, the project instance is updated in-place with server-assigned metadata. The same instance can be used for subsequent operations without needing to fetch it again. ## *classmethod* get\_or\_create() Get an existing project by name or create a new one if it doesn't exist. This is a convenience method that attempts to retrieve a project by name, and if not found, creates a new project with that name. Useful for idempotent project setup in automation scripts and deployment pipelines. ### Parameters The name of the project to retrieve or create. Must follow project naming conventions (slug-like format). ### Returns Either the existing project with the specified name, or a newly created project if none existed. ### Raises * **ValidationError** – If the project name format is invalid. * **ApiError** – If there's an error communicating with the Fiddler API. ### Example ```python theme={null} # Safe project setup - get existing or create new project = Project.get_or_create(name="fraud-detection-prod") print(f"Using project: {project.name} (ID: {project.id})") # Idempotent setup in deployment scripts project = Project.get_or_create(name="ml-pipeline-staging") # Add models safely - project guaranteed to exist model = Model.from_data( source=data, name="model_v1", project_id=project.id ) model.create() # Use in configuration management environments = ["dev", "staging", "prod"] projects = {} for env in environments: projects[env] = Project.get_or_create(name=f"fraud-detection-{env}") ``` This method is idempotent - calling it multiple times with the same name will return the same project. It logs when creating a new project for visibility in automation scenarios. ## delete() Delete the project and all its contained resources. Permanently removes the project from the Fiddler platform, including all associated models, datasets, baselines, alerts, and monitoring configurations. This operation cannot be undone. ### Raises * **NotFound** – If the project doesn't exist or has already been deleted. * **ApiError** – If there's an error communicating with the Fiddler API. * **PermissionError** – If the user doesn't have permission to delete the project. This operation is irreversible and will delete ALL resources associated with the project, including: * All models and their versions * All datasets and published data * All baselines and monitoring configurations * All alert rules and notification settings * All access permissions and project settings ### Example ```python theme={null} # Delete a test or temporary project test_project = Project.from_name(name="temp-experiment") test_project.delete() print(f"Deleted project: {test_project.name}") # Safe deletion with confirmation project = Project.from_name(name="old-project") model_count = len(list(project.models)) if model_count == 0: project.delete() print("Empty project deleted") else: print(f"Project has {model_count} models - deletion cancelled") # Cleanup projects by pattern for project in Project.list(): if project.name.startswith("temp-"): print(f"Deleting temporary project: {project.name}") project.delete() ``` Requires Fiddler platform version 25.2.0 or higher. Consider exporting important data or configurations before deletion. There is no recovery mechanism once a project is deleted. ## *property* models Fetch all the models of this project. ### Yields [`ModelCompact`](/sdk-api/python-client/model-compact) – Lightweight model objects for this project. # ProjectCompact Source: https://docs.fiddler.ai/sdk-api/python-client/project-compact Lightweight project representation for listing and basic operations. Lightweight project representation for listing and basic operations. A minimal project object containing only essential identifiers. Used by various listing operations to efficiently return project information without fetching full project details and associated resources. This class provides a memory-efficient way to work with project references when you don't need the full project functionality but want to access basic information or fetch the complete project when needed. ## Example ```python theme={null} # From project references in other entities model = Model.get(id_="model-uuid") project_compact = model.project # Returns ProjectCompact # Access basic info print(f"Project: {project_compact.name}") print(f"ID: {project_compact.id}") # Fetch full details when needed full_project = project_compact.fetch() print(f"Created: {full_project.created_at}") print(f"Models: {len(list(full_project.models))}") ``` ProjectCompact objects are typically returned by other entities that reference projects. Use .fetch() to get the complete Project instance when you need full functionality like listing models or project operations. ## id ## name ## fetch() Fetch project instance. ### Returns Complete project instance with all details. # RowDataSource Source: https://docs.fiddler.ai/sdk-api/python-client/row-data-source Data source for explainability analysis using a single row of data. Data source for explainability analysis using a single row of data. RowDataSource allows you to perform explainability analysis on a specific data row by providing the row data directly. This is useful when you want to explain a particular prediction or analyze feature importance for a specific instance without referencing stored data. This data source type is ideal for real-time explanations, ad-hoc analysis, or when you have specific data points that you want to analyze independently of your stored datasets. ## Examples Creating a row data source for a loan application: ```python theme={null} row_source = RowDataSource( row={ "age": 35, "income": 75000, "credit_score": 720, "employment_years": 8, "loan_amount": 250000 } ) ``` Creating a row data source for image classification: ```python theme={null} image_row_source = RowDataSource( row={ "image_features": [0.1, 0.5, 0.3, ...], "metadata": "product_image_001.jpg", "category": "electronics" } ) ``` ## source\_type ## row ## model\_config Configuration for the model, should be a dictionary conforming to \[ConfigDict]\[pydantic.config.ConfigDict]. # Segment Source: https://docs.fiddler.ai/sdk-api/python-client/segment Data segment for targeted monitoring and cohort analysis. Data segment for targeted monitoring and cohort analysis. Segment defines subsets of model data based on specific criteria using SQL-like expressions. Segments enable cohort analysis, A/B testing evaluation, targeted monitoring of specific populations, and fairness analysis across different groups. ## Example ```python theme={null} # High-value customer segment high_value_segment = Segment( name="high_value_customers", model_id=model.id, definition="customer_lifetime_value > 10000 and account_age_days > 365", description="Customers with high LTV and established accounts" ).create() # Geographic segment west_coast_segment = Segment( name="west_coast_users", model_id=model.id, definition="state == 'CA' or state == 'OR' or state == 'WA'", description="Users from West Coast states" ).create() # Risk-based segment high_risk_segment = Segment( name="high_risk_applications", model_id=model.id, definition="credit_score < 600 or debt_to_income > 0.4", description="Loan applications with elevated risk factors" ).create() # Age-based demographic segment young_adults_segment = Segment( name="young_adults", model_id=model.id, definition="age >= 18 and age <= 35", description="Young adult demographic (18-35 years)" ).create() # Use segment in alert rule for targeted monitoring segment_alert = AlertRule( name="high_value_drift_alert", model_id=model.id, metric_id="drift_score", priority=Priority.HIGH, compare_to=CompareTo.BASELINE, condition=AlertCondition.GT, bin_size=BinSize.HOUR, critical_threshold=0.7, baseline_id=baseline.id, segment_id=high_value_segment.id ).create() ``` Segments are evaluated during data processing and can be used with any monitoring metric. Complex segment definitions may impact performance, so optimize for efficiency. Segments are particularly useful for fairness monitoring and business-critical cohort analysis. ## create() Create a new Segment on the Fiddler platform. Registers this Segment with the Fiddler platform. The expression must have a name, model\_id, and definition specified before calling create(). ### Returns The same Segment instance with updated server-side attributes (id, created\_at, etc.). ### Raises * **ApiError** – If there's an error communicating with the Fiddler API. * **Conflict** – If a Segment with the same name already exists for this model. ## delete() Delete this Segment from the Fiddler platform. Permanently removes the Segment. This action cannot be undone. Any alert rules or monitors using this Segment must be deleted first. ### Raises * **NotFound** – If the Segment no longer exists. * **ApiError** – If there's an error communicating with the Fiddler API. * **Conflict** – If the Segment is still being used by alert rules or monitors. ## *classmethod* from\_name() Retrieve a Segment by name and model. Fetches a Segment from the Fiddler platform using its name and associated model ID. ### Parameters The name of the Segment to retrieve. UUID or string identifier of the associated Model. ### Returns The Segment instance for the provided parameters. ### Raises * **NotFound** – If no Segment exists with the specified name and model. * **ApiError** – If there's an error communicating with the Fiddler API. ## *classmethod* get() Retrieve a Segment by its unique identifier. Fetches a Segment from the Fiddler platform using its UUID. ### Parameters The unique identifier (UUID) of the Segment to retrieve. Can be provided as a UUID object or string representation. ### Returns The Segment instance with all its configuration and metadata. ### Raises * **NotFound** – If no Segment exists with the specified ID. * **ApiError** – If there's an error communicating with the Fiddler API. ## *classmethod* get\_organization\_id() Get the organization UUID from the global connection. ### Returns Unique identifier of the organization associated with the current connection. ## *classmethod* get\_organization\_name() Get the organization name from the global connection. ### Returns Name of the organization associated with the current connection. ## *classmethod* list() List all Segment instances for a model. Retrieves all Segment instances associated with a specific model. ### Parameters UUID or string identifier of the Model. ### Yields Segment instances for each Segment in the model. ### Raises **ApiError** – If there's an error communicating with the Fiddler API. ### Returns `Iterator[Segment]` ## **init**() Construct a segment instance. # TextEmbedding Source: https://docs.fiddler.ai/sdk-api/python-client/text-embedding Represents custom features derived from text embeddings with TF-IDF analysis. Represents custom features derived from text embeddings with TF-IDF analysis. TextEmbedding extends VectorFeature to handle text-based embeddings with additional text-specific analysis capabilities. It combines vector clustering with TF-IDF analysis to provide both semantic clustering and keyword extraction for text data. The feature type is automatically set to CustomFeatureType.FROM\_TEXT\_EMBEDDING and uses clustering combined with TF-IDF summarization for drift computation. ## Examples ```python theme={null} # Creating a text embedding feature for review analysis: text_feature = TextEmbedding( name="review_sentiment_clusters", column="review_embedding", source_column="review_text", n_clusters=8, n_tags=20 ) # Creating a feature for document classification: doc_feature = TextEmbedding( name="document_topic_clusters", column="doc_embedding", source_column="document_content", n_clusters=12, n_tags=15 ) ``` ## type ## source\_column ## n\_tags ## tf\_idf ## *classmethod* validate\_n\_tags() ### Returns `int` ## model\_config Configuration for the model, should be a dictionary conforming to \[ConfigDict]\[pydantic.config.ConfigDict]. # Unsupported Source: https://docs.fiddler.ai/sdk-api/python-client/unsupported Raised when an unsupported operation is attempted. Raised when an unsupported operation is attempted. This exception occurs when users try to perform operations that are not supported by the current Fiddler platform configuration, client version, or specific model/dataset setup. This can include feature limitations, deprecated functionality, or operations not available for certain model types. Common scenarios include attempting to use features not available in the current platform edition, trying deprecated API methods, or performing operations incompatible with the model's configuration. ## Examples Handling unsupported operations: ```python theme={null} try: model.enable_advanced_feature() except Unsupported as e: print(f"Feature not available: {e.message}") # Use alternative approach or upgrade platform ``` Common unsupported scenarios: ```python theme={null} - Using enterprise features on basic plans - Attempting operations on incompatible model types - Calling deprecated API methods ``` ## message # VectorFeature Source: https://docs.fiddler.ai/sdk-api/python-client/vector-feature Represents custom features derived from a single vector column using clustering analysis. Represents custom features derived from a single vector column using clustering analysis. VectorFeature processes high-dimensional vector data (like embeddings or feature vectors) by applying k-means clustering to create discrete clusters that can be monitored for distribution changes over time. This is particularly useful for monitoring embedding drift in high-dimensional spaces. The feature type is automatically set to CustomFeatureType.FROM\_VECTOR and creates meaningful groupings from vector data for drift detection and anomaly identification. ## source\_column Optional original column if this feature is derived from an embedding ### Examples Creating a feature from a general embedding column: ```python theme={null} vector_feature = VectorFeature( name="embedding_clusters", column="user_embedding", n_clusters=10 ) ``` Creating a feature from model hidden states: ```python theme={null} hidden_feature = VectorFeature( name="hidden_state_clusters", column="model_hidden_layer", n_clusters=15, source_column="input_features" ) ``` ## type ## n\_clusters ## centroids ## column ## *classmethod* validate\_n\_clusters() ### Returns `int` ## model\_config Configuration for the model, should be a dictionary conforming to \[ConfigDict]\[pydantic.config.ConfigDict]. # Webhook Source: https://docs.fiddler.ai/sdk-api/python-client/webhook Webhook for integrating external notification systems with Fiddler alerts. Webhook for integrating external notification systems with Fiddler alerts. A Webhook represents an integration endpoint for delivering alert notifications to external systems like Slack, Microsoft Teams, or custom HTTP endpoints. Webhooks enable real-time alert delivery to team communication tools. ## name Human-readable name for the webhook. Should be descriptive and indicate the target system or team. ## url The webhook endpoint URL provided by the external system. This is the destination where alert notifications will be sent. ## provider The webhook provider type (`WebhookProvider`). Determines message formatting and delivery method. ### Example ```python theme={null} # Create Slack webhook for critical alerts slack_webhook = Webhook( name="critical-alerts-slack", url="https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX", provider=WebhookProvider.SLACK ).create() # Create Microsoft Teams webhook for team notifications teams_webhook = Webhook( name="ml-team-notifications", url="https://outlook.office.com/webhook/xxxxx/IncomingWebhook/xxxxx", provider=WebhookProvider.MS_TEAMS ).create() # List all webhooks webhooks = list(Webhook.list()) for webhook in webhooks: print(f"Webhook: {webhook.name} ({webhook.provider})") # Update webhook URL webhook = Webhook.from_name("critical-alerts-slack") webhook.url = "https://hooks.slack.com/services/NEW/WEBHOOK/URL" webhook.update() ``` Webhook URLs are sensitive credentials that should be kept secure. The provider type determines how messages are formatted and delivered. Test webhooks thoroughly before using them in production alert rules. Initialize a Webhook instance. Creates a webhook configuration for integrating external notification systems with Fiddler alert notifications. The webhook defines where and how alert messages should be delivered to external platforms. ## Parameters Human-readable name for the webhook. Should be descriptive and indicate the target system, team, or purpose (e.g., "ml-team-slack", "critical-alerts-teams"). The webhook endpoint URL provided by the external system. This is the destination where Fiddler will send HTTP POST requests with alert notification payloads. The webhook provider type (SLACK, MS\_TEAMS, or GENERIC). Determines message formatting, payload structure, and delivery method for optimal integration with the target platform. ## Example ```python theme={null} # Slack webhook for ML team alerts slack_webhook = Webhook( name="ml-team-slack-alerts", url="https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX", provider=WebhookProvider.SLACK ) # Microsoft Teams webhook for data quality alerts teams_webhook = Webhook( name="data-quality-teams", url="https://outlook.office.com/webhook/xxxxx/IncomingWebhook/xxxxx", provider=WebhookProvider.MS_TEAMS ) # Generic webhook for custom integrations custom_webhook = Webhook( name="custom-monitoring-system", url="https://monitoring.company.com/webhooks/fiddler", provider=WebhookProvider.GENERIC ) ``` After initialization, call create() to register the webhook with the Fiddler platform. Webhook URLs are sensitive and should be kept secure. ## *classmethod* get() Get the webhook instance using webhook id * **Params uuid:** UUID belongs to the Webhook ### Returns Webhook object ## *classmethod* from\_name() Get the webhook instance using webhook name ### Returns `Webhook` ## *classmethod* list() Get a list of all webhooks in the organization ### Returns `Iterator[Webhook]` ## create() Create a new webhook * **Params name:** name of webhook * **Params url:** webhook url * **Params provider:** Either 'SLACK' or 'MS\_TEAMS' ### Returns Created Webhook object. ## update() Update an existing webhook. ## delete() Delete an existing webhook. # WindowBinSize Source: https://docs.fiddler.ai/sdk-api/python-client/window-bin-size Time granularities for rolling baseline window aggregation. Time granularities for rolling baseline window aggregation. Window bin sizes define the time intervals used for rolling baseline calculations. They determine how far back in time the rolling baseline looks and at what granularity the data is aggregated. This parameter is only used with rolling baselines and works in conjunction with offset\_delta. Rolling Baseline Mechanics: * Window bin size sets the granularity of the sliding window * offset\_delta determines how many bins to look back * Together they define the rolling window: offset\_delta × window\_bin\_size * Example: WEEK + offset\_delta=4 creates a 4-week rolling window Granularity Trade-offs: * **Finer granularity (HOUR)**: More responsive to recent changes, higher sensitivity * **Coarser granularity (MONTH)**: More stable patterns, reduced noise * **Medium granularity (DAY/WEEK)**: Balanced responsiveness and stability Selection Guidelines: * HOUR: High-frequency models with rapid data changes * DAY: Standard operational monitoring for most models * WEEK: Weekly business cycles, batch processing patterns * MONTH: Long-term trends, seasonal patterns, strategic monitoring ## Example ```python theme={null} # Daily rolling baseline looking back 30 days daily_rolling = fdl.Baseline( name="daily_rolling_baseline", model_id=model.id, environment=fdl.EnvType.PRODUCTION, type_=fdl.BaselineType.ROLLING, window_bin_size=fdl.WindowBinSize.DAY, offset_delta=30 ).create() # Weekly rolling baseline looking back 8 weeks weekly_rolling = fdl.Baseline( name="weekly_rolling_baseline", model_id=model.id, environment=fdl.EnvType.PRODUCTION, type_=fdl.BaselineType.ROLLING, window_bin_size=fdl.WindowBinSize.WEEK, offset_delta=8 ).create() ``` Data Volume Considerations: ```python theme={null} - Ensure sufficient data volume within each bin for statistical reliability - Finer granularities require higher prediction frequencies - Consider your model's prediction patterns when selecting bin size - Balance between responsiveness and statistical stability ``` ## HOUR Hourly time bins for high-frequency rolling baselines ## DAY Daily time bins for standard rolling baseline monitoring ## WEEK Weekly time bins for trend analysis and batch patterns ## MONTH Monthly time bins for long-term seasonal pattern detection ## HOUR *= 'Hour'* ## DAY *= 'Day'* ## WEEK *= 'Week'* ## MONTH *= 'Month'* # XaiParams Source: https://docs.fiddler.ai/sdk-api/python-client/xai-params Configuration parameters for explainability (XAI) analysis in Fiddler models. Configuration parameters for explainability (XAI) analysis in Fiddler models. XaiParams defines the configuration for explainability analysis, including custom explanation methods and default explanation strategies. These parameters control how feature importance, SHAP values, and other explainability metrics are computed for your model. This configuration is essential for models that require custom explanation logic or when you want to override the default explanation methods provided by Fiddler's built-in explainability features. ## Examples Creating XAI parameters with custom methods: ```python theme={null} xai_params = XaiParams( custom_explain_methods=["custom_shap", "custom_lime", "domain_specific"], default_explain_method="custom_shap" ) ``` Creating XAI parameters with only default method: ```python theme={null} simple_xai_params = XaiParams( default_explain_method="integrated_gradients" ) ``` Creating XAI parameters for multiple explanation strategies: ```python theme={null} multi_xai_params = XaiParams( custom_explain_methods=[ "business_rule_explainer", "feature_interaction_explainer", "counterfactual_explainer" ], default_explain_method="business_rule_explainer" ) ``` Creating empty XAI parameters (use Fiddler defaults): ```python theme={null} default_xai_params = XaiParams() ``` ## custom\_explain\_methods User-defined explain\_custom method of the model object defined in package.py ## model\_config Configuration for the model, should be a dictionary conforming to \[ConfigDict]\[pydantic.config.ConfigDict]. ## default\_explain\_method Default explanation method # Creates Alert Rules Source: https://docs.fiddler.ai/sdk-api/rest-api/alert-rules/create-alert POST /v3/alert-rules Creates Alert Rules # createNotificationForAlertRule Source: https://docs.fiddler.ai/sdk-api/rest-api/alert-rules/create-notification-for-alert-rule POST /v3/alert-rules/{alert_id}/notification Create Notification for an Alert Rule # Deletes an Alert Rule Source: https://docs.fiddler.ai/sdk-api/rest-api/alert-rules/delete-alert-rule DELETE /v3/alert-rules/{alert_id} Deletes an Alert Rule # List latest alert record for each time bucket during specified time_bucket_start and time_bucket_end for the given alert rule Source: https://docs.fiddler.ai/sdk-api/rest-api/alert-rules/get-alert-record-history GET /v3/alert-rules/{alert_id}/record-history List latest alert record for each time bucket during specified time_bucket_start and time_bucket_end for the given alert rule # Returns Alert Rule for the given id Source: https://docs.fiddler.ai/sdk-api/rest-api/alert-rules/get-alert-rule GET /v3/alert-rules/{alert_id} Returns Alert Rule for the given id # List of all alert records during specified time_bucket_start and time_bucket_end for the given alert rule Source: https://docs.fiddler.ai/sdk-api/rest-api/alert-rules/get-alert-rule-records GET /v3/alert-rules/{alert_id}/records List of all alert records during specified time_bucket_start and time_bucket_end for the given alert rule # Lists all alert rules configured for a model. Source: https://docs.fiddler.ai/sdk-api/rest-api/alert-rules/get-alert-rules GET /v3/alert-rules Lists all alert rules configured for a model. # List of all alert rule summary in the given time_bucket_start and time_bucket_end Source: https://docs.fiddler.ai/sdk-api/rest-api/alert-rules/get-alert-rules-summary GET /v3/alert-rules/summary List of all alert rule summary in the given time_bucket_start and time_bucket_end # Get thresholds that were used to evaluate the given time bin using the given alert rule. Source: https://docs.fiddler.ai/sdk-api/rest-api/alert-rules/get-alert-thresholds-for-time-bin GET /v3/alert-rules/{alert_id}/get-thresholds Get thresholds that were used to evaluate the given time bin using the given alert rule. # Returns notification for the given Alert Rule id Source: https://docs.fiddler.ai/sdk-api/rest-api/alert-rules/get-notification-for-alert-rule GET /v3/alert-rules/{alert_id}/notification Returns notification for the given Alert Rule id # Alert Rules REST API Guide Source: https://docs.fiddler.ai/sdk-api/rest-api/alert-rules/index Discover Fiddler’s Alert Rules REST API guide. Learn to list alerts by time, create alert rules, send notifications for alerts, and more. `POST /v3/alert-rules/{alert_id}/notification` `POST /v3/alert-rules` `DELETE /v3/alert-rules/{alert_id}` `GET /v3/alert-rules/{alert_id}/get-thresholds` `GET /v3/alert-rules/{alert_id}/record-history` `GET /v3/alert-rules/{alert_id}/records` `GET /v3/alert-rules/summary` `GET /v3/alert-rules` `GET /v3/alert-rules/{alert_id}` `GET /v3/alert-rules/{alert_id}/notification` `POST /v3/alert-rules/{alert_id}/test-notification` `PATCH /v3/alert-rules/{alert_id}/notification` `PATCH /v3/alert-rules/{alert_id}` # Send a test notification for the given Alert Rule Source: https://docs.fiddler.ai/sdk-api/rest-api/alert-rules/test-notification-for-alert-rule POST /v3/alert-rules/{alert_id}/test-notification Send a test notification for the given Alert Rule to verify notification configuration # Update by id Source: https://docs.fiddler.ai/sdk-api/rest-api/alert-rules/update-alert-rule PATCH /v3/alert-rules/{alert_id} Update Alert Rule by id # Update by id Source: https://docs.fiddler.ai/sdk-api/rest-api/alert-rules/update-notification-for-alert-rule PATCH /v3/alert-rules/{alert_id}/notification Update Notification by Alert Rule id # Create New Application Source: https://docs.fiddler.ai/sdk-api/rest-api/applications/create-application POST /v3/applications Create New Application # Delete Application Source: https://docs.fiddler.ai/sdk-api/rest-api/applications/delete-application DELETE /v3/applications/{application_id} Delete application and all associated resources asynchronously # Get Application Source: https://docs.fiddler.ai/sdk-api/rest-api/applications/get-application GET /v3/applications/{application_id} Get application by ID # Get Application Metrics Metadata Source: https://docs.fiddler.ai/sdk-api/rest-api/applications/get-application-metrics GET /v3/applications/{application_id}/metrics Retrieves available metrics and aggregations for a GenAI application # List applications Source: https://docs.fiddler.ai/sdk-api/rest-api/applications/get-applications GET /v3/applications Get list of applications in a project for provided query and filters # Applications Source: https://docs.fiddler.ai/sdk-api/rest-api/applications/index REST API endpoints for managing applications in Fiddler Platform. `POST /v3/applications` `DELETE /v3/applications/{application_id}` `GET /v3/applications/{application_id}` `GET /v3/applications/{application_id}/metrics` `GET /v3/applications` `GET /v3/applications/{application_id}/catalog` `GET /v3/applications/{application_id}/catalog/values` # List catalog entries Source: https://docs.fiddler.ai/sdk-api/rest-api/applications/list-catalog GET /v3/applications/{application_id}/catalog Paginated, searchable list of entity names for an application. Returns entity names with semantic concept mappings, data types, first/last seen timestamps, and observation counts. Use query parameters to filter by entity type, data type, or semantic concept name. The `search` parameter performs a case-insensitive substring match on entity names. # List distinct values for a catalog entity Source: https://docs.fiddler.ai/sdk-api/rest-api/applications/list-catalog-values GET /v3/applications/{application_id}/catalog/values Paginated, searchable list of distinct values for a specific entity within an application. Useful for populating filter dropdowns in the Trace Explorer UI. Both `entity_type` and `name` are required — values are always scoped to a specific entity. # List attributes Source: https://docs.fiddler.ai/sdk-api/rest-api/attributes/get-attributes GET /v3/attributes Get list of attributes # Attributes Source: https://docs.fiddler.ai/sdk-api/rest-api/attributes/index REST API endpoints for managing attributes in Fiddler Platform. `GET /v3/attributes` # add baseline to a model Source: https://docs.fiddler.ai/sdk-api/rest-api/baseline/add-baseline POST /v3/baselines Adds a baseline to a model # Delete baseline from a model Source: https://docs.fiddler.ai/sdk-api/rest-api/baseline/delete-baseline DELETE /v3/baselines/{baseline_id} Delete baseline from a model # Get baseline details Source: https://docs.fiddler.ai/sdk-api/rest-api/baseline/get-baseline GET /v3/baselines/{baseline_id} Get baseline details # List of baselines based on user permissions and filters Source: https://docs.fiddler.ai/sdk-api/rest-api/baseline/get-baselines GET /v3/baselines List of baselines based on user permissions and filters # List of baselines of a model Source: https://docs.fiddler.ai/sdk-api/rest-api/baseline/get-model-baselines GET /v3/models/{model_id}/baselines List of baselines of a model # Baselines REST API Guide Source: https://docs.fiddler.ai/sdk-api/rest-api/baseline/index Discover Fiddler’s Baseline feature. Learn how to add, retrieve, delete, and list baselines for a model based on user permissions and filters. `POST /v3/baselines` `DELETE /v3/baselines/{baseline_id}` `GET /v3/baselines/{baseline_id}` `GET /v3/baselines` `GET /v3/models/{model_id}/baselines` # Create new custom metric Source: https://docs.fiddler.ai/sdk-api/rest-api/custom-metrics/create-custom-metric POST /v3/custom-metrics Create new custom metric # Delete custom metric by uuid Source: https://docs.fiddler.ai/sdk-api/rest-api/custom-metrics/delete-custom-metric DELETE /v3/custom-metrics/{uuid} Delete custom metric by uuid # Detail info of a custom metric Source: https://docs.fiddler.ai/sdk-api/rest-api/custom-metrics/get-custom-metric GET /v3/custom-metrics/{uuid} Detail info of a custom metric # List all custom metrics Source: https://docs.fiddler.ai/sdk-api/rest-api/custom-metrics/get-custom-metrics GET /v3/custom-metrics List all custom metrics # List all custom metrics for a model Source: https://docs.fiddler.ai/sdk-api/rest-api/custom-metrics/get-model-custom-metrics GET /v3/models/{model_id}/custom-metrics List all custom metrics for a model # Custom Metrics REST API Guide Source: https://docs.fiddler.ai/sdk-api/rest-api/custom-metrics/index Discover Fiddler’s Custom Metric feature. Learn how to add, retrieve, and delete custom metrics from you Fiddler models. `POST /v3/custom-metrics` `DELETE /v3/custom-metrics/{uuid}` `GET /v3/custom-metrics/{uuid}` `GET /v3/custom-metrics` `GET /v3/models/{model_id}/custom-metrics` # Get environment of a model Source: https://docs.fiddler.ai/sdk-api/rest-api/environment/get-environment GET /v3/environments/{env_id} Retrieve details of a specific environment associated with a model. # List Environments Source: https://docs.fiddler.ai/sdk-api/rest-api/environment/get-environments GET /v3/environments Retrieve a list of environments from authorized projects. # List of environments of a model Source: https://docs.fiddler.ai/sdk-api/rest-api/environment/get-model-environments GET /v3/models/{model_id}/environments Retrieve a list of environments associated with a specific model. # Environments REST API Guide Source: https://docs.fiddler.ai/sdk-api/rest-api/environment/index Learn about Fiddler’s environments API . Learn how to list pre-production and production environment datasets. `GET /v3/environments/{env_id}` `GET /v3/environments` `GET /v3/models/{model_id}/environments` # Add new Evals dataset items Source: https://docs.fiddler.ai/sdk-api/rest-api/evals/add-evals-dataset-items POST /v3/evals/datasets/{dataset_id}/items # Bulk add spans to dataset Source: https://docs.fiddler.ai/sdk-api/rest-api/evals/bulk-add-spans-to-dataset POST /v3/evals/datasets/{dataset_id}/items/from-spans Accept a list of explicit span references and a field mapping, fetch span attributes from ClickHouse, apply the mapping server-side, and write one dataset item per span. All-or-nothing — if any span cannot be resolved, no items are written and a 422 is returned with the list of unresolvable spans. `start_time` and `end_time` are required to bound the ClickHouse lookup to the relevant monthly partitions. Without them, the query would scan every partition for the application. The FE should pass the datagrid's current time range; MCP agents should pass the time range of the spans being exported. Mapping values are span attribute keys as returned by `POST /v3/spans/fields` (e.g. `"system.gen_ai.usage.input_tokens"`, `"user.cost_usd"`). Each key maps to the corresponding value from the span's `span_attributes` dict. # Create an Evals dataset Source: https://docs.fiddler.ai/sdk-api/rest-api/evals/create-evals-dataset POST /v3/evals/datasets # Delete a dataset Source: https://docs.fiddler.ai/sdk-api/rest-api/evals/delete-evals-dataset DELETE /v3/evals/datasets/{dataset_id} # Get a dataset by id Source: https://docs.fiddler.ai/sdk-api/rest-api/evals/get-evals-dataset-by-id GET /v3/evals/datasets/{dataset_id} # List dataset items Source: https://docs.fiddler.ai/sdk-api/rest-api/evals/get-evals-dataset-items GET /v3/evals/datasets/{dataset_id}/items Get list of items for a dataset # Get dataset schema Source: https://docs.fiddler.ai/sdk-api/rest-api/evals/get-evals-dataset-schema GET /v3/evals/datasets/{dataset_id}/schema Discover what field keys exist in each JSON bucket (inputs, expected_outputs, metadata, extras) across this dataset's items, along with a coverage count and inferred data type for each key. Useful for pre-populating a field mapper UI or for an MCP agent to understand what data is available before constructing a mapping. Returns empty objects for all buckets if the dataset has no items. # Evals Source: https://docs.fiddler.ai/sdk-api/rest-api/evals/index REST API endpoints for managing evals in Fiddler Platform. `POST /v3/evals/datasets/{dataset_id}/items` `POST /v3/evals/datasets/{dataset_id}/items/from-spans` `POST /v3/evals/datasets` `DELETE /v3/evals/datasets/{dataset_id}` `GET /v3/evals/datasets/{dataset_id}` `GET /v3/evals/datasets/{dataset_id}/schema` `GET /v3/evals/datasets/{dataset_id}/items` `GET /v3/evals/datasets` `PATCH /v3/evals/datasets/{dataset_id}` # List Evals datasets Source: https://docs.fiddler.ai/sdk-api/rest-api/evals/list-evals-datasets GET /v3/evals/datasets Retrieve datasets with pagination, search, ordering, and filters. # Update a dataset Source: https://docs.fiddler.ai/sdk-api/rest-api/evals/update-evals-dataset PATCH /v3/evals/datasets/{dataset_id} # Evaluation Source: https://docs.fiddler.ai/sdk-api/rest-api/evaluation/index REST API endpoints for managing evaluation in Fiddler Platform. `POST /v3/evals/score` # Score inputs using an evaluator Source: https://docs.fiddler.ai/sdk-api/rest-api/evaluation/score-inputs POST /v3/evals/score Score inputs using an evaluator # Create New Evaluator Rule Source: https://docs.fiddler.ai/sdk-api/rest-api/evaluator-rules/create-evaluator-rule POST /v3/evaluator-rules Create a new Evaluator Rule # Delete Rule Evaluator for an application Source: https://docs.fiddler.ai/sdk-api/rest-api/evaluator-rules/delete-rule-evaluator DELETE /v3/evaluator-rules/{evaluator_rule_id} Delete Rule Evaluator # List evaluator backfills Source: https://docs.fiddler.ai/sdk-api/rest-api/evaluator-rules/get-evaluator-backfills GET /v3/genai-enrichment-backfills Get list of evaluator backfill jobs for provided query and filters # List Rule evaluators Source: https://docs.fiddler.ai/sdk-api/rest-api/evaluator-rules/get-rule-evaluators GET /v3/evaluator-rules Get list of Rule evaluators setup for provided query and filters # Evaluator Rules REST API Guide Source: https://docs.fiddler.ai/sdk-api/rest-api/evaluator-rules/index Discover Fiddler’s Evaluator Rules REST API guide. Learn to list and create evaluator rules, update or delete a rule, map input keys, and list evaluator backfills. `POST /v3/evaluator-rules` `DELETE /v3/evaluator-rules/{evaluator_rule_id}` `POST /v3/evaluator-rules/map-input-keys` `GET /v3/genai-enrichment-backfills` `GET /v3/evaluator-rules` `PATCH /v3/evaluator-rules/{evaluator_rule_id}` # Get attribute names and input fields Source: https://docs.fiddler.ai/sdk-api/rest-api/evaluator-rules/map-input-keys-rule-evaluator POST /v3/evaluator-rules/map-input-keys Get the possible attribute names detected in the application and the input fields with data type to fill out for the evaluator name # Update Rule Evaluator Source: https://docs.fiddler.ai/sdk-api/rest-api/evaluator-rules/update-rule-evaluator PATCH /v3/evaluator-rules/{evaluator_rule_id} Update the Rule evaluator # Archive Evaluator Source: https://docs.fiddler.ai/sdk-api/rest-api/evaluators/archive-evaluator POST /v3/evaluators/{evaluator_id}/archive Archive an evaluator. Sets the evaluator's status to ARCHIVED. Archived evaluators are excluded from active queries and cannot be used in new evaluator rules. # Create New Evaluator Source: https://docs.fiddler.ai/sdk-api/rest-api/evaluators/create-evaluator POST /v3/evaluators Create a new Evaluator # Get Evaluator by ID Source: https://docs.fiddler.ai/sdk-api/rest-api/evaluators/get-evaluator GET /v3/evaluators/{evaluator_id} Get details of a specific evaluator by its ID # List evaluator config schemas Source: https://docs.fiddler.ai/sdk-api/rest-api/evaluators/get-evaluator-config-schemas GET /v3/evaluators/get-config-options Get list of evaluator config schema for each enrichment type with data type # List evaluators Source: https://docs.fiddler.ai/sdk-api/rest-api/evaluators/get-evaluators GET /v3/evaluators Get list of evaluators for provided query and filters # Evaluators REST API Guide Source: https://docs.fiddler.ai/sdk-api/rest-api/evaluators/index Discover Fiddler’s Evaluators REST API guide. Learn to list and create evaluators, get an evaluator by ID, update or archive evaluators, and fetch evaluator configuration options. `POST /v3/evaluators/{evaluator_id}/archive` `POST /v3/evaluators` `GET /v3/evaluators/{evaluator_id}` `GET /v3/evaluators/get-config-options` `GET /v3/evaluators` `PATCH /v3/evaluators/{evaluator_id}` # Update Evaluator Source: https://docs.fiddler.ai/sdk-api/rest-api/evaluators/update-evaluator PATCH /v3/evaluators/{evaluator_id} Update an evaluator's name and/or configuration. Creates a new version of the evaluator and archives the previous version. At least one field (name or enrichment_config) must be provided. # Delete events in Fiddler Platform Source: https://docs.fiddler.ai/sdk-api/rest-api/events/delete-events DELETE /v3/events Delete events in Fiddler Platform # Events Source: https://docs.fiddler.ai/sdk-api/rest-api/events/index REST API endpoints for managing events in Fiddler Platform. `DELETE /v3/events` `POST /v3/events` `PATCH /v3/events` # Publish events to Fiddler Platform Source: https://docs.fiddler.ai/sdk-api/rest-api/events/publish-events POST /v3/events Publish events to Fiddler Platform # Publish update events to Fiddler Platform Source: https://docs.fiddler.ai/sdk-api/rest-api/events/publish-events-update PATCH /v3/events Publish update events to Fiddler Platform # Create New Experiment Source: https://docs.fiddler.ai/sdk-api/rest-api/experiments/create-experiment POST /v3/evals/experiments Create a new experiment # Delete Experiment Source: https://docs.fiddler.ai/sdk-api/rest-api/experiments/delete-experiment DELETE /v3/evals/experiments/{experiment_id} Delete an experiment # getEvalScores Source: https://docs.fiddler.ai/sdk-api/rest-api/experiments/get-eval-scores GET /v3/evals/experiments/{experiment_id}/scores Get list of evaluation scores for an experiment # Get Experiment Source: https://docs.fiddler.ai/sdk-api/rest-api/experiments/get-experiment GET /v3/evals/experiments/{experiment_id} Get experiment by ID # Get Experiment Metrics Source: https://docs.fiddler.ai/sdk-api/rest-api/experiments/get-experiment-metrics GET /v3/evals/experiments/{experiment_id}/metrics Get per-evaluator aggregate metrics for an experiment. Auto-detects each evaluator's chart type based on score cardinality: numeric_range (>10 distinct numeric values, histogram), numeric_categorical (<=10 distinct numeric values, distribution bars), or categorical (label-only scores, distribution with ratios). # Get Experiment Row Metrics Source: https://docs.fiddler.ai/sdk-api/rest-api/experiments/get-experiment-metrics-rows GET /v3/evals/experiments/{experiment_id}/metrics/rows Get top and bottom performing rows via percentile-based outlier detection. Numeric evaluators use P10/P90 thresholds; categorical evaluators flag labels that differ from the mode. Rows are ranked by how many evaluators flagged them as outliers. # List experiment results Source: https://docs.fiddler.ai/sdk-api/rest-api/experiments/get-experiment-results GET /v3/evals/experiments/{experiment_id}/results Get a paginated list of results for an experiment. Each result contains the experiment item outputs, dataset inputs and expected outputs, and all associated evaluation scores (including the evaluator name). **Filtering** (`filter` parameter — JSON-encoded QueryCondition DSL): - `experiment_item_id` — filter by one or more item IDs (operators: `equal`, `not_equal`, `in`, `not_in`) **Ordering** (`ordering` parameter): - `timestamp` / `-timestamp` — sort by item timestamp (default: `-timestamp`) - `created_at` / `-created_at` — sort by backend creation time - `scores.score_value` / `-scores.score_value` — sort by first score value - `scores.{score_name}` / `-scores.{score_name}` — sort by named score value (e.g. `scores.accuracy`, `-scores.toxicity`) # List experiments Source: https://docs.fiddler.ai/sdk-api/rest-api/experiments/get-experiments GET /v3/evals/experiments Get list of experiments for provided query and filters # Experiments Source: https://docs.fiddler.ai/sdk-api/rest-api/experiments/index REST API endpoints for managing experiments in Fiddler Platform. `POST /v3/evals/experiments` `DELETE /v3/evals/experiments/{experiment_id}` `GET /v3/evals/experiments/{experiment_id}` `GET /v3/evals/experiments/{experiment_id}/metrics` `GET /v3/evals/experiments/{experiment_id}/metrics/rows` `GET /v3/evals/experiments/{experiment_id}/scores` `GET /v3/evals/experiments/{experiment_id}/results` `GET /v3/evals/experiments` `PATCH /v3/evals/experiments/{experiment_id}` `POST /v3/evals/experiments/{experiment_id}/results` `POST /v3/evals/experiments/{experiment_id}/items` # Update Experiment Source: https://docs.fiddler.ai/sdk-api/rest-api/experiments/update-experiment PATCH /v3/evals/experiments/{experiment_id} Update an experiment # Upload new experiment items Source: https://docs.fiddler.ai/sdk-api/rest-api/experiments/upload-experiment-items POST /v3/evals/experiments/{experiment_id}/items Upload new experiment items # Upload experiment results Source: https://docs.fiddler.ai/sdk-api/rest-api/experiments/upload-experiment-results POST /v3/evals/experiments/{experiment_id}/results Upload new experiment results, each with an item and its associated scores. # Complete multi-part upload Source: https://docs.fiddler.ai/sdk-api/rest-api/file-upload/complete-multi-part-upload POST /v3/files/multipart-complete Completes the multi-part upload process for a large file in Fiddler. # Upload file in a single part Source: https://docs.fiddler.ai/sdk-api/rest-api/file-upload/file-upload POST /v3/files/upload Uploads a file in a single part to Fiddler. # File Upload REST API Guide Source: https://docs.fiddler.ai/sdk-api/rest-api/file-upload/index Explore API integration with Fiddler’s platform. Learn about file uploads, from single-part to multi-part options, and optimize your workflow effortlessly. `POST /v3/files/multipart-complete` `POST /v3/files/multipart-init` `POST /v3/files/multipart-upload` `POST /v3/files/upload` # Initiate multi-part upload Source: https://docs.fiddler.ai/sdk-api/rest-api/file-upload/initiate-multi-part-upload POST /v3/files/multipart-init Initiates a multi-part upload process for a large file to Fiddler. # Upload file a part of the file Source: https://docs.fiddler.ai/sdk-api/rest-api/file-upload/upload-part POST /v3/files/multipart-upload Uploads a part of a large file to Fiddler as part of a multi-part upload process. # FQL Expressions Source: https://docs.fiddler.ai/sdk-api/rest-api/fql-expressions/index REST API endpoints for managing fql expressions in Fiddler Platform. `GET /v3/fql-expressions` # List available FQL functions Source: https://docs.fiddler.ai/sdk-api/rest-api/fql-expressions/list-fql-expressions GET /v3/fql-expressions Returns the list of FQL functions available for GenAI custom metrics, including function metadata, parameter definitions, and return types. The response is used by the frontend for autocomplete suggestions, signature hints, and documentation in the FQL editor. Currently returns GenAI functions only (from the GenAI function registry plus the `attribute` construct). Extensible to ML context in the future via a query parameter. # Create GenAI Alert Rule Source: https://docs.fiddler.ai/sdk-api/rest-api/genai-alert-rules/create-gen-ai-alert-rule POST /v3/genai-alert-rules Creates a new GenAI Alert Rule # Deletes a GenAI Alert Rule Source: https://docs.fiddler.ai/sdk-api/rest-api/genai-alert-rules/delete-gen-ai-alert-rule DELETE /v3/genai-alert-rules/{alert_rule_id} Deletes a GenAI Alert Rule # Get GenAI Alert Rule Source: https://docs.fiddler.ai/sdk-api/rest-api/genai-alert-rules/get-gen-ai-alert-rule GET /v3/genai-alert-rules/{alert_rule_id} Retrieves a specific GenAI Alert Rule by its ID # GenAI Alert Rules Source: https://docs.fiddler.ai/sdk-api/rest-api/genai-alert-rules/index REST API endpoints for managing genai alert rules in Fiddler Platform. `POST /v3/genai-alert-rules` `DELETE /v3/genai-alert-rules/{alert_rule_id}` `GET /v3/genai-alert-rules/{alert_rule_id}` `GET /v3/genai-alert-rules` `POST /v3/genai-alert-rules/{alert_rule_id}/test-notification` # List GenAI Alert Rules Source: https://docs.fiddler.ai/sdk-api/rest-api/genai-alert-rules/list-gen-ai-alert-rules GET /v3/genai-alert-rules Lists all GenAI Alert Rules with pagination # Send Test Notification Source: https://docs.fiddler.ai/sdk-api/rest-api/genai-alert-rules/test-gen-ai-alert-rule-notification POST /v3/genai-alert-rules/{alert_rule_id}/test-notification Sends a test notification for a GenAI Alert Rule using the configured notification settings. The notification uses the actual alert email template with placeholder breach values so recipients can preview what a real alert notification will look like. # REST API Source: https://docs.fiddler.ai/sdk-api/rest-api/index Reference for the Fiddler REST API. Every operation in the public OpenAPI specification is documented here, grouped by resource. The Fiddler REST API is organized around REST: it has predictable, resource-oriented URLs, accepts and returns JSON-encoded payloads, and uses standard HTTP response codes, authentication, and verbs. Use it to ingest events, manage models, configure alerts, run explainability queries, and more. All endpoints require Bearer token authentication. See [Authentication](/sdk-api/python-client/connection) for details on obtaining a token. `/alert-rules` endpoints `/applications` endpoints `/attributes` endpoints `/baseline` endpoints `/custom-metrics` endpoints `/environment` endpoints `/evals` endpoints `/evaluation` endpoints `/evaluator-rules` endpoints `/evaluators` endpoints `/events` endpoints `/experiments` endpoints `/file-upload` endpoints `/fql-expressions` endpoints `/genai-alert-rules` endpoints `/jobs` endpoints `/llm-gateway` endpoints `/model` endpoints `/projects` endpoints `/queries` endpoints `/scores` endpoints `/segments` endpoints `/server-info` endpoints `/sessions` endpoints `/spans` endpoints `/traces` endpoints `/user-access-keys` endpoints `/users` endpoints ## API Response types Every Fiddler API response is wrapped in an envelope whose `kind` field identifies the response type: `NORMAL`, `PAGINATED`, or `ERROR`. ### Normal response Returned by operations that respond with a single resource or result. The payload is carried in `data`. ```json theme={null} { "api_version": "3.0", "kind": "NORMAL", "data": {} } ``` ### Paginated response Returned by list operations. The `data` object carries the current page in `items`, alongside pagination metadata. ```json theme={null} { "api_version": "3.0", "kind": "PAGINATED", "data": { "page_size": 10, "item_count": 10, "total": 100, "page_count": 10, "page_index": 1, "offset": 0, "items": [] } } ``` ### Error response Returned when a request fails. The `error` object carries an HTTP-aligned `code`, a human-readable `message`, and an `errors` array with per-issue detail. ```json theme={null} { "api_version": "3.0", "kind": "ERROR", "error": { "code": 404, "message": "The requested resource was not found.", "errors": [ { "reason": "ResourceNotFound", "message": "Model 'abc123' was not found in this project.", "help": "" } ] } } ``` ## Rate Limiting Rate limits apply to the endpoint categories listed below. When a limit is exceeded, the API returns **`429 Too Many Requests`**. These are **default limits and are deployment-overridable** — your Fiddler administrator can tune them per environment, and rate limiting can be enabled or disabled per deployment. ### Default limits | Endpoint category | Limit | | ---------------------------------------------------------------------------------------------------------------------------- | ----------------------- | | Metadata **read** — `GET` (list/read) on projects, applications, evaluators, evaluator rules, and related metadata resources | 30 req/s, 1,000 req/min | | Metadata **write** — `POST`/`PATCH`/`DELETE` on the same resources | 10 req/s, 300 req/min | | Spans query — `POST /v3/spans/query` | 10 req/s, 120 req/min | | ML event deletion — `DELETE /v3/events` | 30 req/day | | GenAI bulk delete — `DELETE /v3/traces`, `DELETE /v3/sessions` | 5 req/s, 100 req/day | ### Response headers Responses from rate-limited endpoints include the following headers: | Header | Description | | ----------------------- | ------------------------------------------------------------------------------- | | `X-RateLimit-Limit` | The active rate-limit policy for the endpoint (for example, `30 per 1 second`). | | `X-RateLimit-Remaining` | Requests remaining in the current window. | | `X-RateLimit-Reset` | Unix timestamp (in seconds) at which the current window resets. | | `Retry-After` | Seconds to wait before retrying. Sent only on a `429` response. | ### Per-token limits Limits are enforced **per access token**. Each endpoint keeps its own independent counter, so exhausting the limit on one endpoint does not consume the budget of any other. ### Handling 429 responses When a request returns `429 Too Many Requests`, wait at least the number of seconds indicated by the `Retry-After` header, then retry using **exponential backoff with jitter**. Each operation that enforces a limit also documents its `429 Too Many Requests` response on its API reference page (see the resource groups above). # Get async job details for a job id Source: https://docs.fiddler.ai/sdk-api/rest-api/jobs/get-job GET /v3/jobs/{job_id} Get async job details for a job id # Get details of all background/async jobs Source: https://docs.fiddler.ai/sdk-api/rest-api/jobs/get-jobs GET /v3/jobs Get details of all background/async jobs # Jobs REST API Guide Source: https://docs.fiddler.ai/sdk-api/rest-api/jobs/index Learn how to create requests and responses to retrieve async job details by job ID and view all background/async jobs with the Fiddler Platform. `GET /v3/jobs/{job_id}` `GET /v3/jobs` # Create new LLM provider Source: https://docs.fiddler.ai/sdk-api/rest-api/llm-gateway/create-llm-provider POST /v3/llm-gateway/providers Create a new LLM provider with credentials and models # Delete LLM provider Source: https://docs.fiddler.ai/sdk-api/rest-api/llm-gateway/delete-llm-provider DELETE /v3/llm-gateway/providers/{provider} Delete an LLM provider by name # Get available provider options Source: https://docs.fiddler.ai/sdk-api/rest-api/llm-gateway/get-llm-provider-options GET /v3/llm-gateway/providers/options Get available models for each supported LLM provider # List LLM providers Source: https://docs.fiddler.ai/sdk-api/rest-api/llm-gateway/get-llm-providers GET /v3/llm-gateway/providers Get list of LLM providers with pagination support # LLM Gateway Source: https://docs.fiddler.ai/sdk-api/rest-api/llm-gateway/index REST API endpoints for managing llm gateway in Fiddler Platform. `POST /v3/llm-gateway/providers` `DELETE /v3/llm-gateway/providers/{provider}` `GET /v3/llm-gateway/providers/options` `GET /v3/llm-gateway/providers` `POST /v3/llm-gateway/test-connection` `PUT /v3/llm-gateway/providers/{provider}` # Test LLM connection Source: https://docs.fiddler.ai/sdk-api/rest-api/llm-gateway/test-llm-connection POST /v3/llm-gateway/test-connection Test that a registered model + credential combination works by sending a minimal LLM completion call. Returns HTTP `200` with success/failure for LLM-level results. Returns `4xx` for invalid inputs (unknown model, unknown credential, malformed request) before any LLM call is made. # Update LLM provider Source: https://docs.fiddler.ai/sdk-api/rest-api/llm-gateway/update-llm-provider PUT /v3/llm-gateway/providers/{provider} Update an existing LLM provider's models and credentials. This is a replace operation - pass the complete desired state. For credentials: include existing ones (name/uuid) to keep them, add new ones (name/credential_config) to create them, omit any to remove them. For models: pass the complete list of desired models. Any fields not included will be removed. # Add a new model under a project Source: https://docs.fiddler.ai/sdk-api/rest-api/model/add-model POST /v3/models Add a new model under a project # Delete a model Source: https://docs.fiddler.ai/sdk-api/rest-api/model/delete-model DELETE /v3/models/{model_id} Delete a model # Upload artifacts associated with the model Source: https://docs.fiddler.ai/sdk-api/rest-api/model/deploy-model-artifact POST /v3/models/{model_id}/deploy-artifact Upload artifacts associated with the model # Update artifacts associated with the model Source: https://docs.fiddler.ai/sdk-api/rest-api/model/deploy-model-artifact-update PUT /v3/models/{model_id}/deploy-artifact Update artifacts associated with the model # Deploy a surrogate model Source: https://docs.fiddler.ai/sdk-api/rest-api/model/deploy-surrogate POST /v3/models/{model_id}/deploy-surrogate Deploy a surrogate model # Update a surrogate model Source: https://docs.fiddler.ai/sdk-api/rest-api/model/deploy-surrogate-update PUT /v3/models/{model_id}/deploy-surrogate Update a surrogate model # Get details of a model Source: https://docs.fiddler.ai/sdk-api/rest-api/model/get-model GET /v3/models/{model_id} Details of a model for given model id # Details of all columns Source: https://docs.fiddler.ai/sdk-api/rest-api/model/get-model-all-columns GET /v3/models/{model_id}/columns Details of all columns for a model # getModelColumnV3 Source: https://docs.fiddler.ai/sdk-api/rest-api/model/get-model-column GET /v3/models/{model_id}/columns/{column_id} Details of a specific column for a model # List models Source: https://docs.fiddler.ai/sdk-api/rest-api/model/get-models GET /v3/models Get list of model for provided query and filters # Model REST API Guide Source: https://docs.fiddler.ai/sdk-api/rest-api/model/index Dive into our guide to the Model REST API. Learn to list models, add models to a project, get details, update fields, generate models from samples, and more. `POST /v3/models` `DELETE /v3/models/{model_id}` `POST /v3/models/{model_id}/deploy-surrogate` `GET /v3/models/{model_id}/columns` `POST /v3/model-factory` `GET /v3/models/{model_id}` `GET /v3/models/{model_id}/columns/{column_id}` `GET /v3/models` `PUT /v3/models/{model_id}/deploy-surrogate` `PUT /v3/models/{model_id}/deploy-artifact` `PATCH /v3/models/{model_id}` `POST /v3/models/{model_id}/deploy-artifact` # Generate model from the given data sample Source: https://docs.fiddler.ai/sdk-api/rest-api/model/model-factory POST /v3/model-factory Generate model from the given data sample # Update the fields of a model Source: https://docs.fiddler.ai/sdk-api/rest-api/model/update-model PATCH /v3/models/{model_id} Update the fields of a model. **Schema and spec consistency.** This endpoint does not enforce consistency between the model `schema` (the list of columns) and the model `spec` (which assigns each column a role such as `inputs`, `outputs`, `targets`, `decisions`, `metadata`, or `custom_features`). If you add a column to `schema` without also adding it to the appropriate `spec` array, the column will be ingested into the raw events table but will not appear anywhere else in the Fiddler UI. **PATCH replaces nested objects wholesale.** When you PATCH the `spec` (or `schema`) field, the request body replaces the entire nested object — any role array you omit (`inputs`, `outputs`, `targets`, `decisions`, `metadata`, `custom_features`) is reset to empty on the server. Always read the current model first and merge your additions into the existing arrays before sending the PATCH. To add columns safely, follow the multi-step sequence shown in the code samples on the right: 1. `GET /v3/models/{model_id}` — retrieve the current `schema` and `spec`. 2. `PATCH /v3/models/{model_id}` with an updated `schema` containing the existing columns plus the new columns. 3. `PATCH /v3/models/{model_id}` with an updated `spec` that preserves every existing role array and adds the new columns to the appropriate one. The Fiddler Python SDK and the Fiddler UI enforce this consistency automatically; this note applies to direct REST API integrations. # Create new project Source: https://docs.fiddler.ai/sdk-api/rest-api/projects/create-project POST /v3/projects Create new project # Delete project by id Source: https://docs.fiddler.ai/sdk-api/rest-api/projects/delete-project DELETE /v3/projects/{project_id} Delete project by id # Detail info of a project for the specified project id Source: https://docs.fiddler.ai/sdk-api/rest-api/projects/get-project GET /v3/projects/{project_id} Detail info of a project # List of projects Source: https://docs.fiddler.ai/sdk-api/rest-api/projects/get-projects GET /v3/projects List of projects # Projects REST API Guide Source: https://docs.fiddler.ai/sdk-api/rest-api/projects/index Learn about REST API projects on the Fiddler platform. Explore how to list projects, create a new project, and get detailed info for a specified project ID. `POST /v3/projects` `DELETE /v3/projects/{project_id}` `GET /v3/projects/{project_id}` `GET /v3/projects` # API to fetch metrics used to plot monitoring charts Source: https://docs.fiddler.ai/sdk-api/rest-api/queries/get-queries POST /v3/queries API to fetch metrics used to plot monitoring charts # Queries Source: https://docs.fiddler.ai/sdk-api/rest-api/queries/index REST API endpoints for managing queries in Fiddler Platform. `POST /v3/queries` # Bulk create scores Source: https://docs.fiddler.ai/sdk-api/rest-api/scores/bulk-create-scores POST /v3/scores/bulk Create up to 100 scores in a single request. Per-item validation errors are collected and returned; valid items are committed together in a single batch insert. Infrastructure errors bubble as 500. # Create a score Source: https://docs.fiddler.ai/sdk-api/rest-api/scores/create-score POST /v3/scores Create a new score or annotation. Evaluator scores are read-only through this API — only human, LLM, and code sources are accepted. Returns 201 on success. # Delete a score Source: https://docs.fiddler.ai/sdk-api/rest-api/scores/delete-score DELETE /v3/scores/{score_id} Delete a score by ID. Returns 204 No Content on success. Idempotent — returns 204 even if the score does not exist. Returns 403 if source is evaluator. # Get a single score Source: https://docs.fiddler.ai/sdk-api/rest-api/scores/get-score GET /v3/scores/{score_id} Retrieve a single score by its ID. # Scores Source: https://docs.fiddler.ai/sdk-api/rest-api/scores/index REST API endpoints for managing scores in Fiddler Platform. `POST /v3/scores/bulk` `POST /v3/scores` `DELETE /v3/scores/{score_id}` `GET /v3/scores/{score_id}` `GET /v3/scores` `PATCH /v3/scores/{score_id}` # List scores Source: https://docs.fiddler.ai/sdk-api/rest-api/scores/list-scores GET /v3/scores List scores with optional filters. Supports filtering by target (span, trace, session), score name, source, level, type, annotator, config name, and time range. All filter parameters accept comma-separated values for multi-value matching. Ordering: use the `ordering` query param to sort results. Prefix a field name with `-` for descending. Default is `-created_at`. Valid fields: created_at, name, score_type, source, score_level, annotator_id, config_name, timestamp. The `timestamp` field sorts by the underlying target's timestamp (span/trace/session ingest time), which is not exposed as a separate field in the response. # Update a score Source: https://docs.fiddler.ai/sdk-api/rest-api/scores/update-score PATCH /v3/scores/{score_id} Partially update a score. Only value fields (value, label, text, reasoning, metadata) can be updated. Identity and structural fields (name, score_type, source, targets) cannot be changed — create a new score instead. Returns 403 if source is evaluator. # Create new segment Source: https://docs.fiddler.ai/sdk-api/rest-api/segments/create-segment POST /v3/segments Create new segment # Delete segment by uuid Source: https://docs.fiddler.ai/sdk-api/rest-api/segments/delete-segment DELETE /v3/segments/{uuid} Delete segment by uuid # List all segments for a model Source: https://docs.fiddler.ai/sdk-api/rest-api/segments/get-model-segments GET /v3/models/{model_id}/segments List all segments for a model # Detail info of a segment Source: https://docs.fiddler.ai/sdk-api/rest-api/segments/get-segment GET /v3/segments/{uuid} Detail info of a segment # List all segments Source: https://docs.fiddler.ai/sdk-api/rest-api/segments/get-segments GET /v3/segments List all segments # Segments REST API Guide Source: https://docs.fiddler.ai/sdk-api/rest-api/segments/index Discover Fiddler’s Segments REST API guide. Learn to list, create, view details, delete segments by UUID, and list all segments for a model. `POST /v3/segments` `DELETE /v3/segments/{uuid}` `GET /v3/segments/{uuid}` `GET /v3/segments` `GET /v3/models/{model_id}/segments` # Get server info Source: https://docs.fiddler.ai/sdk-api/rest-api/server-info/get-server-info GET /v3/server-info Get detailed information about the Fiddler server. # Server Info REST API Guide Source: https://docs.fiddler.ai/sdk-api/rest-api/server-info/index Learn API guidelines for retrieving server info with Fiddler’s platform. Discover how to create requests, receive responses, and maximize our solutions. `GET /v3/server-info` # Delete Sessions Source: https://docs.fiddler.ai/sdk-api/rest-api/sessions/delete-sessions DELETE /v3/sessions Delete one or more sessions and all associated data (spans, attributes, evaluator scores, and span content) from the application. This operation is idempotent — returns 204 even if the sessions do not exist. # Sessions Source: https://docs.fiddler.ai/sdk-api/rest-api/sessions/index REST API endpoints for managing sessions in Fiddler Platform. `DELETE /v3/sessions` # Get span field coverage Source: https://docs.fiddler.ai/sdk-api/rest-api/spans/get-span-fields POST /v3/spans/fields Given a filter over spans, return the union of span attribute keys and evaluator outputs that appear in the matching spans, along with a coverage count for each field. Useful for schema discovery and data completeness analysis — e.g. before adding spans to an evaluation dataset, an agent or UI can call this endpoint to understand which attributes are present and how consistently they appear across the selected spans, without fetching full span payloads. The query is bounded internally to the first 10,000 matching spans. When this cap is reached, `sampled` is set to `true` and counts are approximate. # Spans Source: https://docs.fiddler.ai/sdk-api/rest-api/spans/index REST API endpoints for managing spans in Fiddler Platform. `POST /v3/spans/fields` `POST /v3/spans/query` # Query spans Source: https://docs.fiddler.ai/sdk-api/rest-api/spans/query-spans POST /v3/spans/query Search, filter, and paginate through spans with advanced criteria # Delete Traces Source: https://docs.fiddler.ai/sdk-api/rest-api/traces/delete-traces DELETE /v3/traces Delete one or more traces and all associated data (spans, attributes, evaluator scores, and span content) from the application. This operation is idempotent — returns 204 even if the traces do not exist. # Traces Source: https://docs.fiddler.ai/sdk-api/rest-api/traces/index REST API endpoints for managing traces in Fiddler Platform. `DELETE /v3/traces` # Create a new API key. Source: https://docs.fiddler.ai/sdk-api/rest-api/user-access-keys/create-user-access-key POST /v3/user-access-keys Create a new API key for the authenticated user. Requires a unique name per user per organization. The full composite API key (key_id.secret) is returned once in the response and cannot be retrieved again. Enforces MAX_ACCESS_KEYS_PER_USER limit (default 5, new table only). # Delete an API key. Source: https://docs.fiddler.ai/sdk-api/rest-api/user-access-keys/delete-user-access-key DELETE /v3/user-access-keys/{key_id} Delete an API key. The API key is permanently removed and can no longer be used for authentication. # Get a single API key. Source: https://docs.fiddler.ai/sdk-api/rest-api/user-access-keys/get-user-access-key GET /v3/user-access-keys/{key_id} Get metadata for a single API key owned by the authenticated user. Returns `404` if the API key is not found or belongs to another user. # User Access Keys REST API Guide Source: https://docs.fiddler.ai/sdk-api/rest-api/user-access-keys/index Manage Fiddler API keys with the User Access Keys REST API guide. Learn to list, create, retrieve, update, and delete the access keys that authenticate your requests. `POST /v3/user-access-keys` `DELETE /v3/user-access-keys/{key_id}` `GET /v3/user-access-keys/{key_id}` `GET /v3/user-access-keys` `PATCH /v3/user-access-keys/{key_id}` # List the caller's API keys. Source: https://docs.fiddler.ai/sdk-api/rest-api/user-access-keys/list-user-access-keys GET /v3/user-access-keys List the authenticated user's API keys. Returns API key metadata only — secrets and hashes are never returned. Results are paginated. # Update an API key. Source: https://docs.fiddler.ai/sdk-api/rest-api/user-access-keys/update-user-access-key PATCH /v3/user-access-keys/{key_id} Update an API key's mutable fields. Supports updating the API key name and expiration. The new expires_at must be a future timestamp (greater than current time) and cannot exceed 100 years from now. # This API is used to get identity and access related information of a user. It also provides details into the last successful login of the user. Source: https://docs.fiddler.ai/sdk-api/rest-api/users/get-users GET /v3/users List users # Users Source: https://docs.fiddler.ai/sdk-api/rest-api/users/index REST API endpoints for managing users in Fiddler Platform. `GET /v3/users` # clear_llm_context Source: https://docs.fiddler.ai/sdk-api/strands/clear-llm-context Remove any previously set LLM context from a Model instance. Remove any previously set LLM context from a Model instance. After calling this function, subsequent spans created for the model will not carry `gen_ai.llm.context` unless it is set again via `set_llm_context()`. This is equivalent to `set_llm_context(model, None)`. Works automatically in both synchronous and asynchronous contexts. ## Parameters The Model instance to clear context from ## Example ```python theme={null} from strands.models.openai import OpenAIModel from fiddler_strandsagents import set_llm_context, clear_llm_context model = OpenAIModel(api_key="...", model_id="gpt-4") set_llm_context(model, "RAG retrieved documents...") # ... RAG LLM call ... clear_llm_context(model) # ... subsequent non-RAG LLM calls have no context ... ``` # FiddlerInstrumentationHook Source: https://docs.fiddler.ai/sdk-api/strands/fiddler-instrumentation-hook Centralized instrumentation hook for Strands agents with Fiddler integration. Centralized instrumentation hook for Strands agents with Fiddler integration. This hook provider automatically captures telemetry data from Strands agents and enriches OpenTelemetry spans with Fiddler-specific attributes. It handles three key events: before invocation, after tool execution, and after model calls. The hook is automatically injected when using StrandsAgentInstrumentor, so users typically don't need to manually add it to their agents. ## Example ```python theme={null} from strands import Agent from fiddler_strandsagents import FiddlerInstrumentationHook # Manual usage (not needed with StrandsAgentInstrumentor) agent = Agent( model=model, system_prompt="...", hooks=[FiddlerInstrumentationHook()] ) ``` ## register\_hooks() Register hook callbacks with the Strands agent registry. This method is called by the Strands framework to register callbacks for various agent lifecycle events. ### Parameters The HookRegistry to register callbacks with ## tool\_end() Handle the completion of a tool invocation. Enriches the current OpenTelemetry span with: * Custom attributes set via set\_span\_attributes() (prefixed 'fiddler.span.user.') * gen\_ai.tool.input — JSON-serialised input arguments passed to the tool * gen\_ai.tool.output — Text extracted from the tool result content ### Parameters AfterToolCallEvent (or legacy AfterToolInvocationEvent) containing tool execution details ## model\_end() Handle the completion of a model invocation. Enriches the current OpenTelemetry span with: * gen\_ai.llm.context — retrieved context set via set\_llm\_context() * Custom attributes set via set\_span\_attributes() (prefixed 'fiddler.span.user.') * gen\_ai.llm.output — text extracted from the model's response message ### Parameters AfterModelCallEvent (or legacy AfterModelInvocationEvent) containing model execution details ## before\_invocation() Handle the start of an agent invocation. Enriches the current OpenTelemetry span with: * Conversation ID set via set\_conversation\_id() * Session attributes set via set\_session\_attributes() * gen\_ai.llm.input.user — text of the last user message in the invocation Session attributes and conversation ID are also written to `event.agent.trace_attributes` so that Strands (>=1.19.0) propagates them natively to all child spans (model invoke, tool call, event-loop cycle, etc.) without needing manual parent-to-child denormalisation in a SpanProcessor. ### Parameters BeforeInvocationEvent containing agent invocation details # FiddlerSpanProcessor Source: https://docs.fiddler.ai/sdk-api/strands/fiddler-span-processor Backwards-compatible alias for StrandsSpanProcessor. # FiddlerSpanProcessor `FiddlerSpanProcessor` is a backwards-compatible alias for [`StrandsSpanProcessor`](/sdk-api/strands/strands-span-processor). They reference the same class -- `StrandsSpanProcessor` is the canonical name and `FiddlerSpanProcessor` remains exported so existing code continues to work. ```python theme={null} from fiddler_strandsagents import FiddlerSpanProcessor, StrandsSpanProcessor assert FiddlerSpanProcessor is StrandsSpanProcessor # True ``` For the full reference, see [StrandsSpanProcessor](/sdk-api/strands/strands-span-processor). > **Recommendation:** new code should import `StrandsSpanProcessor` directly. # get_conversation_id Source: https://docs.fiddler.ai/sdk-api/strands/get-conversation-id Get the conversation ID for the current agent invocation. Get the conversation ID for the current agent invocation. Retrieves the conversation ID that was previously set using set\_conversation\_id(). Works in both synchronous and asynchronous contexts automatically. ## Parameters The Strands Agent instance to retrieve the conversation ID from ## Returns The conversation ID string, or empty string if none has been set # get_llm_context Source: https://docs.fiddler.ai/sdk-api/strands/get-llm-context Get the LLM context for the current model. Get the LLM context for the current model. Retrieves the context string that was previously set using set\_llm\_context(). Works automatically in both synchronous and asynchronous contexts. ## Parameters The Model instance to retrieve context from ## Returns The LLM context string, or empty string if none has been set ## Example ```python theme={null} from fiddler_strandsagents import set_llm_context, get_llm_context set_llm_context(model, "Important background information") context = get_llm_context(model) print(context) # "Important background information" ``` # get_session_attributes Source: https://docs.fiddler.ai/sdk-api/strands/get-session-attributes Get the session attributes for the current agent invocation. Get the session attributes for the current agent invocation. Retrieves session attributes that were previously set using set\_session\_attributes(). Works in both synchronous and asynchronous contexts automatically. ## Parameters The Strands Agent instance to retrieve session attributes from ## Returns Dictionary of session attribute key-value pairs, or empty dict if none exist # get_span_attributes Source: https://docs.fiddler.ai/sdk-api/strands/get-span-attributes Get span attributes from a Model or AgentTool object. Get span attributes from a Model or AgentTool object. Retrieves custom attributes that were previously set using set\_span\_attributes(). Returns an empty dictionary if no attributes have been set. ## Parameters The Model or AgentTool instance to retrieve attributes from ## Returns Dictionary of attribute key-value pairs, or empty dict if none exist # Introduction Source: https://docs.fiddler.ai/sdk-api/strands/index Complete API reference for fiddler-strandsagents [![PyPI](https://img.shields.io/pypi/v/fiddler-strands)](https://pypi.org/project/fiddler-strands/) ## Overview Complete API reference documentation for the `fiddler-strands` package, which instruments the [Strands Agents SDK](https://strandsagents.com/) and exports OpenTelemetry traces to Fiddler. The package is published to PyPI as **`fiddler-strands`** and imported in Python as **`fiddler_strandsagents`**: ```bash theme={null} pip install fiddler-strands ``` ```python theme={null} from fiddler_strandsagents import StrandsAgentInstrumentor ``` ## Components ### Conversation And Session Conversation and session attribute helpers. `set_conversation_id` / `get_conversation_id` set and read the conversation ID for the current execution context. `set_session_attributes` / `get_session_attributes` replace and read the session attribute dict for the current context. * [get\_conversation\_id](/sdk-api/strands/get-conversation-id) * [get\_session\_attributes](/sdk-api/strands/get-session-attributes) * [set\_conversation\_id](/sdk-api/strands/set-conversation-id) * [set\_session\_attributes](/sdk-api/strands/set-session-attributes) ### Instrumentation `StrandsAgentInstrumentor` installs Fiddler tracing into the Strands Agents runtime. `FiddlerInstrumentationHook` is the Strands hook used internally by the instrumentor. * [FiddlerInstrumentationHook](/sdk-api/strands/fiddler-instrumentation-hook) * [StrandsAgentInstrumentor](/sdk-api/strands/strands-agent-instrumentor) ### Llm Context `set_llm_context` attaches context (e.g. retrieved documents) to a Strands `Model` so it appears on its LLM spans. `clear_llm_context` removes previously set LLM context. `get_llm_context` reads the current LLM context for a model. * [clear\_llm\_context](/sdk-api/strands/clear-llm-context) * [get\_llm\_context](/sdk-api/strands/get-llm-context) * [set\_llm\_context](/sdk-api/strands/set-llm-context) ### Span Attributes `set_span_attributes` and `get_span_attributes` set and read per-span custom attributes. * [get\_span\_attributes](/sdk-api/strands/get-span-attributes) * [set\_span\_attributes](/sdk-api/strands/set-span-attributes) ### Span Processor `StrandsSpanProcessor` propagates parent attributes and patches Strands' missing `gen_ai.system.message` event. `FiddlerSpanProcessor` is a backwards-compatible alias for `StrandsSpanProcessor` (same class object). * [FiddlerSpanProcessor](/sdk-api/strands/fiddler-span-processor) * [StrandsSpanProcessor](/sdk-api/strands/strands-span-processor) # set_conversation_id Source: https://docs.fiddler.ai/sdk-api/strands/set-conversation-id Set the conversation ID for the current agent invocation. Set the conversation ID for the current agent invocation. The conversation ID is used to group related agent invocations together, enabling conversation-level tracing and monitoring in Fiddler's platform. This ID will persist until it is explicitly changed by calling this function again with a new value. ## Parameters The Strands Agent instance to associate with the conversation Unique identifier for the conversation (e.g., session ID, user ID) ## Example ```python theme={null} from strands import Agent from fiddler_strandsagents import set_conversation_id agent = Agent(model=model, system_prompt="...") set_conversation_id(agent, "session_12345") ``` # set_llm_context Source: https://docs.fiddler.ai/sdk-api/strands/set-llm-context Set or clear additional context information for LLM interactions. Set or clear additional context information for LLM interactions. The LLM context allows you to provide additional background information or available options that can be tracked alongside model invocations. This context will be added to telemetry spans as 'gen\_ai.llm.context' and can be used for debugging or analysis in Fiddler's platform. The context persists until explicitly changed by calling this function again with a new value, or cleared by passing `None`. Clearing is useful in multi-step agent workflows where context set after a RAG step should not leak into later non-RAG LLM calls. Works automatically in both synchronous and asynchronous contexts. ## Parameters The Model instance to attach context to Context string providing additional information about available options, constraints, or background for the LLM interaction. Pass `None` to clear any previously set context. ## Example ```python theme={null} from strands.models.openai import OpenAIModel from fiddler_strandsagents import set_llm_context model = OpenAIModel(api_key="...", model_id="gpt-4") set_llm_context( model, 'Available hotels: Hilton, Marriott, Hyatt...' ) # Now when the model is invoked, the context will be # included in the telemetry span agent = Agent(model=model, system_prompt="You are a travel assistant") response = agent("Which hotel should I book?") # Clear context before non-RAG steps set_llm_context(model, None) ``` # set_session_attributes Source: https://docs.fiddler.ai/sdk-api/strands/set-session-attributes Add Fiddler-specific session attributes to an agent's metadata. Add Fiddler-specific session attributes to an agent's metadata. Session attributes provide context about the agent's execution environment, such as user roles, cost centers, or any custom metadata that should be tracked across all invocations within a session. ## Parameters The Strands Agent instance to add session attributes to Key-value pairs of session attributes (str, int, float, or bool values) ## Example ```python theme={null} from strands import Agent from fiddler_strandsagents import set_session_attributes agent = Agent(model=model, system_prompt="...") set_session_attributes(agent, role="customer_support", region="us-west") ``` # set_span_attributes Source: https://docs.fiddler.ai/sdk-api/strands/set-span-attributes Set custom attributes on a Model or AgentTool that can be accessed by logging hooks. Set custom attributes on a Model or AgentTool that can be accessed by logging hooks. This function stores key-value pairs as attributes on the object, making them accessible to hooks during model invocation events. Attributes are automatically scoped to async or sync contexts. ## Parameters The object to set the attribute on (Model or AgentTool instance) Key-value pairs of attributes to set (str, int, float, or bool values) ## Example ```python theme={null} from strands.models.openai import OpenAIModel from fiddler_strandsagents import set_span_attributes model = OpenAIModel(api_key="...", model_id="gpt-4") set_span_attributes(model, model_id="gpt-4", temperature=0.7) ``` # StrandsAgentInstrumentor Source: https://docs.fiddler.ai/sdk-api/strands/strands-agent-instrumentor OpenTelemetry instrumentor for Strands AI agents. OpenTelemetry instrumentor for Strands AI agents. This instrumentor automatically injects FiddlerInstrumentationHook into all Strands Agent instances, enabling automatic observability without manual hook configuration. It also registers a StrandsSpanProcessor for attribute denormalization. The instrumentor follows the OpenTelemetry instrumentation pattern and can be enabled/disabled dynamically. ## Example ```python theme={null} from strands.telemetry import StrandsTelemetry from fiddler_strandsagents import StrandsAgentInstrumentor telemetry = StrandsTelemetry() telemetry.setup_otlp_exporter() # Enable instrumentation instrumentor = StrandsAgentInstrumentor(telemetry) instrumentor.instrument() # Create agents - hooks are automatically injected agent = Agent(model=model, system_prompt="...") ``` Initialize the Strands Agent instrumentor. ## Parameters StrandsTelemetry instance for configuring trace exporters ## instrumentation\_dependencies() Return the list of packages required for instrumentation. ### Returns Collection of package names with version constraints ## instrument() Enable automatic instrumentation of Strands agents. Activates the instrumentor by registering the StrandsSpanProcessor with the tracer provider and patching Agent.**init** to automatically inject FiddlerInstrumentationHook into all agent instances. This method is idempotent - calling it multiple times has the same effect as calling it once. After activation, all newly created agents will automatically include Fiddler's instrumentation hook. ### Parameters **\*\*kwargs** – Additional instrumentation configuration (currently unused) ### Example ```python theme={null} from strands import Agent from strands.telemetry import StrandsTelemetry from fiddler_strandsagents import StrandsAgentInstrumentor # Set up telemetry telemetry = StrandsTelemetry() telemetry.setup_otlp_exporter() # Activate instrumentation instrumentor = StrandsAgentInstrumentor(telemetry) instrumentor.instrument() # Agents created after this point are automatically instrumented agent = Agent(model=model, system_prompt="...") # Check if instrumentation is active if instrumentor.is_instrumented_by_opentelemetry: print("Instrumentation is active") ``` ## uninstrument() Disable automatic instrumentation and restore original behavior. Deactivates the instrumentor by restoring the original Agent.**init** method. Agents created after calling this method will no longer have FiddlerInstrumentationHook automatically injected. Note: This does not affect agents that were already created while instrumentation was active - those will retain their hooks. ### Parameters **\*\*kwargs** – Additional uninstrumentation configuration (currently unused) ### Example ```python theme={null} from fiddler_strandsagents import StrandsAgentInstrumentor instrumentor = StrandsAgentInstrumentor(telemetry) instrumentor.instrument() # Create some agents (automatically instrumented) agent1 = Agent(model=model, system_prompt="...") # Deactivate instrumentation instrumentor.uninstrument() # New agents won't be instrumented agent2 = Agent(model=model, system_prompt="...") # agent1 still has the hook, agent2 does not ``` ## *property* is\_instrumented\_by\_opentelemetry Check whether instrumentation is currently active. ### Returns True if the instrumentor has been activated via instrument() and not yet deactivated via uninstrument(), False otherwise ### Example ```python theme={null} instrumentor = StrandsAgentInstrumentor(telemetry) print(instrumentor.is_instrumented_by_opentelemetry) # False instrumentor.instrument() print(instrumentor.is_instrumented_by_opentelemetry) # True instrumentor.uninstrument() print(instrumentor.is_instrumented_by_opentelemetry) # False ``` # StrandsSpanProcessor Source: https://docs.fiddler.ai/sdk-api/strands/strands-span-processor Propagates parent attributes via `CoreFiddlerSpanProcessor` plus Strands-specific behavior. Propagates parent attributes via `CoreFiddlerSpanProcessor` plus Strands-specific behavior. On every span start this processor: 1. Delegates to `CoreFiddlerSpanProcessor` for standard attribute denormalization. 2. For `chat` spans only: copies the parent's `system_prompt` into a `gen_ai.system.message` event as a workaround for Strands not always emitting that event on the chat span upstream (strands-agents/sdk-python#822). ## on\_start() Called when a span starts. Automatically propagates attributes from parent. ### Parameters The span being started. The parent context, if any.