第 19 期 | 结构化数据输出:用 Pydantic 约束 LLM (EN)

⏱ Est. reading time: 20 min Updated on 5/7/2026

🎯 Learning Objectives

Hey there, future AI masters! Welcome back to our LangChain Full-Stack Masterclass. In the last session, we discussed basic LLM calls and the art of Prompt Engineering. You probably feel pretty comfortable "chatting" with AI now, right? But stopping at single-turn conversations is like having a Swiss Army knife and only using it to peel apples. Our goal is to build an Intelligent Support Copilot. It needs to do much more than just peel apples—it must handle complex, multi-step user requests.

So, in this session, we will dive deep into one of LangChain's core concepts: Chains. This is the key to evolving your AI application from a "single-celled organism" into a "multi-organ system"!

By the end of this session, you will:

  1. Thoroughly understand the core concept of Chains in LangChain and their irreplaceable role in complex tasks. Say goodbye to single LLM calls and step into multi-step intelligent orchestration.
  2. Master the use cases and construction methods of different chains (especially LLMChain and SequentialChain). Know exactly when to use which "chain" to solve specific problems in your support copilot.
  3. Learn to build multi-step processing logic in our Support Copilot, significantly improving its ability to understand and resolve complex issues. For example, how to make it first understand the problem, then look up information, and finally provide a solution.
  4. Learn how to efficiently connect different LangChain components (LLMs, Prompts, Parsers, etc.) to achieve production-grade complex task automation. Make your support copilot truly come alive!

Ready? Let's enter the world of Chains and unleash the true power of LangChain!

📖 Concept Breakdown

Chains: The "Backbone" of LLM Applications

Imagine you are building an intelligent customer support bot. A user asks: "My order number is #XYZ123, why hasn't it shipped yet?"

A simple LLM call might try to answer directly, but it doesn't know what "order #XYZ123" is, nor does it have the permissions to look it up. It might just say: "I cannot check specific order information, please contact human support." This is obviously not the "intelligent" support we want.

To solve this problem, we need to:

  1. Extract Intent and Key Information: The user wants to check their order status, and the order ID is #XYZ123.
  2. Execute External Actions: Call our internal order query API, passing in the order ID.
  3. Process API Results: Parse the shipping status, estimated time of arrival (ETA), etc., returned by the API.
  4. Generate a Friendly Response: Format the queried information into language the user can easily understand.

This series of steps requires an organized workflow to coordinate. In LangChain, this "organized workflow" is a Chain.

The core idea of a Chain is to combine multiple LLM calls or other tools (like data queries, API calls, code execution) into an ordered, multi-step logical flow to complete more complex tasks. It's like an assembly line: each station is responsible for specific processing, and the output of the previous station becomes the input for the next.

Why Do We Need Chains?

  • Overcome LLM Limitations: LLMs are inherently stateless; they process one request at a time. Chains give LLM applications "memory" and the ability to perform "multi-step reasoning."
  • Task Decomposition and Orchestration: Break down a massive, complex task into a series of smaller tasks, where each small task is handled by a chain or a component within a chain.
  • Integrate External Capabilities: Make the LLM more than just a "chatbot." Allow it to seamlessly integrate with your business systems, databases, and APIs to fetch real-time data and execute actual operations.
  • Improve Maintainability and Scalability: Modular design makes it easy to modify, debug, and expand functionalities.

Types and Structures of Chains

LangChain provides a variety of built-in chains, but the two most fundamental and commonly used are:

  1. LLMChain: This is the cornerstone of all chains. It combines a PromptTemplate and a BaseLLM (or BaseChatModel). Its job is simply to take the template and inputs, send a request to the LLM, and get the output. You can think of it as "a templated LLM call."

    • Input: Data required for the template variables.
    • Output: Text generated by the LLM.
  2. SequentialChain (and its simplified version SimpleSequentialChain): This is the key to linking multiple chains together.

    • SimpleSequentialChain: The simplest way to link chains. The complete output of the previous chain serves as the complete input for the next chain. Suitable for linear, branchless, simple workflows.
    • SequentialChain: More powerful and flexible. It allows you to define the input and output variables for each chain, supports multiple inputs and outputs, and can pass intermediate results to specific subsequent chains. This is crucial for complex flow control.

