Packages

Feedback collection, drift detection, and active learning for ML pipelines

Current section

Files

Jump to
crucible_feedback lib crucible_feedback.ex
Raw

lib/crucible_feedback.ex

defmodule CrucibleFeedback do
@moduledoc """
Production feedback loop for ML systems.
"""
alias CrucibleFeedback.{Curation, Drift, Export, Ingestion, Quality, Signals, Triggers}
@type drift_result :: Drift.drift_result()
@doc """
Log an inference event for asynchronous ingestion.
"""
@spec log_inference(map()) :: :ok
def log_inference(event) do
Ingestion.log_inference(event)
end
@doc """
Record a user signal.
"""
@spec record_signal(String.t(), atom(), map()) :: {:ok, map()} | {:error, term()}
def record_signal(inference_id, signal_type, metadata \\ %{}) do
Signals.record_signal(inference_id, signal_type, metadata)
end
@doc """
Record a user edit signal.
"""
@spec record_user_edit(String.t(), String.t()) :: {:ok, map()} | {:error, term()}
def record_user_edit(inference_id, edited_response) do
Signals.record_user_edit(inference_id, edited_response)
end
@doc """
Assess quality for a single event.
"""
@spec assess_quality(map()) :: %{score: float(), checks: list()}
def assess_quality(event) do
Quality.assess(event)
end
@doc """
Return summary quality statistics for a deployment.
"""
@spec get_quality_stats(String.t()) :: map()
def get_quality_stats(deployment_id) do
%{rolling_average: Quality.rolling_average(deployment_id)}
end
@doc """
Detect drift for a deployment.
"""
@spec detect_drift(String.t(), keyword()) :: [drift_result()]
def detect_drift(deployment_id, opts \\ []) do
Drift.detect(deployment_id, opts)
end
@doc """
Return persisted drift history (if configured).
"""
@spec get_drift_history(String.t()) :: [drift_result()]
def get_drift_history(_deployment_id) do
[]
end
@doc """
Curate examples for retraining.
"""
@spec curate(String.t(), keyword()) :: [map()]
def curate(deployment_id, opts \\ []) do
Curation.curate(deployment_id, opts)
end
@doc """
Return count of curated examples for a deployment.
"""
@spec get_curated_count(String.t()) :: integer()
def get_curated_count(deployment_id) do
storage = Application.get_env(:crucible_feedback, :storage)
storage.count_curated_examples(deployment_id, [])
end
@doc """
Check retraining triggers for a deployment.
"""
@spec check_triggers(String.t(), keyword()) :: [{:trigger, atom()}]
def check_triggers(deployment_id, opts \\ []) do
Triggers.check_triggers(deployment_id, opts)
end
@doc """
Export curated data for training.
"""
@spec export(String.t(), keyword()) :: {:ok, Path.t()} | {:error, term()}
def export(deployment_id, opts \\ []) do
Export.export(deployment_id, opts)
end
@doc """
Export preference pairs derived from user edits.
"""
@spec export_preference_pairs(String.t(), keyword()) :: {:ok, Path.t()} | {:error, term()}
def export_preference_pairs(deployment_id, opts \\ []) do
Export.export_preference_pairs(deployment_id, opts)
end
end