Skip to main content

Import LangSmith traces into MLflow as durable local MLflow runs and traces.

Project description

mlflow-langsmith

pytest PyPI version Python versions License: MIT Ruff

Imports a LangSmith run into MLflow as a native MLflow trace. Run tree reconstructed as MLflow spans, source timestamps preserved, raw payload stored as an artifact, lookup tags written.

Use it when you want a LangSmith run to outlast LangSmith retention, sit next to your native MLflow runs in one UI, or act as a stable baseline for an eval suite.

Install

pip install mlflow-langsmith
# or
uv add mlflow-langsmith

Python 3.10, 3.11, 3.12, or 3.13. Depends on langsmith>=0.8, mlflow>=3.12, pydantic>=2.11.

Configure

LANGSMITH_API_KEY=...
MLFLOW_TRACKING_URI=http://127.0.0.1:5000
LANGSMITH_PROJECT=my-project            # optional default for list-langsmith-runs
MLFLOW_EXPERIMENT_NAME=agent-baselines  # optional default for imports

CLI flags and Python kwargs override the env.

CLI

Find a recent LangSmith run:

mlflow-langsmith list-langsmith-runs --limit 10 --success-only

Import it into MLflow:

mlflow-langsmith import-run \
    --langsmith-run-id 019e5a23-a0b8-7491-848f-b251a011e23a \
    --mlflow-experiment-name agent-baselines \
    --baseline-key nightly-regression

Look it back up later:

mlflow-langsmith list-imports  --mlflow-experiment-name agent-baselines
mlflow-langsmith show-import   --langsmith-run-id 019e5a23-a0b8-7491-848f-b251a011e23a

The import shows up in the MLflow UI as a normal trace.

Python

from mlflow_langsmith import import_langsmith_run

result = import_langsmith_run(
    "019e5a23-a0b8-7491-848f-b251a011e23a",
    mlflow_experiment_name="agent-baselines",
    baseline_key="nightly-regression",
    tags={"owner": "eval-platform"},
)

print(result.mlflow_run_id, result.mlflow_trace_id)

Already have a LangSmith Run object (e.g. inside your own eval harness)? Skip the second API call:

from mlflow_langsmith import import_langsmith_run_object
result = import_langsmith_run_object(run, mlflow_experiment_name="agent-baselines")

Resolve a prior import by baseline key. No LangSmith call needed:

from mlflow_langsmith import find_imported_run, load_imported_payload

ref = find_imported_run(baseline_key="nightly-regression")
payload = load_imported_payload(ref.mlflow_run_id)

What gets written

One MLflow run plus one MLflow trace per import, in your chosen experiment.

Spans: LangSmith chain, llm, chat_model, tool, retriever, parser, embedding, agent runs map to the matching MLflow span types. Parent-child relationships and start/end timestamps come from LangSmith, so step durations are real and not import wall-clock time.

Tags: source run id, source trace id, source project, baseline key. Indexable in MLflow search, and what find_imported_run queries against.

Artifacts under langsmith/:

  • raw-run.json (full LangSmith payload, audit copy)
  • normalized-run-tree.json
  • span-manifest.json
  • import-summary.json
  • messages.json, tool-calls.json, token-usage.json, attachments-manifest.json when present

Per-span attributes: token usage, model name, model provider, cost, status. Pulled from LangSmith fields where they exist.

Re-imports

duplicate_mode="skip" is the default. Importing the same LangSmith run twice returns the existing MLflow run. Pass "raise" to fail, "import" to force a new MLflow run.

Sensitive data

Imported artifacts contain the same prompts, responses, tool inputs, tool outputs, and metadata as the original LangSmith trace. Don't import into an MLflow store you wouldn't keep that data in.


For contributors

src layout. uv, pytest, ruff, mypy, pre-commit. CI runs the test suite on Python 3.10, 3.11, 3.12, 3.13.

uv sync
uv run pytest
uv run mypy src
uv run ruff check .

Local MLflow server (sqlite:///experiments/mlflow/mlflow.db):

bash scripts/start_mlflow_dev.sh

End-to-end against a real LangSmith run:

uv run --env-file .env mlflow-langsmith import-run --langsmith-run-id <RUN_ID>

Deeper docs:

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mlflow_langsmith-0.1.2.tar.gz (37.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mlflow_langsmith-0.1.2-py3-none-any.whl (30.5 kB view details)

Uploaded Python 3

File details

Details for the file mlflow_langsmith-0.1.2.tar.gz.

File metadata

  • Download URL: mlflow_langsmith-0.1.2.tar.gz
  • Upload date:
  • Size: 37.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for mlflow_langsmith-0.1.2.tar.gz
Algorithm Hash digest
SHA256 e655ab6729fa7d931cf4ddfb4b1b7c4edc3e572f7f1b0cce221ffdd2a4b34107
MD5 4ec8c19d3436fa9c04cb0087e647272a
BLAKE2b-256 bd3bc0f49217190df2279be2609e8338622410cc823923922d402b4d5217b7ea

See more details on using hashes here.

Provenance

The following attestation bundles were made for mlflow_langsmith-0.1.2.tar.gz:

Publisher: release.yml on dej-h/mlflow-langsmith

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file mlflow_langsmith-0.1.2-py3-none-any.whl.

File metadata

File hashes

Hashes for mlflow_langsmith-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 4a14baf9e88c4c8d3ed479e125d7e81ad354148699ba5a1ed18beb68f32a4a2c
MD5 e9df94ad2cc9c6999e37f010388d64ea
BLAKE2b-256 b63a48b934f6854e30632c3062c327550fc8dac96e38c6759c461827682b5bd6

See more details on using hashes here.

Provenance

The following attestation bundles were made for mlflow_langsmith-0.1.2-py3-none-any.whl:

Publisher: release.yml on dej-h/mlflow-langsmith

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page