Chain Workflows in the Intelligent Support Copilot

Imagine our Intelligent Support Copilot. When a user asks a complex question, it might go through the following chained processing:

graph TD
    A[User Query: "Why hasn't my order #12345 shipped yet?"] --> B(Intent Recognition & Info Extraction)
    B --> C{LLMChain: Extract Order ID & Intent}
    C -- Extracted: ID="12345", Intent="Check Shipping" --> D(Business Data Query)
    D --> E{Tool/Function: Call Order API}
    E -- Returned: Status="Shipped", Courier="SF Express", ETA="Tomorrow" --> F(Result Analysis & Response Generation)
    F --> G{LLMChain: Summarize & Generate Friendly Response}
    G -- Response: "Your order #12345 shipped today via SF Express and is expected to arrive tomorrow." --> H[Reply to User]

    subgraph "LangChain Chain Processing"
        C
        E
        G
    end

Diagram: Chain Processing Workflow of the Intelligent Support Copilot

In this diagram, we see how a complex request is broken down into multiple steps and collaboratively completed by different components (including LLMChain and Tool/Function, which we will learn about later). In this session, we will focus primarily on using LLMChain and SequentialChain to orchestrate pure text processing logic.

For example, a basic text processing chain could be:

  1. LLMChain (Issue Classifier): Inputs the user query, outputs the issue category (e.g., "Returns", "Tech Support", "Order Inquiry").
  2. LLMChain (Information Extractor): Inputs the user query and issue category, outputs key entities (e.g., order ID, product name, fault description).
  3. LLMChain (Draft Response Generator): Inputs the issue category and extracted info, generates a preliminary response draft.

These LLMChains can be linked together using a SequentialChain to achieve a much smarter customer service interaction.

💻 Practical Code Drill

Alright, enough theory, let's roll up our sleeves! Now, let's build an actual chained processing logic for our "Intelligent Support Copilot."

Scenario Setup: Our copilot needs to handle user inquiries regarding product faults. It must not only identify the product and the type of fault but also provide preliminary, personalized troubleshooting suggestions or guidance based on that information.

Core Challenge: This requires two or more steps of LLM reasoning:

  1. Understand user intent and extract key info: What product did the user say is broken? What kind of fault is it?
  2. Generate suggestions based on the info: Provide appropriate next steps tailored to the specific product and fault.

We will use SequentialChain to elegantly solve this problem.

Preparation (Python)

First, ensure you have installed the necessary libraries:

pip install langchain openai python-dotenv

Then, set up your OpenAI API Key. We usually manage sensitive information via environment variables:

# Example .env file content
# OPENAI_API_KEY="sk-your_openai_api_key_here"
import os
from dotenv import load_dotenv

load_dotenv() # Load environment variables from the .env file

from langchain_openai import ChatOpenAI
from langchain.prompts import PromptTemplate
from langchain.chains import LLMChain, SequentialChain

# Initialize a chat model instance
# temperature controls model creativity, 0 means more deterministic
llm = ChatOpenAI(temperature=0.7, model="gpt-4o") # Recommended to use powerful models like gpt-4o or gpt-3.5-turbo

Step 1: Build the First Chain - Issue Classification and Info Extraction

This chain is responsible for identifying the product and fault type from the user's input.

# 1. Define the first Prompt Template: Issue Classification and Information Extraction
# input_variables: Original user query (customer_query)
# output_variables: Extracted product name (product_name) and issue type (issue_type)
prompt_template_1 = PromptTemplate(
    input_variables=["customer_query"],
    template="""You are a professional customer support assistant. Please carefully read the following user query and try to extract the product name and issue type mentioned by the user. If uncertain, indicate 'Unknown'.
    Please return the result in JSON format, for example: {{"product": "Product Name", "issue_type": "Issue Type"}}

    User Query: {customer_query}
    """
)

# 2. Create the first LLMChain instance
# output_key: The output of this chain will be stored in a variable named "extracted_info"
chain_1 = LLMChain(
    llm=llm,
    prompt=prompt_template_1,
    output_key="extracted_info", # CRITICAL! This output_key will serve as the input for the next chain
    verbose=True # Enable verbose to see the intermediate steps of the chain
)

