LangChain v1: crea un assistente per il riepilogo automatico delle riunioni
Scopri come creare un Auto Meeting Recap Assistant con LangChain v1 che riassume le riunioni, estrae gli elementi d’azione e invia i riepiloghi approvati a un Google Doc usando le ultime funzionalità come create_agent e content block.
LangChain è un framework open-source per creare applicazioni IA agentiche che combinano LLM e strumenti. La versione 1.0 segna il passaggio a un core di livello production con un’API semplificata, confini più chiari e una gestione standardizzata dei messaggi tra provider.
In questo tutorial costruiremo uno Streamlit Auto Meeting Recap Assistant che prende appunti grezzi, produce un riepilogo conciso con elementi d’azione e, dopo l’approvazione umana, aggiunge il riepilogo a un Google Doc. Lungo il percorso vedrai in azione il nuovo flusso create_agent, i content block standard e il namespace più snello della v1.
Che cos’è LangChain v1?
LangChain v1 è una release ristrutturata e orientata alla produzione, focalizzata su una superficie piccola e stabile per costruire agenti. Introduce:
create_agent come modo standard per avviare agenti (più pulito rispetto ai vecchi agenti predefiniti).
Contenuti standardizzati tramite content_blocks così i messaggi sono coerenti tra provider.
Output strutturato e middleware per risposte tipizzate e azioni sicure, approvate dall’uomo.
Il pacchetto langchain si concentra sui mattoni per costruire agenti, mentre i moduli legacy si spostano su langchain-classic, facilitando reperibilità e upgrade.
Rispetto alla v0.x, la v1 riduce il carico cognitivo e le particolarità dei provider standardizzando contenuto dei messaggi e orchestrazione degli agenti. Ottieni lo stesso modello mentale sia che usi OpenAI, Anthropic o altri.
Principali miglioramenti tecnici in LangChain v1
La versione originale LangChain v0.x offriva molti pattern per costruire agenti, tuttavia la v1 li consolida in un percorso chiaro usando il blocco create_agent così i tuoi agenti sono più facili da comprendere, testare e distribuire. Offre strumenti più puliti, debug più semplice tramite contenuto standardizzato e un loop dell’agente prevedibile.
Ecco alcuni miglioramenti tecnici chiave inclusi in questa release:
Workflow create_agent: questo loop d’agente pronto per la produzione consente al modello di decidere quando chiamare strumenti e quando terminare. Non dobbiamo più destreggiarci tra più pattern, il che semplifica la personalizzazione.
Content block standard: un modo agnostico rispetto al provider per leggere i messaggi con tracce di ragionamento, chiamate a tool, citazioni e persino elementi multimodali, tutto tramite un’API unificata content_blocks. Strumentazione e log appaiono uguali tra provider.
Output strutturato: l’ultima release include un supporto di prima classe per schemi tipizzati, così puoi fare affidamento su JSON prevedibile senza regex fragili. Questo riduce errori di parsing e chiamate extra.
Middleware: si agganciano al loop dell’agente per approvare azioni rischiose, riassumere la cronologia quando è lunga e redigere PII prima delle chiamate.
Namespace semplificato: il pacchetto langchain ora si concentra sui componenti essenziali per gli agenti, mentre LangGraph fornisce sotto il cofano funzionalità di affidabilità come persistenza e time-travel.
Demo: creare un Auto Meeting Recap Assistant con LangChain v1
In questa sezione implementeremo un’app Streamlit che automatizza i riepiloghi delle riunioni end-to-end. L’app accetta appunti grezzi della riunione con metadati opzionali (titolo, data e partecipanti). Genera quindi un RecapDoc tipizzato, includendo titolo, sintesi, decisioni ed elementi d’azione, in un output strutturato. Con un clic, il riepilogo approvato (preceduto dalla data della riunione) viene aggiunto a un Google Doc designato.
Passo 1: Prerequisiti
Prima di costruire l’Auto Meeting Recap Assistant, ci serve un toolkit minimo per la UI, l’LLM, la validazione tipizzata e l’accesso a Google Docs. I comandi seguenti installano tutto il necessario e impostano la chiave del modello in modo che la tua app possa comunicare con il provider.
Streamlit: esegue l’app web in locale con una UI semplice e pythonica.
langchaine langchain-openai: forniscono la superficie semplificata di LangChain v1 (init_chat_model, output strutturato) e il bridge al provider OpenAI.
pydantic: definisce lo schema rigoroso RecapDoc così il modello restituisce campi tipizzati.
Python-dotenv: carica le variabili d’ambiente da un file .env durante lo sviluppo.
google-auth: gestisce OAuth e la Google Docs API così possiamo aggiungere il riepilogo a un documento.
OPENAI_API_KEY: la chiave API di OpenAI autentica le chiamate al LLM; impostala come variabile d’ambiente (o usa un secrets manager).
Nota: se usi un altro provider (Anthropic, Google o un modello locale), installa l’integrazione langchain-* corrispondente e imposta la chiave API di quel provider.
Con queste dipendenze installate e OPENAI_API_KEY impostata, l’ambiente è pronto. Nei prossimi passi configureremo la Google Docs API tramite Google Cloud.
Passo 2: Abilita la Google Docs API
Per salvare ogni riepilogo in un documento vivo, l’app ha bisogno del permesso di scrivere su Google Docs. Questo passo configura l’accesso end-to-end. Per prima cosa:
Ottieni un file OAuth client (credentials.json) da Google Cloud
Identifica l’ID del Google Doc a cui vuoi aggiungere contenuti
Infine, lascia che l’app crei un token.json riutilizzabile al primo avvio dopo che approvi l’accesso nel browser.
Una volta predisposti questi tre elementi, l’app può aggiungere i riepiloghi al Google Doc scelto con un clic. Puoi revocare o rinnovare l’accesso in qualsiasi momento eliminando token.json ed eseguendo di nuovo l’app.
Passo 2.1: Ottieni credentials.json da Google Cloud
Il file credentials.json è la chiave della tua app per la Google Docs API. Lo generi una volta nella Google Cloud Console come OAuth client per Desktop App. Per iniziare:
Assegnagli il nome che preferisci, poi clicca su Create.
Abilita la Google Docs API
Ora che il progetto è stato creato, abilitiamo l’API necessaria per scrivere in Google Docs.
Vai su APIs & Services e cerca Library. Puoi usare anche la ricerca.
Cerca Google Docs API e clicca Enable. Nota che dovrai disabilitare l’API dopo l’uso per evitare addebiti non necessari.
Configura la schermata di consenso OAuth
Una volta abilitata l’API, dobbiamo impostare l’autenticazione per la nostra email preferita.
Vai su APIs & Services e clicca su OAuthconsentscreen.
Scegli External e compila le informazioni di base dell’app.
Nella sezione Audience / Test users clicca Addusers e aggiungi gli account Gmail che userai, quindi salva.
Lasciare l’app in modalità Testing va bene per lo sviluppo.
Crea le credenziali OAuth client
Il passo finale è generare e scaricare il file credentials.json. Per farlo:
Vai su APIs & Services e clicca su Credentials.
Clicca su + CREATE CREDENTIALS, verrai indirizzato a OAuth client ID.
Sotto Applicationtype seleziona Desktopapp e clicca su Create.
Possono essere necessari fino a 5 minuti per generare client ID e secret, insieme a un file JSON scaricabile.
Salva il file JSON come credentials.json nella stessa cartella del tuo app.py (oppure indica il suo percorso nelle impostazioni dell’app).
Ora disponi di un OAuth client Desktop che l’app può usare per avviare l’accesso tramite browser e richiedere il permesso di accedere a Google Docs per tuo conto.
Passo 2.2: Google Doc ID
L’app deve sapere a quale documento aggiungere contenuti. Il documento è identificato da un ID univoco incorporato nell’URL. Per questo passo,
Apri il Google Doc di destinazione in un browser.
Copia la stringa nell’URL tra /d/ e /edit, per esempio: https://docs.google.com/document/d/<THIS_IS_THE_ID>/edit
Incolla questo Doc ID nel campo “Google Doc ID” dell’app (o nella variabile di configurazione appropriata).
Con l’ID corretto, l’app scriverà i riepiloghi esattamente nel documento selezionato.
Passo 2.3: Token.json
Al primo inserimento, l’app ha bisogno della tua approvazione esplicita per accedere al documento. Dopo l’approvazione, Google restituisce un token che l’app archivia in locale come token.json. Ecco come viene generato questo file:
Esegui l’app e clicca Append to Google Doc.
Si apre una finestra del browser che ti chiede di accedere con uno degli utenti di test aggiunti in precedenza e di approvare l’ambito.
Dopo la conferma, l’app scrive token.json accanto al tuo codice. Questo file contiene token di accesso/refresh riutilizzabili.
Nota: se devi cambiare account o ripetere il consenso, elimina semplicemente token.json e clicca di nuovo Appendto GoogleDoc.
Passo 3: Import
Prima di scrivere la logica, importiamo i moduli che alimentano la UI, i contratti di dati tipizzati, le chiamate al modello e l’integrazione con Google Docs. Raggruppare gli import per scopo mantiene il codice leggibile e rende ovvio quale livello verificare quando qualcosa non funziona.
import os
import io
import json
from datetime import date
from typing import List, Optional
import streamlit as st
from pydantic import BaseModel, Field
from dotenv import load_dotenv
# ---- LangChain v1 surface ----from langchain.agents import create_agent
from langchain.messages import SystemMessage, HumanMessage
from langchain.chat_models import init_chat_model
# ---- Google Docs API ----from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import buildOfferto da
Per questo passo importiamo solo ciò che serve all’app, ossia utility standard come os, io, json, date e hint di typing per percorsi, buffer e serializzazione leggera. Poi importiamo Streamlit per la UI, Pydantic per gli schemi tipizzati RecapDoc, e dotenv per caricare le variabili d’ambiente. La superficie di LangChain v1init_chat_model e create_agent per inizializzare un modello di chat agnostico rispetto al provider e strutturare i prompt e, infine, i componenti della Google Docs API che gestiscono OAuth e ci danno un client autenticato per aggiungere riepiloghi al documento scelto.
Passo 4: Definisci l’output strutturato
Per rendere la risposta del modello affidabile e facile da usare, definiamo un contratto tipizzato per il riepilogo. Usare modelli Pydantic assicura che l’LLM restituisca campi prevedibili che la nostra UI può renderizzare, l’API può archiviare e le automazioni possono validare.
classActionItem(BaseModel):
owner:str= Field(..., description="Person responsible")
task:str= Field(..., description="Short, specific task")
due_date:str= Field(..., description="ISO date (YYYY-MM-DD) or natural language like 'next Friday'")classRecapDoc(BaseModel):
title:str
date:str
attendees: List[str]
summary:str
decisions: List[str]
action_items: List[ActionItem]Offerto da
Ecco i componenti chiave del blocco di codice precedente:
Classe ActionItem: cattura l’essenziale di un’attività di follow-up come owner, task e due_date con descrizioni brevi ed esplicite così il modello le compila pulitamente. Consentire date ISO o frasi naturali mantiene l’input flessibile pur restando analizzabile a valle.
ClasseRecapDoc: rappresenta l’intero riepilogo come un singolo oggetto, inclusi title, date, attendees, un summary conciso, decisions esplicite e un elenco di action_items.
Con LangChain v1, puoi richiedere direttamente questo schema tramite with_structured_output(RecapDoc), riducendo il parsing fragile delle stringhe, migliorando la validazione e consentendo di fallire rapidamente quando mancano campi.
Passo 5: System prompt
Il system prompt stabilisce le regole di base per il tuo assistente. Dice al modello esattamente cosa produrre, cosa evitare e come strutturare l’output affinché i passaggi successivi funzionino in modo affidabile ogni volta.
SYSTEM_PROMPT ="""You are a precise assistant that produces concise, high-signal meeting recaps.
Return a structured RecapDoc with:
- title, date, attendees
- a brief summary (3–6 sentences)
- explicit decisions (bullet-style)
- action_items (each has owner, task, due_date)
Rules:
- Only include info supported by the notes or explicit user inputs.
- Keep action items specific with clear owners and due dates.
- If something is unknown, say "Unknown" rather than inventing details.
"""Offerto da
Il system prompt rende l’assistente preciso e conciso, puntando a riepiloghi ad alto valore informativo invece che trascrizioni. Stampa uno schema netto che include titolo, data, partecipanti, sintesi, decisioni, action_items con regole come sintesi di 3–6 frasi, decisioni puntate ed elementi d’azione con owner, task e scadenza.
Con un system prompt chiaro, il modello produce costantemente riepiloghi strutturati e utilizzabili al primo tentativo.
Passo 6: helper per Google OAuth
In questo passo definiamo una funzione helper che stabilisce una connessione affidabile e riutilizzabile a Google Docs così l’app può aggiungere i riepiloghi al documento scelto. Richiede solo l’ambito Docs e gestisce il consenso iniziale, il refresh del token e la costruzione del servizio.
SCOPES =["https://www.googleapis.com/auth/documents"]defget_google_docs_service(
credentials_path: Optional[str],
token_path:str="token.json",
use_secrets:bool=False):
creds =Noneif use_secrets:try:if"google_credentials_json"in st.secrets:withopen("credentials_temp.json","w")as f:
f.write(st.secrets["google_credentials_json"])
credentials_path ="credentials_temp.json"except Exception:passif os.path.exists(token_path):
creds = Credentials.from_authorized_user_file(token_path, SCOPES)ifnot creds ornot creds.valid:if creds and creds.expired and creds.refresh_token:try:
creds.refresh(Request())except Exception:passifnot creds ornot creds.valid:ifnot credentials_path ornot os.path.exists(credentials_path):raise RuntimeError("Missing Google OAuth credentials. Provide 'credentials.json' ""or set st.secrets['google_credentials_json'].")
flow = InstalledAppFlow.from_client_secrets_file(credentials_path, SCOPES)
creds = flow.run_local_server(port=0)withopen(token_path,"w")as token:
token.write(creds.to_json())return build("docs","v1", credentials=creds)Offerto da
La funzione get_google_docs_service() gestisce OAuth e la creazione del servizio:
Definizione dell’ambito: la funzione usa SCOPES predefiniti per limitare i permessi a Google Docs.
Caricamento credenziali: legge da un credentials.json locale o da st.secrets["google_credentials_json"], il contenitore dei segreti di Streamlit quando use_secrets=True.
Riutilizzo dei token: se esiste token.json, il codice lo carica e, se il token è scaduto, lo aggiorna in silenzio.
Consenso iniziale: se non si trova un token valido, si avvia l’InstalledAppFlow Desktop, che chiede all’utente di autenticarsi nel browser e poi salva token.json per esecuzioni future.
Restituzione del client: infine, costruiamo e restituiamo un client Docs autenticato tramite la funzione build().
Una volta configurato, puoi riutilizzare lo stesso token.json per l’autenticazione o aggiornare automaticamente il token. Per reimpostare l’accesso, elimina token.json ed esegui di nuovo l’app.
Passo 7: utility di append e renderer Markdown
Ora trasformiamo un RecapDoc tipizzato in Markdown pulito da aggiungere al Google Doc di destinazione. Una funzione renderizza il riepilogo, mentre l’altra esegue la scrittura autenticata alla fine del documento.
defappend_plaintext_to_doc(docs_service, document_id:str, text:str):
doc = docs_service.documents().get(documentId=document_id).execute()
end_index = doc.get("body",{}).get("content",[])[-1]["endIndex"]
requests =[{"insertText":{"location":{"index": end_index -1},"text": text +"\n"}}]return docs_service.documents().batchUpdate(
documentId=document_id,
body={"requests": requests}).execute()defrecap_to_markdown(recap: RecapDoc)->str:
lines =[f"# {recap.title} — {recap.date}","",f"**Attendees:** {', '.join(recap.attendees)if recap.attendees else'Unknown'}","","## Summary",
recap.summary.strip(),"","## Decisions",]if recap.decisions:for d in recap.decisions:
lines.append(f"- {d}")else:
lines.append("- None recorded")
lines.append("")
lines.append("## Action Items")if recap.action_items:for ai in recap.action_items:
lines.append(f"- **{ai.owner}** — {ai.task} _(Due: {ai.due_date})_")else:
lines.append("- None recorded")return"\n".join(lines)Offerto da
Le due helper sopra lavorano insieme come segue:
La funzione recap_to_markdown() costruisce un riassunto leggibile. Include un titolo con data, partecipanti, una sintesi concisa ed elementi d’azione con owner, task e scadenza. Passa a “Unknown” o “None recorded” quando mancano campi.
La funzione append_plaintext_to_doc() recupera il documento, trova l’indice finale corrente e invia una singola richiesta insertText tramite documents(). Il testo è aggiunto con un newline finale così le voci successive iniziano su una nuova riga.
Nota: per documenti vuoti, valuta di impostare l’indice di inserimento a 1 se endIndex non è disponibile.
Con il rendering Markdown e l’append a posto, impostiamo il generatore di riepiloghi.
Passo 8: generatore del riepilogo
Questa funzione è il cuore dell’app. Prende appunti grezzi e metadati opzionali, chiama un modello di chat e restituisce un RecapDoc tipizzato così tutto a valle resta prevedibile.
defgenerate_recap(model_name:str, notes:str, title:str, date_str:str, attendees_csv:str)-> RecapDoc:
model = init_chat_model(model=model_name)
structured_llm = model.with_structured_output(RecapDoc)
attendees_hint =[a.strip()for a in attendees_csv.split(",")]if attendees_csv.strip()else[]
user_prompt =("You will receive meeting notes and metadata.\n\n"f"Title: {title or'Unknown'}\n"f"Date: {date_str or'Unknown'}\n"f"Attendees: {attendees_hint if attendees_hint else'Unknown'}\n\n""Notes:\n"f"{notes.strip()}\n")
messages =[
SystemMessage(content=SYSTEM_PROMPT),
HumanMessage(content=user_prompt)]try:
recap = structured_llm.invoke(messages)except Exception as e:
st.error(f"Error generating recap: {e}")
recap = RecapDoc(
title=title or"Unknown",
date=date_str or"Unknown",
attendees=attendees_hint or[],
summary=f"Error generating summary: {str(e)}",
decisions=[],
action_items=[])return recapOfferto da
Il generatore del riepilogo include tre componenti chiave:
Inizializzazione del modello: la funzione init_chat_model() crea un modello di chat per il provider scelto. Poi chiamiamo with_structured_output() per dire al modello esattamente la forma dell’output. Restituisce un oggetto Python che corrisponde ai campi di RecapDoc.
Assemblaggio del prompt: normalizziamo gli input e inviamo due messaggi, incluso un SystemMessage con regole rigide (il system prompt) e un HumanMessage con titolo, data, partecipanti e appunti grezzi.
Generazione strutturata: la funzione structured_llm.invoke() restituisce un RecapDoc validato, evitando il parsing e riducendo le allucinazioni.
Instradando il tuo modello GPT tramite il wrapper di output strutturato di LangChain, il passo del riepilogo diventa affidabile e pronto per il rendering Markdown senza cambiare la logica a valle.
Passo 9: UI Streamlit
Questo passo collega l’intera demo in un’app Streamlit a pagina singola. L’utente incolla gli appunti, aggiunge metadati opzionali, genera un riepilogo strutturato, lo visualizza in anteprima come Markdown e lo aggiunge a un Google Doc con un clic.
defmain():
load_dotenv()
st.set_page_config(page_title="Meeting Recap Assistant (LangChain v1)", page_icon=" ", layout="wide")
st.markdown("<h1 style='text-align: center;'>Meeting Recap Assistant With LangChain v1</h1>", unsafe_allow_html=True)
model_name = os.getenv("LC_MODEL","gpt-4o-mini")
document_id ="10G1k8-2JG_phkpjWM3xZEy2wNg5trUO0SJ2WN7kR3po"
cred_mode ="credentials.json file"
credentials_path = os.getenv("GOOGLE_CREDENTIALS_JSON","credentials.json")
st.subheader(" Add your meeting notes")
colL, colR = st.columns([2,1])with colL:
notes = st.text_area(" ", height=300, placeholder="Paste your raw notes here...")with colR:
title = st.text_input("Meeting Title", value="")
date_str = st.date_input("Meeting Date", value=date.today())
attendees_csv = st.text_input("Attendees (comma-separated)", value="")if"recap"notin st.session_state:
st.session_state.recap =Noneif"markdown_text"notin st.session_state:
st.session_state.markdown_text =None
col1, col2, col3 = st.columns([1,1,2])with col1:
generate_btn = st.button("Generate Recap")with col2:
append_btn = st.button("Append to Google Doc", disabled=(st.session_state.recap isNone))if generate_btn:ifnot notes.strip():
st.error("Please paste some notes.")
st.stop()try:
recap = generate_recap(
model_name=model_name,
notes=notes,
title=title,
date_str=str(date_str),
attendees_csv=attendees_csv,)
st.session_state.recap = recap
st.session_state.markdown_text = recap_to_markdown(recap)
st.rerun()except Exception as e:
st.exception(e)
st.stop()if append_btn and st.session_state.recap isnotNone:try:
use_secrets =(cred_mode =="Streamlit secrets")
service = get_google_docs_service(
credentials_path=credentials_path if cred_mode =="credentials.json file"elseNone,
use_secrets=use_secrets
)
final_text =f"\n\n===== {st.session_state.recap.title} — {st.session_state.recap.date} =====\n\n"+ st.session_state.markdown_text
append_plaintext_to_doc(service, document_id, final_text)
st.success("Recap appended to the Google Doc")except Exception as e:
st.exception(e)if st.session_state.recap isnotNone:
st.markdown("---")
st.markdown(st.session_state.markdown_text)if __name__ =="__main__":
main()Offerto da
L’app Streamlit collega un’unica azione “Generate Recap” al modello ed espone il tutto a una UI web locale, usando:
Input (colonne sinistra/destra): il riquadro a sinistra è un ampio st.text_area per gli appunti grezzi. Quello a destra raccoglie titolo, data e partecipanti.
Output (area di anteprima): quando esiste un riepilogo, l’app mostra un divisore e un’anteprima Markdown del riepilogo strutturato per una revisione rapida.
Collegamento dell’interfaccia (azioni): queste azioni costituiscono il cuore dell’app. Includono:
Generate recap: valida gli appunti, chiama la funzione generate_recap(), converte in Markdown e usa st.rerun() per aggiornare.
Append to Google Doc: crea un client autenticato con get_google_docs_service(), aggiunge un’intestazione datata e inserisce nel documento di destinazione.
Stato: st.session_state archivia l’ultimo RecapDoc e markdown_text così la UI resta stabile tra le riesecuzioni.
Impostazione dell’app: infine, load_dotenv() legge le variabili d’ambiente mentre st.set_page_config() imposta il layout e i percorsi delle credenziali provengono dall’ambiente o da valori predefiniti.
Salva come app.py ed esegui il seguente comando nel terminale.
Ora hai uno strumento end-to-end per i riepiloghi delle riunioni che appare così:
Considerazioni su migrazione e adozione
LangChain v1 semplifica la creazione di agenti con import più semplici e risultati più affidabili grazie a output strutturati e content block standard. Se provieni dalla v0, gestisci l’upgrade come qualsiasi modifica in produzione con versioni bloccate, refactor degli import e nuove primitive.
Alcune considerazioni da tenere a mente:
LangChain v1 usa create_agent invece dei vecchi agenti predefiniti, facendo leva su content block standard e output strutturato; nota che alcune parti più vecchie sono passate a langchain-classic.
Quando aggiorni, blocca langchain>=1.0 e usa Python 3.10+. Preferisci modelli Pydantic per gli output, aggiungi middleware solo dove serve (approvazioni, redazione PII, riassunti) e mantieni langchain-classic se ti servono ancora retriever legacy.
Infine, invia prima un input piccolo e osserva tracce ed errori mantenendo le dipendenze bloccate.
Casi d’uso aggiuntivi per LangChain v1 e sfide
LangChain v1 offre primitive più pulite per app reali, output strutturati affidabili, content block standard tra provider e un modo unificato per costruire agenti. Di seguito, modi pratici per sfruttarlo, insieme ad alcune difficoltà che potresti incontrare in fase di adozione.
Casi d’uso ad alto impatto
Alcuni casi d’uso ad alto impatto di questa versione includono:
Report automatizzati: generare riepiloghi settimanali di progetto come sezioni strutturate, farli passare da un’approvazione rapida umana, quindi pubblicarli su Google Docs o Sheets.
Riepiloghi per il supporto clienti: condensare lunghe discussioni dei ticket in brief chiari con le prossime azioni, registrando le chiamate agli strumenti in modo verificabile.
Assistenti alla ricerca: raccogliere fonti, estrarre citazioni e produrre una griglia di letteratura tipizzata includendo un passaggio di approvazione umana per sicurezza.
Sfide
Con casi d’uso ad alto impatto arrivano alcune sfide:
La migrazione crea attrito: i percorsi di import aggiornati e l’abbandono di pattern ad hoc richiedono spesso refactor del codice, generando attriti.
Le dipendenze devono essere allineate: bisogna assicurarsi che gli SDK dei provider corrispondano alle aspettative della v1 per evitare incompatibilità a runtime.
Sicurezza degli strumenti: infine, le azioni automatizzate dovrebbero essere coperte da test, guardrail e checkpoint con l’uomo nel loop.
Guardando avanti, possiamo aspettarci persistenza, time-travel e osservabilità continuative (tramite LangGraph e LangSmith), insieme a un supporto più ampio dei provider per content block standard e controlli più chiari per i team di produzione.
Conclusione
LangChain v1 è una base solida per costruire agenti affidabili e manutenibili. Questo Auto Meeting Recap Assistant mostra come create_agent, content block standard e output strutturato si combinino per gestire un flusso reale con approvazione umana nel loop e un passaggio senza attriti a Google Docs. Usa le guide ufficiali di migrazione per modernizzare il codice legacy e inizia in piccolo con un’app tutorial come questa per prendere confidenza.
Sono una Google Developers Expert in ML (Gen AI), una Kaggle 3x Expert e una Women Techmakers Ambassador con oltre 3 anni di esperienza nel tech. Ho co-fondato una startup health-tech nel 2020 e sto conseguendo un master in informatica al Georgia Tech, con specializzazione in machine learning.
Scopri i 15 migliori server MCP remoti che stanno trasformando lo sviluppo AI nel 2026. Scopri come migliorano automazione, ragionamento, sicurezza e velocità dei workflow.
LangChain è un framework open-source per creare applicazioni IA agentiche che combinano LLM e strumenti. La versione 1.0 segna il passaggio a un core di livello production con un’API semplificata, confini più chiari e una gestione standardizzata dei messaggi tra provider.
In questo tutorial costruiremo uno Streamlit Auto Meeting Recap Assistant che prende appunti grezzi, produce un riepilogo conciso con elementi d’azione e, dopo l’approvazione umana, aggiunge il riepilogo a un Google Doc. Lungo il percorso vedrai in azione il nuovo flusso
create_agent, i content block standard e il namespace più snello della v1.Che cos’è LangChain v1?
LangChain v1 è una release ristrutturata e orientata alla produzione, focalizzata su una superficie piccola e stabile per costruire agenti. Introduce:
create_agentcome modo standard per avviare agenti (più pulito rispetto ai vecchi agenti predefiniti).Contenuti standardizzati tramite
content_blockscosì i messaggi sono coerenti tra provider.Output strutturato e middleware per risposte tipizzate e azioni sicure, approvate dall’uomo.
Il pacchetto langchain si concentra sui mattoni per costruire agenti, mentre i moduli legacy si spostano su langchain-classic, facilitando reperibilità e upgrade.
Rispetto alla v0.x, la v1 riduce il carico cognitivo e le particolarità dei provider standardizzando contenuto dei messaggi e orchestrazione degli agenti. Ottieni lo stesso modello mentale sia che usi OpenAI, Anthropic o altri.
Principali miglioramenti tecnici in LangChain v1
La versione originale LangChain v0.x offriva molti pattern per costruire agenti, tuttavia la v1 li consolida in un percorso chiaro usando il blocco
create_agentcosì i tuoi agenti sono più facili da comprendere, testare e distribuire. Offre strumenti più puliti, debug più semplice tramite contenuto standardizzato e un loop dell’agente prevedibile.Ecco alcuni miglioramenti tecnici chiave inclusi in questa release:
Workflow
create_agent: questo loop d’agente pronto per la produzione consente al modello di decidere quando chiamare strumenti e quando terminare. Non dobbiamo più destreggiarci tra più pattern, il che semplifica la personalizzazione.Content block standard: un modo agnostico rispetto al provider per leggere i messaggi con tracce di ragionamento, chiamate a tool, citazioni e persino elementi multimodali, tutto tramite un’API unificata
content_blocks. Strumentazione e log appaiono uguali tra provider.Output strutturato: l’ultima release include un supporto di prima classe per schemi tipizzati, così puoi fare affidamento su JSON prevedibile senza regex fragili. Questo riduce errori di parsing e chiamate extra.
Middleware: si agganciano al loop dell’agente per approvare azioni rischiose, riassumere la cronologia quando è lunga e redigere PII prima delle chiamate.
Namespace semplificato: il pacchetto
langchainora si concentra sui componenti essenziali per gli agenti, mentre LangGraph fornisce sotto il cofano funzionalità di affidabilità come persistenza e time-travel.Demo: creare un Auto Meeting Recap Assistant con LangChain v1
In questa sezione implementeremo un’app Streamlit che automatizza i riepiloghi delle riunioni end-to-end. L’app accetta appunti grezzi della riunione con metadati opzionali (titolo, data e partecipanti). Genera quindi un
RecapDoctipizzato, includendo titolo, sintesi, decisioni ed elementi d’azione, in un output strutturato. Con un clic, il riepilogo approvato (preceduto dalla data della riunione) viene aggiunto a un Google Doc designato.Passo 1: Prerequisiti
Prima di costruire l’Auto Meeting Recap Assistant, ci serve un toolkit minimo per la UI, l’LLM, la validazione tipizzata e l’accesso a Google Docs. I comandi seguenti installano tutto il necessario e impostano la chiave del modello in modo che la tua app possa comunicare con il provider.
Ecco a cosa servono i prerequisiti:
Streamlit: esegue l’app web in locale con una UI semplice e pythonica.langchainelangchain-openai: forniscono la superficie semplificata di LangChain v1 (init_chat_model, output strutturato) e il bridge al provider OpenAI.pydantic: definisce lo schema rigorosoRecapDoccosì il modello restituisce campi tipizzati.Python-dotenv: carica le variabili d’ambiente da un file.envdurante lo sviluppo.google-auth: gestisce OAuth e la Google Docs API così possiamo aggiungere il riepilogo a un documento.OPENAI_API_KEY: la chiave API di OpenAI autentica le chiamate al LLM; impostala come variabile d’ambiente (o usa un secrets manager).Nota: se usi un altro provider (Anthropic, Google o un modello locale), installa l’integrazione
langchain-*corrispondente e imposta la chiave API di quel provider.Con queste dipendenze installate e
OPENAI_API_KEYimpostata, l’ambiente è pronto. Nei prossimi passi configureremo la Google Docs API tramite Google Cloud.Passo 2: Abilita la Google Docs API
Per salvare ogni riepilogo in un documento vivo, l’app ha bisogno del permesso di scrivere su Google Docs. Questo passo configura l’accesso end-to-end. Per prima cosa:
Ottieni un file OAuth client (
credentials.json) da Google CloudIdentifica l’ID del Google Doc a cui vuoi aggiungere contenuti
Infine, lascia che l’app crei un
token.jsonriutilizzabile al primo avvio dopo che approvi l’accesso nel browser.Una volta predisposti questi tre elementi, l’app può aggiungere i riepiloghi al Google Doc scelto con un clic. Puoi revocare o rinnovare l’accesso in qualsiasi momento eliminando
token.jsoned eseguendo di nuovo l’app.Passo 2.1: Ottieni credentials.json da Google Cloud
Il file
credentials.jsonè la chiave della tua app per la Google Docs API. Lo generi una volta nella Google Cloud Console come OAuth client per Desktop App. Per iniziare:Crea/seleziona un progetto
Abilita la Google Docs API
Ora che il progetto è stato creato, abilitiamo l’API necessaria per scrivere in Google Docs.
Configura la schermata di consenso OAuth
Una volta abilitata l’API, dobbiamo impostare l’autenticazione per la nostra email preferita.
Crea le credenziali OAuth client
Il passo finale è generare e scaricare il file credentials.json. Per farlo:
Vai su APIs & Services e clicca su Credentials.
Clicca su
+ CREATE CREDENTIALS, verrai indirizzato a OAuth client ID.Possono essere necessari fino a 5 minuti per generare client ID e secret, insieme a un file JSON scaricabile.
Salva il file JSON come
credentials.jsonnella stessa cartella del tuoapp.py(oppure indica il suo percorso nelle impostazioni dell’app).Ora disponi di un OAuth client Desktop che l’app può usare per avviare l’accesso tramite browser e richiedere il permesso di accedere a Google Docs per tuo conto.
Passo 2.2: Google Doc ID
L’app deve sapere a quale documento aggiungere contenuti. Il documento è identificato da un ID univoco incorporato nell’URL. Per questo passo,
Apri il Google Doc di destinazione in un browser.
Copia la stringa nell’URL tra
/d/e/edit, per esempio:https://docs.google.com/document/d/<THIS_IS_THE_ID>/editIncolla questo Doc ID nel campo “Google Doc ID” dell’app (o nella variabile di configurazione appropriata).
Con l’ID corretto, l’app scriverà i riepiloghi esattamente nel documento selezionato.
Passo 2.3: Token.json
Al primo inserimento, l’app ha bisogno della tua approvazione esplicita per accedere al documento. Dopo l’approvazione, Google restituisce un token che l’app archivia in locale come
token.json. Ecco come viene generato questo file:Esegui l’app e clicca Append to Google Doc.
Si apre una finestra del browser che ti chiede di accedere con uno degli utenti di test aggiunti in precedenza e di approvare l’ambito.
Dopo la conferma, l’app scrive
token.jsonaccanto al tuo codice. Questo file contiene token di accesso/refresh riutilizzabili.Nota: se devi cambiare account o ripetere il consenso, elimina semplicemente
token.jsone clicca di nuovo Append to Google Doc.Passo 3: Import
Prima di scrivere la logica, importiamo i moduli che alimentano la UI, i contratti di dati tipizzati, le chiamate al modello e l’integrazione con Google Docs. Raggruppare gli import per scopo mantiene il codice leggibile e rende ovvio quale livello verificare quando qualcosa non funziona.
Per questo passo importiamo solo ciò che serve all’app, ossia utility standard come os, io, json, date e hint di typing per percorsi, buffer e serializzazione leggera. Poi importiamo Streamlit per la UI, Pydantic per gli schemi tipizzati
RecapDoc, edotenvper caricare le variabili d’ambiente. La superficie di LangChain v1init_chat_modelecreate_agentper inizializzare un modello di chat agnostico rispetto al provider e strutturare i prompt e, infine, i componenti della Google Docs API che gestiscono OAuth e ci danno un client autenticato per aggiungere riepiloghi al documento scelto.Passo 4: Definisci l’output strutturato
Per rendere la risposta del modello affidabile e facile da usare, definiamo un contratto tipizzato per il riepilogo. Usare modelli Pydantic assicura che l’LLM restituisca campi prevedibili che la nostra UI può renderizzare, l’API può archiviare e le automazioni possono validare.
Ecco i componenti chiave del blocco di codice precedente:
Classe
ActionItem: cattura l’essenziale di un’attività di follow-up comeowner,taskedue_datecon descrizioni brevi ed esplicite così il modello le compila pulitamente. Consentire date ISO o frasi naturali mantiene l’input flessibile pur restando analizzabile a valle.Classe
RecapDoc: rappresenta l’intero riepilogo come un singolo oggetto, inclusititle,date,attendees, unsummaryconciso,decisionsesplicite e un elenco diaction_items.Con LangChain v1, puoi richiedere direttamente questo schema tramite
with_structured_output(RecapDoc), riducendo il parsing fragile delle stringhe, migliorando la validazione e consentendo di fallire rapidamente quando mancano campi.Passo 5: System prompt
Il system prompt stabilisce le regole di base per il tuo assistente. Dice al modello esattamente cosa produrre, cosa evitare e come strutturare l’output affinché i passaggi successivi funzionino in modo affidabile ogni volta.
Il system prompt rende l’assistente preciso e conciso, puntando a riepiloghi ad alto valore informativo invece che trascrizioni. Stampa uno schema netto che include titolo, data, partecipanti, sintesi, decisioni, action_items con regole come sintesi di 3–6 frasi, decisioni puntate ed elementi d’azione con owner, task e scadenza.
Con un system prompt chiaro, il modello produce costantemente riepiloghi strutturati e utilizzabili al primo tentativo.
Passo 6: helper per Google OAuth
In questo passo definiamo una funzione helper che stabilisce una connessione affidabile e riutilizzabile a Google Docs così l’app può aggiungere i riepiloghi al documento scelto. Richiede solo l’ambito Docs e gestisce il consenso iniziale, il refresh del token e la costruzione del servizio.
La funzione
get_google_docs_service()gestisce OAuth e la creazione del servizio:Definizione dell’ambito: la funzione usa
SCOPESpredefiniti per limitare i permessi a Google Docs.Caricamento credenziali: legge da un
credentials.jsonlocale o dast.secrets["google_credentials_json"], il contenitore dei segreti di Streamlit quandouse_secrets=True.Riutilizzo dei token: se esiste
token.json, il codice lo carica e, se il token è scaduto, lo aggiorna in silenzio.Consenso iniziale: se non si trova un token valido, si avvia l’
InstalledAppFlowDesktop, che chiede all’utente di autenticarsi nel browser e poi salvatoken.jsonper esecuzioni future.Restituzione del client: infine, costruiamo e restituiamo un client Docs autenticato tramite la funzione
build().Una volta configurato, puoi riutilizzare lo stesso
token.jsonper l’autenticazione o aggiornare automaticamente il token. Per reimpostare l’accesso, eliminatoken.jsoned esegui di nuovo l’app.Passo 7: utility di append e renderer Markdown
Ora trasformiamo un
RecapDoctipizzato in Markdown pulito da aggiungere al Google Doc di destinazione. Una funzione renderizza il riepilogo, mentre l’altra esegue la scrittura autenticata alla fine del documento.Le due helper sopra lavorano insieme come segue:
La funzione
recap_to_markdown()costruisce un riassunto leggibile. Include un titolo con data, partecipanti, una sintesi concisa ed elementi d’azione con owner, task e scadenza. Passa a “Unknown” o “None recorded” quando mancano campi.La funzione
append_plaintext_to_doc()recupera il documento, trova l’indice finale corrente e invia una singola richiestainsertTexttramitedocuments(). Il testo è aggiunto con un newline finale così le voci successive iniziano su una nuova riga.Nota: per documenti vuoti, valuta di impostare l’indice di inserimento a 1 se
endIndexnon è disponibile.Con il rendering Markdown e l’append a posto, impostiamo il generatore di riepiloghi.
Passo 8: generatore del riepilogo
Questa funzione è il cuore dell’app. Prende appunti grezzi e metadati opzionali, chiama un modello di chat e restituisce un
RecapDoctipizzato così tutto a valle resta prevedibile.Il generatore del riepilogo include tre componenti chiave:
Inizializzazione del modello: la funzione
init_chat_model()crea un modello di chat per il provider scelto. Poi chiamiamowith_structured_output()per dire al modello esattamente la forma dell’output. Restituisce un oggetto Python che corrisponde ai campi diRecapDoc.Assemblaggio del prompt: normalizziamo gli input e inviamo due messaggi, incluso un
SystemMessagecon regole rigide (il system prompt) e unHumanMessagecon titolo, data, partecipanti e appunti grezzi.Generazione strutturata: la funzione
structured_llm.invoke()restituisce unRecapDocvalidato, evitando il parsing e riducendo le allucinazioni.Instradando il tuo modello GPT tramite il wrapper di output strutturato di LangChain, il passo del riepilogo diventa affidabile e pronto per il rendering Markdown senza cambiare la logica a valle.
Passo 9: UI Streamlit
Questo passo collega l’intera demo in un’app Streamlit a pagina singola. L’utente incolla gli appunti, aggiunge metadati opzionali, genera un riepilogo strutturato, lo visualizza in anteprima come Markdown e lo aggiunge a un Google Doc con un clic.
L’app Streamlit collega un’unica azione “Generate Recap” al modello ed espone il tutto a una UI web locale, usando:
Input (colonne sinistra/destra): il riquadro a sinistra è un ampio
st.text_areaper gli appunti grezzi. Quello a destra raccoglie titolo, data e partecipanti.Output (area di anteprima): quando esiste un riepilogo, l’app mostra un divisore e un’anteprima Markdown del riepilogo strutturato per una revisione rapida.
Collegamento dell’interfaccia (azioni): queste azioni costituiscono il cuore dell’app. Includono:
Generate recap: valida gli appunti, chiama la funzione generate_recap(), converte in Markdown e usa
st.rerun()per aggiornare.Append to Google Doc: crea un client autenticato con
get_google_docs_service(), aggiunge un’intestazione datata e inserisce nel documento di destinazione.Stato:
st.session_statearchivia l’ultimoRecapDocemarkdown_textcosì la UI resta stabile tra le riesecuzioni.Impostazione dell’app: infine,
load_dotenv()legge le variabili d’ambiente mentrest.set_page_config()imposta il layout e i percorsi delle credenziali provengono dall’ambiente o da valori predefiniti.Salva come
app.pyed esegui il seguente comando nel terminale.Ora hai uno strumento end-to-end per i riepiloghi delle riunioni che appare così: