🔗 LangChain · LangChain · LangChain

Join a prompt, a model and a parser with a pipe. Then ask for an object instead of a paragraph, and give an agent a tool. All on a free model on your own machine. · ต่อพรอมป์ต โมเดล และตัวแปลงผลลัพธ์เข้าด้วยกันด้วยท่อ แล้วขอผลลัพธ์เป็นออบเจ็กต์แทนย่อหน้า และให้เครื่องมือกับ agent ทั้งหมดบนโมเดลฟรีในเครื่องของคุณเอง · 用管道把提示词、模型和解析器接起来。然后要一个对象而不是一段话,再给智能体一个工具。全部跑在你自己电脑上的免费模型上。

1 📦 Install it, and meet the pipe · ติดตั้ง แล้วรู้จักท่อ · 安装,认识那根管子

🇬🇧 English

LangChain's one big idea is the pipe. You write a prompt, a model and a parser, and join them with |. What comes out of one goes into the next, like a production line.

Everything here runs on the free qwen3 from Make Your Own AI Teacher. Nothing is sent away, and there is no key.

🇹🇭 ไทย

ความคิดใหญ่ที่สุดของ LangChain คือท่อ คุณเขียนพรอมป์ต โมเดล และตัวแปลงผลลัพธ์ แล้วต่อกันด้วย | สิ่งที่ออกจากตัวหนึ่งไหลเข้าอีกตัว เหมือนสายพานการผลิต

ทุกอย่างในหน้านี้รันบน qwen3 ฟรี จาก สร้างครู AI ของคุณเอง ไม่มีอะไรถูกส่งออกไป และไม่ต้องใช้คีย์

🇨🇳 中文

LangChain 最大的一个想法是管道。你写一个提示词、一个模型、一个解析器,用 | 把它们接起来。前一个的输出流进后一个,像一条流水线。

这一页全部跑在 做一个你自己的 AI 老师里那个免费的 qwen3 上。没有东西被送走,也不需要密钥。

terminal

pip install langchain langchain-ollama

langchain_demo.py — the setup

"""Four small LangChain examples, all against a free model on this machine."""
import time

from langchain.agents import create_agent
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.tools import tool
from langchain_ollama import ChatOllama
from pydantic import BaseModel, Field

model = ChatOllama(model="qwen3", base_url="http://localhost:11434",
                   num_ctx=8192, reasoning=False)      # reasoning=False: no <think> block
CAREFUL reasoning=False is the line that matters. qwen3 normally writes its thinking before the answer, and a chain hands that thinking straight to the next step. Turn it off and the four examples below finish in 48 seconds altogether on a laptop with no graphics card. reasoning=False คือบรรทัดที่สำคัญ ปกติ qwen3 จะเขียนความคิดออกมาก่อนคำตอบ และท่อจะส่งความคิดนั้นต่อไปยังขั้นถัดไปทันที ปิดมันเสีย แล้วตัวอย่างสี่อันข้างล่างจะเสร็จใน 48 วินาทีรวมกัน บนแล็ปท็อปที่ไม่มีการ์ดจอ reasoning=False 是关键的一行。qwen3 默认会先写出自己的思考再给答案,而管道会把那段思考原样交给下一步。关掉它,下面四个例子在一台没有显卡的笔记本上总共 48 秒就跑完了。

2 🔗 One chain: prompt, model, parser · ท่อแรก พรอมป์ต โมเดล ตัวแปลง · 第一条链:提示词、模型、解析器

🇬🇧 English

A prompt template has holes in it. You fill them when you call invoke(), so one chain answers a thousand questions.

StrOutputParser() is the last piece: without it you get a message object, with it you get plain text.

🇹🇭 ไทย

แม่แบบพรอมป์ตมีช่องว่างอยู่ คุณเติมตอนเรียก invoke() ท่อเดียวจึงตอบคำถามได้เป็นพันแบบ

StrOutputParser() คือชิ้นสุดท้าย ถ้าไม่มีมันคุณจะได้ออบเจ็กต์ข้อความ ถ้ามีคุณจะได้ข้อความธรรมดา

🇨🇳 中文

提示词模板里有空。调用 invoke() 时才填,所以一条链能回答上千个问题。

StrOutputParser() 是最后一块:没有它你拿到的是消息对象,有它你拿到的是纯文本。

the chain

# ── 1. the pipe: prompt | model | parser ──────────────────────────────────────
explain = ChatPromptTemplate.from_template(
    "Explain {thing} to a Grade 9 student in two short sentences.")
chain = explain | model | StrOutputParser()
timed("1 CHAIN", lambda: chain.invoke({"thing": "why the sky is blue"}))

what it printed (12s)