Step 2: Build the Second Chain - Troubleshooting Suggestion Generation

This chain will receive the product and fault information extracted by the previous chain, and then generate specific suggestions.

# 3. Define the second Prompt Template: Troubleshooting Suggestions
# input_variables: Needs to receive the output from the previous chain (product_name, issue_type)
prompt_template_2 = PromptTemplate(
    input_variables=["extracted_info"], # Note: Here it receives the content of the output_key from the previous chain
    template="""You are an experienced technical support expert. You have received information about a user's product issue:
    {extracted_info}

    Based on this information, please provide the user with preliminary troubleshooting suggestions or next-step guidance. If the product or issue type is unknown, provide general advice.
    Please keep the tone friendly and professional, and provide clear actionable steps.
    """
)

# 4. Create the second LLMChain instance
# output_key: The output of this chain will be stored in a variable named "final_suggestion"
chain_2 = LLMChain(
    llm=llm,
    prompt=prompt_template_2,
    output_key="final_suggestion",
    verbose=True
)

Step 3: Link All Chains - Using SequentialChain

Now, we will link these two LLMChains together to form a complete processing pipeline.

# 5. Create SequentialChain
# chains: A list of chains arranged in execution order
# input_variables: The initial input for the entire SequentialChain. Here it is the original user query (customer_query)
# output_variables: The final output of the entire SequentialChain. Here we want the final suggestion (final_suggestion)
overall_chain = SequentialChain(
    chains=[chain_1, chain_2],
    input_variables=["customer_query"],
    output_variables=["final_suggestion"],
    verbose=True # Enable verbose to see the execution process of the entire SequentialChain
)

# 6. Run our Intelligent Support Copilot!
customer_query_1 = "My Xiaomi robot vacuum won't charge, is the battery broken?"
response_1 = overall_chain.invoke({"customer_query": customer_query_1})
print("\n--- Customer Query 1 ---")
print(f"User: {customer_query_1}")
print(f"Copilot Suggestion:\n{response_1['final_suggestion']}")

print("\n" + "="*50 + "\n")

customer_query_2 = "My Lenovo laptop boots up to a black screen, what should I do?"
response_2 = overall_chain.invoke({"customer_query": customer_query_2})
print("\n--- Customer Query 2 ---")
print(f"User: {customer_query_2}")
print(f"Copilot Suggestion:\n{response_2['final_suggestion']}")

print("\n" + "="*50 + "\n")

customer_query_3 = "My phone screen is shattered, can it be fixed?"
response_3 = overall_chain.invoke({"customer_query": customer_query_3})
print("\n--- Customer Query 3 ---")
print(f"User: {customer_query_3}")
print(f"Copilot Suggestion:\n{response_3['final_suggestion']}")

print("\n" + "="*50 + "\n")

customer_query_4 = "I don't know what's wrong with my device."
response_4 = overall_chain.invoke({"customer_query": customer_query_4})
print("\n--- Customer Query 4 ---")
print(f"User: {customer_query_4}")
print(f"Copilot Suggestion:\n{response_4['final_suggestion']}")

Code Breakdown:

  • output_key in LLMChain: This is the key to allowing SequentialChain to pass variables correctly! The output of chain_1 is named "extracted_info", and this exact name must match the variable name expected by input_variables in prompt_template_2 of chain_2.
  • input_variables and output_variables in SequentialChain:
    • input_variables defines the initial inputs the entire SequentialChain needs to receive when it runs.
    • output_variables defines which variables the entire SequentialChain will ultimately return.
  • verbose=True: This parameter is a lifesaver for debugging chains! It prints out the inputs, outputs, and LLM call processes for each chain, helping you understand exactly how data flows through the pipeline. It is highly recommended to always keep this enabled during development and debugging.

Through this practical exercise, you've seen how to break down a complex customer service inquiry into logically clear steps, and use LangChain's chain mechanism to link them together, granting our Intelligent Support Copilot powerful "multi-step reasoning" capabilities!

坑与避坑指南 (Pitfalls & Best Practices)

