
Langsmith
- 209 installs
- 40 repo stars
- Updated August 4, 2026
- akillness/oh-my-skills
Trace, evaluate, and debug LangChain/LangGraph agent runs in LangSmith to catch regressions, latency spikes, and bad tool calls in production LLM apps.
About
Uses LangSmith to inspect LangChain and LangGraph traces, score outputs, build evaluation datasets, and debug failing tool calls so teams maintain reliable, measurable agent behavior after deployment.
- LangSmith trace inspection
- LLM run debugging
- Dataset evaluations
- Prompt and chain regression tests
- Production agent observability
Langsmith by the numbers
- 209 all-time installs (skills.sh)
- Ranked #2,828 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/akillness/oh-my-skills --skill langsmithAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 209 |
|---|---|
| repo stars | ★ 40 |
| Last updated | August 4, 2026 |
| Repository | akillness/oh-my-skills ↗ |
What it does
Trace, evaluate, and debug LangChain/LangGraph agent runs in LangSmith to catch regressions, latency spikes, and bad tool calls in production LLM apps.
Files
LangSmith
When to use this skill
- The user already chose LangSmith and needs the smallest useful packet for tracing, evals, review, prompt ownership, or trace propagation.
- A request mentions LangChain tracing, `@traceable` / `traceable`, `wrap_openai` / `wrapOpenAI`, annotation queues, run trees, trace IDs, datasets, or experiment comparison.
- The team needs to decide whether a change needs debugging traces, an offline eval gate, an online review queue, Prompt Hub / prompt-registry work, or multi-service lineage.
- The user has some LangSmith setup already, but confidence is still low and they need an audit / gap review.
Do not use this skill as the main workflow when:
- The real job is generic dashboards / alerts / SLOs / telemetry ownership →
monitoring-observability - The real job is existing-log root-cause triage →
log-analysis - The real job is code-level reproduction / bug isolation →
debugging - The real job is deployment / rollout choreography →
deployment-automation - The real job is generic exported-metrics interpretation or KPI synthesis →
data-analysis - The real job is runtime guardrails / approvals / policy middleware → the relevant security or policy skill
Core idea
langsmith should behave like a workflow packet router, not a giant SDK encyclopedia.
1. Label the request before naming APIs. 2. Choose one primary packet. 3. Pick the smallest instrumentation / eval / review surface that answers the question. 4. Return a compact operator brief. 5. Route adjacent observability, debugging, deployment, and policy work outward fast.
Read these support docs before choosing the packet:
- references/intake-packets-and-route-outs.md
- references/modes-and-routing.md
- references/python-sdk.md
- references/typescript-sdk.md
- references/cli.md
Instructions
Step 1: Normalize the request
Convert the prompt into this intake packet first:
langsmith_packet:
primary_packet: trace-debug | eval | review | prompt-registry | propagation | audit
app_shape: chat | rag | tool-calling | agent | batch-job | multi-service | mixed | unknown
runtime: python | typescript | mixed | cli-only | unknown
request_type: setup | debug | pre-ship gate | production review | prompt decision | cross-service tracing | audit
current_evidence: traces | datasets | evaluators | feedback queues | prompt versions | exported runs | none
confidence_problem: missing traces | noisy traces | no regression gate | weak review rubric | prompt drift | broken lineage | mixed | unknown
route_after: stay-here | monitoring-observability | log-analysis | debugging | deployment-automation | data-analysisChoose one primary packet for the run. If two seem plausible, pick the one that reduces uncertainty fastest.
Step 2: Choose the packet
| Packet | Use when | Main output | Typical signals |
|---|---|---|---|
trace-debug | The real question is “what happened?” | trace-debug packet | missing visibility, wrappers/decorators, trace coverage, metadata discipline |
eval | A change needs pre-ship or regression confidence | eval packet | dataset creation, evaluators, experiments, baseline/candidate comparison |
review | Traces exist but trust is weak in production | review packet | annotation queues, feedback criteria, human scoring, inline review |
prompt-registry | Prompt/version ownership is the bottleneck | prompt packet | Prompt Hub, prompt versions, Git sync, compare prompt variants |
propagation | One request spans services, jobs, tools, or agents | propagation packet | parent/child trace IDs, cross-service headers, multi-hop lineage |
audit | LangSmith is present but still not useful | audit packet | noisy traces, missing IDs, absent evals, unclear prompt ownership |
Packet rules:
- Prefer
trace-debugwhen the team cannot explain the run tree. - Prefer
evalwhen the next risk is shipping without a regression gate. - Prefer
reviewwhen real-user output needs human or structured quality feedback. - Prefer
prompt-registryonly when prompt/version choice is the actual bottleneck. - Prefer
propagationwhen one request fans out beyond a single service boundary. - Prefer
auditwhen the system already “has LangSmith” but confidence is still low.
Step 3: Pick the smallest useful surface
| Surface | Use when | Strengths | Risks |
|---|---|---|---|
Provider wrappers (wrap_openai, wrap_anthropic, wrapOpenAI) | Need quick model-call coverage | Fastest path to visible traces | Misses higher-level workflow context if used alone |
Decorators / traceable() | Need named spans around app functions | Clear span boundaries, reusable | Still needs deliberate placement |
| Manual trace blocks / tracing context | Need scoped or temporary visibility | Good for audits and suspicious blocks | Easy to under-instrument |
| Annotation queues + feedback criteria | Need structured human review | Preserves rubric and reviewer flow | Review ownership still has to be designed |
| Dataset + experiment workflow | Need benchmark or regression checks | Gives pre-ship comparison | Can drift into generic eval theory if not bounded |
| CLI export/list/get flows | Need audit/export operations more than instrumentation | Good for scripts and inspection | Not a substitute for instrumentation design |
| Cross-service propagation headers / metadata | Need end-to-end lineage | Preserves parent/child context | Easy to forget at service boundaries |
Rules:
- Prefer the smallest surface that answers the present question.
- Always name project/workspace/environment grouping.
- Preserve
run_id,trace_id, and metadata if humans or downstream tools will review runs later. - Include shutdown flush / wait behavior for CLIs, workers, and short-lived jobs.
Step 4: Choose the eval or review layer only when needed
| Layer | Use when | Notes |
|---|---|---|
| Deterministic / code evaluator | Output can be checked mechanically | Best first choice for structure/factual rules |
LLM-as-judge (openevals) | Quality is subjective or reference-light | Useful, but not ground truth |
| Human review | Stakes are high or nuance dominates | Needs rubric, reviewer, and cadence |
| Pairwise comparison | Two prompts/models/app versions are being compared | Good for baseline vs candidate decisions |
| Online evaluator | Production traffic needs ongoing scoring | Pair with explicit alert/review semantics |
Do not pretend one layer replaces the others.
Step 5: Return one compact LangSmith brief
Default response shape:
## LangSmith brief
- Packet: trace-debug | eval | review | prompt-registry | propagation | audit
- App shape: ...
- Runtime: ...
- Current evidence: ...
## Chosen surface
- wrappers / decorators / manual trace / dataset+experiment / review queue / prompt registry / propagation headers
## Required config
- `LANGSMITH_API_KEY`
- project/workspace/environment
- endpoint/workspace overrides if self-hosted
## Required IDs / metadata
- `run_id`, `trace_id`, tags, metadata fields, user/session identifiers as needed
## Verification step
- one trace query, one experiment comparison, one queue review check, or one prompt-version sanity check
## Route-out
- next neighboring skill if the bottleneck movesKeep it compact. The point is to leave the user with one smallest next artifact, not a wall of SDK notes.
Step 6: Packet-specific heuristics
For trace-debug
- Start from the missing visibility surface: app span, tool calls, retrieval, provider call, or worker boundary.
- Prefer wrappers plus a few high-value decorators over tracing everything blindly.
- Return the first trace query/filter the team should run once instrumentation lands.
For eval
- Define the smallest dataset that reflects the risky change.
- Separate deterministic checks from LLM-as-judge or human review.
- Name baseline/candidate comparison, experiment naming, concurrency/cost limits, and the ship/no-ship decision point.
For review
- Define feedback keys, scale semantics, reviewer ownership, and queue cadence.
- Preserve
run_id/trace_idso feedback attaches to the right artifact later. - Route broader support-ops workflows out if the issue is bigger than output review.
For prompt-registry
- Explicitly decide whether Prompt Hub / LangSmith should own the prompt or whether Git/app config should stay canonical.
- Connect prompt versions to evals or experiments; do not treat registry as a separate island.
- Be explicit when public hub browsing is reference-only rather than the team's source of truth.
For propagation
- Name parent/child headers, metadata handoff rules, and which services must preserve trace context.
- Keep distributed-systems reliability and alerting concerns routed to generic observability where appropriate.
For audit
- Rank gaps by severity: missing coverage, bad metadata, absent evals, weak review flow, prompt/version ambiguity, broken flush or lineage.
- Recommend the first ratchet, not a giant reinstall plan.
Step 7: Route out aggressively
Switch as soon as LangSmith is no longer the main bottleneck:
- Generic telemetry / dashboards / alerts / SLOs →
monitoring-observability - Existing-log root-cause triage →
log-analysis - Reproduction and bug isolation →
debugging - Rollout / deploy / environment promotion →
deployment-automation - Exported metrics, experiments, or KPI interpretation →
data-analysis - Policy / approval / runtime guardrails → the relevant security or policy skill
Examples
Example 1: Trace-debug packet
Prompt:
Add LangSmith to this FastAPI RAG service so we can debug why answer quality regressed after a retriever change.
Good response shape:
- choose
trace-debug - recommend wrappers plus targeted higher-level spans if retrieval/tools must be visible
- define project/tags/metadata and a flush step for short-lived runs
- route generic service-health observability outward
Example 2: Eval packet
Prompt:
Before we ship this prompt rewrite, build a LangSmith eval workflow with a baseline, a candidate, and one judge for subjective quality.
Good response shape:
- choose
eval - define dataset, evaluator mix, experiment naming, and verification step
- separate deterministic checks from LLM-as-judge and human review
- keep rollout orchestration out of scope
Example 3: Review packet
Prompt:
We already have LangSmith traces, but support leads still do not trust the AI assistant. Set up a review workflow with human scoring.
Good response shape:
- choose
review - define feedback keys, rubric, queue ownership, and run-ID preservation
- keep the answer grounded in review workflow rather than generic prompt management
Example 4: Prompt-registry packet
Prompt:
Should these prompts live in LangSmith Prompt Hub or stay in Git?
Good response shape:
- choose
prompt-registry - compare platform-owned vs Git-owned prompt source of truth
- connect the choice to experiments and release confidence
- stay honest when Prompt Hub is optional
Example 5: Propagation packet
Prompt:
One chat request fans out to workers and tools. How do we keep one trace through LangSmith?
Good response shape:
- choose
propagation - define parent/child IDs, metadata propagation, and service boundaries
- route generic distributed-systems observability outward when needed
Best practices
1. Start with the packet, not the SDK call. 2. Treat LangSmith as a trace/eval/review substrate, not the entire production control plane. 3. Preserve run_id, trace_id, tags, and metadata deliberately. 4. Prefer the smallest useful surface that answers the present question. 5. Keep deterministic checks, LLM judges, and human review distinct. 6. Be explicit when Prompt Hub is optional or reference-only. 7. Include flush/wait behavior for scripts, workers, and cron-style jobs. 8. End with one verification step and one route-out.
References
references/intake-packets-and-route-outs.mdreferences/modes-and-routing.mdreferences/python-sdk.mdreferences/typescript-sdk.mdreferences/cli.md- Official docs: https://docs.langchain.com/langsmith
- SDK repo: https://github.com/langchain-ai/langsmith-sdk
- OpenEvals: https://github.com/langchain-ai/openevals
{
"skill_name": "langsmith",
"evals": [
{
"id": 1,
"prompt": "Add LangSmith to this FastAPI RAG service so we can debug why answer quality regressed after a retriever change.",
"expected_output": "The skill selects the trace-debug packet, recommends an instrumentation surface, and routes generic observability work away from LangSmith.",
"assertions": [
"Response identifies a primary packet equivalent to trace-debug or debugging traces.",
"Response specifies an instrumentation surface such as wrappers, decorators, or manual tracing contexts.",
"Response mentions required config like LANGSMITH_API_KEY and project/environment grouping.",
"Response includes a route-out to monitoring-observability or log-analysis for non-LangSmith concerns."
]
},
{
"id": 2,
"prompt": "Before we ship this prompt rewrite, build a LangSmith eval workflow with a baseline, a candidate, and one judge for subjective quality.",
"expected_output": "The skill selects the eval packet and returns a dataset/evaluator/experiment packet instead of generic SDK trivia.",
"assertions": [
"Response identifies eval or experiment comparison as the primary packet.",
"Response distinguishes evaluator choices such as deterministic checks, LLM-as-judge, pairwise comparison, or human review.",
"Response includes dataset and experiment design guidance.",
"Response does not frame LangSmith as generic deployment orchestration."
]
},
{
"id": 3,
"prompt": "We already have LangSmith traces, but support leads still do not trust the AI assistant. Set up a review workflow with human scoring.",
"expected_output": "The skill selects the review packet, defines feedback keys or rubric items, and explains run ID / trace ID preservation.",
"assertions": [
"Response identifies online feedback, annotation queue, or review workflow as the primary packet.",
"Response includes feedback schema or rubric design guidance.",
"Response mentions preserving run_id or trace_id for later feedback attachment.",
"Response avoids collapsing the request into generic prompt management only."
]
},
{
"id": 4,
"prompt": "Should our prompts live in LangSmith Prompt Hub or stay in Git for now? We want versioning, experiments, and a safe rollout path.",
"expected_output": "The skill selects the prompt-registry packet, compares LangSmith-owned and Git-owned prompt sources of truth, and ties the choice to experiments instead of defaulting blindly to Prompt Hub.",
"assertions": [
"Response identifies prompt-registry or prompt/version ownership as the primary packet.",
"Response compares Prompt Hub against Git or app-config ownership rather than assuming the platform must own prompts.",
"Response connects the prompt decision to experiment comparison or release confidence.",
"Response does not drift into generic tracing or deployment advice."
]
}
]
}
LangSmith CLI Reference
Source: https://docs.langchain.com/langsmith/langsmith-cli
Install: curl -sSL https://raw.githubusercontent.com/langchain-ai/langsmith-cli/main/scripts/install.sh | shInstallation
# Recommended (install script)
curl -sSL https://raw.githubusercontent.com/langchain-ai/langsmith-cli/main/scripts/install.sh | sh
# Go install
go install github.com/langchain-ai/langsmith-cli/cmd/langsmith@latestAuthentication
export LANGSMITH_API_KEY="lsv2_..."
export LANGSMITH_ENDPOINT="..." # Self-hosted instances only
export LANGSMITH_PROJECT="my-project" # Default projectProject Commands
langsmith project list
langsmith project list --name-contains "staging"
langsmith project create --name "my-project"
langsmith project delete --name "old-project"Trace Commands
# List traces
langsmith trace list
langsmith trace list --limit 50 --last-n-minutes 60
langsmith trace list --error # Only errored traces
langsmith trace list --full --include-metadata # With full content
# Get specific trace
langsmith trace get <trace-id>
# Export traces
langsmith trace export -o traces.json
langsmith trace export --format pretty -o traces.txtRun Commands (individual spans)
# List runs
langsmith run list
langsmith run list --run-type llm
langsmith run list --name "OpenAI Call"
langsmith run list --project "my-project"
# Get specific run
langsmith run get <run-id>
# Export
langsmith run export -o runs.jsonThread Commands (conversations)
langsmith thread list
langsmith thread list --project "my-project"
langsmith thread get <thread-id>Dataset Commands
# List datasets
langsmith dataset list
# Create dataset
langsmith dataset create --name "My Dataset"
# Export dataset
langsmith dataset export --name "My Dataset" -o dataset.json
# Import dataset
langsmith dataset import --name "My Dataset" -i dataset.jsonEvaluator Commands
langsmith evaluator list
langsmith evaluator uploadExperiment Commands
langsmith experiment list
langsmith experiment list --dataset "My Dataset"
langsmith experiment get <experiment-id>Output Formats
langsmith trace list # JSON (default)
langsmith trace list --format pretty # Human-readable table
langsmith trace export -o output.json # Write JSON to fileReferences
Intake packets and route-outs
Packet chooser
Use one primary packet per run.
| Packet | Use when | Typical request shape | Route-out signal |
|---|---|---|---|
trace-debug | The team cannot explain what happened in the run tree | add tracing, missing spans, trace coverage, wrapper vs decorator choice | Once the likely failure path is visible and debugging or infra ownership becomes the bottleneck |
eval | A change needs pre-ship or regression confidence | dataset, evaluator, experiment, baseline vs candidate | Once the question becomes rollout policy or generic KPI interpretation |
review | Production traces need structured human or automated scoring | annotation queue, rubric, inline feedback, review cadence | Once the issue becomes support ops, moderation, or broader analytics workflow |
prompt-registry | Prompt/version ownership is unclear | Prompt Hub, Git sync, prompt versions, release confidence | Once prompt source-of-truth is decided and implementation belongs elsewhere |
propagation | One request spans services, workers, or agent hops | cross-service traces, parent/child lineage, headers, metadata handoffs | Once the job becomes generic distributed observability or rollout coordination |
audit | LangSmith exists already but still does not inspire trust | noisy metadata, missing evals, broken lineage, absent review flow | Once the first ratchet is chosen and a neighboring skill owns the next implementation step |
Surface ladder
- Quick trace coverage → provider wrappers + a few high-value decorators
- Named workflow spans →
traceable()/ decorators around application functions - Scoped audit visibility → manual tracing context or targeted trace blocks
- Pre-ship confidence → dataset + evaluator + experiment packet
- Human-review flow → annotation queue + feedback criteria + reviewer ownership
- Cross-service lineage → explicit header / metadata propagation
- Audit/export workflow → CLI list/get/export flows
Required fields to preserve
- project/workspace/environment
run_idtrace_id- tags and metadata fields that support later filtering
- user/session/request identifiers when review or analytics need them
Quick route-outs
- Generic telemetry, dashboards, alerts, or SLOs →
monitoring-observability - Existing-log root-cause work →
log-analysis - Reproduction and code-path diagnosis →
debugging - Deployment or rollout choreography →
deployment-automation - Exported experiment/KPI interpretation →
data-analysis - Runtime policy, approvals, or guardrails → relevant security/policy skill
Smell test
If your next paragraph is mostly about service-health dashboards, incident response, deployment steps, or generic product metrics instead of LangSmith packets, this skill has already done its job.
LangSmith Modes and Routing
Core rule
Start by deciding which LangSmith workflow is failing or needed. Do not start with API snippets.
Modes
1. Debugging traces
Use when the question is “what happened?” or “why did this LLM/app/agent run fail?”
Focus on:
- whether trace coverage includes the app span plus nested LLM/tool/retrieval calls
- project / environment / tag / metadata consistency
- wrapper vs decorator vs manual trace choice
- explicit flush behavior for short-lived jobs
Return:
- minimum instrumentation packet
- metadata/tag standards
- first trace query to verify success
2. Offline evals
Use when a prompt/model/app change needs a regression gate before release.
Focus on:
- dataset shape and coverage
- deterministic vs LLM-as-judge vs pairwise evaluation
- experiment naming and baseline/candidate comparison
- concurrency/cost bounds
Return:
- dataset packet
- evaluator packet
- experiment packet
3. Online feedback and review
Use when traces exist but nobody trusts output quality in production.
Focus on:
- feedback keys and scales
- annotation queue and rubric design
- reviewer ownership and cadence
- run ID / trace ID preservation
Return:
- queue/rubric packet
- required labels
- review flow
4. Prompt registry and experiment comparison
Use when prompt/version choice is the bottleneck.
Focus on:
- whether Prompt Hub should own prompts at all
- version pinning and experiment comparison
- Git/config alternative if LangSmith registry is not the right fit
Return:
- registry decision
- comparison packet
- route-out note if Git/app config should stay canonical
5. Multi-service / agent propagation
Use when one user request fans out across services, workers, tools, or agent hops.
Focus on:
- header/context propagation
- consistent metadata across spans
- what LangSmith should trace versus what generic observability should cover
Return:
- propagation packet
- required headers / IDs
- route-out to generic observability if needed
6. Audit / gap review
Use when LangSmith is installed but confidence is still low.
Focus on:
- missing instrumentation coverage
- noisy or useless metadata
- missing evals or weak review schema
- missing prompt/version clarity
- missing flush or run-ID preservation
Return:
- severity-ranked gap list
- next ratchet
Route-outs
- Generic dashboards / alerts / SLOs / telemetry ownership →
monitoring-observability - Existing-log root-cause triage →
log-analysis - Code-level reproduction / bug isolation →
debugging - Runtime guardrails / approval logic → policy/security skill
- Rollout / deployment orchestration →
deployment-automation - Exported experiment/KPI interpretation →
data-analysis
Minimum evidence packet
For any LangSmith task, try to leave the user with:
- selected mode
- chosen instrumentation surface
- required env/config
- required metadata / IDs / tags
- eval / feedback / queue design if applicable
- verification step
- route-outs
LangSmith Python SDK Reference
Source: https://docs.langchain.com/langsmith | SDK: langsmith v0.7.17+Install: pip install -U langsmithEnvironment Variables
| Variable | Required | Description |
|---|---|---|
LANGSMITH_API_KEY | Yes | API key from smith.langchain.com |
LANGSMITH_TRACING | Yes | true to enable tracing |
LANGSMITH_PROJECT | No | Default project name (default: "default") |
LANGSMITH_ENDPOINT | No | API URL (self-hosted only) |
LANGSMITH_WORKSPACE_ID | No | Required for org-scoped keys |
@traceable Decorator
Full signature:
from langsmith import traceable
@traceable(
run_type: Literal['tool', 'chain', 'llm', 'retriever', 'embedding', 'prompt', 'parser'] = 'chain',
name: str | None = None, # Defaults to function name
metadata: dict | None = None,
tags: list[str] | None = None,
client: Client | None = None,
reduce_fn: Callable | None = None, # For streaming/generator outputs
project_name: str | None = None,
process_inputs: Callable | None = None, # Custom input serializer
process_outputs: Callable | None = None, # Custom output serializer
)
def my_function(...):
...trace() Context Manager
from langsmith import trace
inputs = {"question": "What is 2+2?"}
with trace(name="My Trace", inputs=inputs) as run:
result = my_pipeline(**inputs)
run.outputs = {"answer": result}
trace_id = run.idtracing_context() — Selective Tracing
import langsmith as ls
# Enable for this block only
with ls.tracing_context(enabled=True, project_name="test"):
result = chain.invoke(...)
# Disable despite env var
with ls.tracing_context(enabled=False):
result = chain.invoke(...)
# Use custom client
with ls.tracing_context(client=my_client, project_name="isolated"):
result = chain.invoke(...)wrap_openai() and Other Wrappers
from langsmith.wrappers import wrap_openai, wrap_anthropic
from openai import OpenAI
import anthropic
openai_client = wrap_openai(OpenAI())
anthropic_client = wrap_anthropic(anthropic.Anthropic())
# wrap_gemini() also availableClient — Full API
from langsmith import Client
client = Client(api_key="...", api_url="https://api.smith.langchain.com")Datasets
# Create
dataset = client.create_dataset("name", description="...")
# Add examples
client.create_examples(
dataset_id=dataset.id,
examples=[{"inputs": {...}, "outputs": {...}}]
)
# List, clone, delete
for ds in client.list_datasets(): ...
client.clone_public_dataset("https://smith.langchain.com/public/...")
client.delete_dataset(dataset_id=dataset.id)Evaluation
# Synchronous
results = client.evaluate(
target_fn, # Callable: dict -> dict
data="dataset-name", # str name, UUID, or iterator
evaluators=[eval_fn],
experiment_prefix="v1",
description="...",
max_concurrency=4
)
# Async
results = await client.aevaluate(target_fn, data="...", evaluators=[...])
# Evaluate existing experiment runs
results = client.evaluate_existing(runs, evaluators=[...])
# Pairwise comparison
results = client.evaluate_comparative("exp-name", data="...",
candidate=fn_v2, baseline=fn_v1)Evaluator Function Signatures
# With reference outputs (offline)
def evaluator(inputs: dict, outputs: dict, reference_outputs: dict) -> dict | bool:
return {"key": "correctness", "score": 1, "comment": "..."}
# Or: return outputs["answer"] == reference_outputs["answer"]
# Without reference outputs (online)
def online_evaluator(inputs: dict, outputs: dict) -> dict:
return {"key": "quality", "score": 0.8}Feedback
# Attach to a run
client.create_feedback(
key="thumbs_up",
score=1,
run_id=run_id,
trace_id=trace_id,
comment="Accurate"
)
# Feedback config
client.create_feedback_config("accuracy", feedback_config={
"type": "continuous", "min": 0, "max": 1
})
client.create_feedback_config("label", feedback_config={
"type": "categorical",
"categories": [{"value": 1, "label": "Pass"}, {"value": 0, "label": "Fail"}]
})
client.create_feedback_config("notes", feedback_config={"type": "freeform"})
# List, update, delete
for cfg in client.list_feedback_configs(): print(cfg.feedback_key)
client.update_feedback_config("accuracy", is_lower_score_better=True)
client.delete_feedback_config("accuracy")Annotation Queues
queue = client.create_annotation_queue(
name="Review Queue",
description="...",
rubric_instructions="Score carefully.",
rubric_items=[{
"feedback_key": "accuracy",
"description": "How accurate?",
"score_descriptions": {"0": "Wrong", "1": "Correct"},
"is_required": True,
}]
)Prompt Hub
from langchain_core.prompts import ChatPromptTemplate
# Push
prompt = ChatPromptTemplate([("system", "..."), ("user", "{q}")])
client.push_prompt("my-prompt", object=prompt)
# Pull (latest or specific version)
p = client.pull_prompt("my-prompt")
p = client.pull_prompt("my-prompt:commit-abc123")Projects
client.create_project("my-project")
client.delete_project(project_name="old-project")
for proj in client.list_projects(): print(proj.name)Utility Functions
from langsmith.run_helpers import get_current_run_tree
from langchain_core.tracers.langchain import wait_for_all_tracers
# Get current run (inside @traceable)
@traceable
def my_func():
rt = get_current_run_tree()
headers = rt.to_headers() # For distributed tracing
return headers
# Wait for async trace flush (important in scripts)
wait_for_all_tracers()LangChain Integration
# Auto-trace: just set env vars
import os
os.environ["LANGSMITH_TRACING"] = "true"
from langchain_openai import ChatOpenAI
chain = ChatOpenAI() # All invocations automatically traced
# Add metadata at invocation time
chain.invoke(
{"input": "..."},
{
"tags": ["production"],
"metadata": {"version": "2.0"},
"run_name": "MyChain",
"run_id": str(uuid.uuid4()),
}
)Distributed Tracing
import langsmith
from langsmith.run_helpers import get_current_run_tree
@langsmith.traceable
def parent(inputs):
rt = get_current_run_tree()
headers = rt.to_headers()
# Pass headers to child microservice
@langsmith.traceable
def child(x, headers):
with langsmith.tracing_context(parent=headers):
return do_work(x)openevals — Prebuilt Evaluators
pip install -U openevalsfrom openevals.llm import create_llm_as_judge
from openevals.prompts import CORRECTNESS_PROMPT, CONCISENESS_PROMPT
judge = create_llm_as_judge(
prompt=CORRECTNESS_PROMPT,
model="openai:o3-mini",
feedback_key="correctness",
)
result = judge(inputs=inputs, outputs=outputs, reference_outputs=ref)Available prompts: CORRECTNESS_PROMPT, CONCISENESS_PROMPT, HELPFULNESS_PROMPT, HARMFULNESS_PROMPT
References
LangSmith TypeScript/JavaScript SDK Reference
Source: https://docs.langchain.com/langsmith | SDK: langsmith (npm)Install: npm install langsmithEnvironment Variables
export LANGSMITH_API_KEY="lsv2_..."
export LANGSMITH_TRACING=true
export LANGSMITH_PROJECT="my-project" # optional
export LANGSMITH_ENDPOINT="..." # self-hosted onlytraceable() Wrapper
import { traceable } from "langsmith/traceable";
// Wrap an async function
const pipeline = traceable(
async (question: string): Promise<string> => {
const result = await myLLM(question);
return result;
},
{
name: "My Pipeline",
// run_type, tags, metadata also available
}
);
await pipeline("What is LangSmith?");wrapOpenAI() and Other Wrappers
import { wrapOpenAI } from "langsmith/wrappers";
import { OpenAI } from "openai";
const client = wrapOpenAI(new OpenAI());
// All chat.completions.create() calls are now tracedClient — Core Methods
import { Client } from "langsmith";
const client = new Client({
apiKey: process.env.LANGSMITH_API_KEY,
// apiUrl: "https://api.smith.langchain.com" // self-hosted
});Datasets
// Create
const dataset = await client.createDataset("My Dataset");
// Add examples
await client.createExamples({
inputs: [{ question: "Capital of France?" }],
outputs: [{ answer: "Paris" }],
datasetId: dataset.id
});
// List
for await (const ds of client.listDatasets()) {
console.log(ds.name);
}
// Delete
await client.deleteDataset({ datasetId: dataset.id });Evaluation
import { evaluate } from "langsmith/evaluation";
import type { EvaluationResult } from "langsmith/evaluation";
// Target function
async function myApp(inputs: Record<string, any>) {
return { answer: await callLLM(inputs.question) };
}
// Evaluator
function exactMatch({ inputs, outputs, referenceOutputs }: {
inputs: Record<string, any>;
outputs: Record<string, any>;
referenceOutputs?: Record<string, any>;
}): EvaluationResult {
return {
key: "exact_match",
score: outputs.answer === referenceOutputs?.answer ? 1 : 0
};
}
// Run experiment
await evaluate(myApp, {
data: "My Dataset",
evaluators: [exactMatch],
experimentPrefix: "v1-baseline",
maxConcurrency: 4
});Feedback
// Attach feedback to a run
await client.createFeedback(
runId, // string UUID
"thumbs_up", // feedback key
{
score: 1,
comment: "Great response"
}
);Feedback Config
// Continuous (0-1 slider)
await client.createFeedbackConfig({
feedbackKey: "accuracy",
feedbackConfig: { type: "continuous", min: 0, max: 1 }
});
// Categorical
await client.createFeedbackConfig({
feedbackKey: "label",
feedbackConfig: {
type: "categorical",
categories: [
{ value: 1, label: "Pass" },
{ value: 0, label: "Fail" }
]
}
});
// Freeform
await client.createFeedbackConfig({
feedbackKey: "notes",
feedbackConfig: { type: "freeform" }
});
// List
for await (const cfg of client.listFeedbackConfigs()) {
console.log(cfg.feedbackKey);
}Annotation Queues
const queue = await client.createAnnotationQueue({
name: "Review Queue",
rubricItems: [
{
feedback_key: "accuracy",
description: "How accurate is the response?",
is_required: true
}
]
});Prompt Hub
import { Client } from "langsmith";
import { ChatPromptTemplate } from "@langchain/core/prompts";
import { pull } from "langchain/hub";
const client = new Client();
// Push
const prompt = ChatPromptTemplate.fromMessages([
["system", "You are a helpful assistant."],
["user", "{question}"],
]);
await client.pushPrompt("my-prompt", { object: prompt });
// Pull
const pulled = await pull("my-prompt");
const formatted = await pulled.invoke({ question: "What is LangSmith?" });Projects
await client.createProject({ projectName: "my-project" });
await client.deleteProject({ projectName: "old-project" });
for await (const proj of client.listProjects()) {
console.log(proj.name);
}LangChain (TypeScript) Integration
import { LangChainTracer } from "@langchain/core/tracers/tracer_langchain";
import { getLangchainCallbacks } from "langsmith/langchain";
// Static tracer
const tracer = new LangChainTracer({ projectName: "My Project" });
await chain.invoke({ input: "..." }, { callbacks: [tracer] });
// Dynamic callbacks inside traceable (recommended)
const main = traceable(async (input: string) => {
const callbacks = await getLangchainCallbacks();
return await chain.invoke({ input }, { callbacks });
}, { name: "main" });Wait for Async Trace Flush
import { awaitAllCallbacks } from "@langchain/core/callbacks/promises";
try {
const result = await llm.invoke("...");
} finally {
await awaitAllCallbacks(); // Flush all pending traces
}Custom Run ID for Feedback
import { v4 as uuidv4 } from "uuid";
const runId = uuidv4();
const result = await chain.invoke(
{ input: "..." },
{ runId }
);
// Later attach feedback
await client.createFeedback(runId, "correctness", { score: 1 });References
#!/usr/bin/env python3
"""
LangSmith Quickstart Script
Demonstrates: tracing, evaluation, datasets, feedback, and prompt hub.
Prerequisites:
pip install -U langsmith openai openevals
export LANGSMITH_API_KEY="lsv2_..."
export LANGSMITH_TRACING=true
export OPENAI_API_KEY="sk-..."
Usage:
python3 quickstart.py [--trace | --eval | --prompt | --all]
"""
import os
import sys
import argparse
import uuid
def check_env():
missing = []
if not os.getenv("LANGSMITH_API_KEY"):
missing.append("LANGSMITH_API_KEY")
if not os.getenv("LANGSMITH_TRACING"):
print("⚠ LANGSMITH_TRACING not set — setting to 'true' for this run")
os.environ["LANGSMITH_TRACING"] = "true"
if missing:
print(f"✗ Missing env vars: {', '.join(missing)}")
print(" Run: bash scripts/setup.sh")
sys.exit(1)
# ── Demo 1: Basic tracing ─────────────────────────────────────────────────────
def demo_trace():
print("\n── Demo 1: Tracing ──────────────────────────────────────────────")
try:
from langsmith import traceable
from langsmith.wrappers import wrap_openai
from openai import OpenAI
client = wrap_openai(OpenAI())
@traceable(name="LangSmith Quickstart / RAG")
def pipeline(question: str) -> str:
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": question}]
)
return response.choices[0].message.content
result = pipeline("What is LangSmith used for?")
print(f"✓ Response: {result[:120]}...")
print("✓ Trace saved — view at: https://smith.langchain.com")
except Exception as e:
print(f"✗ Trace demo failed: {e}")
# ── Demo 2: Dataset + evaluation ─────────────────────────────────────────────
def demo_eval():
print("\n── Demo 2: Evaluation ───────────────────────────────────────────")
try:
from langsmith import Client
from langsmith.wrappers import wrap_openai
from openai import OpenAI
ls_client = Client()
oai = wrap_openai(OpenAI())
DATASET_NAME = "LangSmith-Quickstart-Demo"
# Create (or reuse) dataset
existing = [d for d in ls_client.list_datasets() if d.name == DATASET_NAME]
if existing:
dataset = existing[0]
print(f" Using existing dataset: {DATASET_NAME}")
else:
dataset = ls_client.create_dataset(DATASET_NAME)
ls_client.create_examples(
dataset_id=dataset.id,
examples=[
{"inputs": {"q": "Capital of France?"}, "outputs": {"a": "Paris"}},
{"inputs": {"q": "Capital of Japan?"}, "outputs": {"a": "Tokyo"}},
{"inputs": {"q": "Capital of Brazil?"}, "outputs": {"a": "Brasília"}},
]
)
print(f" Created dataset: {DATASET_NAME} (3 examples)")
# Target function
def target(inputs: dict) -> dict:
res = oai.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": f"Answer in one word: {inputs['q']}"}]
)
return {"a": res.choices[0].message.content.strip()}
# Evaluator
def contains_answer(inputs, outputs, reference_outputs):
expected = reference_outputs["a"].lower()
got = outputs["a"].lower()
return {"key": "contains_answer", "score": int(expected in got)}
results = ls_client.evaluate(
target,
data=DATASET_NAME,
evaluators=[contains_answer],
experiment_prefix="quickstart-demo",
max_concurrency=2
)
print(f"✓ Experiment complete — view at: https://smith.langchain.com")
print(f" Results: {results}")
except Exception as e:
print(f"✗ Eval demo failed: {e}")
# ── Demo 3: Feedback ──────────────────────────────────────────────────────────
def demo_feedback():
print("\n── Demo 3: Feedback ─────────────────────────────────────────────")
try:
from langsmith import Client, traceable
from langsmith.wrappers import wrap_openai
from openai import OpenAI
ls_client = Client()
oai = wrap_openai(OpenAI())
run_id = str(uuid.uuid4())
@traceable(name="feedback-demo")
def answer(question: str) -> str:
res = oai.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": question}]
)
return res.choices[0].message.content
result = answer.__wrapped__("What is 2 + 2?") if hasattr(answer, '__wrapped__') else answer("What is 2 + 2?")
ls_client.create_feedback(
key="thumbs_up",
score=1,
comment="Correct!",
run_id=run_id
)
print(f"✓ Feedback attached to run: {run_id}")
except Exception as e:
print(f"✗ Feedback demo failed: {e}")
# ── Demo 4: Prompt Hub ────────────────────────────────────────────────────────
def demo_prompt():
print("\n── Demo 4: Prompt Hub ───────────────────────────────────────────")
try:
from langsmith import Client
ls_client = Client()
try:
from langchain_core.prompts import ChatPromptTemplate
except ImportError:
print(" langchain_core not installed — run: pip install langchain_core")
return
prompt = ChatPromptTemplate([
("system", "You are a helpful AI assistant."),
("user", "{question}"),
])
PROMPT_NAME = "langsmith-quickstart-demo-prompt"
ls_client.push_prompt(PROMPT_NAME, object=prompt)
pulled = ls_client.pull_prompt(PROMPT_NAME)
print(f"✓ Prompt pushed and pulled: {PROMPT_NAME}")
print(f" Messages: {[m.prompt.template for m in pulled.messages]}")
except Exception as e:
print(f"✗ Prompt demo failed: {e}")
def main():
parser = argparse.ArgumentParser(description="LangSmith Quickstart")
parser.add_argument("--trace", action="store_true")
parser.add_argument("--eval", action="store_true")
parser.add_argument("--feedback", action="store_true")
parser.add_argument("--prompt", action="store_true")
parser.add_argument("--all", action="store_true", default=True)
args = parser.parse_args()
check_env()
run_all = args.all and not any([args.trace, args.eval, args.feedback, args.prompt])
if args.trace or run_all:
demo_trace()
if args.eval or run_all:
demo_eval()
if args.feedback or run_all:
demo_feedback()
if args.prompt or run_all:
demo_prompt()
print("\n✓ Quickstart complete — view results at: https://smith.langchain.com\n")
if __name__ == "__main__":
main()
#!/usr/bin/env bash
# LangSmith Setup Script
# Configures environment variables and installs dependencies for LangSmith tracing.
# Usage: bash setup.sh [--python | --typescript | --both]
set -euo pipefail
GREEN='\033[0;32m'; YELLOW='\033[1;33m'; BLUE='\033[0;34m'; RED='\033[0;31m'; NC='\033[0m'
ok() { echo -e "${GREEN}✓${NC} $*"; }
warn() { echo -e "${YELLOW}⚠${NC} $*"; }
info() { echo -e "${BLUE}→${NC} $*"; }
err() { echo -e "${RED}✗${NC} $*"; }
MODE="${1:-both}"
echo ""
echo "LangSmith Setup"
echo "==============="
# ── 1. Check API key ─────────────────────────────────────────────────────────
if [[ -z "${LANGSMITH_API_KEY:-}" ]]; then
warn "LANGSMITH_API_KEY not set."
echo " Get your key at: https://smith.langchain.com → Settings → API Keys"
echo ""
read -rp "Enter LANGSMITH_API_KEY (or press Enter to skip): " api_key
if [[ -n "$api_key" ]]; then
export LANGSMITH_API_KEY="$api_key"
ok "LANGSMITH_API_KEY set for this session"
# Persist to shell profile
PROFILE_FILE="${HOME}/.zshrc"
[[ "$SHELL" == *"bash"* ]] && PROFILE_FILE="${HOME}/.bashrc"
if ! grep -q "LANGSMITH_API_KEY" "$PROFILE_FILE" 2>/dev/null; then
echo "" >> "$PROFILE_FILE"
echo "# LangSmith" >> "$PROFILE_FILE"
echo "export LANGSMITH_API_KEY=\"$api_key\"" >> "$PROFILE_FILE"
echo "export LANGSMITH_TRACING=true" >> "$PROFILE_FILE"
ok "Added to $PROFILE_FILE"
else
warn "LANGSMITH_API_KEY already in $PROFILE_FILE — skipped"
fi
fi
else
ok "LANGSMITH_API_KEY already set"
fi
# ── 2. Set LANGSMITH_TRACING ─────────────────────────────────────────────────
if [[ -z "${LANGSMITH_TRACING:-}" ]]; then
export LANGSMITH_TRACING=true
info "Set LANGSMITH_TRACING=true"
else
ok "LANGSMITH_TRACING=${LANGSMITH_TRACING}"
fi
# ── 3. Install Python SDK ─────────────────────────────────────────────────────
if [[ "$MODE" == "--python" || "$MODE" == "--both" || "$MODE" == "both" ]]; then
info "Installing LangSmith Python SDK..."
if command -v pip >/dev/null 2>&1; then
pip install -U langsmith openai 2>&1 | tail -3
ok "langsmith + openai installed"
# Optional: openevals for prebuilt LLM evaluators
read -rp "Install openevals for LLM-as-judge evaluators? [y/N]: " install_evals
if [[ "$install_evals" =~ ^[Yy]$ ]]; then
pip install -U openevals 2>&1 | tail -2
ok "openevals installed"
fi
else
warn "pip not found — install Python 3.8+ and pip first"
fi
fi
# ── 4. Install TypeScript/JS SDK ─────────────────────────────────────────────
if [[ "$MODE" == "--typescript" || "$MODE" == "--both" || "$MODE" == "both" ]]; then
info "Installing LangSmith TypeScript SDK..."
if command -v npm >/dev/null 2>&1; then
npm install langsmith openai 2>&1 | tail -3
ok "langsmith + openai (npm) installed"
elif command -v yarn >/dev/null 2>&1; then
yarn add langsmith openai 2>&1 | tail -3
ok "langsmith + openai (yarn) installed"
else
warn "npm/yarn not found — install Node.js first"
fi
fi
# ── 5. Install LangSmith CLI ─────────────────────────────────────────────────
info "Checking LangSmith CLI..."
if ! command -v langsmith >/dev/null 2>&1; then
read -rp "Install LangSmith CLI? [y/N]: " install_cli
if [[ "$install_cli" =~ ^[Yy]$ ]]; then
curl -sSL https://raw.githubusercontent.com/langchain-ai/langsmith-cli/main/scripts/install.sh | sh
ok "LangSmith CLI installed"
fi
else
ok "LangSmith CLI already installed: $(langsmith --version 2>/dev/null || echo 'version unknown')"
fi
# ── 6. Verify connection ─────────────────────────────────────────────────────
echo ""
info "Verifying LangSmith connection..."
if [[ -n "${LANGSMITH_API_KEY:-}" ]]; then
if python3 -c "
from langsmith import Client
try:
c = Client()
list(c.list_projects())
print('Connection: OK')
except Exception as e:
print(f'Connection error: {e}')
exit(1)
" 2>/dev/null; then
ok "LangSmith connection verified"
else
warn "Could not verify connection — check API key and network"
fi
fi
echo ""
echo "LangSmith Setup Complete"
echo "========================"
echo " Environment:"
echo " LANGSMITH_API_KEY = ${LANGSMITH_API_KEY:-<not set>}"
echo " LANGSMITH_TRACING = ${LANGSMITH_TRACING:-false}"
echo " LANGSMITH_PROJECT = ${LANGSMITH_PROJECT:-<default>}"
echo ""
echo " Quick test:"
echo " python3 scripts/quickstart.py"
echo ""
echo " Docs: https://docs.langchain.com/langsmith"
N:langsmith
D:[langsmith] Route LangSmith work into one workflow packet before touching SDK code. Use when users need LangSmith tracing, offline evals, annotation/review queues, prompt-registry decisions, audit/gap review, or cross-service trace propagation for an LLM app or agent workflow. Choose one packet: trace-debug, eval, review, prompt-registry, propagation, or audit. Triggers on: LangSmith, LangChain tracing, @traceable/traceable, wrap_openai/wrapOpenAI, datasets, experiments, annotation queues, feedback criteria, Prompt Hub, run trees, or trace IDs. Not for generic alerting/SLO design, deployment orchestration, or runtime guardrails outside LangSmith.
G:langsmith langchain tracing observability evaluation prompt-hub datasets openevals traceable wrap_openai wrapOpenAI annotation-queue run-tree trace-id propagation audit
U[6]:
Add or review LangSmith tracing for chat apps, RAG pipelines, tool-calling backends, or agents
Build offline eval packets before a prompt/model/app change ships
Add online feedback, annotation queues, or review rubrics for production traces
Compare Prompt Hub against Git/app-config prompt ownership
Preserve trace lineage across services, workers, or agent/tool boundaries
Audit an existing LangSmith setup that still lacks trustworthy visibility or evaluation
S[5]{n,action,details}:
1,Normalize request,Classify app shape runtime current evidence confidence problem and next route before naming APIs
2,Choose packet,Pick trace-debug eval review prompt-registry propagation or audit
3,Choose surface,Select wrappers decorators tracing context annotation queues datasets experiments CLI flows or propagation headers
4,Return brief,Include required config IDs metadata verification step and one next artifact
5,Route out,Send generic observability debugging deployment analytics or policy work to adjacent skills instead of overclaiming LangSmith
R[5]:
Treat LangSmith as a trace/eval/review substrate not the whole production control plane
Preserve run_id trace_id project env tags and metadata deliberately
Use the smallest useful surface first
Keep deterministic checks LLM judges and human review distinct
Include flush or wait behavior for short-lived scripts workers and CLIs
E[4]{type,code}:
Trace-debug packet,packet=trace-debug plus wrappers/decorators project tags metadata and flush step
Eval packet,packet=eval plus dataset evaluators experiment prefix baseline/candidate comparison
Review packet,packet=review plus feedback keys annotation queue rubric and run_id preservation
Prompt packet,packet=prompt-registry plus Prompt Hub vs Git ownership and experiment linkage