Module 4 of 12
LangChain Expression Language (LCEL)
Current Study Module
LangChain - Prompts & Structured Outputs
Document Loaders & Text Splitters
Module 03 • Prompt Engineering & Validation

Prompts & Structured Outputs

In enterprise systems, natural language outputs can be unpredictable. Applications need guaranteed, type-safe data structures—such as JSON, Pydantic objects, or database records. Learn how to design parameterized prompt templates and enforce strict structured outputs usingwith_structured_output.

1. Advanced Prompt Templates

Modern chat models expect an array of structured messages differentiated by roles:system (persona and behavioral boundaries), human (user question), and ai (model history or few-shot demonstration):

from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder

# Multi-role prompt template with placeholder for dynamic history
chat_prompt = ChatPromptTemplate.from_messages([
    ("system", "You are an automated triage bot for a financial API. Categorize severity."),
    MessagesPlaceholder(variable_name="chat_history", optional=True),
    ("human", "User Issue Report: {error_log}")
])

2. Guaranteed Type-Safe Extraction with Pydantic

Using OpenAI and Anthropic native function-calling APIs under the hood,model.with_structured_output() forces the model to adhere strictly to your data model schema. If the model attempts to generate conversational filler, the API enforces strict JSON schema conformance:

from typing import List, Optional
from pydantic import BaseModel, Field
from langchain_openai import ChatOpenAI

# 1. Define schema using Pydantic v2
class IncidentReport(BaseModel):
    service_name: str = Field(description="The microservice affected (e.g. auth-service, payment-gateway)")
    severity: str = Field(description="Severity level: LOW, MEDIUM, HIGH, CRITICAL")
    error_code: Optional[int] = Field(default=None, description="HTTP or internal error code")
    root_cause_hypothesis: str = Field(description="Probable architectural root cause")
    action_items: List[str] = Field(description="Recommended immediate mitigation steps")

# 2. Bind schema to LLM
llm = ChatOpenAI(model="gpt-4o", temperature=0)
structured_llm = llm.with_structured_output(IncidentReport)

# 3. Execute
raw_log = """
[CRITICAL] 2026-10-15 14:22:01 payment-gateway: Connection pool exhausted. 
PostgreSQL returned code 53300 (too many connections). Checkout service failing 98% of credit card transactions.
"""

result: IncidentReport = structured_llm.invoke(f"Extract incident report from log: {raw_log}")

print("Service:", result.service_name)
print("Severity:", result.severity)
print("Root Cause:", result.root_cause_hypothesis)
print("Action Items:", result.action_items)

3. Structured Outputs in TypeScript with Zod

In TypeScript environments (Node.js, Next.js), LangChain integrates natively with Zod:

import { z } from "zod";
import { ChatOpenAI } from "@langchain/openai";

// Define schema with Zod
const UserProfileSchema = z.object({
  fullName: z.string().describe("User's full legal name"),
  email: z.string().email().describe("Primary contact email"),
  roles: z.array(z.string()).describe("Security roles assigned to user"),
  riskScore: z.number().min(0).max(100).describe("Automated risk assessment score")
});

const model = new ChatOpenAI({ model: "gpt-4o-mini", temperature: 0 });
const structuredModel = model.withStructuredOutput(UserProfileSchema);

const userRecord = await structuredModel.invoke(
  "Extract user: Alice Kumar, senior devops lead, email: alice@example.corp. Clean account history."
);

console.log(userRecord.fullName, userRecord.riskScore);

Explore Related Tools

Hand-picked utilities and calculators related to this tool.

Related Tools