想象你开了一家 AI 餐厅:后厨的“菜谱”是 LangChain 写好的提示词模板、大模型和输出解析器,它们串成一条加工流水线,能把顾客的问题变成一份满意的回答。但问题来了——菜谱再好,客人也不能直接闯进后厨翻锅铲。你需要一个前台经理,把后厨的烹饪流程翻译成客人看得懂的“菜单”(接口)、帮客人下单(请求)、按顺序上菜(响应),甚至一边做饭一边把半成品端给客人看(流式输出)。 这个前台经理就是 LangServe。它不重写你的任何业务逻辑,只是巧妙地把 LangChain 的“可运行链”包装成标准的 REST API,并自动附赠一份 OpenAPI 文档。而支撑它正常运转的“餐厅建筑骨架”是 FastAPI——一个高性能的 Python Web 框架。餐厅还要有门禁(鉴权)、限流(排队控制)和后厨大屏(健康监控),这些都可以在 FastAPI 体系里顺手完成。 这篇文章会带你从零走一遍“开餐厅”的全流程:备菜(构建链)→ 前台开业(LangServe 注册)→ 智能菜单(OpenAPI)→ 边做边上菜(SSE 流式)→ 多窗口接待(异步并发)→ 装修加固(FastAPI 集成)→ 门禁排队(鉴权限流)→ 后厨大屏(监控运维)。全部用最生活化的比喻讲透,让你真正明白每一步在做什么、为什么这么做。
对 AI 从业者而言,LangServe 是把模型应用从“本地玩具”变成“线上服务”的关键一跃。掌握它,你就能独立完成 LLM 应用的服务化部署、接口设计与上线运维,这是 AI 后端工程师和平台工程师的必备技能。
目录
可视化演示
动态演示用LangServe部署LL的核心机制,通过开始/执行/监控/完成四种模式展示关键概念与交互流程。
本节配有交互动效(进入视口后自动加载,约 3KB)。
用LangServe部署LL:Lang LangServe快速封装LL 自动生成REST接口与Open 核心机制可视化 用LangServe部署LL整体架构与关键组件
一、应用配置:菜谱与备料
开餐厅的第一步不是装修门面,而是先把菜谱定下来。你要回答三个问题:客人怎么描述需求?后厨用什么方法烹饪?端上桌的菜应该长什么样?在 LangChain 世界里,这三个问题对应三样“备料”:提示词模板(PromptTemplate)负责把用户的问题包装成模型听得懂的指令;大模型(LLM)负责真正思考并生成文字;输出解析器(OutputParser)负责把模型的原始回答整理成规范格式。
把这三样串起来,就用管道符 |,像传送带一样连接:模板产生的提示词送到模型,模型的输出再交给解析器。这样连成的整体在 LangChain 中叫作 Runnable(可运行链)。它有一个统一的接口,可以 .invoke() 同步调用,也可以 .ainvoke() 异步调用,还可以 .stream() 流式调用——后面所有的 API 服务能力,都是建立在“链是统一接口”这个基础上的。
从数学视角看,整条链就是一个复合函数:输入原始问题,输出最终答案。
菜谱配齐了,后厨能跑通一道菜,接下来就该考虑怎么让外面的客人点单——这就是 LangServe 要登场的时候。
- 提示词模板把用户的原始问题装进预设的指令框架里,好比服务员把客人的口味需求写成标准下单备注。
- 模型推理大模型接收提示词后,生成一段自然语言回答,这是整个流程的核心工序。
- 输出解析器把模型输出的原始文本拆解成结构化结果,比如只抽取 JSON 中的某个字段。
- 复合运算外层函数套内层函数,上一环的输出是下一环的输入,最终得到完整答案。
二、服务化包装:前台经理上岗
后厨有菜谱,但客人不能直接冲进后厨喊“给我炒一个”。你需要一个前台经理,负责把后厨的烹饪能力翻译成客人能理解的下单方式。LangServe 就是这位前台经理。它提供一行核心 API:add_routes(app, chain, path="/chat"),把一条 Runnable 链“挂”到一个 FastAPI 应用上,随即自动生成对应的 HTTP 端点。
端点(endpoint)就是“菜单上的一道菜”。LangServe 默认会为每条链生成几个标准端点:POST /chat/invoke 是同步调用,适合一问一答;POST /chat/stream 是流式调用,适合打字机效果;POST /chat/batch 是批量调用,适合一次处理多条输入。你不需要手动写视图函数、不需要定义路由逻辑,因为 Runnable 已经统一了“输入→输出”的形式,LangServe 知道怎么把你的 Python 函数变成 HTTP 请求。
这背后的映射关系可以写成:每一个可运行链都能被翻译成一组路径与方法。
前台经理上岗后,客人能点菜了,但面对五花八门的菜单,客人怎么知道每道菜里有什么、忌口怎么填?这时候就需要一份贴心的“点菜说明”。
- RunnableLangChain 中任意可调用的链对象,都有统一的输入输出协议,是能被服务化的前提。
- path接口的 URL 路径,例如
/chat/invoke,决定客户端该去哪个“窗口”下单。 - methodHTTP 方法,LangServe 的调用型端点统一使用 POST,表示“提交数据并获取结果”。
- 映射 FLangServe 自动完成从“链”到“接口集合”的转换,开发者无需手写路由。
三、自动文档:智能菜单生成
一家好餐厅的菜单,不会只写“宫保鸡丁”四个字,还会标注辣度、配料、是否含花生。API 也一样,调用方需要知道:请求体里该传什么字段、字段类型是什么、哪些必填、响应长什么样。传统做法是手写接口文档,费时且容易和代码脱节。LangServe 依托 FastAPI 与 Pydantic,自动生成一份会随代码实时更新的“智能菜单”——OpenAPI 文档。
你启动服务后,直接访问 /docs 就能看到 Swagger 调试页面,每个接口的参数、请求体示例、响应模型一目了然,甚至可以直接在页面上点击"Try it out"发起请求。这份文档不是手写的,而是从 chain 的输入输出类型自动推导出来的。因为 LangChain 的 Runnable 自带输入输出 schema,LangServe 能知道链需要什么字段、输出什么结构。
如果把 API 文档看作一个信息集合,它可以抽象成三部分:
有了智能菜单,客人能正确点菜了。但有些菜(比如烤鸭),客人希望看着师傅现场片皮、一片一片上桌,而不是等整只鸭子做好才端上来——大模型生成文字也有同样的需求。
- 路径集合文档里记录了所有可用接口的 URL,帮助调用方快速定位功能。
- 方法集合每个路径允许的 HTTP 方法,约束了调用方式。
- 数据模式请求和响应的字段结构、类型与校验规则,来自 Pydantic 模型。
- 三元组三部分合在一起构成完整的接口说明书,也是生成 Swagger 页面的数据来源。
四、流式输出:边做菜边上菜
传统 API 的响应方式像“整桌菜做好才上齐”:客户端发一个请求,服务器闷头算几十秒,最后一次性返回完整结果。用户盯着空白页面干等,体验很差,尤其大模型生成几百个 token 时,等待感会被无限放大。SSE(Server-Sent Events,服务器推送事件) 改变了这一点:它是基于 HTTP 的长连接,服务器可以分多次把数据推送给客户端。
LangServe 自动提供的 /stream 端点就是这样:“后厨”每生成一个 token,就立刻通过 SSE 推送给“客人”。前端拿到增量数据后逐字渲染,就形成了我们熟悉的“打字机效果”。和 WebSocket 不同,SSE 是单向的(服务器→客户端),实现简单,天然适配大模型生成场景,因为它只需要服务器往客户端推文字,不需要客户端频繁回传消息。
一次流式生成的完整结果,其实是一个有序的 token 序列:
边做菜边上菜解决了体验问题,但生意一好,门口排起长队怎么办?这时候就得考虑多开几个服务窗口了。
- token 序列模型把回答拆成一个个小片段(token),按顺序排列构成完整输出。
- 条件概率每一步生成新 token 时,模型计算的是“在已知前文的情况下,下一个词的概率分布”。
- 采样生成从概率分布中选取一个 token 作为第 t 个输出,再拼到前文后面继续生成。
- 逐步累积T 个 token 按顺序拼起来,就得到了最终完整回答。
五、并发异步:多窗口同时接待
假设后厨做一道菜要 10 秒,只有一个服务窗口时,10 个客人就要等 100 秒。可如果开 5 个窗口同时接待,理论上 20 秒就能全部送完。API 服务也是同样的道理:当大量请求同时到达时,如果服务端逐个处理,后面的请求只能排队干等。但如果服务端能在“等待模型返回”的间隙去处理其他请求,就能大幅提升吞吐量。
FastAPI 和 LangServe 都原生支持 async/await 异步编程。Python 的协程(coroutine)让程序在等待网络 IO 时主动让出 CPU,去执行另一个任务。LangChain 的 Runnable 提供了 .ainvoke()、.astream() 等异步方法,配合 asyncio.gather() 可以并发执行多个链调用。
假设单批处理 N 个请求,并发度为 C,每批耗时约 t,那么总耗时大约是:
多窗口同时接待提升了效率,但要让整个餐厅长期稳定运转,还需要考虑选址装修、水电消防这些基础设施——对应到技术上,就是 FastAPI 的工程化集成。
- 请求数量N 表示总共有多少个请求需要被处理,是任务总量的度量。
- 并发度C 表示同时处理的请求数,由协程并发数或线程池大小决定。
- 批次数量把 N 个请求分成若干批,每批同时处理 C 个,批次数为 N/C 向上取整。
- 总耗时批次数乘以每批耗时,就是处理完所有请求的近似总时长。
六、FastAPI集成:餐厅骨架加固
一个餐厅能容纳多少客人、安不安全,取决于建筑骨架。对于 API 服务来说,这个骨架就是 FastAPI。LangServe 并不是一个独立服务器,它把链包装成 FastAPI 的 APIRouter,然后挂载到你的 FastAPI 应用上。这意味着你可以把 LangServe 生成的接口和自定义的业务接口放在同一个服务里,共用端口、中间件、配置。
启动方式也极简:uvicorn main:app --host 0.0.0.0 --port 8000。一行命令就把服务跑起来。生产环境中你还可以在这个骨架上继续加固:接入 CORS 中间件解决跨域问题,挂载自定义路由处理业务逻辑,用 Nginx 做反向代理和 TLS 加密,甚至跑多个 worker 提升并发能力。
多个路由模块挂载到同一个应用,本质上是模块的“并集”:
骨架加固后,餐厅可以对外营业了。但开门迎客不能什么人都放进来,也不能一次放太多人进来,否则后厨会被挤爆——这就引出了安全防护的话题。
- 路由模块router_i 是独立的路由集合,LangServe 生成的就是其中之一,也可以自定义。
- 合并运算将所有路由模块合并到同一个应用实例,共用中间件与生命周期。
- 统一入口所有路由共享同一个端口和进程,客户端通过不同路径访问不同功能。
- 扩展性新增功能只需再挂一个 Router,不影响已有接口,方便团队协作。
七、安全防护:门禁与限流
餐厅生意火爆时,如果来者不拒,后厨会手忙脚乱,成本也会失控。API 服务同样面临两个问题:谁能调用(鉴权)和 一次能调多少(限流)。LangServe 本身不强制鉴权,但因为它构建在 FastAPI 之上,你可以非常方便地加上各种防护。
鉴权的常见做法是 API Key:客户端在请求头里带上 Authorization: Bearer sk-xxx,服务端通过 FastAPI 的依赖注入(Depends)检查这个 Key 是否合法,不合法直接返回 401。限流则常用令牌桶算法:想象一个桶,每秒往里面放固定数量的令牌,每个请求取走一个令牌,桶空了就拒绝服务并返回 429(Too Many Requests)。桶的容量决定了允许的瞬时突发流量。
令牌桶的更新规则可以写成:
有了门禁和排队,餐厅秩序井然。但作为老板,你还得随时知道今天接了多少单、出餐快不快、后厨有没有异常——这就需要一块“后厨大屏”。
- 当前令牌数B_k 表示第 k 次请求后桶里剩余的令牌数,是限流判断的依据。
- 补充令牌每秒补充 r 个令牌,距上次请求越久,补充越多,但不超过桶容量 C。
- 容量上限min 操作让令牌数封顶在 C,防止长期不访问后积累过多令牌造成突发流量。
- 消耗令牌每次请求取走一个令牌,减一后就是新状态;如果结果小于 0,则拒绝请求。
八、运维监控:后厨大屏看全局
餐厅老板最怕什么?怕后厨着火了还不知道。API 服务上线后,你必须持续掌握它的健康状况:服务活着吗?响应慢吗?调用量有多大?有没有报错?健康检查是最基础的一环:在 FastAPI 中加一个 /healthz 端点,返回 200 和状态信息,负载均衡器定期轮询这个端点,一旦返回异常就自动摘除流量。
更完整的监控还包含日志与可观测性:记录每个请求的耗时、token 用量、错误信息,配合 Prometheus 采集指标、Grafana 绘制监控面板,甚至接入 LangSmith 查看链内部每一步的调用详情。这样当模型输出异常或外部 API 超时时,你能第一时间定位问题。
服务的可用性(uptime)本质上就是正常运行时间在总时长中的占比:
到这一步,你的 AI 餐厅已经完成了从后厨到前厅、从门禁到大屏的全部建设。回顾整条链路:LangChain 负责“做菜”,LangServe 负责“接待”,FastAPI 提供“场地”,安全防护和监控运维则让这家餐厅能长期稳定营业。
- 正常运行时间t_up 表示服务在一段时间内能正常响应的累计时长。
- 总观测时间t_total 表示统计的时间窗口总长度。
- 可用率计算两者相除再乘 100%,得到服务可用性百分比,是衡量稳定性的核心指标。
- 百分比表示例如 99.9% 表示一年中停机时间不超过约 8.7 小时。
AI 应用场景
场景一:企业知识库问答机器人接入内部 IM
阶段:服务化部署与上线
解决的问题:过去企业把 RAG 问答链跑在本地脚本里,员工提问要先找工程师执行脚本,效率和安全性都很差。用 LangServe 把问答链部署成 REST API 后,任何系统都能通过 HTTP 调用它,且天然具备并发处理能力。
具体案例:某金融公司把内部规章制度问答链封装成 /ask 接口,挂载到 FastAPI 应用上,再加一层 API Key 鉴权。随后将接口接入企业微信机器人,员工在对话框 @ 机器人就能查询报销规则、休假政策,后端服务自动调用 LangServe 接口完成检索与回答。
场景二:内容平台 AI 写作助手
阶段:流式交互与前端对接
解决的问题:大模型生成文章通常需要数秒甚至数十秒。如果采用传统“完整返回”模式,用户只能盯着加载动画干等。通过 LangServe 的 /stream 端点,前端用 SSE 实时接收 token,逐字呈现生成过程,用户的等待感大幅降低。
具体案例:某在线写作平台集成 AI 续写功能,前端调用 /stream 接口,利用浏览器原生 EventSource 读取数据流。用户每次点击“续写”,页面上的文字就像真人打字一样逐字出现,生成完毕还能保留完整内容供编辑。
场景三:多模型服务聚合网关
阶段:安全治理与统一运维
解决的问题:当团队同时上线多个 LangServe 应用(如摘要链、翻译链、分类链),各自管理端口、密钥和限额非常混乱。统一挂载到一个 FastAPI 网关后,可以在网关层集中做鉴权、限流、日志记录和成本统计。
具体案例:某 AI 创业公司把所有 LangServe 路由挂到同一个 FastAPI 应用,网关层实现令牌桶限流:免费用户每秒 5 次、付费用户每秒 50 次。所有请求都记录 token 用量并写入日志,月底按项目维度统计成本,极大减轻了运维负担。
Python 演示
"""使用 LangServe 快速部署 LLM 链,并附加鉴权、限流与健康检查。"""import asyncioimport timefrom fastapi import FastAPI, Depends, HTTPException, Requestfrom fastapi.middleware.cors import CORSMiddlewarefrom langchain.prompts import ChatPromptTemplatefrom langchain_openai import ChatOpenAIfrom langserve import add_routes API_TOKEN = "sk-langserve-demo-123" def require_token(request: Request): token = request.headers.get("Authorization", "").replace("Bearer ", "") if token != API_TOKEN: raise HTTPException(status_code=401, detail="invalid api token") return True class TokenBucket: def __init__(self, capacity=10, rate=2.0): self.capacity = capacity self.rate = rate self.tokens = capacity self.last_refill = time.monotonic() def consume(self, amount=1): now = time.monotonic() self.tokens = min(self.capacity, self.tokens + (now - self.last_refill) * self.rate) self.last_refill = now if self.tokens >= amount: self.tokens -= amount return True return False bucket = TokenBucket() async def rate_limit(request: Request): if not bucket.consume(): raise HTTPException(status_code=429, detail="too many requests, slow down") app = FastAPI(title="LLM API 服务", version="1.0.0")app.add_middleware(CORSMiddleware, allow_origins=["*"], allow_methods=["*"], allow_headers=["*"]) prompt = ChatPromptTemplate.from_template("请清晰简洁地回答问题:{question}")model = ChatOpenAI(model="gpt-4o-mini", temperature=0.3)chain = prompt | model # 提示词模板与模型串成 Runnable 链 add_routes(app, chain, path="/chat") # LangServe 一键暴露 REST/SSE 端点 @app.get("/healthz")async def healthz(): return {"status": "ok", "timestamp": time.time()} @app.post("/v1/chat", dependencies=[Depends(require_token), Depends(rate_limit)])async def chat_proxy(payload: dict): """带鉴权与限流的二次包装接口。""" question = payload.get("question", "") answer = await chain.ainvoke({"question": question}) return {"answer": answer.content} if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=8000)
chain = prompt | model用管道符把提示词模板和大模型串成一条 Runnable 链,这是被服务化的核心对象。add_routes(app, chain, path="/chat")一行代码把链自动映射为/chat/invoke、/chat/stream等 REST 端点。class TokenBucket实现令牌桶限流器,通过容量和速率控制请求频率。bucket.consume()每次请求消耗一个令牌,返回 False 说明桶空,应拒绝请求。async def rate_limit(request: Request)FastAPI 依赖项,在请求进入业务逻辑前执行限流检查。dependencies=[Depends(require_token), Depends(rate_limit)]声明式地给自定义接口追加鉴权和限流逻辑。await chain.ainvoke({"question": question})异步调用链,等待模型生成时不会阻塞其他请求。uvicorn.run(app, host="0.0.0.0", port=8000)用 uvicorn 启动 FastAPI 应用,让服务真正对外提供服务。
常见误区
误区LangServe 是不是要单独安装一套服务器,和 FastAPI 是两套系统?我是不是得专门学一套新的部署体系?
正解LangServe 本质上是 FastAPI 的一个“增强插件”,它把链包装成路由后挂载到 FastAPI 应用上,依然靠 uvicorn 启动。它没有自己的独立服务器,也没有脱离 FastAPI 的生态,两者是“装修”和“毛坯房”的关系——装修再华丽,也还是住在那套房子里。
为何常见:LangServe 这个命名看起来像一个独立产品,加上很多人直接使用现成模板启动服务,容易产生“这是一套独立系统”的错觉。
误区既然 LangServe 自动生成了所有端点,那我是不是没法在这些端点前面插一脚做安全检查了?
正解LangServe 生成的路由同样挂在 FastAPI 应用里,FastAPI 的中间件、依赖注入、HTTP 拦截器对它们完全生效。你可以在 app 层面加全局中间件,也可以自定义一个新的 /v1/chat 接口做鉴权后再转发给链处理,相当于在前台经理前面再加一位“保安”。
为何常见:初学者以为自动生成的代码是“黑盒”,看不到路由定义就觉得无法干预,实际上它在框架内完全可控。
误区SSE 和 WebSocket 都是服务器推送数据,效果差不多,随便选一个就行。
正解SSE 是单向的 HTTP 流(服务器→客户端),实现简单、自动重连,非常适合大模型生成的逐字输出场景,前端用一个 EventSource 对象就能接收。WebSocket 是双向全双工通信,适合聊天室、实时协作这类需要客户端频繁发消息的场景。选 SSE 是为了“服务器单向推文字”这件事足够简单可靠,并不是因为它功能更多。
为何常见:两者都能“持续推送数据”,这种表象让初学者误以为可以互相替代。
误区LangServe 提供了 /batch,那我传一个很大的列表进去,它就会自动用很多线程并发处理,速度应该比 /invoke 快很多。
正解/batch 的逻辑是“循环依次调用链”,它只是把多次调用合并成一次 HTTP 请求的便捷接口,方便客户端减少网络往返,并不代表服务端会自动为这批请求创建大量并发任务。想要并发加速,应该自己用 asyncio.gather 在服务端组合多个异步调用,同时还要注意控制并发度,避免打爆下游模型服务。
为何常见:命名和直觉让学习者把“批量”和“并发”画了等号,忽略了批量只是接口形态、并发才是运行机制。
误区LangServe 应用上线是不是必须用某个云服务商的专用 AI 部署平台,否则跑不起来?
正解LangServe 服务就是一个标准的 FastAPI 应用,任何能跑 Python 的环境都可以部署:一台云服务器加 uvicorn、一个 Docker 容器、或者 Kubernetes 集群,甚至内网一台 Linux 机器都行。云平台只是帮你简化了运维,并不是必要条件。先把它当作普通 Web 服务看待,问题就简单多了。
为何常见:网上教程常以云平台为例演示部署,学习者容易把“一种做法”误认为“唯一做法”。
面试题
Q1. LangServe 最核心的职责是什么?
- A.把 LangChain 链包装成 REST API 服务← 正确答案
- B.训练和微调大语言模型
- C.为前端自动生成页面组件
- D.压缩模型体积降低推理成本
答案:A。LangServe 就是把一条 Runnable 链变成 API 接口的“前台经理”,它不负责训练模型、不生成页面、不压缩模型。它专注于服务化这一步,其他工作分别由训练平台、前端框架和模型优化工具完成。
Q2. 在 LangServe 中,注册链到应用应该使用哪个函数?
- A.add_routes(app, chain, path)← 正确答案
- B.mount_llm(chain, path)
- C.register_api(chain)
- D.serve_runnable(chain)
答案:A。LangServe 提供的一键注册函数是 add_routes,它把链挂载到 FastAPI 应用并自动生成端点。其他选项都不是 LangServe 的 API,记住“add routes“就是”添加路由”这个直觉即可。
Q3. LangServe 中的 /docs 页面主要有什么作用?
- A.展示自动生成的接口文档并调试← 正确答案
- B.存储所有用户问答记录
- C.管理大模型训练数据
- D.配置服务器带宽限制
答案:A。/docs 是 FastAPI 自动生成的 Swagger 调试页面,展示每个接口的参数、请求体和响应格式,还能在线发起测试请求。它不等同于数据库存储、训练数据管理或网络配置,是给开发者看的“智能菜单”。
Q4. 下面哪个接口用于同步调用 LangServe 服务?
- A./chat/invoke← 正确答案
- B./chat/hello
- C./chat/process
- D./chat/analyze
答案:A。LangServe 默认生成的同步调用端点是 /invoke,代表“发起一次调用并等待完整结果”。其他路径都不是标准端点,实际生效的路径以 add_routes 注册的路由前缀加 /invoke 为准。
Q5. SSE 流式输出最适合描述哪种响应方式?
- A.服务器逐段推送生成文本← 正确答案
- B.服务器一次返回完整数据
- C.客户端反复轮询拉取结果
- D.客户端上传完整文件内容
答案:A。SSE 的特点是服务器通过 HTTP 长连接分多次推送数据,正好匹配大模型逐 token 生成的节奏,用户能看到文字一点点出现。一次性返回是传统 API,轮询是另一种机制,上传文件则与 SSE 无关。
Q6. LangServe 默认会为一条链生成哪些端点?
- A./invoke 同步调用端点← 正确答案
- B./stream 流式输出端点← 正确答案
- C./batch 批量调用端点← 正确答案
- D./train 模型训练端点
答案:ABC。LangServe 为每条链默认生成同步调用(invoke)、流式输出(stream)和批量调用(batch)三类端点。它不提供训练能力,/train 不是它的功能,训练属于模型开发阶段。
Q7. 用 FastAPI 依赖注入给 LangServe 接口加鉴权属于哪种实现?
- A.在请求处理前插入校验逻辑← 正确答案
- B.修改模型内部注意力权重
- C.删除链中的提示词模板
- D.关闭服务端事件流协议
答案:A。FastAPI 的 Depends 机制会在请求进入业务逻辑之前执行校验函数,适合做 API Key 检查。它不涉及模型参数、不修改链的组成、也不影响 SSE 协议,是一种“门禁前置”的做法。
Q8. 令牌桶限流中“桶容量”参数主要控制什么?
- A.允许的瞬时突发流量大小← 正确答案
- B.模型生成内容的长度
- C.网络连接的最大带宽
- D.请求体字段的数量上限
答案:A。桶容量决定令牌最多能积累多少个,也就是系统允许的最大突发请求量。容量越大,短时间冲进来的请求越多;它和生成长度、带宽、字段数量都没有直接关系。
Q9. 生产环境部署 LangServe 服务时,合理的加固措施有哪些?
- A.用 Nginx 做反向代理加 TLS 加密← 正确答案
- B.在网关层限制请求频率← 正确答案
- C.配置健康检查端点供负载均衡探测← 正确答案
- D.禁止所有日志输出以提升性能
答案:ABC。生产部署需要在前面加反向代理和 HTTPS、做限流保护后端、用健康检查让负载均衡器感知实例状态。日志对问题排查至关重要,正确做法是保留关键日志而非全部关闭。
Q10. 使用 asyncio.gather 并发调用 LangChain 链时需要注意什么?
- A.避免并发数超过下游模型服务限额← 正确答案
- B.防止循环中重复创建大量客户端对象← 正确答案
- C.最好搭配限流与重试策略← 正确答案
- D.并发数越高吞吐量一定无限提升
答案:ABC。并发能提升吞吐,但受限于下游模型服务的速率限制和自身资源,超过限额会被拒请求或拖垮服务。应复用客户端、控制并发上限、配合限流与重试,而不是盲目追求无限并发,因此 D 是错误的。