Import LangSmith traces into MLflow as durable local MLflow runs and traces.
Project description
mlflow-langsmith
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.jsonspan-manifest.jsonimport-summary.jsonmessages.json,tool-calls.json,token-usage.json,attachments-manifest.jsonwhen 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:
- docs/langsmith-to-mlflow-trace-strategy.md: span mapping, timestamp handling, normalization rules
- docs/local-mlflow-dev.md: local tracking store layout
- docs/pypi-release.md: TestPyPI / PyPI release workflow
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e655ab6729fa7d931cf4ddfb4b1b7c4edc3e572f7f1b0cce221ffdd2a4b34107
|
|
| MD5 |
4ec8c19d3436fa9c04cb0087e647272a
|
|
| BLAKE2b-256 |
bd3bc0f49217190df2279be2609e8338622410cc823923922d402b4d5217b7ea
|
Provenance
The following attestation bundles were made for mlflow_langsmith-0.1.2.tar.gz:
Publisher:
release.yml on dej-h/mlflow-langsmith
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mlflow_langsmith-0.1.2.tar.gz -
Subject digest:
e655ab6729fa7d931cf4ddfb4b1b7c4edc3e572f7f1b0cce221ffdd2a4b34107 - Sigstore transparency entry: 1644390300
- Sigstore integration time:
-
Permalink:
dej-h/mlflow-langsmith@2e1790d3fd1ccd033340056d8cebdd68b06256e8 -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/dej-h
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@2e1790d3fd1ccd033340056d8cebdd68b06256e8 -
Trigger Event:
push
-
Statement type:
File details
Details for the file mlflow_langsmith-0.1.2-py3-none-any.whl.
File metadata
- Download URL: mlflow_langsmith-0.1.2-py3-none-any.whl
- Upload date:
- Size: 30.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4a14baf9e88c4c8d3ed479e125d7e81ad354148699ba5a1ed18beb68f32a4a2c
|
|
| MD5 |
e9df94ad2cc9c6999e37f010388d64ea
|
|
| BLAKE2b-256 |
b63a48b934f6854e30632c3062c327550fc8dac96e38c6759c461827682b5bd6
|
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
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mlflow_langsmith-0.1.2-py3-none-any.whl -
Subject digest:
4a14baf9e88c4c8d3ed479e125d7e81ad354148699ba5a1ed18beb68f32a4a2c - Sigstore transparency entry: 1644390391
- Sigstore integration time:
-
Permalink:
dej-h/mlflow-langsmith@2e1790d3fd1ccd033340056d8cebdd68b06256e8 -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/dej-h
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@2e1790d3fd1ccd033340056d8cebdd68b06256e8 -
Trigger Event:
push
-
Statement type: