LangChain per Data Scientist nel 2026: LLM, Agent e Domande da Colloquio

Padroneggiare LangChain 0.3 per la data science: catene LCEL, pattern RAG, agent ReAct e sistemi di memoria. Include domande da colloquio e strategie di deployment in produzione.

Diagramma tutorial LangChain per Data Scientist

LangChain 0.3 si è affermato come framework di riferimento per la costruzione di applicazioni basate su LLM nei workflow di data science in produzione. Questo tutorial copre le astrazioni fondamentali, le architetture degli agent e i pattern di retrieval che i data scientist incontrano sia nei progetti reali che nei colloqui tecnici.

LangChain nel 2026

LangChain Expression Language (LCEL) permette la composizione dichiarativa di catene con streaming, parallelizzazione e fallback. La sintassi LCEL deve essere padroneggiata prima di affrontare gli agent: la maggior parte delle domande da colloquio presuppone familiarità con gli operatori pipe e i runnable.

Comprensione dei Componenti Core di LangChain

LangChain organizza l'orchestrazione degli LLM in quattro astrazioni primarie: Model, Prompt, Chain e Agent. Ogni astrazione si costruisce sulla precedente, creando un sistema componibile per workflow AI complessi.

Il livello Model avvolge diversi provider LLM (OpenAI, Anthropic, modelli locali) dietro un'interfaccia unificata. Questa astrazione permette di cambiare provider senza modificare la logica applicativa, aspetto critico per l'ottimizzazione dei costi e la flessibilità rispetto ai fornitori.

python
# langchain_setup.py
from langchain_openai import ChatOpenAI
from langchain_anthropic import ChatAnthropic
from langchain_core.messages import HumanMessage, SystemMessage

# Initialize with specific model and temperature
openai_model = ChatOpenAI(
    model="gpt-4o",
    temperature=0.1,  # Lower temperature for deterministic outputs
    max_tokens=2048
)

# Anthropic model with same interface
anthropic_model = ChatAnthropic(
    model="claude-sonnet-4-20250514",
    temperature=0.1
)

# Both models accept identical message format
messages = [
    SystemMessage(content="You are a data science expert."),
    HumanMessage(content="Explain gradient boosting in one sentence.")
]

# Swap models without changing message structure
response = openai_model.invoke(messages)

L'interfaccia unificata significa che le pipeline dati possono alternare tra provider in base a requisiti di costo, latenza o capacità.

Costruzione di Chain con Sintassi Pipe LCEL

LangChain Expression Language sostituisce la classe legacy LLMChain con una sintassi pipe-based più flessibile. Le catene LCEL sono runnable che supportano nativamente streaming, batching ed esecuzione asincrona.

python
# lcel_chain.py
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser, JsonOutputParser
from pydantic import BaseModel, Field

# Define structured output schema
class DataInsight(BaseModel):
    metric: str = Field(description="The metric being analyzed")
    trend: str = Field(description="Upward, downward, or stable")
    confidence: float = Field(description="Confidence score 0-1")

# Create prompt template with variables
prompt = ChatPromptTemplate.from_messages([
    ("system", "Analyze the following data and extract insights."),
    ("human", "Dataset: {dataset_description}\nFocus on: {metric}")
])

# LCEL chain with pipe operator
model = ChatOpenAI(model="gpt-4o", temperature=0)
parser = JsonOutputParser(pydantic_object=DataInsight)

chain = prompt | model | parser  # Pipe syntax composes runnables

# Invoke with input dictionary
result = chain.invoke({
    "dataset_description": "Monthly sales data showing 15% increase",
    "metric": "revenue growth"
})
# Returns: DataInsight(metric='revenue growth', trend='upward', confidence=0.85)

Le catene LCEL gestiscono automaticamente la conversione dei tipi tra componenti. Il prompt template produce un PromptValue, che il modello converte in una risposta, che il parser struttura nello schema Pydantic.

Retrieval-Augmented Generation per Applicazioni Dati

I pattern RAG migliorano le risposte LLM con contesto specifico del dominio recuperato da database vettoriali. Per le applicazioni di data science, RAG permette di interrogare documentazione, analisi precedenti o knowledge base di dominio.

python
# rag_pipeline.py
from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from langchain_chroma import Chroma
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnablePassthrough

# Initialize embeddings and vector store
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
vectorstore = Chroma(
    collection_name="data_docs",
    embedding_function=embeddings,
    persist_directory="./chroma_db"
)

# Create retriever with relevance threshold
retriever = vectorstore.as_retriever(
    search_type="similarity_score_threshold",
    search_kwargs={"score_threshold": 0.7, "k": 4}
)

# RAG prompt with context injection
rag_prompt = ChatPromptTemplate.from_messages([
    ("system", """Answer based on the provided context only.
Context: {context}
If the context doesn't contain relevant information, say so."""),
    ("human", "{question}")
])

# Format documents into context string
def format_docs(docs):
    return "\n\n".join(doc.page_content for doc in docs)

