跪拜 Guibai
← Back to the summary

LangChain in 5 Minutes: Build Your First AI Demo with Model I/O

This article mainly walks through a basic LangChain Model I/O (Model Input/Output): that is, how you feed data "into the model" (Input) and how you "get results" from the model (Output).

We'll start with the most basic: initialize the model -> user input -> model invocation. Complete the minimal loop. Prompt engineering, structured output, and message types will be covered later.

Below is a diagram of LangChain Model I/O: the "input/output protocol layer" for model invocation

image.png

Table of Contents

Why use LangChain to develop AI applications?

Nowadays, AI model providers are emerging one after another. This is good for the industry as a whole, driving rapid AI development. But for developers, it's not that friendly.

In real projects, we often don't use just one model provider's service. For example, we might simultaneously integrate:

At this point, the problem arises: 👉 Different providers have different API invocation methods, parameter formats, and return structures

If you write a set of adaptation logic for each model:

This is where LangChain's value lies:

👉 Unified model invocation method, shielding underlying differences

You can think of it as:

LangChain ≈ JDBC in Java

Just develop against a unified interface, and you can flexibly switch between different model providers.

See the diagram:

image.png

LangChain source code reflection:

👉 Enumerate each provider, then implement through dynamic import + a unified ConfigurableModel proxy (details not discussed)

image.png

LangChain is not just about "unified model invocation"; it is essentially a complete AI application development framework with many built-in core capabilities, such as:

But to be honest, for most frontend/application developers:

👉 What is most commonly used in daily work is still:


Large Model ≠ Complete AI Application

Many people have a misconception:

"Having a large model equals having an AI application"

Actually, it doesn't.

You can think of a large model as a "super brain" that possesses:

But it itself lacks:

Therefore, a complete AI application usually looks like this:

AI Agent = LLM (Brain) + Memory + Planning + Tools

👉 LangChain is precisely the tool that helps you "assemble" these capabilities.

Let's start with a demo to get a taste 😄😄😄

Model Application (Alibaba Cloud Bailian: Free Credits Available)

Click the link below, read the documentation, and follow the instructions to apply for an API Key.

image.png

image.png

image.png

Development Environment Setup

mkdir langchain-project
cd langchain-project
npm init -y
src/langchain-invoke.mjs

Note:

👉 After engineering, using .js directly is perfectly fine.

Initialize the Model

pnpm install langchain
import { initChatModel } from 'langchain';
const model = initChatModel(
   'qwen-coder-turbo' // model name
    {
        modelProvider: "openai", // Tell the factory: although it's xxx service, use OpenAI's SDK logic
        baseUrl: "https://dashscope.aliyuncs.com/compatible-mode/v1" // Corresponds to the field in the SDK
        apiKey: 'sk-d69fd787d37241fxxxxe8bb914292108'  // Corresponds to the field in the SDK
    }
)

Model Invocation

We are using ChatModel (conversation model) here, initialized with initChatModel.

👉 Features:

Using invoke

const response = await model.invoke("Why do parrots have colorful feathers?");
console.log(response);
// console.log(response.content);

image.png

Return Result Explanation

The return value is an AIMessage object, for example:

{
  content: "Because feathers contain pigments and structural colors...",
  ...
}

👉 If you only care about the text content:

console.log(response.content);

🎉 Summary

At this point, we have completed:

👉 A most basic LangChain Demo is up and running. Isn't it simple?

Advanced Supplement

❗ Don't Let Your API Key "Naked" – Use .env

Hardcoding the API Key directly in the code:

apiKey: 'sk-xxx'

👉 Only suitable for temporary testing 👉 Very dangerous in production environments (key will leak)

Use dotenv to manage environment variables

pnpm install dotenv
# OpenAI API Configuration

# OpenAI API Key
OPENAI_API_KEY=sk-d69fd787d37241xxxf9e8bb914292108
# OpenAI API Base URL
OPENAI_BASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1
# Model Name
MODEL_NAME=qwen-coder-turbo

image.png

// import dotenv from "dotenv";
// dotenv.config();
import 'dotenv/config';
import { initChatModel } from 'langchain';

const model = await initChatModel(process.env.MODEL_NAME, {
  modelProvider: 'openai',
  apiKey: process.env.OPENAI_API_KEY,
  baseUrl: process.env.OPENAI_BASE_URL,
});

const result = await model.invoke("Why do parrots have colorful feathers?");
console.log(result);
node_modules
.env
package-lock.json
.DS_Store

Why sometimes can't read .env?

Initially, to save time, I directly cd into the src directory and executed:

node ./langchain-invoke.mjs

It immediately reported an error: 👉 Prompt saying API Key not found

🧠 Root Cause

The problem lies in this point:

dotenv by default looks for the .env file based on the current working directory (process.cwd)

That is to say:

👉 Node doesn't know where your "project root directory" is

👉 It only knows: which directory you executed the node command from

👉 There is no .env under src, so naturally it can't read it.

Another Way to Initialize the Model: ChatOpenAI

In earlier LangChain usage, we often directly used model classes like ChatOpenAI. However, with the advent of the multi-model era, LangChain provides initChatModel as a unified entry point, allowing developers to switch between different model providers without modifying business code, achieving true model decoupling.

