Tracing med LangSmith
Instrumentera er LangChain-applikation med LangSmith-tracing för att registrera varje kedjesteg, LLM-anrop, tokenantal och fördröjning i en sökbar trace explorer.
Tracing med LangSmith är en gratis lektion i AI Engineering Academy på CoddyKit. Detta är lektion 2 av 4. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för AI Engineering Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i AI Engineering Academy innehåller totalt 4 lektioner.
Vad är LangSmith?
LangSmith är en observability-plattform som är särskilt utvecklad för LLM-applikationer. Den fångar automatiskt traces för varje LangChain-körning — varje kedjesteg, LLM-anrop, verktygskörning, hämtning och output-parser — och visar dem i en sökbar hierarkisk trace explorer. Ni kan filtrera traces efter fördröjning, kostnad, felstatus eller anpassade metadata och spela upp valfri trace igen för att debugga fel.
# Install: pip install langsmith
import os
# Set environment variables to enable automatic tracing
os.environ['LANGCHAIN_TRACING_V2'] = 'true'
os.environ['LANGCHAIN_API_KEY'] = 'lsv2_...your_key_here...'
os.environ['LANGCHAIN_PROJECT'] = 'my-rag-app' # project name in LangSmith UI
# That's all - LangChain now sends traces to LangSmith automatically
# No code changes needed to your chain or agentAutomatisk tracing utan kodändringar
Den mest övertygande funktionen i LangSmith är att varje LangChain-operation automatiskt trace:as utan ytterligare kod när ni har angett de tre miljövariablerna. Varje LCEL-kedja, varje ChatOpenAI-anrop, varje retriever-anrop och varje verktygskörning fångas med indata, utdata, tidsmätningar och tokenantal. Ni kan aktivera LangSmith-tracing i produktion genom att ändra en enda miljövariabel.
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
# This chain is automatically traced - no extra code needed
llm = ChatOpenAI(model='gpt-4o')
prompt = ChatPromptTemplate.from_template('Answer this question: {question}')
chain = prompt | llm | StrOutputParser()
# This call creates a trace in LangSmith showing:
# - The formatted prompt (with question substituted)
# - The LLM call with model, temperature, token counts
# - The parsed output
# - End-to-end latency and cost
result = chain.invoke({'question': 'What is RAG?'})
print(result)Tracing av RAG-pipelines
För RAG-applikationer är LangSmith-traces särskilt värdefulla eftersom de fångar hela pipelinen för hämtning följt av generering. Ni kan se vilka dokument som hämtades, vilka likhetspoäng de hade, hur kontexten formaterades i prompten och vad LLM:en genererade. Det blir då omedelbart tydligt om ett felaktigt svar berodde på bristfällig hämtning eller dålig generering.
from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from langchain_community.vectorstores import Chroma
from langchain_core.runnables import RunnablePassthrough
embeddings = OpenAIEmbeddings()
vectorstore = Chroma(embedding_function=embeddings)
retriever = vectorstore.as_retriever(search_kwargs={'k': 5})
rag_chain = (
{'context': retriever, 'question': RunnablePassthrough()}
| ChatPromptTemplate.from_template('Context: {context}\n\nQuestion: {question}\n\nAnswer:')
| ChatOpenAI(model='gpt-4o')
| StrOutputParser()
)
# LangSmith traces EVERY step:
# 1. Retriever: query embedding + vector search + returned documents (with scores)
# 2. Prompt: formatted template with context injected
# 3. LLM: full prompt, response, tokens, latency, cost
# 4. Parser: final string output
answer = rag_chain.invoke('What is the capital of France?')Lägga till metadata i traces
Som standard innehåller LangSmith-traces indata och utdata för varje steg. Ni kan berika traces med anpassade metadatataggar: användar-ID, sessions-ID, värden för feature flags, A/B-testvariant eller annan kontext som hjälper er att filtrera och analysera traces i användargränssnittet. Använd RunnableConfig för att skicka metadata som visas i varje trace från den förfrågan.
from langchain_core.runnables import RunnableConfig
def handle_user_request(user_id: str, query: str, ab_variant: str):
config = RunnableConfig(
tags=['production', ab_variant],
metadata={
'user_id': user_id,
'ab_variant': ab_variant,
'feature': 'rag_qa'
}
)
result = rag_chain.invoke(query, config=config)
return result
# In LangSmith UI you can now:
# - Filter traces by user_id to debug a specific user's issue
# - Compare latency between ab_variant='A' and ab_variant='B'
# - See all traces tagged 'production' vs 'staging'Skapa spans manuellt
För kod som inte går via LangChain (anpassade API-anrop, databasfrågor och förbehandlingssteg) kan ni skapa manuella spans direkt med LangSmith-klienten. Då fångas även stegen utanför LangChain i samma trace som LangChain-stegen, vilket ger en fullständig bild av körningsvägen för varje förfrågan.
from langsmith import Client, traceable
client = Client()
# Decorate functions to auto-trace them
@traceable(name='preprocess_query')
def preprocess_query(raw_query: str) -> str:
# This step is now traced even though it doesn't use LangChain
cleaned = raw_query.strip().lower()
cleaned = ' '.join(cleaned.split()) # normalize whitespace
return cleaned
@traceable(name='fetch_user_history')
def fetch_user_history(user_id: str) -> list[str]:
# Database call - also traced
return db.query('SELECT message FROM chat_history WHERE user_id = ? ORDER BY timestamp DESC LIMIT 5', user_id)
# All three steps appear in the same trace
def handle_request(user_id: str, raw_query: str):
query = preprocess_query(raw_query) # traced
history = fetch_user_history(user_id) # traced
result = rag_chain.invoke({'query': query, 'history': history}) # traced by LangChain
return resultUtvärdera traces i LangSmith
LangSmith innehåller ett utvärderingsramverk som låter er köra utvärderare på ert trace-dataset. Ni kan välja en uppsättning trace:ade exempel, köra automatiserade utvärderare (inklusive LLM-as-judge-bedömare för korrekthet och relevans) och jämföra resultaten mellan olika pipelineversioner. På så sätt blir era produktions-traces en återkopplingsloop för att förbättra applikationen.
from langsmith.evaluation import evaluate, LangChainStringEvaluator
# Create an evaluator that uses an LLM to judge correctness
correctness_evaluator = LangChainStringEvaluator(
'qa',
config={'llm': ChatOpenAI(model='gpt-4o')}
)
# Run evaluation against a dataset of traced examples
results = evaluate(
rag_chain,
data='my-rag-test-set', # name of dataset in LangSmith
evaluators=[correctness_evaluator],
experiment_prefix='rag-v2-chunking-test'
)
print('Evaluation results:')
print(f'Correctness: {results.results["correctness"].mean():.2f}')
print(f'Average latency: {results.results["latency"].mean():.2f}s')Skapa testdataset från traces
En av LangSmiths mest kraftfulla funktioner är möjligheten att skapa testdataset direkt från produktions-traces. När ni upptäcker en intressant trace (ett fel, ett kantfall eller ett bra exempel) kan ni lägga till den i ett dataset med ett enda klick. Med tiden bygger ni upp en omfattande regressionssvit från verkliga användarfrågor i stället för syntetiska exempel.
from langsmith import Client
client = Client()
# Create a dataset from existing traces
dataset = client.create_dataset('rag-regression-tests')
# Add examples from production traces (by trace ID)
for trace_id in failed_trace_ids:
run = client.read_run(trace_id)
client.create_example(
inputs=run.inputs,
outputs={'answer': run.outputs.get('output', '')},
dataset_id=dataset.id,
metadata={'source': 'production_failure', 'date': run.start_time.isoformat()}
)
print(f'Added {len(failed_trace_ids)} examples to regression test dataset')Filtrera och söka bland traces
I produktion kommer ni att ha tusentals traces. LangSmiths användargränssnitt och API stöder avancerad filtrering och sökning: hitta traces med fördröjning över en viss tröskel, en specifik feltyp, från en viss användare, med ett visst nyckelord i outputen eller med ett completion-tokenantal över en gräns. Det gör det praktiskt att undersöka specifika felkategorier eller övervaka specifika användares beteende.
from langsmith import Client
client = Client()
# Find slow traces (useful for performance investigation)
slow_runs = client.list_runs(
project_name='my-rag-app',
filter='gt(latency, 5)', # latency > 5 seconds
limit=20
)
# Find error traces
error_runs = client.list_runs(
project_name='my-rag-app',
filter='eq(error, true)',
limit=50
)
# Find traces from a specific user
user_runs = client.list_runs(
project_name='my-rag-app',
filter='has(metadata, user_id="user_abc123")',
limit=100
)
for run in slow_runs:
print(f'Slow run: {run.id}, latency: {run.end_time - run.start_time}')Jämföra experiment i LangSmith
LangSmith stöder experimentjämförelse: kör samma testdataset genom två versioner av pipelinen (till exempel chunkstorlek 500 jämfört med chunkstorlek 1 000) och jämför dem sida vid sida utifrån mätvärden för fördröjning, kostnad och kvalitet. Då blir det enkelt att verifiera att en pipelineändring är en förbättring och inte en regression innan den distribueras till produktion.
from langsmith.evaluation import evaluate
test_dataset = 'my-rag-eval-set'
# Run experiment A: chunk size 500
results_a = evaluate(
rag_pipeline_v1,
data=test_dataset,
evaluators=[correctness_evaluator, relevance_evaluator],
experiment_prefix='chunk-500'
)
# Run experiment B: chunk size 1000
results_b = evaluate(
rag_pipeline_v2,
data=test_dataset,
evaluators=[correctness_evaluator, relevance_evaluator],
experiment_prefix='chunk-1000'
)
# Compare in LangSmith UI: Experiments tab shows A vs B side by side
# Or compare programmatically:
print(f'Correctness - v1: {results_a.results["correctness"].mean():.2f}, v2: {results_b.results["correctness"].mean():.2f}')LangSmith i produktion
LangSmith finns som en hostad SaaS-tjänst på smith.langchain.com och som ett alternativ för self-hosting. I produktion kan tracing göras asynkront (icke-blockerande) för att undvika att den lägger till fördröjning i den kritiska körvägen. Ni kan också sampla traces (till exempel bara trace:a 10 % av förfrågningarna i en produktionstjänst med hög trafik) för att begränsa kostnaden och samtidigt behålla insyn. Kontrollpanelen visar grafer i realtid över förfrågningsvolym, fördröjning, kostnad och felfrekvens.
import os
# Production configuration
os.environ['LANGCHAIN_TRACING_V2'] = 'true'
os.environ['LANGCHAIN_ENDPOINT'] = 'https://api.smith.langchain.com'
os.environ['LANGCHAIN_PROJECT'] = 'production'
# Enable async tracing (non-blocking - does not add latency to requests)
os.environ['LANGCHAIN_CALLBACKS_BACKGROUND'] = 'true'
# Optional: sample 10% of traces to reduce cost in high-traffic scenarios
import random
def should_trace() -> bool:
return random.random() < 0.10 # 10% sampling rate
def handle_request(query):
config = RunnableConfig()
if not should_trace():
config = RunnableConfig(callbacks=[]) # disable tracing for this request
return rag_chain.invoke(query, config=config)LangSmith jämfört med anpassad loggning
Ni kan bygga ett eget system för spårningsloggning, och för vissa användningsfall är det rätt val. LangSmiths fördelar jämfört med anpassad loggning är: integration med LangChain utan kod, ett specialbyggt gränssnitt för att utforska LLM-spårningar (inte generiska Kibana-/Grafana-dashboards), inbyggt stöd för utvärdering och jämförelse av experiment samt automatisk spårning av tokenantal och kostnader. Nackdelen är leverantörsberoende och kostnader i stor skala.
Snabbtest
Testa er förståelse av spårning med LangSmith från den här lektionen.
Sammanfattning av lektionen
I den här lektionen lärde ni er att LangSmith möjliggör automatisk spårning från början till slut av LangChain-applikationer genom att tre miljövariabler anges, utan kodändringar, att dekoratorn @traceable utökar spårningen till steg som inte använder LangChain, till exempel databas-anrop och förbearbetning, samt att jämförelse av experiment gör det möjligt att validera förbättringar av pipelinen mot en testdatauppsättning innan driftsättning. Nästa steg är att utforska Langfuse som ett modellagnostiskt alternativ för observability.
Lär dig Python med en AI-lärare – gratis
Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.
- Kurser
- 30
- Lektioner
- 120
Vanliga frågor
Är lektionen ”Tracing med LangSmith” gratis?
Ja – hela texten till ”Tracing med LangSmith” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i AI Engineering Academy, kan Ni uppgradera till CoddyKit PRO. Kursen i AI Engineering Academy innehåller totalt 4 lektioner.
Vad lär jag mig i ”Tracing med LangSmith”?
Instrumentera er LangChain-applikation med LangSmith-tracing för att registrera varje kedjesteg, LLM-anrop, tokenantal och fördröjning i en sökbar trace explorer. Ni övar på AI Engineering Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.
Behöver jag någon erfarenhet för att börja lära mig AI Engineering Academy?
Du behöver inga förkunskaper. Utbildningen i AI Engineering Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 2 av 4.
Hur lång tid tar lektionen ”Tracing med LangSmith”?
De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.
Kan jag skriva och köra kod i den här AI Engineering Academy-lektionen?
Ja. Varje AI Engineering Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.
Alla lektioner i den här kursen
- Varför LLM-applikationer är svåra att felsöka
- Tracing med LangSmith
- Langfuse för modelloberoende observability
- Aviseringar om fördröjning, kostnad och försämrad kvalitet