你要把整个 LLM 应用看成 6 层:
- 输入层:用户问题、历史消息、系统提示词
- 模型层:LLM 调用、参数控制、流式输出
- 编排层:Runnable、LCEL、Chain、Graph
- 知识层:文档加载、切分、Embedding、检索、RAG
- 行动层:Tool Calling、Agent、外部 API
- 运行层:记忆、重试、回退、日志、持久化
以后你让 Codex 写代码,基本就是在说:
“帮我把这 6 层里的哪几层拼起来。”
二、LangChain 最该记住的知识点
先记一句话:
LangChain 的本质不是“一个聊天库”,而是“把 prompt、model、parser、retriever、tool 这些组件拼起来的框架”。
你要记的核心组件:
PromptTemplate / ChatPromptTemplate
作用:定义输入模板。
你要知道什么时候用普通字符串模板,什么时候用聊天消息模板。MessagesPlaceholder
作用:把历史消息插进 prompt。
以后你想做多轮对话,这个几乎必用。ChatModel
作用:真正调用模型。
你至少要知道:- .invoke() 单次调用
- .stream() 流式输出
- .batch() 批量调用
OutputParser
作用:把模型输出变成程序能用的格式。
常见:- StrOutputParser
- JSON/结构化输出解析
Runnable
这是最重要的底层抽象。
你可以理解成:LangChain 里一切能被执行的东西,最好都按 Runnable 去思考。LCEL
就是 prompt | llm | parser 这种写法。
你要形成习惯:以后写 LangChain,优先想 LCEL,而不是手搓流程。
三、你必须真正理解的 Runnable 思维
这块非常关键,因为你以后指挥 Codex 时,最常用的就是这套表达。
你要记住:
Runnable 是统一协议
意思是很多组件都能按同一种方式执行。三个常见执行方式
- invoke
- batch
- stream
| 是管道
前一个组件输出,直接给后一个组件输入。RunnableParallel
作用:并行跑多个子任务。
比如同时生成摘要、关键词、标题。RunnablePassthrough.assign()
作用:保留原输入,再动态补字段。
RAG 场景里常拿来补 context。
你以后给 Codex 下指令时,可以直接这么说:
“用 LCEL 写,不要手搓流程。”
“这里用 RunnablePassthrough.assign() 把检索结果挂到 context。”
“这两个子任务改成 RunnableParallel 并行执行。”
四、Prompt 你真正要掌握的不是写文案,而是控输入
你以后不要把 Prompt 当作文案优化,而要当成“输入协议设计”。
要记住四件事:
- 系统提示词决定角色和边界
- 用户输入只是变量,不是全部上下文
- 历史消息要显式注入
- 输出格式要提前约束
以后你让 Codex 写 prompt,可以直接说:
“给我一个 ChatPromptTemplate,包含 system、history、human 三段。”
“输出严格限制为 JSON。”
“不要让模型自由发挥,提示词里加失败兜底规则。”
五、RAG 是以后最常写的能力
你必须把 RAG 当成标准模块,而不是高级技巧。
RAG 核心链路就五步:
- 加载文档
- 切分文档
- 生成向量
- 向量检索
- 把检索结果塞回 prompt 再生成
你至少要记住这些对象:
- Document
- Loader
- TextSplitter
- Embedding
- VectorStore
- Retriever
以后你可以直接命令 Codex:
“先把 markdown 文档加载成 Document。”
“用递归文本分割器按 chunk_size=500, overlap=50 切分。”
“用 embedding 写入 FAISS。”
“把 vectorstore 转成 retriever,再接到 RAG chain 里。”
六、RAG 里最关键的是切分和检索,不是模型
很多人会误以为 RAG 效果差是模型不行,其实多数问题出在前面。
你要记住:
- chunk_size 太大
检索命中不准。 - chunk_size 太小
上下文不完整。 - chunk_overlap
用来减少切断语义的问题,但不是越大越好。 - similarity
最基础的检索。 - score_threshold
过滤掉相似度太低的结果。 - MMR
让结果既相关,又不要太重复。
以后你下指令时要会说:
“这个检索改成 mmr,避免返回太多重复片段。”
“加 score_threshold,别把低相关内容也塞进上下文。”
“重新调 chunk_size,现在召回太碎了。”
七、Embedding 和 VectorStore 只需要抓住本质
不要一上来背很多库,先记本质:
- Embedding
把文本变成向量,方便按语义相似度搜索。 - VectorStore
存向量并支持相似度检索。 - Retriever
是给上层调用的统一检索接口。
常见理解:
- FAISS:本地、轻量、原型快
- Weaviate/Pinecone:更偏服务化/生产化
你以后说需求时,表达应该很清楚:
“先用 FAISS 做本地原型,不上云向量库。”
“向量库最后统一暴露 retriever,不要业务层直接操作底层 store。”
八、ReRank 是 RAG 效果提升的关键手段
这个很值得记,因为以后你会经常遇到“检索到了一堆差不多但不够准的内容”。
本质流程是:
- 先向量检索召回一批候选
- 再用重排模型按 query-doc 相关性重新排序
- 只把最相关的文档给 LLM
你可以把它理解成:
“向量检索负责粗筛,ReRank 负责精排。”
以后你可以直接让 Codex:
“先 top_k 召回 10 条,再做 rerank,只保留前 3 条进 prompt。”
九、Tool Calling 是你以后做实用 AI 应用的核心
如果只是聊天,LLM 只会“说”。
加了工具调用,它才会“做”。
你要记住流程:
- 定义工具
- 给工具写清楚参数 schema
- 用 bind_tools() 绑定给模型
- 模型返回 tool_calls
- 执行工具
- 把结果回灌给模型,生成最终答案
关键理解:
模型不是直接执行函数。
模型只是先决定“该调用哪个工具、传什么参数”。
以后你指挥 Codex 可以这样说:
“把这个天气查询封装成 tool,用 pydantic 定义参数。”
“模型层启用 bind_tools()。”
“如果有 tool_calls,执行工具后再走一次 LLM 总结结果。”
十、Agent 不要神化,本质就是带决策循环的工具调用
你先记一句最实用的话:
Agent = 模型 + 工具 + 决策循环
它和普通 chain 的区别是:
普通 chain 是你提前写死流程。
Agent 是让模型在运行时决定下一步干什么。
你要记住两个方向:
- ReACT
通过 prompt 让模型输出思考、动作、观察。 - Tool Calling Agent
利用模型原生函数调用能力来做决策。
以后实战里,优先级一般是:
支持函数调用的模型 -> 优先 Tool Calling
不支持函数调用 -> 再考虑 ReACT
十一、LangGraph 是复杂流程编排,不只是 Agent
这个你一定要记牢,因为以后你让 Codex 写复杂 AI 工作流时,LangGraph 会很好用。
核心概念只有四个:
- State
共享状态,节点之间传的数据。 - Node
一个执行步骤。 - Edge
节点之间怎么走。 - 条件边 / 循环
决定流程分支和 반복执行。
一句话理解:
LangChain 更像线性拼装。
LangGraph 更像状态机工作流。
十二、LangGraph 你最该记的能力
- 条件分支
根据状态决定走哪条边。 - 循环
比如模型决定要不要继续调用工具。 - 持久化
用 checkpointer 保存状态。 - Human-in-the-loop
在某个节点前后中断,让人确认。 - 子图
把复杂流程拆成多个小图再组合。
以后你给 Codex 的命令可以很明确:
“这里不要普通 chain,改成 LangGraph。”
“定义一个 State,至少包含 messages、context、next_step。”
“加条件边:有 tool call 就走 tools,没有就结束。”
“在执行敏感工具前 interrupt_before,让人确认。”
十三、记忆系统要会分层理解
你不要只记“memory 能记住聊天”。
要分成三类:
- 短期记忆
最近几轮对话。 - 摘要记忆
把早期对话压缩成摘要。 - 持久化记忆
写文件、数据库、checkpoint。
核心原则:
不是把所有历史都塞进去。
而是只保留“当前任务有用的信息”。
以后你可以指挥 Codex:
“加一个窗口记忆,只保留最近 6 轮。”
“历史太长时,旧消息压成摘要。”
“会话状态用 thread_id 区分并持久化。”
十四、健壮性是 AI 代码必须单独设计的
你这套笔记里也有这部分,实战非常重要。
要记住:
- 重试
模型调用、工具调用、网络请求都可能失败。 - 回退
主模型失败时切备用模型,或者走简化路径。 - 错误捕获
工具失败不能直接把整个流程打崩。 - 日志和回调
你要能看到每一步发生了什么。
以后你可以直接说:
“给这个 Runnable 加重试和 fallback。”
“工具报错不要抛死,返回结构化错误信息。”
“把中间步骤打印出来,便于调试。”
十五、以后你指挥 Codex,最好用这种表达方式
不要说:
“帮我写个聊天机器人。”
要说成可执行需求:
- “用 LangChain 写一个 RAG 问答链,文档源是本地 markdown,向量库用 FAISS。”
- “Prompt 用 ChatPromptTemplate,包含 system、history、human。”
- “检索器用 mmr,top_k=5,再 rerank 成 top_3。”
- “链路用 LCEL 实现,不要手搓。”
- “如果用户问题需要实时信息,就走 tool calling 调搜索工具。”
- “复杂流程改成 LangGraph,加条件边和 checkpoint。”
- “所有外部调用加超时、重试和错误处理。”
- “输出必须是结构化 JSON,方便前端消费。”
这种说法,Codex 最容易一次写对。
十六、你现在最值得背下来的最小知识清单
如果只保留最小集合,就背这个:
- PromptTemplate / ChatPromptTemplate
- MessagesPlaceholder
- ChatModel.invoke / stream / batch
- OutputParser
- Runnable
- LCEL
- RunnableParallel
- RunnablePassthrough.assign
- Document / Loader / TextSplitter
- Embedding
- VectorStore / Retriever
- similarity / threshold / mmr
- RAG
- ReRank
- bind_tools
- tool_calls
- Agent
- State / Node / Edge
- Checkpoint
- Memory
十七、你可以把整个知识体系压缩成一句话
以后你脑子里就放这句:
“先用 Prompt 和 Model 做基础生成,用 Runnable/LCEL 做编排,用 RAG 提供知识,用 Tool/Agent 提供行动,用 LangGraph 管复杂流程,用 Memory 和 Checkpoint 管状态,用重试回退和日志保证稳定。”