第 16 期 | 多 Agent 协作:将任务拆解为工作流 (EN)

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

Subtitle: Building Your First Intelligent Support Copilot Prototype: Connecting LLMs with Basic Prompts

Alright, future AI architects, welcome to the LangChain Full-Stack Masterclass! I'm your host—a ten-year veteran in the AI trenches and your dedicated mentor. Today, we're starting from scratch to master LangChain, the ultimate weapon in your AI toolkit.

As you've likely noticed, the tech world has been buzzing since the advent of Large Language Models (LLMs). But a powerful LLM alone isn't enough. It's like holding a top-tier sports car engine, only to realize you have no chassis, steering wheel, or brakes. LangChain is the "chassis" and "control system" that houses this engine, gets it running, and ultimately puts it on the racetrack.

Our ultimate goal is to build a production-grade Intelligent Support Copilot. Don't underestimate customer support—it's the frontline of enterprise-user communication, where efficiency and experience are paramount. Imagine equipping your support team with an AI assistant that is online 24/7, responds in milliseconds, accurately grasps user intent, and delivers personalized help. That's an absolute game-changer. Today, we'll build the simplest skeleton for this copilot, giving it a voice and a basic understanding of our questions. Ready? Let's roll!

🎯 Learning Objectives

In this lesson, you won't just be writing a few lines of code; you'll be building a foundational understanding of LangChain and the broader landscape of LLM application development. Specifically, by the end of this session, you will:

  1. Understand LangChain's core value and design philosophy: Move beyond the "API call" mindset and understand why frameworks like LangChain are essential for complex LLM apps.
  2. Master LangChain's foundational components: Deep dive into LLMs, Prompts, and Chains—the "Hello World" pillars of the LangChain ecosystem.
  3. Build your first LangChain application: Get hands-on and build a prototype of an intelligent support copilot capable of answering simple questions, experiencing the journey from idea to code.
  4. Develop a holistic view of LLM app development: Gain an initial understanding of how LangChain weaves fragmented LLM capabilities into a logical, scalable system, laying the groundwork for advanced development.

📖 Under the Hood

What is LangChain and Why Does It Exist?

First, let's clear up a common misconception: LangChain is not a large language model; it is a framework. Its core mission is to help developers build applications powered by LLMs more efficiently and flexibly. Think of it as a box of Lego bricks filled with pre-built, composable modules that allow you to rapidly construct complex structures.

Why do we need LangChain?

Sure, you can call the APIs of OpenAI, Anthropic, or other providers directly. But as soon as you start building anything slightly complex, you'll hit several roadblocks:

  • Prompt management is a hassle: Different scenarios require different prompts. How do you efficiently create, manage, and reuse them?
  • Context management is a nightmare: LLMs are stateless; they have no memory. Every interaction is isolated. How do you make the model remember previous turns in a conversation to maintain continuity?
  • Tool integration is a hard requirement: LLMs are great at text generation and comprehension, but terrible at math, querying databases, or calling external APIs. How do you make the LLM act as a "brain" that commands "limbs" to execute tasks?
  • Orchestrating complex workflows: Real-world applications are rarely a simple "Input -> LLM -> Output" pipeline. They involve multi-step reasoning, conditional logic, and parallel processing.
  • Observability and debugging: When an app grows complex, how do you trace the LLM's reasoning path to pinpoint issues?

LangChain was born to solve these exact pain points. It provides standardized interfaces and abstractions to encapsulate, chain, and extend LLM capabilities, allowing you to focus on business logic rather than low-level plumbing.

The Core Components of LangChain: LLMs, Prompts, and Chains

In the LangChain universe, there are a few core concepts you absolutely must master:

  1. LLMs (Large Language Models):

    • This is the most fundamental component, representing an abstract wrapper around various large language models. Whether it's OpenAI's GPT series, Google's Gemini, or the open-source Llama, LangChain provides a unified interface.
    • It handles sending your requests to the model and receiving the response. You can configure parameters like the model name, temperature (which controls creativity), and max tokens.
    • In our Support Copilot project, the LLM is the "brain" responsible for understanding user queries and generating answers.
  2. Prompts:

    • Prompts are the language we use to communicate with LLMs. A well-crafted prompt yields more accurate and useful responses.
    • LangChain offers PromptTemplate, which allows you to define prompts with placeholders and dynamically inject variables. This drastically improves prompt reusability and management.
    • For our copilot, we can define a template that sets the LLM's persona ("You are a professional support assistant") and injects the user's question.
  3. Chains:

    • Chains are a central concept in LangChain. They link multiple components (like an LLM and a Prompt) together to form a sequential workflow.
    • The simplest chain might just be "PromptTemplate -> LLM", but complex chains can include multiple steps, logical routing, and even external tool calls.
    • LangChain introduced LCEL (LangChain Expression Language), a highly powerful and flexible way to build chains. It allows you to pipe components together seamlessly.