# RAG chain with parallel retrieval
rag_chain = (
    {"context": retriever | format_docs, "question": RunnablePassthrough()}
    | rag_prompt
    | ChatOpenAI(model="gpt-4o", temperature=0)
)

# Query with automatic retrieval
answer = rag_chain.invoke("What normalization method works best for skewed distributions?")

Il RunnablePassthrough preserva la domanda originale mentre il retriever recupera il contesto in parallelo. Questo pattern scala sui workload di produzione con overhead di latenza minimo.

Pronto a superare i tuoi colloqui su Data Science & ML?

Pratica con i nostri simulatori interattivi, flashcards e test tecnici.

Implementazione di Agent ReAct per Task sui Dati

Gli agent estendono le catene con capacità di tool-calling e loop di ragionamento. Il pattern ReAct (Reasoning + Acting) alterna passi di pensiero e azione, permettendo agli agent di risolvere problemi multi-step.

python
# react_agent.py
from langchain_openai import ChatOpenAI
from langchain_core.tools import tool
from langgraph.prebuilt import create_react_agent
import pandas as pd
import numpy as np

# Define data analysis tools
@tool
def calculate_statistics(data: str, column: str) -> str:
    """Calculate descriptive statistics for a column in CSV data."""
    df = pd.read_csv(pd.io.common.StringIO(data))
    stats = df[column].describe()
    return stats.to_string()

@tool
def detect_outliers(data: str, column: str, method: str = "iqr") -> str:
    """Detect outliers using IQR or Z-score method."""
    df = pd.read_csv(pd.io.common.StringIO(data))
    values = df[column]
    
    if method == "iqr":
        q1, q3 = values.quantile([0.25, 0.75])
        iqr = q3 - q1
        outliers = values[(values < q1 - 1.5 * iqr) | (values > q3 + 1.5 * iqr)]
    else:  # z-score
        z_scores = np.abs((values - values.mean()) / values.std())
        outliers = values[z_scores > 3]
    
    return f"Found {len(outliers)} outliers: {outliers.tolist()[:10]}"

@tool
def correlation_analysis(data: str, col1: str, col2: str) -> str:
    """Calculate Pearson correlation between two columns."""
    df = pd.read_csv(pd.io.common.StringIO(data))
    corr = df[col1].corr(df[col2])
    return f"Correlation between {col1} and {col2}: {corr:.4f}"

# Create ReAct agent with tools
model = ChatOpenAI(model="gpt-4o", temperature=0)
tools = [calculate_statistics, detect_outliers, correlation_analysis]

agent = create_react_agent(
    model=model,
    tools=tools,
    state_modifier="You are a data analyst. Use tools to analyze data step by step."
)

# Agent reasons about which tools to use
result = agent.invoke({
    "messages": [("human", "Analyze the sales column for outliers and basic stats")]
})

Il decorator @tool registra le funzioni come tool dell'agent con generazione automatica dello schema dai type hint e dalle docstring. L'agent decide quando chiamare ogni tool in base ai requisiti del task.

Pattern di Memoria per Analisi Conversazionali

Le sessioni di analisi dati prolungate richiedono memoria conversazionale per mantenere il contesto attraverso le interazioni. LangChain fornisce multiple strategie di memoria ottimizzate per diversi casi d'uso.

python
# memory_patterns.py
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.chat_history import InMemoryChatMessageHistory
from langchain_core.runnables.history import RunnableWithMessageHistory

# Initialize model and prompt with history placeholder
model = ChatOpenAI(model="gpt-4o", temperature=0.1)

prompt = ChatPromptTemplate.from_messages([
    ("system", "You are a data science assistant helping with analysis."),
    MessagesPlaceholder(variable_name="history"),  # Inject conversation history
    ("human", "{input}")
])

chain = prompt | model

# Session-based message store
message_stores = {}

def get_session_history(session_id: str):
    if session_id not in message_stores:
        message_stores[session_id] = InMemoryChatMessageHistory()
    return message_stores[session_id]

# Wrap chain with message history
chain_with_history = RunnableWithMessageHistory(
    chain,
    get_session_history,
    input_messages_key="input",
    history_messages_key="history"
)

# Conversation maintains context across invocations
config = {"configurable": {"session_id": "analysis_session_1"}}

response1 = chain_with_history.invoke(
    {"input": "I'm analyzing customer churn data with 50k rows"},
    config=config
)
# Later in the same session
response2 = chain_with_history.invoke(
    {"input": "What sampling strategy should I use for this dataset size?"},
    config=config
)  # Agent remembers the 50k rows context

I deployment in produzione tipicamente sostituiscono InMemoryChatMessageHistory con store supportati da Redis o PostgreSQL per la persistenza attraverso i riavvii del server.

Domande da Colloquio su LangChain e Risposte

I colloqui tecnici per posizioni di ML engineering e data science includono sempre più domande su LangChain. Queste valutano tipicamente la comprensione delle astrazioni core, delle considerazioni di produzione e delle strategie di debugging.

Argomenti Comuni nei Colloqui

