LangSmith
LangSmith is LangChain's platform for monitoring and evaluating LLM applications. The LangSmith exporter sends your traces to LangSmith, providing insights into model performance and debugging capabilities, plus evaluation workflows.
InstallationDirect link to Installation
- npm
- pnpm
- Yarn
- Bun
npm install @mastra/langsmith@latest
pnpm add @mastra/langsmith@latest
yarn add @mastra/langsmith@latest
bun add @mastra/langsmith@latest
ConfigurationDirect link to Configuration
PrerequisitesDirect link to Prerequisites
- LangSmith Account: Sign up at smith.langchain.com
- API Key: Generate an API key in LangSmith Settings → API Keys
- Environment Variables: Set your credentials
# Required
LANGSMITH_API_KEY=ls-xxxxxxxxxxxx
# Optional
LANGCHAIN_PROJECT=my-project # Default project for traces
LANGSMITH_BASE_URL=https://api.smith.langchain.com # For self-hosted
Zero-Config SetupDirect link to Zero-Config Setup
With environment variables set, use the exporter with no configuration:
import { Mastra } from '@mastra/core'
import { Observability } from '@mastra/observability'
import { LangSmithExporter } from '@mastra/langsmith'
export const mastra = new Mastra({
observability: new Observability({
configs: {
langsmith: {
serviceName: 'my-service',
exporters: [new LangSmithExporter()],
},
},
}),
})
Explicit ConfigurationDirect link to Explicit Configuration
You can also pass credentials directly (takes precedence over environment variables):
import { Mastra } from '@mastra/core'
import { Observability } from '@mastra/observability'
import { LangSmithExporter } from '@mastra/langsmith'
export const mastra = new Mastra({
observability: new Observability({
configs: {
langsmith: {
serviceName: 'my-service',
exporters: [
new LangSmithExporter({
apiKey: process.env.LANGSMITH_API_KEY,
}),
],
},
},
}),
})
Configuration optionsDirect link to Configuration options
Complete ConfigurationDirect link to Complete Configuration
new LangSmithExporter({
// Required credentials
apiKey: process.env.LANGSMITH_API_KEY!,
// Optional settings
apiUrl: process.env.LANGSMITH_BASE_URL, // Default: https://api.smith.langchain.com
projectName: 'my-project', // Project to send traces to (overrides LANGCHAIN_PROJECT env var)
callerOptions: {
// HTTP client options
timeout: 30000, // Request timeout in ms
maxRetries: 3, // Retry attempts
},
logLevel: 'info', // Diagnostic logging: debug | info | warn | error
// LangSmith-specific options
hideInputs: false, // Hide input data in UI
hideOutputs: false, // Hide output data in UI
})
Environment variablesDirect link to Environment variables
| Variable | Description |
|---|---|
LANGSMITH_API_KEY | Your LangSmith API key (required) |
LANGCHAIN_PROJECT | Default project name for traces (optional, defaults to "default") |
LANGSMITH_BASE_URL | API URL for self-hosted instances (optional) |
The projectName config option takes precedence over the LANGCHAIN_PROJECT environment variable, allowing you to programmatically route traces to different projects.
Dynamic configurationDirect link to Dynamic configuration
You can override at runtime LangSmith settings per-span using withLangsmithMetadata. This is useful for routing traces to different projects based on runtime conditions (e.g., customer, environment, or feature).
Using the HelperDirect link to Using the Helper
Use withLangsmithMetadata with buildTracingOptions to set LangSmith-specific options:
import { Agent } from '@mastra/core/agent'
import { buildTracingOptions } from '@mastra/observability'
import { withLangsmithMetadata } from '@mastra/langsmith'
export const supportAgent = new Agent({
id: 'support-agent',
name: 'support-agent',
instructions: 'You are a helpful support agent.',
model: 'openai/gpt-6.1-sol',
defaultOptions: {
tracingOptions: buildTracingOptions(withLangsmithMetadata({ projectName: 'customer-support' })),
},
})
Dynamic Project RoutingDirect link to Dynamic Project Routing
Use requestContext to route traces to different projects based on runtime conditions.
import { Agent } from '@mastra/core/agent'
import { buildTracingOptions } from '@mastra/observability'
import { withLangsmithMetadata } from '@mastra/langsmith'
export const supportAgent = new Agent({
id: 'support-agent',
name: 'support-agent',
instructions: 'You are a helpful support agent.',
model: 'openai/gpt-6.1-sol',
defaultOptions: ({ requestContext }) => {
const userTier = requestContext?.get('user-tier') as string
const userId = requestContext?.get('user-id') as string
return {
tracingOptions: buildTracingOptions(
withLangsmithMetadata({
projectName: userTier === 'enterprise' ? 'enterprise-traces' : 'standard-traces',
sessionId: userId,
}),
),
}
},
})
Available FieldsDirect link to Available Fields
The withLangsmithMetadata helper accepts these fields:
| Field | Type | Description |
|---|---|---|
projectName | string | Override the project for this trace |
sessionId | string | Group related traces by session |
sessionName | string | Display name for the session |
All fields are optional. The helper merges with any existing metadata, so you can call it multiple times or combine with other tracing options.
Conversation threadsDirect link to Conversation threads
LangSmith groups runs into a Thread using the session_id metadata key. The exporter sets it on every run of a trace. The root run takes the first value it finds: an explicit withLangsmithMetadata({ sessionId }), then sessionId in span metadata, then the Mastra memory threadId. Child runs take the session of their parent run, so a delegated sub-agent stays in the conversation's Thread even though it runs on its own derived thread.
Agents with memory set threadId on each run, so turns on the same memory thread appear as one Thread in LangSmith without extra configuration:
const memory = { thread: 'thread-123', resource: 'user-1' }
await agent.generate('hi', { memory })
await agent.generate('and again', { memory })
Scores and feedbackDirect link to Scores and feedback
Scores sent through mastra.observability.addScore() show up in LangSmith as feedback on the matching run. A score with only a traceId is attached to the trace's root run; a score with a spanId is attached to that span's run.
await mastra.observability.addScore({
traceId,
correlationContext: { traceId },
score: { scorerId: 'user-feedback', scoreSource: 'user', score: 1, reason: 'Helpful answer' },
})
Each LangSmith run id is derived from its Mastra span id, so a span-level score works from any process, after a restart, and long after the trace was exported. A trace-level score finds the root run in the exporter's project through the mastra_trace_id metadata the exporter stores on every run. Runs exported by earlier versions of @mastra/langsmith keep their original ids and can only be scored from the process that exported them. The same derivation is exported as langsmithRunIdFor() if you need to link to a run from your own UI:
import { langsmithRunIdFor } from '@mastra/langsmith'
const runId = langsmithRunIdFor(spanId)