The Support Copilot Prototype Workflow (Mermaid Diagram)

To better understand how these three core components work together, let's look at the workflow of our Support Copilot prototype:

graph TD
    A[User Input] --> B{PromptTemplate: Format Query};
    B -- Inject Variables --> C[LLM: Large Language Model];
    C -- Generate Response --> D[OutputParser: Format Output Optional];
    D --> E[Copilot Returns Answer];

    style A fill:#f9f,stroke:#333,stroke-width:2px;
    style B fill:#bbf,stroke:#333,stroke-width:2px;
    style C fill:#ccf,stroke:#333,stroke-width:2px;
    style D fill:#fbf,stroke:#333,stroke-width:2px;
    style E fill:#9f9,stroke:#333,stroke-width:2px;

Workflow Breakdown:

  1. User Input: The user asks the copilot a question.
  2. PromptTemplate: Instead of sending the raw question directly to the LLM, the copilot uses a predefined PromptTemplate to format it. This template provides context, sets the persona (e.g., "You are a professional intelligent support assistant"), and includes a placeholder for the user's question.
  3. LLM (Large Language Model): The fully formatted prompt is sent to the LLM. Based on its training data and the prompt's instructions, the LLM generates an answer tailored to the user's query.
  4. OutputParser (Optional): Sometimes, the raw output from the LLM needs further processing, such as extracting specific information or converting it to JSON. The OutputParser helps structure or format this output. We might not need it in our initial prototype, but it will be crucial later.
  5. Copilot Returns Answer: Finally, the processed (and potentially parsed) answer is returned to the user.

This is the most basic LangChain application loop. Starting to see how the theory connects to practice?

💻 Hands-on Coding (Applying it to the Copilot Project)

Enough theory—time to roll up our sleeves! We'll use both Python and TypeScript to demonstrate how to build this Support Copilot prototype.

Prerequisites

  1. Install LangChain libraries:
    • Python:
      pip install langchain langchain-openai python-dotenv
      
    • TypeScript:
      npm install langchain @langchain/openai dotenv
      # or yarn add langchain @langchain/openai dotenv
      
  2. Set up your OpenAI API Key:
    • Create a .env file in your project root and add your OpenAI API Key.
    OPENAI_API_KEY="YOUR_OPENAI_API_KEY_HERE"
    
    • Important Note: Never hardcode your API Key into your source code. Using environment variables is a best practice!

Python Implementation

import os
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough

# 1. Load environment variables
load_dotenv()
openai_api_key = os.getenv("OPENAI_API_KEY")

if not openai_api_key:
    raise ValueError("OPENAI_API_KEY is not set. Please check your .env file.")

print("✅ Environment variables loaded successfully. Building the Support Copilot...")

# 2. Initialize the LLM
# We use ChatOpenAI because it's optimized for conversational use cases.
# The temperature parameter controls "creativity"; 0 means more deterministic and less random.
llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0, api_key=openai_api_key)
print("✅ LLM initialized.")

# 3. Define the PromptTemplate
# This is a ChatPromptTemplate, which can include System, Human, and AI messages.
# For a support copilot, the System message sets its persona and behavior.
prompt = ChatPromptTemplate.from_messages(
    [
        ("system", "You are a professional intelligent support assistant. Your task is to answer user questions about our products and services in a friendly, accurate, and concise manner. If a question falls outside your knowledge base, politely inform the user and suggest they contact human support."),
        ("human", "{question}"), # {question} is a placeholder that will be filled by user input
    ]
)
print("✅ PromptTemplate defined.")

# 4. Define the OutputParser
# Here we use StrOutputParser, which simply converts the LLM's output into a string.
output_parser = StrOutputParser()
print("✅ OutputParser defined.")

# 5. Build the Chain - Using LangChain Expression Language (LCEL)
# LCEL allows us to pipe components together intuitively and powerfully.
# Flow: User Input -> PromptTemplate -> LLM -> OutputParser
rag_chain = (
    {"question": RunnablePassthrough()} # Takes the raw user input and passes it as the "question" variable
    | prompt                            # Injects "question" into the prompt template
    | llm                               # Sends the formatted prompt to the LLM
    | output_parser                     # Parses the LLM's output
)
print("✅ Chain built successfully.")

