直接调 OpenAI API 就够了,为什么还要 LangChain?
简单场景确实不需要。但当应用从「一个 Prompt」长成「可用的 AI 系统」,复杂度会集中在组件协作上:Prompt 管理、结构化输出、Tool 接入、RAG、多步编排与调试。
LangChain 不替代 LLM,而是把这些组件串成可组合、可维护的流水线。
一、没有 LangChain 的世界
最简单的 LLM 调用
以 Node.js 为例:
javascript
import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
});
const response = await client.chat.completions.create({
model: "gpt-4.1",
messages: [
{
role: "user",
content: "给登录页加一个忘记密码入口,帮我写个 React 组件",
},
],
});
console.log(response.choices[0].message.content);
非常简单:一次请求,一次响应,模型直接吐出代码片段,没有 JSON 解析、没有查仓库、也没有对照内部规范。
什么时候开始变复杂
产品提出完整需求:
做一个「智能代码助手」:用户用自然语言描述功能(比如「给登录页加一个忘记密码入口」),系统自动生成代码,并结合该项目的 GitHub 仓库现状和内部开发规范,输出一份结构化的技术方案报告。
拆解下来,后端要完成五件事:
| 步骤 | 做什么 | 为什么复杂 |
|---|---|---|
| 1. 生成代码 | 根据用户描述调用 LLM 产出代码 | 需要维护 Prompt 模板、上下文注入 |
| 2. 输出 JSON | 把结果解析成 { files, summary, risks } 等固定字段 |
LLM 输出不稳定,需要 Parser |
| 3. 查 GitHub | 调用 API 获取仓库结构、已有文件、PR 规范 | 需要 Tool 封装和鉴权 |
| 4. 检索知识库 | 从向量库拉取内部编码规范、架构文档 | 需要 RAG 流水线 |
| 5. 生成报告 | 把代码、仓库信息、规范文档合并,输出最终报告 | 多源数据合并 + 二次 LLM 调用 |
#mermaid-svg-be9k5WxmhZrxRPVt{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-be9k5WxmhZrxRPVt .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-be9k5WxmhZrxRPVt .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-be9k5WxmhZrxRPVt .error-icon{fill:#552222;}#mermaid-svg-be9k5WxmhZrxRPVt .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-be9k5WxmhZrxRPVt .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-be9k5WxmhZrxRPVt .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-be9k5WxmhZrxRPVt .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-be9k5WxmhZrxRPVt .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-be9k5WxmhZrxRPVt .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-be9k5WxmhZrxRPVt .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-be9k5WxmhZrxRPVt .marker{fill:#333333;stroke:#333333;}#mermaid-svg-be9k5WxmhZrxRPVt .marker.cross{stroke:#333333;}#mermaid-svg-be9k5WxmhZrxRPVt svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-be9k5WxmhZrxRPVt p{margin:0;}#mermaid-svg-be9k5WxmhZrxRPVt .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-be9k5WxmhZrxRPVt .cluster-label text{fill:#333;}#mermaid-svg-be9k5WxmhZrxRPVt .cluster-label span{color:#333;}#mermaid-svg-be9k5WxmhZrxRPVt .cluster-label span p{background-color:transparent;}#mermaid-svg-be9k5WxmhZrxRPVt .label text,#mermaid-svg-be9k5WxmhZrxRPVt span{fill:#333;color:#333;}#mermaid-svg-be9k5WxmhZrxRPVt .node rect,#mermaid-svg-be9k5WxmhZrxRPVt .node circle,#mermaid-svg-be9k5WxmhZrxRPVt .node ellipse,#mermaid-svg-be9k5WxmhZrxRPVt .node polygon,#mermaid-svg-be9k5WxmhZrxRPVt .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-be9k5WxmhZrxRPVt .rough-node .label text,#mermaid-svg-be9k5WxmhZrxRPVt .node .label text,#mermaid-svg-be9k5WxmhZrxRPVt .image-shape .label,#mermaid-svg-be9k5WxmhZrxRPVt .icon-shape .label{text-anchor:middle;}#mermaid-svg-be9k5WxmhZrxRPVt .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-be9k5WxmhZrxRPVt .rough-node .label,#mermaid-svg-be9k5WxmhZrxRPVt .node .label,#mermaid-svg-be9k5WxmhZrxRPVt .image-shape .label,#mermaid-svg-be9k5WxmhZrxRPVt .icon-shape .label{text-align:center;}#mermaid-svg-be9k5WxmhZrxRPVt .node.clickable{cursor:pointer;}#mermaid-svg-be9k5WxmhZrxRPVt .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-be9k5WxmhZrxRPVt .arrowheadPath{fill:#333333;}#mermaid-svg-be9k5WxmhZrxRPVt .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-be9k5WxmhZrxRPVt .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-be9k5WxmhZrxRPVt .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-be9k5WxmhZrxRPVt .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-be9k5WxmhZrxRPVt .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-be9k5WxmhZrxRPVt .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-be9k5WxmhZrxRPVt .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-be9k5WxmhZrxRPVt .cluster text{fill:#333;}#mermaid-svg-be9k5WxmhZrxRPVt .cluster span{color:#333;}#mermaid-svg-be9k5WxmhZrxRPVt div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-be9k5WxmhZrxRPVt .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-be9k5WxmhZrxRPVt rect.text{fill:none;stroke-width:0;}#mermaid-svg-be9k5WxmhZrxRPVt .icon-shape,#mermaid-svg-be9k5WxmhZrxRPVt .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-be9k5WxmhZrxRPVt .icon-shape p,#mermaid-svg-be9k5WxmhZrxRPVt .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-be9k5WxmhZrxRPVt .icon-shape .label rect,#mermaid-svg-be9k5WxmhZrxRPVt .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-be9k5WxmhZrxRPVt .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-be9k5WxmhZrxRPVt .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-be9k5WxmhZrxRPVt :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 用户输入功能描述
LLM 生成代码
解析为 JSON 结构
GitHub API 查仓库信息
RAG 检索内部规范文档
合并数据,生成最终报告
原本只是一次 chat.completions.create,现在要串起五条链路。你的代码很快会变成:
javascript
const requirement = "给登录页加一个忘记密码入口";
const prompt = buildCodeGenPrompt(requirement);
const llmResult = await callLLM(prompt);
const codeDraft = parseCodeResult(llmResult);
const repoInfo = await fetchGitHubRepo("my-org/web-app");
const standards = await vectorSearch("前端表单组件开发规范");
const report = await generateReport({ requirement, codeDraft, repoInfo, standards });
真正复杂的,已经不是调用模型,而是组织这些组件------入参出参各不相同,改一处 Prompt 可能影响 Parser 和下游 Tool。
这正是 LangChain 要解决的问题。第二至五节将沿上表五个环节依次展开,说明 LangChain 在每一层提供的抽象与实现方式。
二、Runnable 与 Chain ------ 步骤 1:生成代码
对应环节 :步骤 1 · 生成代码 | 核心抽象 :Runnable、
pipe、Chain
LangChain 最核心的思想只有一句话:Everything is Runnable------所有组件都可以执行,都可以组合。
#mermaid-svg-rVXsgfUtXdlu9XME{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-rVXsgfUtXdlu9XME .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-rVXsgfUtXdlu9XME .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-rVXsgfUtXdlu9XME .error-icon{fill:#552222;}#mermaid-svg-rVXsgfUtXdlu9XME .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-rVXsgfUtXdlu9XME .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-rVXsgfUtXdlu9XME .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-rVXsgfUtXdlu9XME .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-rVXsgfUtXdlu9XME .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-rVXsgfUtXdlu9XME .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-rVXsgfUtXdlu9XME .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-rVXsgfUtXdlu9XME .marker{fill:#333333;stroke:#333333;}#mermaid-svg-rVXsgfUtXdlu9XME .marker.cross{stroke:#333333;}#mermaid-svg-rVXsgfUtXdlu9XME svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-rVXsgfUtXdlu9XME p{margin:0;}#mermaid-svg-rVXsgfUtXdlu9XME .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-rVXsgfUtXdlu9XME .cluster-label text{fill:#333;}#mermaid-svg-rVXsgfUtXdlu9XME .cluster-label span{color:#333;}#mermaid-svg-rVXsgfUtXdlu9XME .cluster-label span p{background-color:transparent;}#mermaid-svg-rVXsgfUtXdlu9XME .label text,#mermaid-svg-rVXsgfUtXdlu9XME span{fill:#333;color:#333;}#mermaid-svg-rVXsgfUtXdlu9XME .node rect,#mermaid-svg-rVXsgfUtXdlu9XME .node circle,#mermaid-svg-rVXsgfUtXdlu9XME .node ellipse,#mermaid-svg-rVXsgfUtXdlu9XME .node polygon,#mermaid-svg-rVXsgfUtXdlu9XME .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-rVXsgfUtXdlu9XME .rough-node .label text,#mermaid-svg-rVXsgfUtXdlu9XME .node .label text,#mermaid-svg-rVXsgfUtXdlu9XME .image-shape .label,#mermaid-svg-rVXsgfUtXdlu9XME .icon-shape .label{text-anchor:middle;}#mermaid-svg-rVXsgfUtXdlu9XME .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-rVXsgfUtXdlu9XME .rough-node .label,#mermaid-svg-rVXsgfUtXdlu9XME .node .label,#mermaid-svg-rVXsgfUtXdlu9XME .image-shape .label,#mermaid-svg-rVXsgfUtXdlu9XME .icon-shape .label{text-align:center;}#mermaid-svg-rVXsgfUtXdlu9XME .node.clickable{cursor:pointer;}#mermaid-svg-rVXsgfUtXdlu9XME .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-rVXsgfUtXdlu9XME .arrowheadPath{fill:#333333;}#mermaid-svg-rVXsgfUtXdlu9XME .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-rVXsgfUtXdlu9XME .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-rVXsgfUtXdlu9XME .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-rVXsgfUtXdlu9XME .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-rVXsgfUtXdlu9XME .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-rVXsgfUtXdlu9XME .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-rVXsgfUtXdlu9XME .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-rVXsgfUtXdlu9XME .cluster text{fill:#333;}#mermaid-svg-rVXsgfUtXdlu9XME .cluster span{color:#333;}#mermaid-svg-rVXsgfUtXdlu9XME div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-rVXsgfUtXdlu9XME .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-rVXsgfUtXdlu9XME rect.text{fill:none;stroke-width:0;}#mermaid-svg-rVXsgfUtXdlu9XME .icon-shape,#mermaid-svg-rVXsgfUtXdlu9XME .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-rVXsgfUtXdlu9XME .icon-shape p,#mermaid-svg-rVXsgfUtXdlu9XME .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-rVXsgfUtXdlu9XME .icon-shape .label rect,#mermaid-svg-rVXsgfUtXdlu9XME .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-rVXsgfUtXdlu9XME .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-rVXsgfUtXdlu9XME .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-rVXsgfUtXdlu9XME :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 统一接口:invoke()
Prompt
Model
Parser
Tool
Retriever
Runnable:统一插头
回到第一节的胶水代码,五个步骤其实是五种不同的调用方式------入参、出参、错误处理各写各的。Runnable 把它们统一成同一种插头:
| 方法 | 用途 |
|---|---|
invoke(input) |
单次调用 |
batch(inputs) |
批量调用 |
stream(input) |
流式输出 |
pipe(next) |
串联下一个 Runnable |
以步骤 1 为例,三个 Runnable 职责不同,调用方式相同:
① Prompt ------把 { requirement } 格式化成 Message[]
javascript
const prompt = ChatPromptTemplate.fromTemplate(
`根据以下需求生成代码:\n{requirement}`
);
const messages = await prompt.invoke({
requirement: "给登录页加一个忘记密码入口",
});
② Model ------把 Message[] 发给 LLM,拿回 AIMessage
javascript
const model = new ChatOpenAI({ model: "gpt-4.1" });
const aiMessage = await model.invoke(messages);
③ Parser ------把 AIMessage 转成 string
javascript
const parser = new StringOutputParser();
const codeText = await parser.invoke(aiMessage);
三步串起来,数据形态的变化是:
#mermaid-svg-pwIpMZ6EwWUMh7uO{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-pwIpMZ6EwWUMh7uO .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-pwIpMZ6EwWUMh7uO .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-pwIpMZ6EwWUMh7uO .error-icon{fill:#552222;}#mermaid-svg-pwIpMZ6EwWUMh7uO .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-pwIpMZ6EwWUMh7uO .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-pwIpMZ6EwWUMh7uO .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-pwIpMZ6EwWUMh7uO .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-pwIpMZ6EwWUMh7uO .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-pwIpMZ6EwWUMh7uO .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-pwIpMZ6EwWUMh7uO .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-pwIpMZ6EwWUMh7uO .marker{fill:#333333;stroke:#333333;}#mermaid-svg-pwIpMZ6EwWUMh7uO .marker.cross{stroke:#333333;}#mermaid-svg-pwIpMZ6EwWUMh7uO svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-pwIpMZ6EwWUMh7uO p{margin:0;}#mermaid-svg-pwIpMZ6EwWUMh7uO .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-pwIpMZ6EwWUMh7uO .cluster-label text{fill:#333;}#mermaid-svg-pwIpMZ6EwWUMh7uO .cluster-label span{color:#333;}#mermaid-svg-pwIpMZ6EwWUMh7uO .cluster-label span p{background-color:transparent;}#mermaid-svg-pwIpMZ6EwWUMh7uO .label text,#mermaid-svg-pwIpMZ6EwWUMh7uO span{fill:#333;color:#333;}#mermaid-svg-pwIpMZ6EwWUMh7uO .node rect,#mermaid-svg-pwIpMZ6EwWUMh7uO .node circle,#mermaid-svg-pwIpMZ6EwWUMh7uO .node ellipse,#mermaid-svg-pwIpMZ6EwWUMh7uO .node polygon,#mermaid-svg-pwIpMZ6EwWUMh7uO .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-pwIpMZ6EwWUMh7uO .rough-node .label text,#mermaid-svg-pwIpMZ6EwWUMh7uO .node .label text,#mermaid-svg-pwIpMZ6EwWUMh7uO .image-shape .label,#mermaid-svg-pwIpMZ6EwWUMh7uO .icon-shape .label{text-anchor:middle;}#mermaid-svg-pwIpMZ6EwWUMh7uO .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-pwIpMZ6EwWUMh7uO .rough-node .label,#mermaid-svg-pwIpMZ6EwWUMh7uO .node .label,#mermaid-svg-pwIpMZ6EwWUMh7uO .image-shape .label,#mermaid-svg-pwIpMZ6EwWUMh7uO .icon-shape .label{text-align:center;}#mermaid-svg-pwIpMZ6EwWUMh7uO .node.clickable{cursor:pointer;}#mermaid-svg-pwIpMZ6EwWUMh7uO .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-pwIpMZ6EwWUMh7uO .arrowheadPath{fill:#333333;}#mermaid-svg-pwIpMZ6EwWUMh7uO .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-pwIpMZ6EwWUMh7uO .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-pwIpMZ6EwWUMh7uO .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-pwIpMZ6EwWUMh7uO .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-pwIpMZ6EwWUMh7uO .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-pwIpMZ6EwWUMh7uO .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-pwIpMZ6EwWUMh7uO .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-pwIpMZ6EwWUMh7uO .cluster text{fill:#333;}#mermaid-svg-pwIpMZ6EwWUMh7uO .cluster span{color:#333;}#mermaid-svg-pwIpMZ6EwWUMh7uO div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-pwIpMZ6EwWUMh7uO .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-pwIpMZ6EwWUMh7uO rect.text{fill:none;stroke-width:0;}#mermaid-svg-pwIpMZ6EwWUMh7uO .icon-shape,#mermaid-svg-pwIpMZ6EwWUMh7uO .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-pwIpMZ6EwWUMh7uO .icon-shape p,#mermaid-svg-pwIpMZ6EwWUMh7uO .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-pwIpMZ6EwWUMh7uO .icon-shape .label rect,#mermaid-svg-pwIpMZ6EwWUMh7uO .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-pwIpMZ6EwWUMh7uO .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-pwIpMZ6EwWUMh7uO .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-pwIpMZ6EwWUMh7uO :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} { requirement }
Prompt.invoke()
Message
Model.invoke()
AIMessage
Parser.invoke()
string
Chain:pipe 把三步合成一次调用
手写三步需要手动传参;用 pipe 等价于:
javascript
const codeGenChain = prompt.pipe(model).pipe(parser);
const codeText = await codeGenChain.invoke({
requirement: "给登录页加一个忘记密码入口",
});
一次 invoke,框架自动完成 Prompt → Model → Parser 的流转------即 Chain,也是 LangChain 对步骤 1 的实现方式。
#mermaid-svg-wyv322LlDDYNNkTL{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-wyv322LlDDYNNkTL .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-wyv322LlDDYNNkTL .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-wyv322LlDDYNNkTL .error-icon{fill:#552222;}#mermaid-svg-wyv322LlDDYNNkTL .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-wyv322LlDDYNNkTL .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-wyv322LlDDYNNkTL .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-wyv322LlDDYNNkTL .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-wyv322LlDDYNNkTL .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-wyv322LlDDYNNkTL .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-wyv322LlDDYNNkTL .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-wyv322LlDDYNNkTL .marker{fill:#333333;stroke:#333333;}#mermaid-svg-wyv322LlDDYNNkTL .marker.cross{stroke:#333333;}#mermaid-svg-wyv322LlDDYNNkTL svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-wyv322LlDDYNNkTL p{margin:0;}#mermaid-svg-wyv322LlDDYNNkTL .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-wyv322LlDDYNNkTL .cluster-label text{fill:#333;}#mermaid-svg-wyv322LlDDYNNkTL .cluster-label span{color:#333;}#mermaid-svg-wyv322LlDDYNNkTL .cluster-label span p{background-color:transparent;}#mermaid-svg-wyv322LlDDYNNkTL .label text,#mermaid-svg-wyv322LlDDYNNkTL span{fill:#333;color:#333;}#mermaid-svg-wyv322LlDDYNNkTL .node rect,#mermaid-svg-wyv322LlDDYNNkTL .node circle,#mermaid-svg-wyv322LlDDYNNkTL .node ellipse,#mermaid-svg-wyv322LlDDYNNkTL .node polygon,#mermaid-svg-wyv322LlDDYNNkTL .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-wyv322LlDDYNNkTL .rough-node .label text,#mermaid-svg-wyv322LlDDYNNkTL .node .label text,#mermaid-svg-wyv322LlDDYNNkTL .image-shape .label,#mermaid-svg-wyv322LlDDYNNkTL .icon-shape .label{text-anchor:middle;}#mermaid-svg-wyv322LlDDYNNkTL .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-wyv322LlDDYNNkTL .rough-node .label,#mermaid-svg-wyv322LlDDYNNkTL .node .label,#mermaid-svg-wyv322LlDDYNNkTL .image-shape .label,#mermaid-svg-wyv322LlDDYNNkTL .icon-shape .label{text-align:center;}#mermaid-svg-wyv322LlDDYNNkTL .node.clickable{cursor:pointer;}#mermaid-svg-wyv322LlDDYNNkTL .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-wyv322LlDDYNNkTL .arrowheadPath{fill:#333333;}#mermaid-svg-wyv322LlDDYNNkTL .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-wyv322LlDDYNNkTL .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-wyv322LlDDYNNkTL .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-wyv322LlDDYNNkTL .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-wyv322LlDDYNNkTL .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-wyv322LlDDYNNkTL .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-wyv322LlDDYNNkTL .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-wyv322LlDDYNNkTL .cluster text{fill:#333;}#mermaid-svg-wyv322LlDDYNNkTL .cluster span{color:#333;}#mermaid-svg-wyv322LlDDYNNkTL div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-wyv322LlDDYNNkTL .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-wyv322LlDDYNNkTL rect.text{fill:none;stroke-width:0;}#mermaid-svg-wyv322LlDDYNNkTL .icon-shape,#mermaid-svg-wyv322LlDDYNNkTL .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-wyv322LlDDYNNkTL .icon-shape p,#mermaid-svg-wyv322LlDDYNNkTL .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-wyv322LlDDYNNkTL .icon-shape .label rect,#mermaid-svg-wyv322LlDDYNNkTL .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-wyv322LlDDYNNkTL .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-wyv322LlDDYNNkTL .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-wyv322LlDDYNNkTL :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} input: { requirement }
codeGenChain.invoke
output: 代码文本
步骤 1 可由 Chain 完整覆盖。步骤 2 则引入新的约束:输出须为 { files, summary, risks } 结构,而非纯文本------Model 与 Parser 的用法均需调整。
三、结构化输出 ------ 步骤 2:结构化 JSON
对应环节 :步骤 2 · 输出 JSON | 核心抽象 :Schema、
withStructuredOutput
步骤 1 的 Chain 输出的是字符串,下游步骤 3~5 需要的是结构化对象。如果只靠 Prompt 让模型返回 JSON:
javascript
const result = await model.invoke(
"给登录页加忘记密码入口,返回 files、summary、risks 的 JSON"
);
同一条 Prompt,模型可能返回 Markdown 代码块、字段名对不上的 JSON、或把 risks 写进 summary------fetchGitHubRepo 和 generateReport 无法稳定消费。
LangChain 用 Schema 约束输出(底层依赖 JSON Mode),目的是固定 LLM 的回复格式:
javascript
import { z } from "zod";
const codeDraftSchema = z.object({
files: z.array(z.object({ path: z.string(), content: z.string() })),
summary: z.string(),
risks: z.array(z.string()),
});
const structuredModel = model.withStructuredOutput(codeDraftSchema);
const codeDraft = await structuredModel.invoke(
"给登录页加一个忘记密码入口"
);
json
{
"files": [
{ "path": "src/pages/Login.tsx", "content": "..." },
{ "path": "src/api/auth.ts", "content": "..." }
],
"summary": "新增忘记密码入口,调用 /auth/reset-password 接口",
"risks": ["需确认现有 auth 中间件是否支持", "移动端样式需单独适配"]
}
#mermaid-svg-Ji4io3iFCRGC8sZU{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Ji4io3iFCRGC8sZU .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Ji4io3iFCRGC8sZU .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Ji4io3iFCRGC8sZU .error-icon{fill:#552222;}#mermaid-svg-Ji4io3iFCRGC8sZU .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Ji4io3iFCRGC8sZU .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Ji4io3iFCRGC8sZU .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Ji4io3iFCRGC8sZU .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Ji4io3iFCRGC8sZU .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Ji4io3iFCRGC8sZU .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Ji4io3iFCRGC8sZU .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Ji4io3iFCRGC8sZU .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Ji4io3iFCRGC8sZU .marker.cross{stroke:#333333;}#mermaid-svg-Ji4io3iFCRGC8sZU svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Ji4io3iFCRGC8sZU p{margin:0;}#mermaid-svg-Ji4io3iFCRGC8sZU .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-Ji4io3iFCRGC8sZU .cluster-label text{fill:#333;}#mermaid-svg-Ji4io3iFCRGC8sZU .cluster-label span{color:#333;}#mermaid-svg-Ji4io3iFCRGC8sZU .cluster-label span p{background-color:transparent;}#mermaid-svg-Ji4io3iFCRGC8sZU .label text,#mermaid-svg-Ji4io3iFCRGC8sZU span{fill:#333;color:#333;}#mermaid-svg-Ji4io3iFCRGC8sZU .node rect,#mermaid-svg-Ji4io3iFCRGC8sZU .node circle,#mermaid-svg-Ji4io3iFCRGC8sZU .node ellipse,#mermaid-svg-Ji4io3iFCRGC8sZU .node polygon,#mermaid-svg-Ji4io3iFCRGC8sZU .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Ji4io3iFCRGC8sZU .rough-node .label text,#mermaid-svg-Ji4io3iFCRGC8sZU .node .label text,#mermaid-svg-Ji4io3iFCRGC8sZU .image-shape .label,#mermaid-svg-Ji4io3iFCRGC8sZU .icon-shape .label{text-anchor:middle;}#mermaid-svg-Ji4io3iFCRGC8sZU .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-Ji4io3iFCRGC8sZU .rough-node .label,#mermaid-svg-Ji4io3iFCRGC8sZU .node .label,#mermaid-svg-Ji4io3iFCRGC8sZU .image-shape .label,#mermaid-svg-Ji4io3iFCRGC8sZU .icon-shape .label{text-align:center;}#mermaid-svg-Ji4io3iFCRGC8sZU .node.clickable{cursor:pointer;}#mermaid-svg-Ji4io3iFCRGC8sZU .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-Ji4io3iFCRGC8sZU .arrowheadPath{fill:#333333;}#mermaid-svg-Ji4io3iFCRGC8sZU .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-Ji4io3iFCRGC8sZU .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-Ji4io3iFCRGC8sZU .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Ji4io3iFCRGC8sZU .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-Ji4io3iFCRGC8sZU .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Ji4io3iFCRGC8sZU .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-Ji4io3iFCRGC8sZU .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Ji4io3iFCRGC8sZU .cluster text{fill:#333;}#mermaid-svg-Ji4io3iFCRGC8sZU .cluster span{color:#333;}#mermaid-svg-Ji4io3iFCRGC8sZU div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-Ji4io3iFCRGC8sZU .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-Ji4io3iFCRGC8sZU rect.text{fill:none;stroke-width:0;}#mermaid-svg-Ji4io3iFCRGC8sZU .icon-shape,#mermaid-svg-Ji4io3iFCRGC8sZU .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Ji4io3iFCRGC8sZU .icon-shape p,#mermaid-svg-Ji4io3iFCRGC8sZU .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-Ji4io3iFCRGC8sZU .icon-shape .label rect,#mermaid-svg-Ji4io3iFCRGC8sZU .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Ji4io3iFCRGC8sZU .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-Ji4io3iFCRGC8sZU .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-Ji4io3iFCRGC8sZU :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} LLM 输出
Schema 校验
codeDraft 对象
→ 步骤 3 / 4 / 5
codeDraft.files 可以交给 GitHub diff 对比,codeDraft.risks 可以注入最终报告------解析逻辑从业务代码挪到了框架层。
步骤 2 通过 Schema 约束得以实现。步骤 3 的需求本质不同:须由 LLM 决策是否、何时调用外部 API,而非仅格式化输出。
四、Tool 与 Tool Calling ------ 步骤 3:GitHub 集成
对应环节 :步骤 3 · 查 GitHub | 核心抽象 :
tool()、bindTools、执行循环
第一节的写法是硬编码:
javascript
const repoInfo = await fetchGitHubRepo("my-org/web-app"); // 写死仓库,写死调用时机
Tool Calling 换了一种方式------何时查、查哪个仓库,由模型根据用户问题决定:
javascript
// 用户问 "分析 web-app" → 模型返回 tool_call
// 用户问 "这段代码什么意思" → 模型直接回答,不调 Tool
const modelWithTools = model.bindTools([githubTool]);
Tool Calling 是 OpenAI / LangChain 的常用叫法;Anthropic 称 Tool Use ,早期也称 Function Calling------指的都是同一件事。
#mermaid-svg-zVOUoN8yryxARuMu{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-zVOUoN8yryxARuMu .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-zVOUoN8yryxARuMu .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-zVOUoN8yryxARuMu .error-icon{fill:#552222;}#mermaid-svg-zVOUoN8yryxARuMu .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-zVOUoN8yryxARuMu .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-zVOUoN8yryxARuMu .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-zVOUoN8yryxARuMu .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-zVOUoN8yryxARuMu .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-zVOUoN8yryxARuMu .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-zVOUoN8yryxARuMu .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-zVOUoN8yryxARuMu .marker{fill:#333333;stroke:#333333;}#mermaid-svg-zVOUoN8yryxARuMu .marker.cross{stroke:#333333;}#mermaid-svg-zVOUoN8yryxARuMu svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-zVOUoN8yryxARuMu p{margin:0;}#mermaid-svg-zVOUoN8yryxARuMu .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-zVOUoN8yryxARuMu .cluster-label text{fill:#333;}#mermaid-svg-zVOUoN8yryxARuMu .cluster-label span{color:#333;}#mermaid-svg-zVOUoN8yryxARuMu .cluster-label span p{background-color:transparent;}#mermaid-svg-zVOUoN8yryxARuMu .label text,#mermaid-svg-zVOUoN8yryxARuMu span{fill:#333;color:#333;}#mermaid-svg-zVOUoN8yryxARuMu .node rect,#mermaid-svg-zVOUoN8yryxARuMu .node circle,#mermaid-svg-zVOUoN8yryxARuMu .node ellipse,#mermaid-svg-zVOUoN8yryxARuMu .node polygon,#mermaid-svg-zVOUoN8yryxARuMu .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-zVOUoN8yryxARuMu .rough-node .label text,#mermaid-svg-zVOUoN8yryxARuMu .node .label text,#mermaid-svg-zVOUoN8yryxARuMu .image-shape .label,#mermaid-svg-zVOUoN8yryxARuMu .icon-shape .label{text-anchor:middle;}#mermaid-svg-zVOUoN8yryxARuMu .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-zVOUoN8yryxARuMu .rough-node .label,#mermaid-svg-zVOUoN8yryxARuMu .node .label,#mermaid-svg-zVOUoN8yryxARuMu .image-shape .label,#mermaid-svg-zVOUoN8yryxARuMu .icon-shape .label{text-align:center;}#mermaid-svg-zVOUoN8yryxARuMu .node.clickable{cursor:pointer;}#mermaid-svg-zVOUoN8yryxARuMu .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-zVOUoN8yryxARuMu .arrowheadPath{fill:#333333;}#mermaid-svg-zVOUoN8yryxARuMu .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-zVOUoN8yryxARuMu .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-zVOUoN8yryxARuMu .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-zVOUoN8yryxARuMu .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-zVOUoN8yryxARuMu .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-zVOUoN8yryxARuMu .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-zVOUoN8yryxARuMu .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-zVOUoN8yryxARuMu .cluster text{fill:#333;}#mermaid-svg-zVOUoN8yryxARuMu .cluster span{color:#333;}#mermaid-svg-zVOUoN8yryxARuMu div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-zVOUoN8yryxARuMu .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-zVOUoN8yryxARuMu rect.text{fill:none;stroke-width:0;}#mermaid-svg-zVOUoN8yryxARuMu .icon-shape,#mermaid-svg-zVOUoN8yryxARuMu .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-zVOUoN8yryxARuMu .icon-shape p,#mermaid-svg-zVOUoN8yryxARuMu .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-zVOUoN8yryxARuMu .icon-shape .label rect,#mermaid-svg-zVOUoN8yryxARuMu .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-zVOUoN8yryxARuMu .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-zVOUoN8yryxARuMu .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-zVOUoN8yryxARuMu :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 做法 B · LangChain Tool Calling
tool_calls
用户问题
LLM 决策
运行时执行
GitHub API
LLM 继续推理
做法 A · 第一节写法
固定调用
业务代码
GitHub API
定义 Tool(对 GitHub API 的 Runnable 封装):
javascript
import { tool } from "@langchain/core/tools";
const githubTool = tool(
async ({ owner, repo }) => {
const tree = await fetchRepoTree(owner, repo);
return JSON.stringify(tree);
},
{
name: "fetch_github_repo",
description: "查询 GitHub 仓库的目录结构和协作信息",
schema: z.object({ owner: z.string(), repo: z.string() }),
}
);
用户问:「分析 my-org/web-app,为忘记密码功能生成改造方案」------模型返回 Tool Call,运行时执行后再推理:
GitHub Tool 运行时 LLM 用户 GitHub Tool 运行时 LLM 用户 #mermaid-svg-zKRVVE0asQDVkc5x{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-zKRVVE0asQDVkc5x .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-zKRVVE0asQDVkc5x .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-zKRVVE0asQDVkc5x .error-icon{fill:#552222;}#mermaid-svg-zKRVVE0asQDVkc5x .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-zKRVVE0asQDVkc5x .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-zKRVVE0asQDVkc5x .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-zKRVVE0asQDVkc5x .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-zKRVVE0asQDVkc5x .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-zKRVVE0asQDVkc5x .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-zKRVVE0asQDVkc5x .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-zKRVVE0asQDVkc5x .marker{fill:#333333;stroke:#333333;}#mermaid-svg-zKRVVE0asQDVkc5x .marker.cross{stroke:#333333;}#mermaid-svg-zKRVVE0asQDVkc5x svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-zKRVVE0asQDVkc5x p{margin:0;}#mermaid-svg-zKRVVE0asQDVkc5x .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-zKRVVE0asQDVkc5x text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-zKRVVE0asQDVkc5x .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-zKRVVE0asQDVkc5x .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-zKRVVE0asQDVkc5x .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-zKRVVE0asQDVkc5x .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-zKRVVE0asQDVkc5x #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-zKRVVE0asQDVkc5x .sequenceNumber{fill:white;}#mermaid-svg-zKRVVE0asQDVkc5x #sequencenumber{fill:#333;}#mermaid-svg-zKRVVE0asQDVkc5x #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-zKRVVE0asQDVkc5x .messageText{fill:#333;stroke:none;}#mermaid-svg-zKRVVE0asQDVkc5x .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-zKRVVE0asQDVkc5x .labelText,#mermaid-svg-zKRVVE0asQDVkc5x .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-zKRVVE0asQDVkc5x .loopText,#mermaid-svg-zKRVVE0asQDVkc5x .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-zKRVVE0asQDVkc5x .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-zKRVVE0asQDVkc5x .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-zKRVVE0asQDVkc5x .noteText,#mermaid-svg-zKRVVE0asQDVkc5x .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-zKRVVE0asQDVkc5x .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-zKRVVE0asQDVkc5x .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-zKRVVE0asQDVkc5x .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-zKRVVE0asQDVkc5x .actorPopupMenu{position:absolute;}#mermaid-svg-zKRVVE0asQDVkc5x .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-zKRVVE0asQDVkc5x .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-zKRVVE0asQDVkc5x .actor-man circle,#mermaid-svg-zKRVVE0asQDVkc5x line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-zKRVVE0asQDVkc5x :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 分析 web-app,生成忘记密码方案tool_calls(owner=my-org, repo=web-app)执行 Tool仓库 tree、auth 相关文件结果塞回上下文结合仓库现状输出方案
模型负责决策,Tool 负责执行,运行时负责闭环 。当 Tool 不止一个、调用顺序无法预先写死时,就进入 Agent 模式------LangChain 的 createReactAgent 会把上述循环自动迭代。
步骤 3 由 Tool Calling 机制承接。步骤 4 须检索模型训练数据之外的私有知识库;步骤 5 则将前述环节的产物合并为最终报告。
五、RAG 与报告组装 ------ 步骤 4 & 5:知识检索与报告生成
对应环节 :步骤 4 · 检索知识库 / 步骤 5 · 生成报告 | 核心抽象:Retriever、RAG Chain、reportChain
模型知道 React 怎么写,但不知道你们的组件命名规范、PR 模板、安全红线。步骤 4 通过 RAG 把私有文档注入上下文:
#mermaid-svg-Nbq6JaPR12K5nEph{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Nbq6JaPR12K5nEph .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Nbq6JaPR12K5nEph .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Nbq6JaPR12K5nEph .error-icon{fill:#552222;}#mermaid-svg-Nbq6JaPR12K5nEph .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Nbq6JaPR12K5nEph .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Nbq6JaPR12K5nEph .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Nbq6JaPR12K5nEph .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Nbq6JaPR12K5nEph .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Nbq6JaPR12K5nEph .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Nbq6JaPR12K5nEph .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Nbq6JaPR12K5nEph .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Nbq6JaPR12K5nEph .marker.cross{stroke:#333333;}#mermaid-svg-Nbq6JaPR12K5nEph svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Nbq6JaPR12K5nEph p{margin:0;}#mermaid-svg-Nbq6JaPR12K5nEph .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-Nbq6JaPR12K5nEph .cluster-label text{fill:#333;}#mermaid-svg-Nbq6JaPR12K5nEph .cluster-label span{color:#333;}#mermaid-svg-Nbq6JaPR12K5nEph .cluster-label span p{background-color:transparent;}#mermaid-svg-Nbq6JaPR12K5nEph .label text,#mermaid-svg-Nbq6JaPR12K5nEph span{fill:#333;color:#333;}#mermaid-svg-Nbq6JaPR12K5nEph .node rect,#mermaid-svg-Nbq6JaPR12K5nEph .node circle,#mermaid-svg-Nbq6JaPR12K5nEph .node ellipse,#mermaid-svg-Nbq6JaPR12K5nEph .node polygon,#mermaid-svg-Nbq6JaPR12K5nEph .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Nbq6JaPR12K5nEph .rough-node .label text,#mermaid-svg-Nbq6JaPR12K5nEph .node .label text,#mermaid-svg-Nbq6JaPR12K5nEph .image-shape .label,#mermaid-svg-Nbq6JaPR12K5nEph .icon-shape .label{text-anchor:middle;}#mermaid-svg-Nbq6JaPR12K5nEph .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-Nbq6JaPR12K5nEph .rough-node .label,#mermaid-svg-Nbq6JaPR12K5nEph .node .label,#mermaid-svg-Nbq6JaPR12K5nEph .image-shape .label,#mermaid-svg-Nbq6JaPR12K5nEph .icon-shape .label{text-align:center;}#mermaid-svg-Nbq6JaPR12K5nEph .node.clickable{cursor:pointer;}#mermaid-svg-Nbq6JaPR12K5nEph .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-Nbq6JaPR12K5nEph .arrowheadPath{fill:#333333;}#mermaid-svg-Nbq6JaPR12K5nEph .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-Nbq6JaPR12K5nEph .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-Nbq6JaPR12K5nEph .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Nbq6JaPR12K5nEph .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-Nbq6JaPR12K5nEph .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Nbq6JaPR12K5nEph .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-Nbq6JaPR12K5nEph .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Nbq6JaPR12K5nEph .cluster text{fill:#333;}#mermaid-svg-Nbq6JaPR12K5nEph .cluster span{color:#333;}#mermaid-svg-Nbq6JaPR12K5nEph div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-Nbq6JaPR12K5nEph .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-Nbq6JaPR12K5nEph rect.text{fill:none;stroke-width:0;}#mermaid-svg-Nbq6JaPR12K5nEph .icon-shape,#mermaid-svg-Nbq6JaPR12K5nEph .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Nbq6JaPR12K5nEph .icon-shape p,#mermaid-svg-Nbq6JaPR12K5nEph .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-Nbq6JaPR12K5nEph .icon-shape .label rect,#mermaid-svg-Nbq6JaPR12K5nEph .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Nbq6JaPR12K5nEph .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-Nbq6JaPR12K5nEph .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-Nbq6JaPR12K5nEph :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 查询:前端表单组件规范
Embedding
向量检索
Top-K 规范文档
与 codeDraft 拼接 Prompt
LLM 生成
合规性说明
Retriever 本身也是 Runnable:
javascript
const retriever = vectorStore.asRetriever();
const docs = await retriever.invoke("前端表单组件命名与样式规范");
// 命中:《前端编码规范 v3》《Auth 模块安全 checklist》
RAG Chain 把检索和生成 pipe 在一起:
javascript
const ragChain = RunnableSequence.from([
{ context: retriever, question: new RunnablePassthrough() },
ragPrompt,
model,
parser,
]);
const complianceNotes = await ragChain.invoke(
"给登录页加忘记密码入口,需遵循哪些内部规范?"
);
步骤 5:多源数据合并与报告生成
至此,各环节的中间产物均已就绪------codeDraft(第三节)、repoInfo(第四节)、complianceNotes(第五节)。步骤 5 通过 reportChain 将多源数据合并,经二次 LLM 调用生成最终报告:
javascript
const report = await reportChain.invoke({
requirement,
codeDraft, // 步骤 2
repoInfo, // 步骤 3
complianceNotes, // 步骤 4
});
#mermaid-svg-clK3nFfalXX0R8yd{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-clK3nFfalXX0R8yd .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-clK3nFfalXX0R8yd .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-clK3nFfalXX0R8yd .error-icon{fill:#552222;}#mermaid-svg-clK3nFfalXX0R8yd .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-clK3nFfalXX0R8yd .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-clK3nFfalXX0R8yd .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-clK3nFfalXX0R8yd .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-clK3nFfalXX0R8yd .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-clK3nFfalXX0R8yd .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-clK3nFfalXX0R8yd .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-clK3nFfalXX0R8yd .marker{fill:#333333;stroke:#333333;}#mermaid-svg-clK3nFfalXX0R8yd .marker.cross{stroke:#333333;}#mermaid-svg-clK3nFfalXX0R8yd svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-clK3nFfalXX0R8yd p{margin:0;}#mermaid-svg-clK3nFfalXX0R8yd .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-clK3nFfalXX0R8yd .cluster-label text{fill:#333;}#mermaid-svg-clK3nFfalXX0R8yd .cluster-label span{color:#333;}#mermaid-svg-clK3nFfalXX0R8yd .cluster-label span p{background-color:transparent;}#mermaid-svg-clK3nFfalXX0R8yd .label text,#mermaid-svg-clK3nFfalXX0R8yd span{fill:#333;color:#333;}#mermaid-svg-clK3nFfalXX0R8yd .node rect,#mermaid-svg-clK3nFfalXX0R8yd .node circle,#mermaid-svg-clK3nFfalXX0R8yd .node ellipse,#mermaid-svg-clK3nFfalXX0R8yd .node polygon,#mermaid-svg-clK3nFfalXX0R8yd .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-clK3nFfalXX0R8yd .rough-node .label text,#mermaid-svg-clK3nFfalXX0R8yd .node .label text,#mermaid-svg-clK3nFfalXX0R8yd .image-shape .label,#mermaid-svg-clK3nFfalXX0R8yd .icon-shape .label{text-anchor:middle;}#mermaid-svg-clK3nFfalXX0R8yd .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-clK3nFfalXX0R8yd .rough-node .label,#mermaid-svg-clK3nFfalXX0R8yd .node .label,#mermaid-svg-clK3nFfalXX0R8yd .image-shape .label,#mermaid-svg-clK3nFfalXX0R8yd .icon-shape .label{text-align:center;}#mermaid-svg-clK3nFfalXX0R8yd .node.clickable{cursor:pointer;}#mermaid-svg-clK3nFfalXX0R8yd .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-clK3nFfalXX0R8yd .arrowheadPath{fill:#333333;}#mermaid-svg-clK3nFfalXX0R8yd .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-clK3nFfalXX0R8yd .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-clK3nFfalXX0R8yd .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-clK3nFfalXX0R8yd .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-clK3nFfalXX0R8yd .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-clK3nFfalXX0R8yd .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-clK3nFfalXX0R8yd .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-clK3nFfalXX0R8yd .cluster text{fill:#333;}#mermaid-svg-clK3nFfalXX0R8yd .cluster span{color:#333;}#mermaid-svg-clK3nFfalXX0R8yd div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-clK3nFfalXX0R8yd .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-clK3nFfalXX0R8yd rect.text{fill:none;stroke-width:0;}#mermaid-svg-clK3nFfalXX0R8yd .icon-shape,#mermaid-svg-clK3nFfalXX0R8yd .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-clK3nFfalXX0R8yd .icon-shape p,#mermaid-svg-clK3nFfalXX0R8yd .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-clK3nFfalXX0R8yd .icon-shape .label rect,#mermaid-svg-clK3nFfalXX0R8yd .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-clK3nFfalXX0R8yd .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-clK3nFfalXX0R8yd .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-clK3nFfalXX0R8yd :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 步骤 2 · codeDraft
reportChain
步骤 3 · repoInfo
步骤 4 · complianceNotes
步骤 5 · 最终报告
LangChain 还提供了 Document Loader、Text Splitter、VectorStore 等配套抽象------RAG 流水线同样纳入 Runnable 组合体系。
至此,「智能代码助手」五步链路的组件层已全部可由 LangChain 覆盖。 当流程规则超出线性 Pipeline 的能力边界时,则需要引入编排层。
六、Chain 的边界:何时需要编排层
对应环节 :五步链路之上 · 流程编排 | 能力边界:分支、循环、共享状态
前五步如果固定顺序、从不回退,Chain 完全够用:
#mermaid-svg-AB1PfFxYgcSs7NiA{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-AB1PfFxYgcSs7NiA .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-AB1PfFxYgcSs7NiA .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-AB1PfFxYgcSs7NiA .error-icon{fill:#552222;}#mermaid-svg-AB1PfFxYgcSs7NiA .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-AB1PfFxYgcSs7NiA .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-AB1PfFxYgcSs7NiA .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-AB1PfFxYgcSs7NiA .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-AB1PfFxYgcSs7NiA .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-AB1PfFxYgcSs7NiA .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-AB1PfFxYgcSs7NiA .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-AB1PfFxYgcSs7NiA .marker{fill:#333333;stroke:#333333;}#mermaid-svg-AB1PfFxYgcSs7NiA .marker.cross{stroke:#333333;}#mermaid-svg-AB1PfFxYgcSs7NiA svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-AB1PfFxYgcSs7NiA p{margin:0;}#mermaid-svg-AB1PfFxYgcSs7NiA .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-AB1PfFxYgcSs7NiA .cluster-label text{fill:#333;}#mermaid-svg-AB1PfFxYgcSs7NiA .cluster-label span{color:#333;}#mermaid-svg-AB1PfFxYgcSs7NiA .cluster-label span p{background-color:transparent;}#mermaid-svg-AB1PfFxYgcSs7NiA .label text,#mermaid-svg-AB1PfFxYgcSs7NiA span{fill:#333;color:#333;}#mermaid-svg-AB1PfFxYgcSs7NiA .node rect,#mermaid-svg-AB1PfFxYgcSs7NiA .node circle,#mermaid-svg-AB1PfFxYgcSs7NiA .node ellipse,#mermaid-svg-AB1PfFxYgcSs7NiA .node polygon,#mermaid-svg-AB1PfFxYgcSs7NiA .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-AB1PfFxYgcSs7NiA .rough-node .label text,#mermaid-svg-AB1PfFxYgcSs7NiA .node .label text,#mermaid-svg-AB1PfFxYgcSs7NiA .image-shape .label,#mermaid-svg-AB1PfFxYgcSs7NiA .icon-shape .label{text-anchor:middle;}#mermaid-svg-AB1PfFxYgcSs7NiA .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-AB1PfFxYgcSs7NiA .rough-node .label,#mermaid-svg-AB1PfFxYgcSs7NiA .node .label,#mermaid-svg-AB1PfFxYgcSs7NiA .image-shape .label,#mermaid-svg-AB1PfFxYgcSs7NiA .icon-shape .label{text-align:center;}#mermaid-svg-AB1PfFxYgcSs7NiA .node.clickable{cursor:pointer;}#mermaid-svg-AB1PfFxYgcSs7NiA .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-AB1PfFxYgcSs7NiA .arrowheadPath{fill:#333333;}#mermaid-svg-AB1PfFxYgcSs7NiA .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-AB1PfFxYgcSs7NiA .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-AB1PfFxYgcSs7NiA .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-AB1PfFxYgcSs7NiA .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-AB1PfFxYgcSs7NiA .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-AB1PfFxYgcSs7NiA .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-AB1PfFxYgcSs7NiA .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-AB1PfFxYgcSs7NiA .cluster text{fill:#333;}#mermaid-svg-AB1PfFxYgcSs7NiA .cluster span{color:#333;}#mermaid-svg-AB1PfFxYgcSs7NiA div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-AB1PfFxYgcSs7NiA .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-AB1PfFxYgcSs7NiA rect.text{fill:none;stroke-width:0;}#mermaid-svg-AB1PfFxYgcSs7NiA .icon-shape,#mermaid-svg-AB1PfFxYgcSs7NiA .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-AB1PfFxYgcSs7NiA .icon-shape p,#mermaid-svg-AB1PfFxYgcSs7NiA .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-AB1PfFxYgcSs7NiA .icon-shape .label rect,#mermaid-svg-AB1PfFxYgcSs7NiA .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-AB1PfFxYgcSs7NiA .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-AB1PfFxYgcSs7NiA .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-AB1PfFxYgcSs7NiA :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 生成代码
解析 JSON
查 GitHub
RAG 检索
生成报告
但产品很快会加规则:
循环------Review 不通过则重新生成:
#mermaid-svg-JnmBCfy7N3Ia6l5s{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-JnmBCfy7N3Ia6l5s .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-JnmBCfy7N3Ia6l5s .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-JnmBCfy7N3Ia6l5s .error-icon{fill:#552222;}#mermaid-svg-JnmBCfy7N3Ia6l5s .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-JnmBCfy7N3Ia6l5s .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-JnmBCfy7N3Ia6l5s .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-JnmBCfy7N3Ia6l5s .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-JnmBCfy7N3Ia6l5s .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-JnmBCfy7N3Ia6l5s .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-JnmBCfy7N3Ia6l5s .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-JnmBCfy7N3Ia6l5s .marker{fill:#333333;stroke:#333333;}#mermaid-svg-JnmBCfy7N3Ia6l5s .marker.cross{stroke:#333333;}#mermaid-svg-JnmBCfy7N3Ia6l5s svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-JnmBCfy7N3Ia6l5s p{margin:0;}#mermaid-svg-JnmBCfy7N3Ia6l5s .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-JnmBCfy7N3Ia6l5s .cluster-label text{fill:#333;}#mermaid-svg-JnmBCfy7N3Ia6l5s .cluster-label span{color:#333;}#mermaid-svg-JnmBCfy7N3Ia6l5s .cluster-label span p{background-color:transparent;}#mermaid-svg-JnmBCfy7N3Ia6l5s .label text,#mermaid-svg-JnmBCfy7N3Ia6l5s span{fill:#333;color:#333;}#mermaid-svg-JnmBCfy7N3Ia6l5s .node rect,#mermaid-svg-JnmBCfy7N3Ia6l5s .node circle,#mermaid-svg-JnmBCfy7N3Ia6l5s .node ellipse,#mermaid-svg-JnmBCfy7N3Ia6l5s .node polygon,#mermaid-svg-JnmBCfy7N3Ia6l5s .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-JnmBCfy7N3Ia6l5s .rough-node .label text,#mermaid-svg-JnmBCfy7N3Ia6l5s .node .label text,#mermaid-svg-JnmBCfy7N3Ia6l5s .image-shape .label,#mermaid-svg-JnmBCfy7N3Ia6l5s .icon-shape .label{text-anchor:middle;}#mermaid-svg-JnmBCfy7N3Ia6l5s .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-JnmBCfy7N3Ia6l5s .rough-node .label,#mermaid-svg-JnmBCfy7N3Ia6l5s .node .label,#mermaid-svg-JnmBCfy7N3Ia6l5s .image-shape .label,#mermaid-svg-JnmBCfy7N3Ia6l5s .icon-shape .label{text-align:center;}#mermaid-svg-JnmBCfy7N3Ia6l5s .node.clickable{cursor:pointer;}#mermaid-svg-JnmBCfy7N3Ia6l5s .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-JnmBCfy7N3Ia6l5s .arrowheadPath{fill:#333333;}#mermaid-svg-JnmBCfy7N3Ia6l5s .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-JnmBCfy7N3Ia6l5s .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-JnmBCfy7N3Ia6l5s .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-JnmBCfy7N3Ia6l5s .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-JnmBCfy7N3Ia6l5s .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-JnmBCfy7N3Ia6l5s .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-JnmBCfy7N3Ia6l5s .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-JnmBCfy7N3Ia6l5s .cluster text{fill:#333;}#mermaid-svg-JnmBCfy7N3Ia6l5s .cluster span{color:#333;}#mermaid-svg-JnmBCfy7N3Ia6l5s div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-JnmBCfy7N3Ia6l5s .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-JnmBCfy7N3Ia6l5s rect.text{fill:none;stroke-width:0;}#mermaid-svg-JnmBCfy7N3Ia6l5s .icon-shape,#mermaid-svg-JnmBCfy7N3Ia6l5s .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-JnmBCfy7N3Ia6l5s .icon-shape p,#mermaid-svg-JnmBCfy7N3Ia6l5s .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-JnmBCfy7N3Ia6l5s .icon-shape .label rect,#mermaid-svg-JnmBCfy7N3Ia6l5s .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-JnmBCfy7N3Ia6l5s .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-JnmBCfy7N3Ia6l5s .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-JnmBCfy7N3Ia6l5s :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Pass
Fail
Generate
Review
生成报告
END
条件分支------RAG 命中「禁止修改 Auth 核心模块」则直接终止:
#mermaid-svg-vG5xqIkJnshs6Fr4{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-vG5xqIkJnshs6Fr4 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-vG5xqIkJnshs6Fr4 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-vG5xqIkJnshs6Fr4 .error-icon{fill:#552222;}#mermaid-svg-vG5xqIkJnshs6Fr4 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-vG5xqIkJnshs6Fr4 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-vG5xqIkJnshs6Fr4 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-vG5xqIkJnshs6Fr4 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-vG5xqIkJnshs6Fr4 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-vG5xqIkJnshs6Fr4 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-vG5xqIkJnshs6Fr4 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-vG5xqIkJnshs6Fr4 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-vG5xqIkJnshs6Fr4 .marker.cross{stroke:#333333;}#mermaid-svg-vG5xqIkJnshs6Fr4 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-vG5xqIkJnshs6Fr4 p{margin:0;}#mermaid-svg-vG5xqIkJnshs6Fr4 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-vG5xqIkJnshs6Fr4 .cluster-label text{fill:#333;}#mermaid-svg-vG5xqIkJnshs6Fr4 .cluster-label span{color:#333;}#mermaid-svg-vG5xqIkJnshs6Fr4 .cluster-label span p{background-color:transparent;}#mermaid-svg-vG5xqIkJnshs6Fr4 .label text,#mermaid-svg-vG5xqIkJnshs6Fr4 span{fill:#333;color:#333;}#mermaid-svg-vG5xqIkJnshs6Fr4 .node rect,#mermaid-svg-vG5xqIkJnshs6Fr4 .node circle,#mermaid-svg-vG5xqIkJnshs6Fr4 .node ellipse,#mermaid-svg-vG5xqIkJnshs6Fr4 .node polygon,#mermaid-svg-vG5xqIkJnshs6Fr4 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-vG5xqIkJnshs6Fr4 .rough-node .label text,#mermaid-svg-vG5xqIkJnshs6Fr4 .node .label text,#mermaid-svg-vG5xqIkJnshs6Fr4 .image-shape .label,#mermaid-svg-vG5xqIkJnshs6Fr4 .icon-shape .label{text-anchor:middle;}#mermaid-svg-vG5xqIkJnshs6Fr4 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-vG5xqIkJnshs6Fr4 .rough-node .label,#mermaid-svg-vG5xqIkJnshs6Fr4 .node .label,#mermaid-svg-vG5xqIkJnshs6Fr4 .image-shape .label,#mermaid-svg-vG5xqIkJnshs6Fr4 .icon-shape .label{text-align:center;}#mermaid-svg-vG5xqIkJnshs6Fr4 .node.clickable{cursor:pointer;}#mermaid-svg-vG5xqIkJnshs6Fr4 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-vG5xqIkJnshs6Fr4 .arrowheadPath{fill:#333333;}#mermaid-svg-vG5xqIkJnshs6Fr4 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-vG5xqIkJnshs6Fr4 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-vG5xqIkJnshs6Fr4 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-vG5xqIkJnshs6Fr4 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-vG5xqIkJnshs6Fr4 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-vG5xqIkJnshs6Fr4 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-vG5xqIkJnshs6Fr4 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-vG5xqIkJnshs6Fr4 .cluster text{fill:#333;}#mermaid-svg-vG5xqIkJnshs6Fr4 .cluster span{color:#333;}#mermaid-svg-vG5xqIkJnshs6Fr4 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-vG5xqIkJnshs6Fr4 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-vG5xqIkJnshs6Fr4 rect.text{fill:none;stroke-width:0;}#mermaid-svg-vG5xqIkJnshs6Fr4 .icon-shape,#mermaid-svg-vG5xqIkJnshs6Fr4 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-vG5xqIkJnshs6Fr4 .icon-shape p,#mermaid-svg-vG5xqIkJnshs6Fr4 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-vG5xqIkJnshs6Fr4 .icon-shape .label rect,#mermaid-svg-vG5xqIkJnshs6Fr4 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-vG5xqIkJnshs6Fr4 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-vG5xqIkJnshs6Fr4 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-vG5xqIkJnshs6Fr4 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 无红线
命中红线
RAG 检索
Generate
END
生成报告
并行------GitHub 查询与 RAG 检索同时进行:
#mermaid-svg-fYt7wbaBgmsnNdai{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-fYt7wbaBgmsnNdai .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-fYt7wbaBgmsnNdai .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-fYt7wbaBgmsnNdai .error-icon{fill:#552222;}#mermaid-svg-fYt7wbaBgmsnNdai .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-fYt7wbaBgmsnNdai .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-fYt7wbaBgmsnNdai .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-fYt7wbaBgmsnNdai .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-fYt7wbaBgmsnNdai .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-fYt7wbaBgmsnNdai .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-fYt7wbaBgmsnNdai .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-fYt7wbaBgmsnNdai .marker{fill:#333333;stroke:#333333;}#mermaid-svg-fYt7wbaBgmsnNdai .marker.cross{stroke:#333333;}#mermaid-svg-fYt7wbaBgmsnNdai svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-fYt7wbaBgmsnNdai p{margin:0;}#mermaid-svg-fYt7wbaBgmsnNdai .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-fYt7wbaBgmsnNdai .cluster-label text{fill:#333;}#mermaid-svg-fYt7wbaBgmsnNdai .cluster-label span{color:#333;}#mermaid-svg-fYt7wbaBgmsnNdai .cluster-label span p{background-color:transparent;}#mermaid-svg-fYt7wbaBgmsnNdai .label text,#mermaid-svg-fYt7wbaBgmsnNdai span{fill:#333;color:#333;}#mermaid-svg-fYt7wbaBgmsnNdai .node rect,#mermaid-svg-fYt7wbaBgmsnNdai .node circle,#mermaid-svg-fYt7wbaBgmsnNdai .node ellipse,#mermaid-svg-fYt7wbaBgmsnNdai .node polygon,#mermaid-svg-fYt7wbaBgmsnNdai .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-fYt7wbaBgmsnNdai .rough-node .label text,#mermaid-svg-fYt7wbaBgmsnNdai .node .label text,#mermaid-svg-fYt7wbaBgmsnNdai .image-shape .label,#mermaid-svg-fYt7wbaBgmsnNdai .icon-shape .label{text-anchor:middle;}#mermaid-svg-fYt7wbaBgmsnNdai .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-fYt7wbaBgmsnNdai .rough-node .label,#mermaid-svg-fYt7wbaBgmsnNdai .node .label,#mermaid-svg-fYt7wbaBgmsnNdai .image-shape .label,#mermaid-svg-fYt7wbaBgmsnNdai .icon-shape .label{text-align:center;}#mermaid-svg-fYt7wbaBgmsnNdai .node.clickable{cursor:pointer;}#mermaid-svg-fYt7wbaBgmsnNdai .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-fYt7wbaBgmsnNdai .arrowheadPath{fill:#333333;}#mermaid-svg-fYt7wbaBgmsnNdai .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-fYt7wbaBgmsnNdai .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-fYt7wbaBgmsnNdai .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-fYt7wbaBgmsnNdai .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-fYt7wbaBgmsnNdai .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-fYt7wbaBgmsnNdai .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-fYt7wbaBgmsnNdai .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-fYt7wbaBgmsnNdai .cluster text{fill:#333;}#mermaid-svg-fYt7wbaBgmsnNdai .cluster span{color:#333;}#mermaid-svg-fYt7wbaBgmsnNdai div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-fYt7wbaBgmsnNdai .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-fYt7wbaBgmsnNdai rect.text{fill:none;stroke-width:0;}#mermaid-svg-fYt7wbaBgmsnNdai .icon-shape,#mermaid-svg-fYt7wbaBgmsnNdai .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-fYt7wbaBgmsnNdai .icon-shape p,#mermaid-svg-fYt7wbaBgmsnNdai .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-fYt7wbaBgmsnNdai .icon-shape .label rect,#mermaid-svg-fYt7wbaBgmsnNdai .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-fYt7wbaBgmsnNdai .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-fYt7wbaBgmsnNdai .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-fYt7wbaBgmsnNdai :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Generate codeDraft
查 GitHub
RAG 检索
Merge
生成报告
Chain 本质是 Pipeline ,而非 State Machine------缺少共享状态、条件路由、循环回退与 Checkpoint。这属于编排层的能力范畴,需由 LangGraph 承接。
七、LangGraph:LangChain 的编排层
对应环节 :Review 回退、红线拦截、断点恢复 | 架构关系:LangGraph 负责编排,LangChain 提供组件
LangChain 覆盖 Prompt / Model / Parser / Tool / RAG 等组件层能力;LangGraph 负责流程编排与状态管理:
| 能力 | 在「智能代码助手」中 |
|---|---|
| 状态管理 | requirement、codeDraft、repoInfo 等共享于全流程 |
| 条件路由 | RAG 命中红线 → 终止;Review 通过 → 生成报告 |
| 循环执行 | Review 失败 → 带审查意见回到 Generate |
| Checkpoint | 进程崩溃后从断点恢复 |
| Human-in-the-Loop | 修改 Auth 核心模块前等待 Tech Lead 确认 |
把 Review 回退落到 LangGraph:
#mermaid-svg-BwPoop5Z8A5WH0XI{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-BwPoop5Z8A5WH0XI .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-BwPoop5Z8A5WH0XI .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-BwPoop5Z8A5WH0XI .error-icon{fill:#552222;}#mermaid-svg-BwPoop5Z8A5WH0XI .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-BwPoop5Z8A5WH0XI .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-BwPoop5Z8A5WH0XI .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-BwPoop5Z8A5WH0XI .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-BwPoop5Z8A5WH0XI .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-BwPoop5Z8A5WH0XI .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-BwPoop5Z8A5WH0XI .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-BwPoop5Z8A5WH0XI .marker{fill:#333333;stroke:#333333;}#mermaid-svg-BwPoop5Z8A5WH0XI .marker.cross{stroke:#333333;}#mermaid-svg-BwPoop5Z8A5WH0XI svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-BwPoop5Z8A5WH0XI p{margin:0;}#mermaid-svg-BwPoop5Z8A5WH0XI .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-BwPoop5Z8A5WH0XI .cluster-label text{fill:#333;}#mermaid-svg-BwPoop5Z8A5WH0XI .cluster-label span{color:#333;}#mermaid-svg-BwPoop5Z8A5WH0XI .cluster-label span p{background-color:transparent;}#mermaid-svg-BwPoop5Z8A5WH0XI .label text,#mermaid-svg-BwPoop5Z8A5WH0XI span{fill:#333;color:#333;}#mermaid-svg-BwPoop5Z8A5WH0XI .node rect,#mermaid-svg-BwPoop5Z8A5WH0XI .node circle,#mermaid-svg-BwPoop5Z8A5WH0XI .node ellipse,#mermaid-svg-BwPoop5Z8A5WH0XI .node polygon,#mermaid-svg-BwPoop5Z8A5WH0XI .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-BwPoop5Z8A5WH0XI .rough-node .label text,#mermaid-svg-BwPoop5Z8A5WH0XI .node .label text,#mermaid-svg-BwPoop5Z8A5WH0XI .image-shape .label,#mermaid-svg-BwPoop5Z8A5WH0XI .icon-shape .label{text-anchor:middle;}#mermaid-svg-BwPoop5Z8A5WH0XI .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-BwPoop5Z8A5WH0XI .rough-node .label,#mermaid-svg-BwPoop5Z8A5WH0XI .node .label,#mermaid-svg-BwPoop5Z8A5WH0XI .image-shape .label,#mermaid-svg-BwPoop5Z8A5WH0XI .icon-shape .label{text-align:center;}#mermaid-svg-BwPoop5Z8A5WH0XI .node.clickable{cursor:pointer;}#mermaid-svg-BwPoop5Z8A5WH0XI .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-BwPoop5Z8A5WH0XI .arrowheadPath{fill:#333333;}#mermaid-svg-BwPoop5Z8A5WH0XI .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-BwPoop5Z8A5WH0XI .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-BwPoop5Z8A5WH0XI .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-BwPoop5Z8A5WH0XI .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-BwPoop5Z8A5WH0XI .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-BwPoop5Z8A5WH0XI .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-BwPoop5Z8A5WH0XI .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-BwPoop5Z8A5WH0XI .cluster text{fill:#333;}#mermaid-svg-BwPoop5Z8A5WH0XI .cluster span{color:#333;}#mermaid-svg-BwPoop5Z8A5WH0XI div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-BwPoop5Z8A5WH0XI .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-BwPoop5Z8A5WH0XI rect.text{fill:none;stroke-width:0;}#mermaid-svg-BwPoop5Z8A5WH0XI .icon-shape,#mermaid-svg-BwPoop5Z8A5WH0XI .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-BwPoop5Z8A5WH0XI .icon-shape p,#mermaid-svg-BwPoop5Z8A5WH0XI .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-BwPoop5Z8A5WH0XI .icon-shape .label rect,#mermaid-svg-BwPoop5Z8A5WH0XI .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-BwPoop5Z8A5WH0XI .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-BwPoop5Z8A5WH0XI .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-BwPoop5Z8A5WH0XI :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Pass
Fail
用户提交需求
Generate codeDraft
Review 规范审查
Generate 最终报告
END
每个 Node 内部仍使用 LangChain 的 Chain、Model、Tool 实现具体逻辑------LangGraph 管流程,LangChain 管组件,二者同属一个生态,呈上下层协作关系。
- LangChain :一个组件库,提供大量现成的"零件"(如模型接口、提示词模板、检索器等)。它通过 pipe (LangChain 表达式语言) 将这些零件高效地组装成线性流程,适合快速构建和简单任务。
- LangGraph :一个负责状态管理和复杂编排的"运行时"。它不取代 LangChain,而是利用其组件,提供更强大的图结构(Graph)模型来构建应用
| 维度 | LangChain (上层建筑) | LangGraph (底层引擎) |
|---|---|---|
| 核心抽象 | 链 (Chain) / 线性流程 | 图 (Graph) / 状态机 |
| 控制流 | 主要由静态边定义的线性流水线。即便有工具调用,其逻辑也基本是顺序性的。 | 灵活的图结构,原生支持条件分支、循环、并行,并能处理重试机制。这对于实现复杂决策和递归任务至关重要。 |
| 状态管理 | 相对简单,通过Memory组件在步骤间传递上下文,但较难支持复杂的状态回溯。 |
内置强大的持久化状态。状态在一个共享的数据结构中流转,并且系统支持保存状态快照(Checkpoint)。 |
| 适用场景 | 简单、线性的一次性任务 。例如基础的 RAG(检索增强生成)、文档摘要等。 | 复杂、有状态的系统。例如需要多轮交互的智能体(Agent)、长流程业务自动化,以及必须支持人工介入的复杂流程 |
八、LangChain 在 Agent 生态中的位置
#mermaid-svg-MDlEPqyGIhAt8qfx{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-MDlEPqyGIhAt8qfx .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-MDlEPqyGIhAt8qfx .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-MDlEPqyGIhAt8qfx .error-icon{fill:#552222;}#mermaid-svg-MDlEPqyGIhAt8qfx .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-MDlEPqyGIhAt8qfx .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-MDlEPqyGIhAt8qfx .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-MDlEPqyGIhAt8qfx .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-MDlEPqyGIhAt8qfx .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-MDlEPqyGIhAt8qfx .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-MDlEPqyGIhAt8qfx .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-MDlEPqyGIhAt8qfx .marker{fill:#333333;stroke:#333333;}#mermaid-svg-MDlEPqyGIhAt8qfx .marker.cross{stroke:#333333;}#mermaid-svg-MDlEPqyGIhAt8qfx svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-MDlEPqyGIhAt8qfx p{margin:0;}#mermaid-svg-MDlEPqyGIhAt8qfx .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-MDlEPqyGIhAt8qfx .cluster-label text{fill:#333;}#mermaid-svg-MDlEPqyGIhAt8qfx .cluster-label span{color:#333;}#mermaid-svg-MDlEPqyGIhAt8qfx .cluster-label span p{background-color:transparent;}#mermaid-svg-MDlEPqyGIhAt8qfx .label text,#mermaid-svg-MDlEPqyGIhAt8qfx span{fill:#333;color:#333;}#mermaid-svg-MDlEPqyGIhAt8qfx .node rect,#mermaid-svg-MDlEPqyGIhAt8qfx .node circle,#mermaid-svg-MDlEPqyGIhAt8qfx .node ellipse,#mermaid-svg-MDlEPqyGIhAt8qfx .node polygon,#mermaid-svg-MDlEPqyGIhAt8qfx .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-MDlEPqyGIhAt8qfx .rough-node .label text,#mermaid-svg-MDlEPqyGIhAt8qfx .node .label text,#mermaid-svg-MDlEPqyGIhAt8qfx .image-shape .label,#mermaid-svg-MDlEPqyGIhAt8qfx .icon-shape .label{text-anchor:middle;}#mermaid-svg-MDlEPqyGIhAt8qfx .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-MDlEPqyGIhAt8qfx .rough-node .label,#mermaid-svg-MDlEPqyGIhAt8qfx .node .label,#mermaid-svg-MDlEPqyGIhAt8qfx .image-shape .label,#mermaid-svg-MDlEPqyGIhAt8qfx .icon-shape .label{text-align:center;}#mermaid-svg-MDlEPqyGIhAt8qfx .node.clickable{cursor:pointer;}#mermaid-svg-MDlEPqyGIhAt8qfx .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-MDlEPqyGIhAt8qfx .arrowheadPath{fill:#333333;}#mermaid-svg-MDlEPqyGIhAt8qfx .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-MDlEPqyGIhAt8qfx .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-MDlEPqyGIhAt8qfx .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-MDlEPqyGIhAt8qfx .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-MDlEPqyGIhAt8qfx .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-MDlEPqyGIhAt8qfx .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-MDlEPqyGIhAt8qfx .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-MDlEPqyGIhAt8qfx .cluster text{fill:#333;}#mermaid-svg-MDlEPqyGIhAt8qfx .cluster span{color:#333;}#mermaid-svg-MDlEPqyGIhAt8qfx div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-MDlEPqyGIhAt8qfx .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-MDlEPqyGIhAt8qfx rect.text{fill:none;stroke-width:0;}#mermaid-svg-MDlEPqyGIhAt8qfx .icon-shape,#mermaid-svg-MDlEPqyGIhAt8qfx .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-MDlEPqyGIhAt8qfx .icon-shape p,#mermaid-svg-MDlEPqyGIhAt8qfx .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-MDlEPqyGIhAt8qfx .icon-shape .label rect,#mermaid-svg-MDlEPqyGIhAt8qfx .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-MDlEPqyGIhAt8qfx .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-MDlEPqyGIhAt8qfx .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-MDlEPqyGIhAt8qfx :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 基础设施
组件层 · LangChain 的核心定位
编排层
LangGraph
LangChain
Model API
Tool / MCP
RAG / VectorStore
| 框架 / 协议 | 职责 | 与本文的关系 |
|---|---|---|
| LangChain | Prompt、Model、Parser、Tool、RAG | §二~§五 的主体 |
| LangGraph | 状态图、条件路由、循环、Checkpoint | §六~§七 的延伸 |
| OpenAI Agents SDK | OpenAI 生态的 Agent 运行时 | 与 LangGraph 定位类似 |
| MCP | Tool 的标准化接入协议 | 解决 Tool 跨服务复用 |
九、什么时候该用
| 你的「智能代码助手」走到哪一步 | 建议 |
|---|---|
| 单次问答、一个 Prompt 搞定 | 直接调 API |
| 固定顺序的多步 Prompt(分析 → 设计 → 生成) | LangChain Chain |
| 需要 JSON 输出 + GitHub Tool + 内部规范 RAG(前五步) | LangChain 组件层 |
| Review 回退、红线拦截、断点恢复 | 加 LangGraph |
| 已有成熟编排,只需 LLM 封装 | 只用 LangChain 的 Model / Parser |
判断标准:如果系统只有 1-2 个固定步骤,直接调 API;如果步骤超过 3 个且需要频繁切换模型/Tool/RAG,用 LangChain 组件;如果出现分支、回退、人工审批,上 LangGraph。但每一步引入都要评估:框架省下的胶水代码,是否 worth 它带来的抽象复杂度。
总结
LangChain 不是模型框架,而是 AI 应用开发框架。
它解决的不是「怎么调用 LLM」,而是第一节五条链路里的组件协作问题:
#mermaid-svg-rpcRdsfBJPMa99w7{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-rpcRdsfBJPMa99w7 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-rpcRdsfBJPMa99w7 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-rpcRdsfBJPMa99w7 .error-icon{fill:#552222;}#mermaid-svg-rpcRdsfBJPMa99w7 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-rpcRdsfBJPMa99w7 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-rpcRdsfBJPMa99w7 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-rpcRdsfBJPMa99w7 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-rpcRdsfBJPMa99w7 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-rpcRdsfBJPMa99w7 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-rpcRdsfBJPMa99w7 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-rpcRdsfBJPMa99w7 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-rpcRdsfBJPMa99w7 .marker.cross{stroke:#333333;}#mermaid-svg-rpcRdsfBJPMa99w7 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-rpcRdsfBJPMa99w7 p{margin:0;}#mermaid-svg-rpcRdsfBJPMa99w7 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-rpcRdsfBJPMa99w7 .cluster-label text{fill:#333;}#mermaid-svg-rpcRdsfBJPMa99w7 .cluster-label span{color:#333;}#mermaid-svg-rpcRdsfBJPMa99w7 .cluster-label span p{background-color:transparent;}#mermaid-svg-rpcRdsfBJPMa99w7 .label text,#mermaid-svg-rpcRdsfBJPMa99w7 span{fill:#333;color:#333;}#mermaid-svg-rpcRdsfBJPMa99w7 .node rect,#mermaid-svg-rpcRdsfBJPMa99w7 .node circle,#mermaid-svg-rpcRdsfBJPMa99w7 .node ellipse,#mermaid-svg-rpcRdsfBJPMa99w7 .node polygon,#mermaid-svg-rpcRdsfBJPMa99w7 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-rpcRdsfBJPMa99w7 .rough-node .label text,#mermaid-svg-rpcRdsfBJPMa99w7 .node .label text,#mermaid-svg-rpcRdsfBJPMa99w7 .image-shape .label,#mermaid-svg-rpcRdsfBJPMa99w7 .icon-shape .label{text-anchor:middle;}#mermaid-svg-rpcRdsfBJPMa99w7 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-rpcRdsfBJPMa99w7 .rough-node .label,#mermaid-svg-rpcRdsfBJPMa99w7 .node .label,#mermaid-svg-rpcRdsfBJPMa99w7 .image-shape .label,#mermaid-svg-rpcRdsfBJPMa99w7 .icon-shape .label{text-align:center;}#mermaid-svg-rpcRdsfBJPMa99w7 .node.clickable{cursor:pointer;}#mermaid-svg-rpcRdsfBJPMa99w7 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-rpcRdsfBJPMa99w7 .arrowheadPath{fill:#333333;}#mermaid-svg-rpcRdsfBJPMa99w7 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-rpcRdsfBJPMa99w7 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-rpcRdsfBJPMa99w7 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-rpcRdsfBJPMa99w7 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-rpcRdsfBJPMa99w7 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-rpcRdsfBJPMa99w7 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-rpcRdsfBJPMa99w7 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-rpcRdsfBJPMa99w7 .cluster text{fill:#333;}#mermaid-svg-rpcRdsfBJPMa99w7 .cluster span{color:#333;}#mermaid-svg-rpcRdsfBJPMa99w7 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-rpcRdsfBJPMa99w7 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-rpcRdsfBJPMa99w7 rect.text{fill:none;stroke-width:0;}#mermaid-svg-rpcRdsfBJPMa99w7 .icon-shape,#mermaid-svg-rpcRdsfBJPMa99w7 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-rpcRdsfBJPMa99w7 .icon-shape p,#mermaid-svg-rpcRdsfBJPMa99w7 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-rpcRdsfBJPMa99w7 .icon-shape .label rect,#mermaid-svg-rpcRdsfBJPMa99w7 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-rpcRdsfBJPMa99w7 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-rpcRdsfBJPMa99w7 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-rpcRdsfBJPMa99w7 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Prompt 管理
Chain 组合
结构化输出
Tool Calling
RAG
报告组装
LangGraph 编排
回到开篇的问题------为什么不直接调 API?
因为「智能代码助手」这样的系统,难点不在 LLM 调用,而在 Prompt、Parser、Tool、RAG 如何统一接口、自由组合。LangChain 用 Runnable 和 Chain 提供了这套组件层;流程变复杂时,LangGraph 在同一生态内接手编排。
LangChain 不是终点,但几乎是所有 Agent 系统绕不开的起点。