πŸŽ“ LangChain Learning Path - Step 7 of 7

πŸ““ Hands-On Practice
⬇️ Download Jupyter Notebook - Set up LangSmith tracing and learn to debug and monitor your AI applications.


The Problem: AI is a Black Box

When your AI agent doesn’t work as expected, it’s hard to know why:

flowchart LR Q["❓ User Question"] --> BB["⬛ Black Box
Agent"] --> R["❌ Wrong Answer"] Note["What happened inside?
- Which tools were called?
- What did the LLM see?
- Where did it go wrong?"] style BB fill:#fecaca,stroke:#dc2626 style Note fill:#fef3c7,stroke:#d97706

Common problems:

LangSmith solves this by making everything visible!


What is LangSmith?

LangSmith is like a video replay system for your AI - it records every step so you can see exactly what happened.

flowchart TB A["πŸ€– Your Agent"] --> LS["πŸ“Ή LangSmith
Records Everything"] LS --> T["πŸ“Š Traces
See each step"] LS --> D["πŸ” Debugging
Find issues"] LS --> P["⚑ Performance
Optimize speed"] LS --> C["πŸ’° Costs
Track spending"] style A fill:#dbeafe,stroke:#2563eb style LS fill:#fef3c7,stroke:#d97706 style T fill:#d1fae5,stroke:#059669 style D fill:#fce7f3,stroke:#db2777 style P fill:#e0e7ff,stroke:#6366f1 style C fill:#fef3c7,stroke:#d97706

Real-world analogy: Like a sports replay - you can see every play, slow it down, and understand what went wrong.


Getting Started

Step 1: Sign Up

  1. Go to smith.langchain.com
  2. Sign up for free account
  3. Create a new project

Step 2: Get API Key

  1. Go to Settings β†’ API Keys
  2. Create new API key
  3. Copy it

Step 3: Configure Your Code

# Add to .env file
LANGCHAIN_TRACING_V2=true
LANGCHAIN_API_KEY=your_langsmith_api_key
LANGCHAIN_PROJECT=your_project_name
import os
from dotenv import load_dotenv

load_dotenv()

# That's it! LangSmith is now tracking your agent

Understanding Traces

What is a Trace?

A trace is a complete record of one interaction with your agent.

flowchart TB Start["πŸ‘€ User: What's the weather?"] --> Trace["πŸ“Ή Trace Starts"] Trace --> Step1["πŸ€– LLM Call 1:
Decides to use tool"] Step1 --> Step2["πŸ”§ Tool Call:
get_weather('NYC')"] Step2 --> Step3["πŸ€– LLM Call 2:
Formats answer"] Step3 --> End["πŸ’¬ Response:
It's sunny, 72Β°F"] style Trace fill:#fef3c7,stroke:#d97706 style Step1 fill:#dbeafe,stroke:#2563eb style Step2 fill:#fce7f3,stroke:#db2777 style Step3 fill:#dbeafe,stroke:#2563eb style End fill:#d1fae5,stroke:#059669

Each trace shows:


Viewing Traces in LangSmith

The Trace View

When you open a trace, you see a timeline:

Trace: "What's the weather in New York?"
β”œβ”€ πŸ€– ChatOpenAI (230ms, $0.002)
β”‚  β”œβ”€ Input: "What's the weather in New York?"
β”‚  └─ Output: [calls get_weather tool]
β”‚
β”œβ”€ πŸ”§ get_weather (45ms, $0.000)
β”‚  β”œβ”€ Input: {"city": "New York"}
β”‚  └─ Output: "Sunny, 72Β°F"
β”‚
└─ πŸ€– ChatOpenAI (180ms, $0.001)
   β”œβ”€ Input: [tool result + original question]
   └─ Output: "It's sunny and 72Β°F in New York!"

Total: 455ms, $0.003

What You Can See

flowchart LR subgraph info["πŸ“Š Trace Information"] I1["Inputs & Outputs"] I2["Token usage"] I3["Latency"] I4["Costs"] I5["Errors"] end style info fill:#d1fae5,stroke:#059669

Common Debugging Scenarios

Scenario 1: Agent Uses Wrong Tool

Problem: Agent calls send_email instead of search_email

How to debug:

  1. Open trace in LangSmith
  2. Find the LLM call before tool use
  3. Check the Prompt tab
  4. See what the LLM saw

What you might find:

Available tools:
- send_email: Send an email    ← Tool description unclear!
- search_email: Find emails

User: "Find my emails from Bob"

Fix: Improve tool description:

@tool
def search_email(query: str) -> str:
    """
    SEARCH for existing emails (does NOT send).
    Use this to FIND or LOOKUP emails.
    """

Scenario 2: LLM Hallucination

Problem: Agent makes up information not in the retrieved documents

How to debug:

  1. Find the generation step
  2. Check the Context provided
  3. Compare to the output

Example:

Context provided:
"Employee handbook says: 15 vacation days"

LLM output:
"You get 20 vacation days and unlimited sick leave"
                ↑ Made up!        ↑ Not in context!

Fix: Add stricter prompt:

prompt = """
CRITICAL: Only use information from the provided context.
If info is not in context, say "I don't have that information."
Do NOT make up or infer information.

Context: {context}
"""

Scenario 3: Slow Performance

Problem: Agent takes 10 seconds to respond

How to debug:

  1. Look at timing for each step
  2. Find the bottleneck

Example trace:

β”œβ”€ Retrieval (50ms) βœ… Fast
β”œβ”€ LLM Call 1 (8000ms) ❌ SLOW!
└─ LLM Call 2 (100ms) βœ… Fast

Total: 8150ms

Fix: Reduce input size for slow LLM call:

# Before: Sending entire document (10,000 tokens)
# After: Send only relevant chunks (500 tokens)

Scenario 4: High Costs

Problem: $50 bill for 100 requests

How to debug:

  1. Click β€œAnalytics” in LangSmith
  2. See cost breakdown
  3. Find expensive calls

What you might find:

GPT-4 calls: $45 (10,000 requests with 4,000 tokens each)
GPT-3.5 calls: $5 (1,000 requests)

Fix: Use cheaper model when possible:

# For simple tasks
cheap_model = ChatOpenAI(model="gpt-3.5-turbo")

# For complex tasks only
expensive_model = ChatOpenAI(model="gpt-4")

Monitoring Patterns

Pattern 1: Testing Changes

Compare before and after:

# Tag your runs
from langsmith import traceable

@traceable(run_type="chain", tags=["version-1"])
def old_chain(input):
    # Old implementation
    pass

@traceable(run_type="chain", tags=["version-2"])
def new_chain(input):
    # New improved implementation
    pass

# In LangSmith, filter by tags and compare metrics

Pattern 2: Quality Monitoring

Track quality metrics:

flowchart TB Prod["πŸš€ Production Agent"] --> Track["πŸ“Š Track Metrics"] Track --> M1["βœ… Success rate"] Track --> M2["⏱️ Response time"] Track --> M3["πŸ’° Cost per request"] Track --> M4["😊 User satisfaction"] Track --> Alert{"Metrics
drop?"} Alert -->|Yes| Notify["πŸ”” Alert team"] style Prod fill:#dbeafe,stroke:#2563eb style Track fill:#fef3c7,stroke:#d97706 style Alert fill:#fce7f3,stroke:#db2777 style Notify fill:#fecaca,stroke:#dc2626

Pattern 3: Error Tracking

Automatically detect issues:

from langsmith import Client

client = Client()

# Get failed runs
failed_runs = client.list_runs(
    project_name="my-project",
    filter="error eq true",
    start_time=yesterday
)

for run in failed_runs:
    print(f"Error: {run.error}")
    print(f"Input: {run.inputs}")
    # Alert or fix automatically

Advanced Features

1. Datasets & Testing

Create test sets to ensure quality:

from langsmith import Client

client = Client()

# Create dataset
dataset = client.create_dataset("customer-service-tests")

# Add examples
client.create_examples(
    dataset_id=dataset.id,
    inputs=[
        {"question": "What's my order status?"},
        {"question": "How do I return an item?"},
    ],
    outputs=[
        {"should_use_tool": "check_order"},
        {"should_use_tool": "return_policy"},
    ]
)

# Run tests
def test_agent():
    for example in dataset.examples:
        result = agent.invoke(example.inputs)
        # Validate result matches expected output

2. Feedback & Ratings

Collect user feedback:

from langsmith import Client

client = Client()

# User gives feedback
client.create_feedback(
    run_id=run_id,
    key="helpfulness",
    score=5,  # 1-5 stars
    comment="Very helpful!"
)

# View feedback in LangSmith dashboard

3. Playground Testing

Test prompts interactively:

  1. Go to LangSmith Playground
  2. Paste your prompt
  3. Try different inputs
  4. See results immediately
  5. Compare versions side-by-side

Real-World Example

Let’s add full observability to our Research Assistant:

import os
from dotenv import load_dotenv
from langsmith import traceable
from langchain_openai import ChatOpenAI
from langgraph.prebuilt import create_react_agent

# Enable tracing
load_dotenv()
os.environ["LANGCHAIN_TRACING_V2"] = "true"
os.environ["LANGCHAIN_PROJECT"] = "research-assistant"

# Tools with better descriptions for debugging
@traceable(name="web_search_tool")
def web_search(query: str) -> str:
    """
    Search the web for information.
    
    WHEN TO USE: User asks about current info, facts, or research topics.
    DO NOT USE: For personal info, past conversations, or saved notes.
    """
    # Implementation
    pass

@traceable(name="save_notes_tool")
def save_notes(content: str, title: str) -> str:
    """
    Save research findings to notes.
    
    WHEN TO USE: After finding important information worth remembering.
    DO NOT USE: For every small detail.
    """
    # Implementation
    pass

# Create agent with metadata
agent = create_react_agent(
    ChatOpenAI(model="gpt-4"),
    tools=[web_search, save_notes],
    state_modifier="You are a research assistant..."
)

# Track user sessions
@traceable(
    run_type="chain",
    name="research_session",
    tags=["production", "v2.0"]
)
def handle_user_query(user_id: str, query: str):
    """Handle user query with full tracing."""
    
    config = {
        "configurable": {"thread_id": user_id},
        "metadata": {
            "user_id": user_id,
            "environment": "production"
        },
        "tags": ["user_query"]
    }
    
    result = agent.invoke({"messages": [("user", query)]}, config)
    
    return result["messages"][-1].content

# Use it
response = handle_user_query("user_123", "Research quantum computing")

What you get in LangSmith:

Session: research_session
β”œβ”€ Metadata: user_id=user_123, environment=production
β”œβ”€ Tags: production, v2.0, user_query
β”‚
β”œβ”€ πŸ”§ web_search_tool (234ms, $0.000)
β”‚  └─ Output: "Quantum computing uses..."
β”‚
β”œβ”€ πŸ€– ChatOpenAI (890ms, $0.005)
β”‚  └─ Decides to save notes
β”‚
└─ πŸ”§ save_notes_tool (45ms, $0.000)
   └─ Saved: "Quantum Computing Basics"

Total: 1169ms, $0.005
βœ… Success

Best Practices

1. Add Meaningful Tags

tags = [
    "environment:production",
    "user_type:premium",
    "feature:research",
    "version:2.1"
]

2. Include Metadata

metadata = {
    "user_id": "12345",
    "session_id": "abc",
    "feature_flags": ["new_ui"],
    "model_version": "gpt-4"
}

3. Name Your Traces

@traceable(name="generate_report", run_type="chain")
def generate_report(data):
    # Clear name in dashboard
    pass

4. Monitor Key Metrics

Set up alerts for:

5. Regular Reviews

Weekly:


Troubleshooting Tips

Traces Not Showing Up?

Check:

# 1. Environment variables set?
print(os.getenv("LANGCHAIN_TRACING_V2"))  # Should be "true"
print(os.getenv("LANGCHAIN_API_KEY"))     # Should have value

# 2. Internet connection working?

# 3. Project name correct?
print(os.getenv("LANGCHAIN_PROJECT"))

# 4. Try manual trace
from langsmith import Client
client = Client()
client.create_run(...)  # Test connection

Too Many Traces?

Filter traces:

# Only trace in development
if os.getenv("ENVIRONMENT") == "development":
    os.environ["LANGCHAIN_TRACING_V2"] = "true"

Need to Hide Sensitive Data?

@traceable(name="process_payment", 
          hide_inputs=True,   # Don't log input
          hide_outputs=True)  # Don't log output
def process_payment(card_number, cvv):
    # Sensitive operation
    pass

The Debugging Workflow

flowchart TB Issue["πŸ› Issue Reported"] --> Find["πŸ” Find Trace
in LangSmith"] Find --> Analyze["πŸ“Š Analyze Steps"] Analyze --> Root["🎯 Find Root Cause"] Root --> Fix["πŸ”§ Fix Code"] Fix --> Test["βœ… Test with
Same Input"] Test --> Verify["πŸ“Ή Compare
New Trace"] Verify --> Deploy["πŸš€ Deploy Fix"] style Issue fill:#fecaca,stroke:#dc2626 style Find fill:#fef3c7,stroke:#d97706 style Analyze fill:#dbeafe,stroke:#2563eb style Root fill:#fce7f3,stroke:#db2777 style Fix fill:#d1fae5,stroke:#059669 style Deploy fill:#d1fae5,stroke:#059669

What You’ve Learned

βœ… Why observability matters for AI
βœ… Setting up LangSmith
βœ… Reading and understanding traces
βœ… Debugging common issues
βœ… Monitoring production systems
βœ… Testing and quality assurance
βœ… Best practices for tracing

You now have the tools to build, debug, and monitor production AI systems!


πŸŽ‰ Congratulations!

You’ve completed the LangChain Learning Path! You now know:

  1. Foundations - LLM orchestration concepts
  2. Essentials - Chat models, prompting, LCEL
  3. Tool Calling - Extending LLMs with capabilities
  4. RAG - Teaching AI about your documents
  5. LangGraph - Building complex agent workflows
  6. Projects - Building complete applications
  7. Observability - Debugging and monitoring

What’s Next?


Resources


Keep Learning

More Topics to Explore:

Other Resources:


Thank you for learning with us! πŸš€

Now go build amazing AI applications! 🎯