The sky appears blue because sunlight passes through the atmosphere and shorter blue wavelengths are scattered in all directions by tiny gas molecules. This scattered blue light reaches our eyes, making the sky look blue on a clear day.

3 🧱 Structured output: an object, not a paragraph · ผลลัพธ์มีโครงสร้าง ได้ออบเจ็กต์ ไม่ใช่ย่อหน้า · 结构化输出:拿到对象,不是段落

🇬🇧 English

Ask for a shape and you get a shape. You describe it once with pydantic, and with_structured_output() makes the model fill it in — fields you can use in code, not a paragraph you have to cut up.

🇹🇭 ไทย

ขอรูปแบบ แล้วคุณจะได้รูปแบบนั้น คุณอธิบายมันครั้งเดียวด้วย pydantic แล้ว with_structured_output() ให้โมเดลเติมค่าลงไป ได้ฟิลด์ที่เอาไปใช้ในโค้ดได้เลย ไม่ใช่ย่อหน้าที่ต้องมานั่งตัด

🇨🇳 中文

你要什么形状,就得到什么形状。用 pydantic 描述一次,with_structured_output() 让模型把它填满 —— 得到的是代码里能直接用的字段,而不是一段还要自己去切的文字。

the shape, and the call

# ── 2. structured output: you get an object, not a paragraph ──────────────────
class Word(BaseModel):
    word: str = Field(description="an English word a market seller would use")
    thai: str = Field(description="the Thai translation")
    example: str = Field(description="one short example sentence")


timed("2 STRUCTURED",
      lambda: model.with_structured_output(Word).invoke(
          "Give one useful English word for a Chiang Mai market."))

what it printed (7s)

word='Warorot' thai='วอร์ร็อต' example='Warorot Market is a popular spot for local crafts and street food.'
CAREFUL Look closely at that answer. The shape is perfect — three fields, all filled, Thai included — and the content is wrong: Warorot is the name of a market, not “a useful English word” a seller would say. Structured output guarantees the shape and nothing else. Check the values like you would check any other answer. ดูคำตอบนั้นให้ดี รูปแบบสมบูรณ์แบบ คือสามฟิลด์ เติมครบ มีภาษาไทยด้วย แต่เนื้อหาผิด Warorot เป็นชื่อตลาด ไม่ใช่ “คำภาษาอังกฤษที่มีประโยชน์” ที่คนขายจะพูด ผลลัพธ์แบบมีโครงสร้างรับประกันแค่รูปแบบ ไม่ได้รับประกันอย่างอื่น ให้ตรวจค่าที่ได้เหมือนตรวจคำตอบอื่น ๆ 仔细看那个答案。形状完美 —— 三个字段全填了,还带泰文 —— 但内容是错的:Warorot 是一个市场的名字,不是摊主会说的那种“有用的英文单词”。结构化输出只保证形状,别的都不保证。拿到的值要像检查任何答案一样去检查。

4 ⛓️ Two steps, joined · ต่อสองขั้นเข้าด้วยกัน · 把两步接起来

🇬🇧 English

Chains join to chains. The first one explains something; the second rewrites it shorter. The dictionary at the front says which hole the first chain's answer fills.

This is the shape behind most LangChain code you will read: small pieces, joined with |.

🇹🇭 ไทย

ท่อต่อกับท่อได้ ท่อแรกอธิบายเรื่องหนึ่ง ท่อที่สองเขียนใหม่ให้สั้นลง ส่วน dictionary ข้างหน้าบอกว่าคำตอบของท่อแรกจะไปเติมช่องไหน

นี่คือรูปร่างที่อยู่เบื้องหลังโค้ด LangChain ส่วนใหญ่ที่คุณจะได้อ่าน คือชิ้นเล็ก ๆ ต่อกันด้วย |

🇨🇳 中文

链可以接链。第一条解释一件事,第二条把它改短。前面那个字典说明第一条链的答案填进哪个空。

这就是你将读到的大多数 LangChain 代码的形状:小块,用 | 接起来。

two chains, one pipe

# ── 3. two steps, joined ──────────────────────────────────────────────────────
shorten = ChatPromptTemplate.from_template(
    "Rewrite this in one sentence a beginner can read:\n\n{text}")
two_step = {"text": chain} | shorten | model | StrOutputParser()
timed("3 TWO STEPS", lambda: two_step.invoke({"thing": "why rice fields need water"}))

what it printed (13s)

Rice plants need water to grow because their roots use it to get nutrients and oxygen, and water also helps them stand upright and develop their grains.

5 🧰 An agent with a tool · agent ที่มีเครื่องมือ · 带工具的智能体

🇬🇧 English