# 6. Simulate user queries and run the copilot
print("\n--- Support Copilot Session Started ---")

# Scenario 1: Product inquiry
user_question_1 = "What are the main features of your smartwatches?"
print(f"\nUser: {user_question_1}")
response_1 = rag_chain.invoke({"question": user_question_1})
print(f"Copilot: {response_1}")

# Scenario 2: Service inquiry
user_question_2 = "My order number is XYZ12345. When will it be shipped?"
print(f"\nUser: {user_question_2}")
response_2 = rag_chain.invoke({"question": user_question_2})
print(f"Copilot: {response_2}")

# Scenario 3: Out-of-scope question
user_question_3 = "What will the weather be like in Beijing tomorrow?"
print(f"\nUser: {user_question_3}")
response_3 = rag_chain.invoke({"question": user_question_3})
print(f"Copilot: {response_3}")

print("\n--- Support Copilot Session Ended ---")

TypeScript Implementation

import * as dotenv from "dotenv";
import { ChatOpenAI } from "@langchain/openai";
import { ChatPromptTemplate } from "@langchain/core/prompts";
import { StringOutputParser } from "@langchain/core/output_parsers";
import { RunnablePassthrough } from "@langchain/core/runnables";

// 1. Load environment variables
dotenv.config();
const openaiApiKey = process.env.OPENAI_API_KEY;

if (!openaiApiKey) {
  throw new Error("OPENAI_API_KEY is not set. Please check your .env file.");
}

console.log("✅ Environment variables loaded successfully. Building the Support Copilot...");

// 2. Initialize the LLM
const llm = new ChatOpenAI({
  model: "gpt-3.5-turbo",
  temperature: 0, // Controls "creativity"; 0 means more deterministic and less random
  apiKey: openaiApiKey,
});
console.log("✅ LLM initialized.");

// 3. Define the PromptTemplate
const prompt = ChatPromptTemplate.fromMessages([
  [
    "system",
    "You are a professional intelligent support assistant. Your task is to answer user questions about our products and services in a friendly, accurate, and concise manner. If a question falls outside your knowledge base, politely inform the user and suggest they contact human support.",
  ],
  ["human", "{question}"], // {question} is a placeholder that will be filled by user input
]);
console.log("✅ PromptTemplate defined.");

// 4. Define the OutputParser
const outputParser = new StringOutputParser();
console.log("✅ OutputParser defined.");

// 5. Build the Chain - Using LangChain Expression Language (LCEL)
// LCEL allows us to pipe components together intuitively and powerfully.
// Flow: User Input -> PromptTemplate -> LLM -> OutputParser
const ragChain = RunnablePassthrough.assign({
  question: (input: string) => input, // Takes the raw user input and passes it as the "question" variable
})
  .pipe(prompt) // Injects "question" into the prompt template
  .pipe(llm) // Sends the formatted prompt to the LLM
  .pipe(outputParser); // Parses the LLM's output

console.log("✅ Chain built successfully.");

// 6. Simulate user queries and run the copilot
async function runCustomerService() {
  console.log("\n--- Support Copilot Session Started ---");

  // Scenario 1: Product inquiry
  const userQuestion1 = "What are the main features of your smartwatches?";
  console.log(`\nUser: ${userQuestion1}`);
  const response1 = await ragChain.invoke(userQuestion1);
  console.log(`Copilot: ${response1}`);

  // Scenario 2: Service inquiry
  const userQuestion2 = "My order number is XYZ12345. When will it be shipped?";
  console.log(`\nUser: ${userQuestion2}`);
  const response2 = await ragChain.invoke(userQuestion2);
  console.log(`Copilot: ${response2}`);

  // Scenario 3: Out-of-scope question
  const userQuestion3 = "What will the weather be like in Beijing tomorrow?";
  console.log(`\nUser: ${userQuestion3}`);
  const response3 = await ragChain.invoke(userQuestion3);
  console.log(`Copilot: ${response3}`);

  console.log("\n--- Support Copilot Session Ended ---");
}

runCustomerService();

Code Walkthrough & Application in the Copilot Project