Gli intervistatori si concentrano su tre aree: pattern di composizione delle catene, tecniche di ottimizzazione RAG e strategie di affidabilità degli agent. Aspettarsi di progettare una pipeline di retrieval alla lavagna o di fare debug di uno scenario di allucinazione.

D: Spiega la differenza tra catene e agent in LangChain.

Le catene eseguono una sequenza predeterminata di operazioni - da prompt a modello a parser - senza decisioni a runtime. Gli agent aggiungono un loop di ragionamento che seleziona dinamicamente i tool in base ai risultati intermedi. Le catene sono adatte a workflow strutturati come pipeline di trasformazione dati; gli agent gestiscono task aperti che richiedono selezione adattiva dei tool.

D: Come si riducono le allucinazioni in un'applicazione RAG?

Multiple strategie lavorano insieme: aumentare la precisione del retrieval con ricerca ibrida (combinando retriever densi e sparsi), aggiungere scoring di rilevanza per filtrare chunk a bassa confidenza, includere attribuzione delle fonti nei prompt, implementare verifica delle risposte contro il contesto recuperato e usare impostazioni di temperature più basse per query fattuali. I pattern di feature engineering per la qualità degli embedding influenzano anche l'accuratezza del retrieval.

D: Cosa sono i runnable e perché LangChain li usa?

I runnable sono l'astrazione base che implementa il protocollo Runnable con metodi invoke, stream, batch e ainvoke. Ogni componente - prompt, modelli, parser, retriever - è un runnable. Questa uniformità permette la composizione con l'operatore pipe, dove i tipi di output corrispondono automaticamente alle aspettative di input. I runnable forniscono anche parallelizzazione integrata, logica di retry e streaming senza codice aggiuntivo.

D: Come implementeresti risposte in streaming per un'interfaccia chat?

python
# streaming_example.py
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate

prompt = ChatPromptTemplate.from_template("Explain {concept} in detail")
model = ChatOpenAI(model="gpt-4o", streaming=True)

chain = prompt | model

# Stream yields chunks as they arrive
for chunk in chain.stream({"concept": "backpropagation"}):
    print(chunk.content, end="", flush=True)

Il metodo stream produce oggetti AIMessageChunk contenenti risposte parziali. Per le applicazioni web, questi chunk tipicamente alimentano Server-Sent Events o connessioni WebSocket.

D: Descrivi strategie per testare applicazioni LangChain.

Testare applicazioni LLM richiede approcci multipli: test unitari con risposte del modello mock per comportamento deterministico delle catene, test di integrazione con modelli reali per l'efficacia dei prompt, dataset di valutazione con output attesi per il rilevamento delle regressioni e tool di tracing come LangSmith per il debugging in produzione. Mockare il livello modello durante la CI per evitare costi API e flakiness.

Considerazioni per il Deployment in Produzione

Il deployment di applicazioni LangChain richiede attenzione a latenza, costi e affidabilità oltre a quanto rivelano gli ambienti di sviluppo.

Gestione dei Costi dei Token

Le applicazioni RAG in produzione possono generare costi significativi in token. Implementare middleware per il conteggio dei token, impostare alert di budget e considerare strategie di caching per query ripetute. Un singolo loop di agent con multiple chiamate a tool può consumare migliaia di token per richiesta.

Il caching riduce sia la latenza che i costi per query ripetute. Il layer di caching di LangChain memorizza le risposte del modello indicizzate per hash del prompt:

python
# caching_setup.py
from langchain_core.globals import set_llm_cache
from langchain_community.cache import RedisCache
import redis

# Redis cache for distributed deployments
redis_client = redis.Redis(host="localhost", port=6379)
set_llm_cache(RedisCache(redis_client))

# Subsequent identical queries hit cache
model = ChatOpenAI(model="gpt-4o")
response1 = model.invoke("What is gradient descent?")  # API call
response2 = model.invoke("What is gradient descent?")  # Cache hit

Per le pipeline MLOps, integrare LangChain con l'experiment tracking per monitorare versioni dei prompt, configurazioni del modello e metriche di qualità delle risposte nel tempo.

Inizia a praticare!

Metti alla prova le tue conoscenze con i nostri simulatori di colloquio e test tecnici.

Conclusione

  • LangChain 0.3 organizza l'orchestrazione LLM in Model, Prompt, Chain e Agent - ogni astrazione componibile tramite sintassi pipe LCEL
  • Le implementazioni RAG richiedono soglie di retrieval calibrate, scoring di rilevanza e formattazione del contesto per accuratezza in produzione
  • Gli agent ReAct gestiscono task dati multi-step ragionando sulla selezione dei tool a runtime
  • I pattern di memoria mantengono il contesto conversazionale attraverso le sessioni di analisi usando message store basati su sessione
  • La preparazione ai colloqui deve coprire le distinzioni tra catene e agent, strategie di riduzione delle allucinazioni e pattern di composizione dei runnable
  • I deployment in produzione necessitano di caching, budgeting dei token e tooling di osservabilità per la gestione di costi e affidabilità

Tag

#langchain
#llm
#data-science
#agents
#rag
#interview

Condividi

Articoli correlati