While the chain mechanism is powerful, there are some "pitfalls" in real-world applications that we need to be aware of in advance to avoid stepping on landmines. As your senior mentor, I don't want you taking unnecessary detours!

  1. Input/Output Variable Mismatch (The Naming Game)

    • The Pitfall: This is the most common error with SequentialChain! The output_key of one chain must perfectly match the variable name expected by the input_variables in the PromptTemplate of the next chain. Case sensitivity or typos will cause the chain to fail with a KeyError.
    • Best Practice:
      • Standardize Naming: Adopt clear, consistent naming conventions for output_key and input_variables right from the start.
      • verbose=True is your best friend: Always enable verbose=True when debugging. It clearly prints the inputs and outputs of each chain, allowing you to see at a glance if variables are passing correctly.
      • Test Step-by-Step: If a chain is very long, test each LLMChain independently first to ensure they work correctly on their own before combining them.
  2. Over-chaining and Performance Issues (The Chain Reaction Overload)

    • The Pitfall: Theoretically, you can link chains infinitely, but every LLM call introduces latency and cost. If a task could be completed with one slightly more complex Prompt but is instead broken down into seven or eight simple LLMChains, you are wasting resources and degrading the user experience.
    • Best Practice:
      • Appropriate Task Granularity: Balance is key. Break tasks down small enough so the LLM can handle them reliably, but don't over-decompose. If one LLMChain can do the job, don't use two.
      • Parallel Thinking: Some steps don't necessarily require strict sequential order. In the future, we will learn how to execute tasks in parallel.
      • Caching Strategies: For repetitive LLM calls, consider using LangChain's caching mechanisms to reduce actual API calls.
  3. Context Loss and Incomplete Information Transfer (The Amnesia Effect)

    • The Pitfall: In a multi-step chain, if an intermediate chain fails to pass crucial information completely to subsequent chains, the LLM might "forget" important context, leading to poor response quality or logical errors. For example, if step one extracts an order ID, but step two's Prompt template doesn't include that order ID, it cannot use it.
    • Best Practice:
      • Explicit Passing: Ensure every PromptTemplate includes all the contextual information it needs.
      • Careful output_variables Design: In a SequentialChain, carefully define output_variables to ensure all variables needed by subsequent chains are correctly exported from intermediate chains.
      • Prompt Engineering: Design Prompts that summarize and retain key information, such as explicitly referencing previously extracted info in the response.
  4. Error Handling and Robustness (The Fragile Chain)

    • The Pitfall: If any LLM call within the chain fails (e.g., API rate limits, network errors, LLM returning malformed formats), the execution of the entire chain will halt. Production-grade applications must handle these exceptions gracefully.
    • Best Practice:
      • try-except Wrappers: When calling chain.invoke(), use Python's try-except blocks to catch potential exceptions.
      • Prompt Resilience: When designing Prompts, anticipate that the LLM might return unexpected formats. Prompt it to return specific error messages upon failure, or use output parsers to increase robustness.
      • Retry Mechanisms: For temporary API errors, consider implementing simple retry logic.

Remember, building AI applications is an iterative process. Experiment boldly, debug carefully, and you will master these advanced techniques!

📝 Session Summary

Congratulations, future AI architects! In this session, we deeply explored the crucial Chains mechanism in LangChain.

We theoretically understood why chains are the "backbone" for building complex LLM applications, and how they grant our Intelligent Support Copilot the ability to perform "multi-step reasoning" and "task orchestration." We focused on the foundational building block, LLMChain, and learned how to use SequentialChain to elegantly link multiple LLMChains together to complete a complex workflow—from user query classification and information extraction to final suggestion generation.

Through practical coding, you built a working prototype of a support copilot capable of handling product troubleshooting. It is no longer a simple Q&A machine, but an intelligent agent capable of multi-step reasoning based on context.

Finally, we previewed the potential "pitfalls" you might encounter during chain-based development and how to cleverly avoid them. These advanced insights will be invaluable assets on your future development journey.

By mastering Chains, you have truly stepped into the core world of LangChain. Next up, we will build upon this foundation and add even more superpowers to our Intelligent Support Copilot, such as how to make it interact with external Tools, fetch real-time data, and even autonomously decide its action paths!

Keep up the great work, and see you in the next session!