The code above, whether in Python or TypeScript, clearly demonstrates LangChain's core trio:

  • LLM (ChatOpenAI): We chose gpt-3.5-turbo because it's fast, cost-effective, and perfect as the "brain" of our copilot. Setting temperature=0 ensures deterministic and consistent answers, avoiding unnecessary "creativity" which is crucial in customer support scenarios.
  • PromptTemplate (ChatPromptTemplate): We used a system message to give the LLM a clear persona: "a professional intelligent support assistant." This persona setting is key to a successful LLM app; it guides the model to generate answers in the correct context and tone. The {question} placeholder makes the prompt dynamic.
  • Chain (LCEL): Using the | (Python) or .pipe() (TypeScript) operator, we connected the user input, prompt template, LLM, and output parser like a pipeline. This declarative chaining is the essence of modern LangChain development, making complex logic clear and readable. RunnablePassthrough ensures the raw user input is passed to the next step in the chain, specifically to fill the {question} placeholder in the prompt.

Through this simple chain, our Support Copilot can now:

  1. Understand user queries: The LLM parses natural language input.
  2. Adopt a specific persona: It answers questions using a "professional support" tone.
  3. Provide basic information: It gives generalized answers to "known" product or service questions.
  4. Recognize knowledge boundaries: When faced with questions outside its "cognitive" scope, it politely declines and directs the user to human support.

This is the first milestone of our Intelligent Support Copilot! While basic, it now possesses conversational capabilities, laying a solid foundation for advanced features like memory, knowledge retrieval, and tool calling.

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

As a veteran, I've seen too many beginners stumble here. Don't worry, I'll point you in the right direction:

  1. Mishandling API Keys:
    • Gotcha: Hardcoding the OPENAI_API_KEY directly in your code or pushing it to a Git repository. This is a massive security risk!
    • Best Practice: Always use environment variables (a .env file paired with python-dotenv or dotenv). In production, use secure secret management services (like AWS Secrets Manager, Azure Key Vault, or Kubernetes Secrets).
  2. Choosing the Wrong LLM:
    • Gotcha: Immediately defaulting to the most powerful model (like gpt-4) or the cheapest model (like gpt-3.5-turbo) without considering the use case.
    • Best Practice: Balance cost, speed, and performance based on your scenario. For early-stage support scenarios, gpt-3.5-turbo is often the king of ROI. Only upgrade when you need complex reasoning or higher accuracy. Different models have different capability boundaries and token limits.
  3. The "Dark Art" of Prompt Engineering:
    • Gotcha: Writing overly long, convoluted, or vague prompts, expecting the LLM to "guess" your intent.
    • Best Practice: Prompt engineering is an art, but more importantly, a science. Clarity, specificity, and conciseness are key. Give the LLM a clear Persona, a specific Task, explicit Constraints, and a defined Format. In our copilot example, we explicitly defined its role and how it should handle out-of-scope questions.
  4. Blocking with Synchronous Calls:
    • Gotcha: Using synchronous calls like chain.invoke() in web services or high-concurrency scenarios, leading to slow server responses or blocking.
    • Best Practice: All LangChain components support asynchronous execution (.ainvoke() / await chain.invoke()). In production-grade apps, especially for I/O-bound tasks (like calling external APIs), always use async to improve concurrency and response times.
  5. Lack of Error Handling:
    • Gotcha: Failing to handle LLM API failures, network interruptions, or abnormal model responses, causing the app to crash.
    • Best Practice: Always wrap LLM calls in try-except (Python) or try-catch (TypeScript) blocks. Implement retry mechanisms and graceful degradation strategies. For example, if an LLM call fails, try a fallback model or simply prompt the user to try again later.

📝 Lesson Wrap-Up

Congratulations! In this lesson, we didn't just deeply understand LangChain's core value and its three pillars—LLMs, Prompts, and Chains—we also built the very first version of our "Intelligent Support Copilot." While this simple assistant isn't ready to work a 24/7 shift just yet, it can speak, understand basic user intents, and recognize its own limitations. This is our first step from zero to a production-grade application!

We saw how LangChain takes scattered LLM capabilities and makes them controllable, reusable, and scalable through structured components and chain orchestration. This sets a rock-solid foundation for the advanced features we'll build next, such as complex memory modules, external tool integrations, and knowledge base retrieval.

In the next lesson, we will dive deep into LangChain's Memory module. You might be wondering, "Does our current copilot have the memory of a goldfish?" Exactly! Every conversation feels like a first encounter. So, how do we make our copilot remember the user's chat history to provide a more coherent and personalized service? Stay tuned for the next episode!