pnpm install @langchain/openai
import { ChatOpenAI } from '@langchain/openai';
const model = new ChatOpenAI({
  model: process.env.MODEL_NAME,
  apiKey: process.env.OPENAI_API_KEY,
  configuration: {
    baseURL: process.env.OPENAI_BASE_URL,
  },
});
const result = await model.invoke("Why do parrots have colorful feathers?");
console.log(result);

Difference between initChatModel and ChatOpenAI

👉 ChatOpenAI = Model SDK for OpenAI (specific implementation) 👉 initChatModel = Unified model entry point (abstraction layer + factory pattern)

Architecture Comparison

# ChatOpenAI (single provider)
Your code → ChatOpenAI → OpenAI API

# initChatModel (multi-model architecture)
Your code → initChatModel → Provider Adapter → Any model

Message Types

Above we already encountered AIMessage, which, as the name suggests, represents the message returned by AI. In addition, LangChain defines a series of standard message types:

Demo
import { SystemMessage, HumanMessage, AIMessage } from "langchain";

const messages = [
  new SystemMessage("You are a poetry expert"),
  new HumanMessage("Write a haiku about spring"),
  new AIMessage("Cherry blossoms bloom..."),
];
const response = await model.invoke(messages);
const messages = [
  { role: "system", content: "You are a poetry expert" },
  { role: "user", content: "Write a haiku about spring" },
  { role: "assistant", content: "Cherry blossoms bloom..." },
];
const response = await model.invoke(messages);

His demo is relatively simple; refer to the official documentation. https://docs.langchain.com/oss/javascript/langchain/messages

🤔 Why not just return a string?

You might have a question:

👉 "When I ask AI a question, can't it just return a string? Why wrap it in an AIMessage?"

🤔 Conclusion First

The existence of Message is not to "add an extra layer," but to upgrade AI's output from "text" to "an orchestrateable data structure."

4 Real Problems Solved by Message (Key Points)

Message is the "state carrier" of the AI execution process, which will run through the entire subsequent learning flow, so it is crucial!!!

1️⃣ Allows AI to "Invoke System Capabilities"

AIMessage.tool_calls

👉 Used for:


👉 Without Message:

AI can only "suggest you do it"

👉 With Message:

AI can "drive the system to do it for you"

2️⃣ Allows AI to Output "Structured Data"

For example, if you are doing e-commerce (which you are doing now) 👇

User says:

Help me generate a product title

👉 string:

"2024 New Men's Sports Shoes, Breathable and Comfortable"

👉 You still have to parse it yourself 😓


👉 Message + Structured:

{
  content: "",
  additional_kwargs: {
    title: "2024 New Men's Sports Shoes",
    keywords: ["Breathable", "Comfortable"],
    category: "Sports Shoes"
  }
}

💥 Third value:

Natively supports structured output (suitable for business systems)


3️⃣ Supports Multi-turn Dialogue (Context)

[
  new SystemMessage("You are an e-commerce operations assistant"),
  new HumanMessage("Help me optimize the title"),
  new AIMessage("Please provide product information"),
  new HumanMessage("Men's running shoes")
]

👉 If it were just a string:

❌ All context is lost


💥 Fourth value:

Message = Dialogue context container



4️⃣ Supports "Intermediate States" (Very Critical)

In complex workflows, AI doesn't just return the final result:


👉 For example:

Think → Call tool → Think again → Output result

👉 Message can carry:


Other Model Invocation Methods

Above we used invoke to call the model. You can see that it returns the complete result after generation is finished, so it often requires waiting for some time.

If you want to see the model's output in real-time like a "typewriter" (streaming return), you can use the stream method, allowing results to be output as they are generated, improving the interactive experience. Additionally, there is batch for batch processing model requests.

// stream
const stream = await model.stream("Help me generate a product title for BYD"); 
for await (const chunk of stream) { 
    // console.log('stream:', chunk);
    // console.log(chunk.text) 
    console.log(chunk.content) 
}

image.png

🎉 Summary

This article focuses on LangChain's Model I/O, completing the minimal loop from model initialization → input construction → model invocation → output parsing.

The main content includes:

  1. Why use LangChain Unify differences between different model providers through a unified interface, while providing rich component capabilities, allowing us to focus on business development instead of dealing with various compatibility issues.

  2. Model Initialization Taking the most common ChatModel as an example, it introduces how to use initChatModel to initialize the model, and the configuration of core parameters like apiKey, baseUrl, and supplements the practice of using dotenv environment variables.

  3. Message Types Through the model's return value AIMessage, it introduces message types like SystemMessage, HumanMessage, and explains the syntax for object form and dictionary form. It also explains: 👉 Why the model doesn't just return a string, but uses the Message structure – because Message is the "state carrier" of the AI execution process, capable of supporting tool calls, multi-turn dialogue, intermediate states, and structured output.

  4. Model Invocation Methods Compares three invocation methods: invoke, stream, batch:

    • invoke: Returns all at once, suitable for debugging
    • stream: Streaming output, more suitable for actual interactive scenarios (mainstream method)
    • batch: Batch processing requests

At this point, a most basic AI Demo has been completed. I believe you now have an overall understanding of LangChain's Model I/O.

However, the understanding of Message is still at the "usable" stage. 👉 In the next article, we will delve into LangChain's message mechanism and how it drives Tool and Agent execution.

For the sake of smooth sentences, some AI-assisted writing has been added. I hope you understand 🐶🐶🐶

This is an introductory article. If there are any omissions, please feel free to correct me 🤝🤝🤝