Skip to content
Notifications
Clear all

Migrated from LangSmith to Freeplay - what broke and what got better

1 Posts
1 Users
0 Reactions
5 Views
(@migrate_mentor_7)
Eminent Member
Joined: 1 month ago
Posts: 25
Topic starter   [#1162]

Hello everyone. Just wrapped up a six-month migration project for our client's LLM evaluation and monitoring stack, moving them from LangSmith to Freeplay. As many of you know, these platforms are complex beasts—shifting one is like trying to swap the engine on a moving car. I wanted to share a detailed post-mortem, focusing not just on the "why" but the concrete "what broke" and "what improved." I'll walk through our methodical approach, the stumbles, and the wins.

First, some context. Our client had a mature LangSmith setup with about 200+ test traces a day, a custom evaluation suite built around LangChain, and heavy reliance on datasets and dataset comparisons. Their pain points were primarily cost predictability and the desire for more granular, SQL-accessible telemetry to feed into their Snowflake-based analytics.

### What Broke (The Migration Headaches)

The migration wasn't a simple lift-and-shift. Here's where we hit friction:

* **Dataset & Test Definition Conversion:** LangSmith's concept of "datasets" and "tests" doesn't map 1:1 to Freeplay. We had to rebuild their evaluation suites in Freeplay's **Test Suites**. This meant scripting the conversion of their LangSmith dataset rows into Freeplay's expected format. The main hurdle was that their evaluation logic was embedded in LangChain `run_evaluator` calls. We had to extract that logic and rewire it into Freeplay's **Custom Graders**.

Example of a simple Python function we had to adapt for a Freeplay Custom Grader:
```python
# Formerly a LangChain evaluator
def is_helpful(response, input):
# ... complex logic
return {"score": score, "reasoning": reasoning}

# Adapted for Freeplay (simplified)
def grader_callback(trace):
# Extract inputs/outputs from the Freeplay trace object
llm_output = trace.get_output_text()
user_input = trace.get_input_text()
# Re-use the core logic
result = is_helpful(llm_output, user_input)
return {
"score": result["score"],
"metadata": {"reasoning": result["reasoning"]}
}
```
* **Trace Data Model Shift:** LangSmith traces are deeply nested objects. Freeplay uses a flatter, more columnar structure aligned with their SQL-based **Signals**. This meant our client's internal dashboards that parsed specific fields from the LangSmith trace payload had to be completely rewritten. The `invocation_id` they used for joins in their old system became Freeplay's `trace_id`.
* **Loss of the LangChain Integration "Glue":** The native, drop-in LangSmith integration was a big loss initially. While Freeplay's SDK is robust, we had to methodically replace `LangSmith` callbacks in their existing LangChain code with `Freeplay` callbacks, which required careful testing to ensure no trace data was dropped.

### What Got Better (The Payoff)

After the initial hump, the benefits became very clear:

* **Cost Transparency & Control:** This was the biggest win. Freeplay's pricing model, based on **Signal** volume, was far more predictable for the client. In LangSmith, they were constantly anxious about trace volume spikes. With Freeplay, they could design Signals to capture only the critical, aggregatable metrics they needed for dashboards, ignoring verbose step-level details unless debugging.
* **SQL-Native Analytics:** Freeplay's automatic sinking of Signals to BigQuery (Snowflake is also supported) was a game-changer. Their data team could now write direct, performant queries without an intermediary ETL step.
```sql
-- Example: Simple daily performance trend query their analysts could now run directly
SELECT
DATE(timestamp) as eval_date,
AVG(CAST(score AS FLOAT64)) as avg_helpfulness_score
FROM `project.freeplay_signals.helpfulness_signal`
WHERE timestamp > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)
GROUP BY eval_date
ORDER BY eval_date;
```
* **Test Suite Flexibility:** While rebuilding tests was painful, the outcome was more maintainable. Freeplay's **Test Suites**, which can run over both static datasets and live production traffic samples, provided a unified view of model performance. The ability to version prompt templates and compare results side-by-side was more intuitive for their product team.
* **Performance & Reliability:** We observed a noticeable reduction in latency for the tracing callbacks in production. Freeplay's batching and ingestion pipeline seemed less prone to the occasional queuing delays they experienced during peak loads with their previous setup.

### Our Step-by-Step Migration Playbook (Condensed)

For those considering a similar move, here was our high-level process:

1. **Parallel Pilot:** Instrumented a non-critical service to send traces to **both** LangSmith and Freeplay for a month. Used this to validate data completeness.
2. **Signal Design Session:** Worked with the client's data team to define which metrics (**Signals**) were crucial for KPIs versus debugging. Started lean.
3. **Grader Migration:** Converted one evaluator at a time, running the same dataset through both the old LangSmith and new Freeplay test suites to ensure score parity.
4. **Dashboard Re-alignment:** Once Signal data was flowing to BigQuery, we incrementally re-built their core dashboards in Looker before the cutover.
5. **Phased Cutover:** Switched services over one-by-one based on priority, keeping the old LangSmith data archived for historical comparison.

The migration was a significant effort, but the shift towards a more analytics-friendly, cost-predictable system has been a major long-term win for the client. The key is to budget time for the conceptual remapping, not just the technical lift.

If you're planning a similar migration, my advice is to start with the data model: what questions do you need to answer from your traces, and what's the simplest set of Signals to get you there? The rest, while tedious, follows from that.

-- MigrateMentor


MigrateMentor


   
Quote