A chain always runs the same steps. An agent decides. Give it a tool and a question, and it chooses whether to call the tool before answering.

create_agent() hands back a LangGraph object, so you call it with a list of messages and read the last one. That is LangChain 1.x showing its plumbing.

🇹🇭 ไทย

ท่อทำขั้นตอนเดิมทุกครั้ง ส่วน agent เป็นคนตัดสินใจ ให้เครื่องมือกับคำถามไป แล้วมันเลือกเองว่าจะเรียกเครื่องมือก่อนตอบหรือไม่

create_agent() คืนออบเจ็กต์ของ LangGraph มา คุณจึงเรียกมันด้วยลิสต์ของข้อความ แล้วอ่านข้อความสุดท้าย นี่คือท่อภายในของ LangChain 1.x ที่โผล่ออกมาให้เห็น

🇨🇳 中文

链每次都走同样的步骤,而智能体自己决定。给它一个工具和一个问题,它自己决定回答前要不要调用工具。

create_agent() 返回的是一个 LangGraph 对象,所以你用一串消息调用它,再读最后一条。这是 LangChain 1.x 把自己的管道露了出来。

the tool, and the agent

# ── 4. an agent with a tool ───────────────────────────────────────────────────
@tool
def lessons_in_a_day(minutes: int) -> str:
    """Says how many lessons fit in a seven hour school day.

    Args:
        minutes: how long one lesson lasts.
    """
    return f"{(7 * 60) // minutes} lessons of {minutes} minutes fit in a seven hour school day."


agent = create_agent(model, tools=[lessons_in_a_day],
                     system_prompt="You are a school planner. Use the tool before you answer.")
timed("4 AGENT", lambda: agent.invoke(
    {"messages": [{"role": "user", "content": "How many 45 minute lessons fit in a school day?"}]}
)["messages"][-1].content)

what it printed (16s)

There are 9 lessons of 45 minutes each that fit in a seven-hour school day.
CAREFUL The tool did the arithmetic, and the answer is right: seven hours is 420 minutes, and 420 ÷ 45 is 9. That is the point of a tool — the model decides when to count, and Python does the counting. เครื่องมือเป็นคนคิดเลข และคำตอบถูก เจ็ดชั่วโมงคือ 420 นาที และ 420 ÷ 45 ได้ 9 นี่คือจุดประสงค์ของเครื่องมือ โมเดลตัดสินใจว่าเมื่อไรต้องนับ ส่วน Python เป็นคนนับ 算数是工具做的,答案也对:七小时是 420 分钟,420 ÷ 45 等于 9。这正是工具的意义 —— 模型决定什么时候该算,Python 负责算。

6 👉 LangChain, or one of the others? · เลือก LangChain หรือตัวอื่น · 选 LangChain,还是别的?

🇬🇧 English

  • A fixed set of steps — explain, translate, shorten, extract into fields: LangChain. The pipe is easy to read and easy to test, because it does the same thing every time.
  • One job that code would solve — counting, reading a file, calling an API: smolagents, which writes real Python instead.
  • Several roles, or a conversation — a writer and a checker, two sides and a judge: CrewAI and AutoGen.

They all sit on the same free model on your own machine. The library only decides the shape of the work, never how good the model is.

🇹🇭 ไทย

  • ขั้นตอนที่แน่นอน เช่น อธิบาย แปล ย่อ แล้วดึงออกมาเป็นฟิลด์ ให้ใช้ LangChain ท่ออ่านง่ายและทดสอบง่าย เพราะมันทำเหมือนเดิมทุกครั้ง
  • งานเดียวที่แก้ด้วยโค้ดได้ เช่น นับ อ่านไฟล์ เรียก API ให้ใช้ smolagents ที่เขียน Python จริง ๆ แทน
  • หลายบทบาท หรือบทสนทนา เช่น คนเขียนกับคนตรวจ หรือสองฝ่ายกับกรรมการ ให้ใช้ CrewAI และ AutoGen

ทั้งหมดนี้วางอยู่บนโมเดลฟรีตัวเดียวกันบนเครื่องของคุณ ไลบรารีตัดสินแค่รูปร่างของงาน ไม่เคยตัดสินว่าโมเดลเก่งแค่ไหน

🇨🇳 中文

  • 固定的几步 —— 解释、翻译、缩短、抽成字段:用 LangChain。管道好读也好测,因为它每次都做同样的事。
  • 一件用代码就能解决的事 —— 数数、读文件、调 API:用 smolagents,它会直接写 Python。
  • 多个角色,或者一场对话 —— 一个写一个检查,或者两方加一个评判:用 CrewAI 和 AutoGen

它们都跑在你自己电脑上同一个免费模型上。库只决定工作的形状,从来不决定模型有多好。