[{"data":1,"prerenderedAt":923},["ShallowReactive",2],{"note:\u002Frag\u002F02-runnable基础接口层":3},{"id":4,"title":5,"body":6,"date":903,"description":904,"draft":905,"extension":906,"featured":905,"kind":907,"lastmod":903,"meta":908,"navigation":116,"path":912,"planned":913,"section":914,"seo":915,"source":916,"stem":917,"tags":918,"toc":116,"weight":921,"__hash__":922},"notes\u002Frag\u002F02-Runnable基础接口层.md","基础接口层",{"type":7,"value":8,"toc":885},"minimark",[9,16,21,24,56,59,85,89,94,141,145,214,218,223,238,242,247,294,298,369,376,382,481,488,584,588,592,595,628,632,635,672,676,679,765,788,792,878,881],[10,11,12],"blockquote",{},[13,14,15],"p",{},"一句话总结：Runnable 是 LangChain 所有组件的统一接口协议，让 Prompt、LLM、Parser、Retriever 等组件可以用同一套方式调用、组合和扩展。",[17,18,20],"h2",{"id":19},"一-runnable-是什么","一、 Runnable 是什么",[13,22,23],{},"Runnable 是整个 LangChain 的基础接口层。只要某个组件实现了 Runnable，它就能：",[25,26,27,46,53],"ul",{},[28,29,30,31,35,36,35,39,35,42,45],"li",{},"用 ",[32,33,34],"code",{},"invoke()","、",[32,37,38],{},"ainvoke()",[32,40,41],{},"stream()",[32,43,44],{},"batch()"," 统一调用。",[28,47,48,49,52],{},"通过 ",[32,50,51],{},"|"," 管道符与其他 Runnable 组合成链。",[28,54,55],{},"内置重试、回退和生命周期钩子能力。",[13,57,58],{},"常见的 Runnable 组件包括：",[25,60,61,67,73,79],{},[28,62,63,64],{},"Prompt 模板：",[32,65,66],{},"ChatPromptTemplate",[28,68,69,70],{},"大模型：",[32,71,72],{},"ChatOpenAI",[28,74,75,76],{},"输出解析器：",[32,77,78],{},"StrOutputParser",[28,80,81,82],{},"检索器：",[32,83,84],{},"vectorstore.as_retriever()",[17,86,88],{"id":87},"二-核心方法","二、 核心方法",[90,91,93],"h3",{"id":92},"_1-invoke同步调用","1. invoke：同步调用",[95,96,101],"pre",{"className":97,"code":98,"language":99,"meta":100,"style":100},"language-python shiki shiki-themes github-light github-dark","from langchain_openai import ChatOpenAI\n\nllm = ChatOpenAI(model=\"gpt-4o-mini\")\n\nresult = llm.invoke(\"请用一句话介绍 LangChain\")\nprint(result.content)\n","python","",[32,102,103,111,118,124,129,135],{"__ignoreMap":100},[104,105,108],"span",{"class":106,"line":107},"line",1,[104,109,110],{},"from langchain_openai import ChatOpenAI\n",[104,112,114],{"class":106,"line":113},2,[104,115,117],{"emptyLinePlaceholder":116},true,"\n",[104,119,121],{"class":106,"line":120},3,[104,122,123],{},"llm = ChatOpenAI(model=\"gpt-4o-mini\")\n",[104,125,127],{"class":106,"line":126},4,[104,128,117],{"emptyLinePlaceholder":116},[104,130,132],{"class":106,"line":131},5,[104,133,134],{},"result = llm.invoke(\"请用一句话介绍 LangChain\")\n",[104,136,138],{"class":106,"line":137},6,[104,139,140],{},"print(result.content)\n",[90,142,144],{"id":143},"_2-ainvoke异步调用","2. ainvoke：异步调用",[95,146,148],{"className":97,"code":147,"language":99,"meta":100,"style":100},"import asyncio\n\nfrom langchain_openai import ChatOpenAI\n\nllm = ChatOpenAI(model=\"gpt-4o-mini\")\n\n\nasync def main():\n    result = await llm.ainvoke(\"请用一句话介绍 LangChain\")\n    print(result.content)\n\n\nasyncio.run(main())\n",[32,149,150,155,159,163,167,171,175,180,186,192,198,203,208],{"__ignoreMap":100},[104,151,152],{"class":106,"line":107},[104,153,154],{},"import asyncio\n",[104,156,157],{"class":106,"line":113},[104,158,117],{"emptyLinePlaceholder":116},[104,160,161],{"class":106,"line":120},[104,162,110],{},[104,164,165],{"class":106,"line":126},[104,166,117],{"emptyLinePlaceholder":116},[104,168,169],{"class":106,"line":131},[104,170,123],{},[104,172,173],{"class":106,"line":137},[104,174,117],{"emptyLinePlaceholder":116},[104,176,178],{"class":106,"line":177},7,[104,179,117],{"emptyLinePlaceholder":116},[104,181,183],{"class":106,"line":182},8,[104,184,185],{},"async def main():\n",[104,187,189],{"class":106,"line":188},9,[104,190,191],{},"    result = await llm.ainvoke(\"请用一句话介绍 LangChain\")\n",[104,193,195],{"class":106,"line":194},10,[104,196,197],{},"    print(result.content)\n",[104,199,201],{"class":106,"line":200},11,[104,202,117],{"emptyLinePlaceholder":116},[104,204,206],{"class":106,"line":205},12,[104,207,117],{"emptyLinePlaceholder":116},[104,209,211],{"class":106,"line":210},13,[104,212,213],{},"asyncio.run(main())\n",[90,215,217],{"id":216},"_3-stream流式输出","3. stream：流式输出",[13,219,220,222],{},[32,221,41],{}," 会按顺序返回内容片段，适合实现打字机式的流式回答。",[95,224,226],{"className":97,"code":225,"language":99,"meta":100,"style":100},"for chunk in llm.stream(\"请用一句话介绍 LangChain\"):\n    print(chunk.content, end=\"\")\n",[32,227,228,233],{"__ignoreMap":100},[104,229,230],{"class":106,"line":107},[104,231,232],{},"for chunk in llm.stream(\"请用一句话介绍 LangChain\"):\n",[104,234,235],{"class":106,"line":113},[104,236,237],{},"    print(chunk.content, end=\"\")\n",[90,239,241],{"id":240},"_4-batch批量调用","4. batch：批量调用",[13,243,244,246],{},[32,245,44],{}," 同时处理多个输入，适合批量问答或批量文本处理。",[95,248,250],{"className":97,"code":249,"language":99,"meta":100,"style":100},"questions = [\n    \"LangChain 是什么？\",\n    \"Runnable 是什么？\",\n]\n\nresults = llm.batch(questions)\n\nfor result in results:\n    print(result.content)\n",[32,251,252,257,262,267,272,276,281,285,290],{"__ignoreMap":100},[104,253,254],{"class":106,"line":107},[104,255,256],{},"questions = [\n",[104,258,259],{"class":106,"line":113},[104,260,261],{},"    \"LangChain 是什么？\",\n",[104,263,264],{"class":106,"line":120},[104,265,266],{},"    \"Runnable 是什么？\",\n",[104,268,269],{"class":106,"line":126},[104,270,271],{},"]\n",[104,273,274],{"class":106,"line":131},[104,275,117],{"emptyLinePlaceholder":116},[104,277,278],{"class":106,"line":137},[104,279,280],{},"results = llm.batch(questions)\n",[104,282,283],{"class":106,"line":177},[104,284,117],{"emptyLinePlaceholder":116},[104,286,287],{"class":106,"line":182},[104,288,289],{},"for result in results:\n",[104,291,292],{"class":106,"line":188},[104,293,197],{},[90,295,297],{"id":296},"_5-核心方法小结","5. 核心方法小结",[299,300,301,317],"table",{},[302,303,304],"thead",{},[305,306,307,311,314],"tr",{},[308,309,310],"th",{},"方法",[308,312,313],{},"调用方式",[308,315,316],{},"适用场景",[318,319,320,333,345,357],"tbody",{},[305,321,322,327,330],{},[323,324,325],"td",{},[32,326,34],{},[323,328,329],{},"同步",[323,331,332],{},"普通单次调用",[305,334,335,339,342],{},[323,336,337],{},[32,338,38],{},[323,340,341],{},"异步",[323,343,344],{},"异步接口或并发场景",[305,346,347,351,354],{},[323,348,349],{},[32,350,41],{},[323,352,353],{},"流式",[323,355,356],{},"逐字输出、实时展示",[305,358,359,363,366],{},[323,360,361],{},[32,362,44],{},[323,364,365],{},"批量",[323,367,368],{},"多个输入一次处理",[17,370,372,373,375],{"id":371},"三-管道符-组合","三、 管道符 ",[32,374,51],{}," 组合",[13,377,378,379,381],{},"Runnable 最核心的能力是通过 ",[32,380,51],{}," 把多个组件组合成一条链。前一个组件的输出会作为后一个组件的输入。",[95,383,385],{"className":97,"code":384,"language":99,"meta":100,"style":100},"from langchain_core.output_parsers import StrOutputParser\nfrom langchain_core.prompts import ChatPromptTemplate\nfrom langchain_openai import ChatOpenAI\n\nprompt = ChatPromptTemplate.from_messages([\n    (\"system\", \"你是一位严谨的助手\"),\n    (\"human\", \"请总结以下内容：{content}\"),\n])\n\nllm = ChatOpenAI(model=\"gpt-4o-mini\")\nparser = StrOutputParser()\n\nchain = prompt | llm | parser\n\nresult = chain.invoke({\n    \"content\": \"Runnable 是 LangChain 所有组件的统一接口协议。\",\n})\n\nprint(result)\n",[32,386,387,392,397,401,405,410,415,420,425,429,433,438,442,447,452,458,464,470,475],{"__ignoreMap":100},[104,388,389],{"class":106,"line":107},[104,390,391],{},"from langchain_core.output_parsers import StrOutputParser\n",[104,393,394],{"class":106,"line":113},[104,395,396],{},"from langchain_core.prompts import ChatPromptTemplate\n",[104,398,399],{"class":106,"line":120},[104,400,110],{},[104,402,403],{"class":106,"line":126},[104,404,117],{"emptyLinePlaceholder":116},[104,406,407],{"class":106,"line":131},[104,408,409],{},"prompt = ChatPromptTemplate.from_messages([\n",[104,411,412],{"class":106,"line":137},[104,413,414],{},"    (\"system\", \"你是一位严谨的助手\"),\n",[104,416,417],{"class":106,"line":177},[104,418,419],{},"    (\"human\", \"请总结以下内容：{content}\"),\n",[104,421,422],{"class":106,"line":182},[104,423,424],{},"])\n",[104,426,427],{"class":106,"line":188},[104,428,117],{"emptyLinePlaceholder":116},[104,430,431],{"class":106,"line":194},[104,432,123],{},[104,434,435],{"class":106,"line":200},[104,436,437],{},"parser = StrOutputParser()\n",[104,439,440],{"class":106,"line":205},[104,441,117],{"emptyLinePlaceholder":116},[104,443,444],{"class":106,"line":210},[104,445,446],{},"chain = prompt | llm | parser\n",[104,448,450],{"class":106,"line":449},14,[104,451,117],{"emptyLinePlaceholder":116},[104,453,455],{"class":106,"line":454},15,[104,456,457],{},"result = chain.invoke({\n",[104,459,461],{"class":106,"line":460},16,[104,462,463],{},"    \"content\": \"Runnable 是 LangChain 所有组件的统一接口协议。\",\n",[104,465,467],{"class":106,"line":466},17,[104,468,469],{},"})\n",[104,471,473],{"class":106,"line":472},18,[104,474,117],{"emptyLinePlaceholder":116},[104,476,478],{"class":106,"line":477},19,[104,479,480],{},"print(result)\n",[13,482,483,484,487],{},"组合后的 ",[32,485,486],{},"chain"," 本身也是一个 Runnable，所以同样支持：",[95,489,491],{"className":97,"code":490,"language":99,"meta":100,"style":100},"# 流式输出\nfor chunk in chain.stream({\"content\": \"LangChain 是一个大模型应用开发框架\"}):\n    print(chunk, end=\"\")\n\n# 批量处理\nresults = chain.batch([\n    {\"content\": \"第一段文本\"},\n    {\"content\": \"第二段文本\"},\n])\n\n# 异步调用\nimport asyncio\n\n\nasync def main():\n    answer = await chain.ainvoke({\"content\": \"异步处理一段文本\"})\n    print(answer)\n\n\nasyncio.run(main())\n",[32,492,493,498,503,508,512,517,522,527,532,536,540,545,549,553,557,561,566,571,575,579],{"__ignoreMap":100},[104,494,495],{"class":106,"line":107},[104,496,497],{},"# 流式输出\n",[104,499,500],{"class":106,"line":113},[104,501,502],{},"for chunk in chain.stream({\"content\": \"LangChain 是一个大模型应用开发框架\"}):\n",[104,504,505],{"class":106,"line":120},[104,506,507],{},"    print(chunk, end=\"\")\n",[104,509,510],{"class":106,"line":126},[104,511,117],{"emptyLinePlaceholder":116},[104,513,514],{"class":106,"line":131},[104,515,516],{},"# 批量处理\n",[104,518,519],{"class":106,"line":137},[104,520,521],{},"results = chain.batch([\n",[104,523,524],{"class":106,"line":177},[104,525,526],{},"    {\"content\": \"第一段文本\"},\n",[104,528,529],{"class":106,"line":182},[104,530,531],{},"    {\"content\": \"第二段文本\"},\n",[104,533,534],{"class":106,"line":188},[104,535,424],{},[104,537,538],{"class":106,"line":194},[104,539,117],{"emptyLinePlaceholder":116},[104,541,542],{"class":106,"line":200},[104,543,544],{},"# 异步调用\n",[104,546,547],{"class":106,"line":205},[104,548,154],{},[104,550,551],{"class":106,"line":210},[104,552,117],{"emptyLinePlaceholder":116},[104,554,555],{"class":106,"line":449},[104,556,117],{"emptyLinePlaceholder":116},[104,558,559],{"class":106,"line":454},[104,560,185],{},[104,562,563],{"class":106,"line":460},[104,564,565],{},"    answer = await chain.ainvoke({\"content\": \"异步处理一段文本\"})\n",[104,567,568],{"class":106,"line":466},[104,569,570],{},"    print(answer)\n",[104,572,573],{"class":106,"line":472},[104,574,117],{"emptyLinePlaceholder":116},[104,576,577],{"class":106,"line":477},[104,578,117],{"emptyLinePlaceholder":116},[104,580,582],{"class":106,"line":581},20,[104,583,213],{},[17,585,587],{"id":586},"四-内置重试与回退","四、 内置重试与回退",[90,589,591],{"id":590},"_1-重试with_retry","1. 重试：with_retry",[13,593,594],{},"当模型调用失败时，可以自动重试，适合应对网络抖动、限流等临时错误。",[95,596,598],{"className":97,"code":597,"language":99,"meta":100,"style":100},"robust_llm = llm.with_retry(\n    stop_after_attempt=3,  # 最多尝试 3 次\n)\n\nresult = robust_llm.invoke(\"请介绍 LangChain\")\nprint(result.content)\n",[32,599,600,605,610,615,619,624],{"__ignoreMap":100},[104,601,602],{"class":106,"line":107},[104,603,604],{},"robust_llm = llm.with_retry(\n",[104,606,607],{"class":106,"line":113},[104,608,609],{},"    stop_after_attempt=3,  # 最多尝试 3 次\n",[104,611,612],{"class":106,"line":120},[104,613,614],{},")\n",[104,616,617],{"class":106,"line":126},[104,618,117],{"emptyLinePlaceholder":116},[104,620,621],{"class":106,"line":131},[104,622,623],{},"result = robust_llm.invoke(\"请介绍 LangChain\")\n",[104,625,626],{"class":106,"line":137},[104,627,140],{},[90,629,631],{"id":630},"_2-回退with_fallbacks","2. 回退：with_fallbacks",[13,633,634],{},"主模型不可用时，自动切换到备用模型，提升整体可用性。",[95,636,638],{"className":97,"code":637,"language":99,"meta":100,"style":100},"primary_llm = ChatOpenAI(model=\"gpt-4o-mini\")\nbackup_llm = ChatOpenAI(model=\"gpt-4o\")\n\nllm_with_fallback = primary_llm.with_fallbacks([backup_llm])\n\nresult = llm_with_fallback.invoke(\"请介绍 LangChain\")\nprint(result.content)\n",[32,639,640,645,650,654,659,663,668],{"__ignoreMap":100},[104,641,642],{"class":106,"line":107},[104,643,644],{},"primary_llm = ChatOpenAI(model=\"gpt-4o-mini\")\n",[104,646,647],{"class":106,"line":113},[104,648,649],{},"backup_llm = ChatOpenAI(model=\"gpt-4o\")\n",[104,651,652],{"class":106,"line":120},[104,653,117],{"emptyLinePlaceholder":116},[104,655,656],{"class":106,"line":126},[104,657,658],{},"llm_with_fallback = primary_llm.with_fallbacks([backup_llm])\n",[104,660,661],{"class":106,"line":131},[104,662,117],{"emptyLinePlaceholder":116},[104,664,665],{"class":106,"line":137},[104,666,667],{},"result = llm_with_fallback.invoke(\"请介绍 LangChain\")\n",[104,669,670],{"class":106,"line":177},[104,671,140],{},[17,673,675],{"id":674},"五-生命周期钩子","五、 生命周期钩子",[13,677,678],{},"Runnable 在运行过程中会触发不同阶段的事件，可以通过 Callback 监听这些事件，例如记录日志、统计耗时、监控调用结果。",[95,680,682],{"className":97,"code":681,"language":99,"meta":100,"style":100},"from langchain_core.callbacks import BaseCallbackHandler\nfrom langchain_openai import ChatOpenAI\n\n\nclass MyHandler(BaseCallbackHandler):\n    def on_llm_start(self, serialized, prompts, **kwargs):\n        print(\"LLM 开始调用\")\n\n    def on_llm_end(self, response, **kwargs):\n        print(\"LLM 调用结束\")\n\n\nllm = ChatOpenAI(model=\"gpt-4o-mini\")\n\nresult = llm.invoke(\n    \"请介绍 LangChain\",\n    config={\"callbacks\": [MyHandler()]},\n)\n",[32,683,684,689,693,697,701,706,711,716,720,725,730,734,738,742,746,751,756,761],{"__ignoreMap":100},[104,685,686],{"class":106,"line":107},[104,687,688],{},"from langchain_core.callbacks import BaseCallbackHandler\n",[104,690,691],{"class":106,"line":113},[104,692,110],{},[104,694,695],{"class":106,"line":120},[104,696,117],{"emptyLinePlaceholder":116},[104,698,699],{"class":106,"line":126},[104,700,117],{"emptyLinePlaceholder":116},[104,702,703],{"class":106,"line":131},[104,704,705],{},"class MyHandler(BaseCallbackHandler):\n",[104,707,708],{"class":106,"line":137},[104,709,710],{},"    def on_llm_start(self, serialized, prompts, **kwargs):\n",[104,712,713],{"class":106,"line":177},[104,714,715],{},"        print(\"LLM 开始调用\")\n",[104,717,718],{"class":106,"line":182},[104,719,117],{"emptyLinePlaceholder":116},[104,721,722],{"class":106,"line":188},[104,723,724],{},"    def on_llm_end(self, response, **kwargs):\n",[104,726,727],{"class":106,"line":194},[104,728,729],{},"        print(\"LLM 调用结束\")\n",[104,731,732],{"class":106,"line":200},[104,733,117],{"emptyLinePlaceholder":116},[104,735,736],{"class":106,"line":205},[104,737,117],{"emptyLinePlaceholder":116},[104,739,740],{"class":106,"line":210},[104,741,123],{},[104,743,744],{"class":106,"line":449},[104,745,117],{"emptyLinePlaceholder":116},[104,747,748],{"class":106,"line":454},[104,749,750],{},"result = llm.invoke(\n",[104,752,753],{"class":106,"line":460},[104,754,755],{},"    \"请介绍 LangChain\",\n",[104,757,758],{"class":106,"line":466},[104,759,760],{},"    config={\"callbacks\": [MyHandler()]},\n",[104,762,763],{"class":106,"line":472},[104,764,614],{},[13,766,767,768,35,771,774,775,35,778,35,781,35,784,787],{},"除了 ",[32,769,770],{},"on_llm_start",[32,772,773],{},"on_llm_end","，LangChain 还提供 ",[32,776,777],{},"on_chain_start",[32,779,780],{},"on_chain_end",[32,782,783],{},"on_retriever_start",[32,785,786],{},"on_retriever_end"," 等钩子，分别对应链路、模型和检索器的生命周期。",[17,789,791],{"id":790},"六-小结","六、 小结",[299,793,794,807],{},[302,795,796],{},[305,797,798,801,804],{},[308,799,800],{},"能力",[308,802,803],{},"作用",[308,805,806],{},"示例",[318,808,809,823,837,848,864],{},[305,810,811,814,817],{},[323,812,813],{},"统一调用",[323,815,816],{},"所有组件用相同方法调用",[323,818,819,35,821],{},[32,820,34],{},[32,822,38],{},[305,824,825,828,831],{},[323,826,827],{},"流式与批量",[323,829,830],{},"适配实时展示和批量任务",[323,832,833,35,835],{},[32,834,41],{},[32,836,44],{},[305,838,839,842,845],{},[323,840,841],{},"管道组合",[323,843,844],{},"用 `",[323,846,847],{},"` 把组件组成链",[305,849,850,853,856],{},[323,851,852],{},"重试与回退",[323,854,855],{},"提升调用稳定性",[323,857,858,35,861],{},[32,859,860],{},"with_retry()",[32,862,863],{},"with_fallbacks()",[305,865,866,869,872],{},[323,867,868],{},"生命周期钩子",[323,870,871],{},"监控组件运行过程",[323,873,874,35,876],{},[32,875,770],{},[32,877,780],{},[13,879,880],{},"Runnable 是 LangChain 应用的地基，Prompt、LLM、Parser、Retriever 等组件都建立在这一接口之上。",[882,883,884],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":100,"searchDepth":113,"depth":113,"links":886},[887,888,895,897,901,902],{"id":19,"depth":113,"text":20},{"id":87,"depth":113,"text":88,"children":889},[890,891,892,893,894],{"id":92,"depth":120,"text":93},{"id":143,"depth":120,"text":144},{"id":216,"depth":120,"text":217},{"id":240,"depth":120,"text":241},{"id":296,"depth":120,"text":297},{"id":371,"depth":113,"text":896},"三、 管道符 | 组合",{"id":586,"depth":113,"text":587,"children":898},[899,900],{"id":590,"depth":120,"text":591},{"id":630,"depth":120,"text":631},{"id":674,"depth":113,"text":675},{"id":790,"depth":113,"text":791},"2026-04-14","理解 LangChain Runnable 统一接口，以及同步、异步、流式、批量、重试与回退等核心调用方式。",false,"md","article",{"migration":909},{"generator":910,"sourceSha256":911},"nuxt-site\u002Fscripts\u002Fmigrate-content.mjs","003fa2c8deef2339c5802a6ccc8e26c474820f9822d08f406836b116aefe71ed","\u002Frag\u002F02-runnable基础接口层",null,"rag",{"title":5,"description":904},"content\u002Frag\u002F02-Runnable基础接口层.md","rag\u002F02-Runnable基础接口层",[919,920],"RAG","LangChain",24,"Oo2qm7BeLo0evt3aAshm_V6I0hBuMSyFJGU-MzsQtyM",1791279145488]