给一台猜词机器装上手脚 —— LangChain 快速入门
LangChain 快速入门。全文只回答一个问题:语言模型和能干活的系统之间,差的那些零件叫什么名字,怎么装。
文本版 · 供搜索与朗读
给一台猜词机器装上手脚 — LangChain 快速入门
目录
先看一个实验
这台机器到底会什么
LangChain 卖的是什么
十行代码,跑通第一圈
给它一个笔记本
null 和 258
demo 与真系统之间隔着什么
今天就能做的事
Quickstart · LangChain 1.x · Python
给一台猜词机器装上手脚
LangChain 快速入门。全文只回答一个问题:语言模型和能干活的系统之间,差的那些零件叫什么名字,怎么装。
2026-09-07 · 代码对照官方 1.x 文档核实[1] · 全文约 12 分钟 · 动手部分约 10 分钟
§先看一个实验
《了不起的盖茨比》全书按行算,大约五万行。把一道题扔给一个语言模型:「这里面有多少行包含 Gatsby 这个词?」不许它编,不知道就报 null。
没装任何工具的那个版本,交了白卷:输出 null。它想查,够不着,只好承认。换一个装了 grep 工具的版本再跑,答案变成 258,还附了一条:第一次出现在第 181 行。这是官方教程里真实跑过的实验,两个输出都来自官方文档的示例记录[1]。
一个 null,一个 258。
这篇教程要讲的就是这两个数之间的差距。它比大多数人以为的要小——差距不在模型的脑子上。装的东西都很便宜,十分钟就能装完。装完之后你自己跑一遍那道题。
01这台机器到底会什么
动零件之前,得先搞清楚这台机器的本事边界在哪。拿你最熟的东西做参照:手机输入法。你打字的时候,它猜下一个词。语言模型就是那个猜词游戏的专业版——它读过的文本比任何人一辈子读的都多,全部本事是回答一个问题:「照这么说下去,下一个词接什么最像?」
现在把这位模型请进一间办公室,当作一位新来的同事。这位同事聪明绝顶,读过图书馆里所有的书。但他有三个毛病,正好对应办公室里最要命的三样东西。
他够不着。他坐在一个玻璃隔间里,文件柜、你的电脑、电话,什么都在玻璃外面。你说「帮我看看报表第三页」,他做不到。他只能猜报表上写了什么。
他记不住。这位同事每天下班就失忆。今天聊得再透,明天他一个字都不记得。语言模型对「上一次对话」的默认记忆就是零。
他只能猜。你问报表第三页写了什么,他不会起身去拿报表。他按读过的所有报表,给你一个「最像的说法」。听起来像查。全程在猜。
还有一条藏在账单里:他每开口一次,你付一次钱,按字数算。让他多转几圈,就多付几次。
第一章的答案是:一个看不见、记不住、只能猜、还按字收费的猜词机器。听起来很糟?先别下结论。它的聪明是真的,缺的从来都不是智商,是几样便宜的基建。
02LangChain 卖的是什么
一句话:给上面那位同事,配一间像样的办公室。
能打的电话和够得着的抽屉,官方叫它工具(tools);下班不丢的笔记本,官方叫它记忆(memory);把这一切串起来的工作流程,官方叫它 agent。
agent 这个词被讲得很玄。拆开看,笨得可爱,就一个循环:
agent 循环全程:模型开口点菜,你的 Python 上菜,结果贴回对话,模型看着结果决定下一步。圆圈转够之前,谁也不知道答案长什么样。
模型不干活,模型点菜。
看图。模型说「我要调用 get_weather,参数是上海」——真去执行的是你的 Python。执行完把结果贴回对话,模型看着结果决定:继续点菜,还是交出最终答案。一圈一圈转,直到它不再点菜。所谓「智能」,全在模型那边;循环本身是一截水管,笨得可爱,胜在通。
简化契约
LangChain 里还有提示词模板、输出解析、RAG 检索器、LangGraph 工作流、部署监控一整个家族。这篇只拆一条主线:工具、循环、记忆。别的部件不会消失,而且都挂在这同一根水管上。先看清水流,再认阀门。
03十行代码,跑通第一圈
最小可用的 agent 长什么样?先装包、配 key:
Terminal
pip install -U langchain
export OPENAI_API_KEY="sk-..." # 用哪家模型,就配哪家的 key
然后是全部主角。数一数,去掉空行和注释,核心就十来行:
agent.py
from langchain.agents import create_agent
def get_weather(city: str) -> str:
"""Get current weather for a city."""
return f"It's always sunny in {city}!"
agent = create_agent(
model="openai:gpt-5.5", # 换供应商 = 换前缀,如 openrouter:… / ollama:…
tools=[get_weather],
system_prompt="You are a helpful assistant.",
)
result = agent.invoke({
"messages": [{"role": "user", "content": "上海今天天气怎么样?"}]
})
blocks = result["messages"][-1].content_blocks # 最后一条消息的内容块
print(blocks[-1]["text"])
输出
上海今天晴。 (模型的措辞会不一样,意思是这个意思)
逐行拆。get_weather 是个再普通不过的 Python 函数,加了一行文档字符串。create_agent 把模型和工具装进上一章画的那个循环。invoke 发出第一句话,result 里躺着一整段对话记录;最后一条消息的内容块(官方叫 content_blocks)里,text 字段就是答案。
真正要紧的是那行 docstring。模型从头到尾没有打开你的函数看里面写了什么——它只读抽屉上的标签。标签写着「Get current weather for a city」,它就信这是查天气的。在这个系统里,模型的全部世界就是一堆标签,加一个电话。
顺便欣赏一个细节:get_weather 在撒谎。它不管三七二十一,永远返回晴天。模型拿着「上海晴」照样端给你,一点不起疑。它不是傻子,它只是被设计成信任标签的那一方。这里记住一条:你的工具质量,基本就是这套系统的智商上限。
这一节回答了开头的问题:一个函数、一行标签、一次 create_agent。就这么回事。
04给它一个笔记本
失忆症怎么治?上笔记本。官方管这叫 checkpointer:
memory.py
from langgraph.checkpoint.memory import InMemorySaver
from langchain.agents import create_agent
checkpointer = InMemorySaver()
agent = create_agent(
model="openai:gpt-5.5",
tools=[get_weather],
checkpointer=checkpointer, # 挂上笔记本
)
config = {"configurable": {"thread_id": "xiao-lin-001"}}
agent.invoke({"messages": [{"role": "user",
"content": "我叫小林,住在上海。"}]}, config)
agent.invoke({"messages": [{"role": "user",
"content": "我叫什么?住哪儿?"}]}, config)
# → 你叫小林,住上海。
每轮对话结束,过程记进本子;下一轮开始,先翻本子再开口。thread_id 是本子封皮上的编号——同一份代码同时伺候一千个用户,一人一个编号,互不串账。
一个坑
InMemorySaver 名字里的 In,是「在内存里」。进程一关,本子烧掉。要真记住,换成 SQLite、Postgres 的 checkpointer——官方把这套接口做成了可拔插的,换零件,不换思路。
失忆症有解了:五秒记忆变无限期,代价只是多传一个编号。
05null 和 258
现在回来算开头那笔账:猜和查,差距到底在哪?官方教程的实验是这样搭的[1]:同一个问题,两个版本的 agent。没装工具的那个,系统提示词里明令「不许编,不知道就返回 null」——它照办了,交白卷。装了工具的那个,用官方另一个小包 deepagents:
deep.py
pip install deepagents # 先在终端装
from deepagents import create_deep_agent
def fetch_page(url: str) -> str:
"""Download a web page and return its raw text."""
import urllib.request
with urllib.request.urlopen(url) as r:
return r.read().decode("utf-8")
def grep_lines(haystack: str, needle: str) -> str:
"""Return every line of `haystack` containing `needle`, with line numbers."""
return "\n".join(
f"{i}: {line}"
for i, line in enumerate(haystack.splitlines(), 1)
if needle in line
)
deep_agent = create_deep_agent(
model="openai:gpt-5.5",
tools=[fetch_page, grep_lines],
)
deepagents 出厂自带几样东西:一张任务清单(它管这叫计划)、一组文件工具(grep、读文件),还有拆任务用的子 agent[3]。这里我们只额外给两个工具:一个下载网页,一个按关键词捞行。
装上工具之后,这个 agent 干的事一点都不神奇:抓全书文本,grep 一遍「Gatsby」,数行数,报 258,顺手报了第一次出现的位置。每一步都是土办法。办法本身土得很,聪明的是挑办法的那个环节——它知道该 grep,grep 完该数数,数完该住口。
没有魔法,全是土办法。
同一道题的两份答卷,一边交白卷,一边给出可核对的行数与行号:
没装工具的 agent
null
想查,够不着。提示词不许编,只能交白卷。
装了 grep 的 deep agent
258
行包含 "Gatsby",首次出现在第 181 行(第一章)
抓全文 → grep → 数行数。每一步都留了记录,可回放、可核对。
输出为官方文档示例值;实际结果随模型与执行而变。
回到开头的两个数。同一个模型,同一天,一次 null,一次 258。差距不在脑子上。在基建上。
我的看法是:诚实从来不是模型的性格,是基建。想要一个不瞎编的系统,光在提示词里喊「不许编」远远不够——你得给它够得着的抽屉。第一章那个「听起来很糟」的猜词机器,缺的从来就是这几样便宜东西。
06demo 与真系统之间隔着什么
十行代码跑通了,是不是就能上线了?先泼一盆我自己的冷水:我第一次接这类循环的时候,也以为跑通就是学会。后来线上炸出来一堆 demo 里根本看不见的坑。按我交过的学费,至少有这三个。
坑一 · 标签会过期
函数改了,docstring 忘了改,模型照着旧标签点菜,点出来的参数对不上新函数。把 docstring 当用户界面来写——改函数必改标签。
坑二 · 每一圈都收费
循环转五圈,模型费付五次,按字数算。demo 无感,流量上来会疼。盯着 messages 数组怎么长大,就是盯着账单怎么长大。
坑三 · 跑通不等于靠谱
demo 验证的是「这条顺路存在」,生产要回答的是「它错的时候,错在第几圈」。给每一圈留记录(官方的 LangSmith 干的就是这个[2]),出错才有得查。流程摆得再齐全,也代替不了你亲眼核对结果。
这一章的答案是:demo 与真系统之间,隔着标签维护、账单和可回放的记录。三样都不难。难的是别在跑通的那一刻就把它们忘干净。
§今天就能做的事
不用等哪个周末,按顺序做三件事:
pip install -U langchain,配好你那家的 key,跑通第三章的十行。
把 get_weather 换成一个真函数——读一个本地文件,或者查一次真天气。改标签的时候想想坑一。
把盖茨比那道题自己跑一遍:先跑不装工具的版本,再装上 grep。亲眼看一眼 null 和 258。
这篇没有讲 RAG,没有讲流式输出,没有讲部署。不着急,那些都挂在这同一根水管上。你手里已经有了最要紧的东西:知道这个循环怎么转,认识这位同事的两副面孔——猜,和查。
猜和查的差距,不是模型的性格问题。是基建问题。
基建问题有个好处:能修。事情就是这样。
事实来源
[1] LangChain 官方 Quickstart(create_agent / deepagents / Gatsby 实验):docs.langchain.com/oss/python/langchain/quickstart
[2] LangChain v1 变更说明(create_agent 成为标准做法):docs.langchain.com/oss/python/releases/langchain-v1
[3] deepagents(计划清单、文件工具、子 agent):docs.langchain.com/oss/python/langchain/deep-agents
文中输出为官方文档示例值,实际结果随模型与执行而变 · 代码核实日期 2026-09-07