【LangChain 1.x】04、模型调用方式|invoke、stream、batch、异步调用

前言

上篇,介绍了 LangChain 1.x Models 模型层架构、两种模型初始化方式对比、统一入口 init_chat_model 的使用方法

传送门:【LangChain 1.x】03、Models 模型层简介与 init_chat_model 模型统一初始化

本篇,聚焦 LangChain 1.x 的模型调用方式 :和大家一起学习同步调用(invokestreambatch)和异步调用(ainvokeastreamabatch)两种模式,梳理每种方式的特点、适用场景和实践经验,覆盖业务开发中大部分的模型交互场景

一、invoke 同步调用

1.1 基础用法

invoke 是常用的模型调用方式,适用于单次请求、快速响应的场景,返回完整的 AIMessage 对象

1.1.1 简单字符串调用

基础的调用方式,直接传入字符串问题:

python 复制代码
from my_llm import deepseek_llm

response = deepseek_llm.invoke("为什么鹦鹉会说话?")
print(f"响应类型: {type(response)}")
print(f"响应内容: {response.content}")

返回结果:

arduino 复制代码
=== 简单 invoke 调用 ===
响应类型: <class 'langchain_core.messages.ai.AIMessage'>
响应内容: 鹦鹉会"说话"并不是像人类一样真正理解语言的含义,而是源于它们独特的**发声器官结构**和**强大的模仿学习能力**。这背后涉及生物学、神经学和进化行为三个层面。

简单来说,鹦鹉"说话"是**天生的模仿天赋**与**后天社会互动需求**结合的结果。

### 1. 独特的生理结构:会"唱歌"的器官...略

1.1.2 消息列表调用

支持传入消息列表来表示对话历史,每条消息都有对应的角色:

python 复制代码
conversation = [
    {"role": "system", "content": "你是一个有帮助的助手,专门将英语翻译成法语。"},
    {"role": "user", "content": "翻译:我喜欢编程。"},
    {"role": "assistant", "content": "J'aime la programmation."},
    {"role": "user", "content": "翻译:我喜欢构建应用程序。"}
]

response = deepseek_llm.invoke(conversation)
print(f"翻译结果: {response.content}")

返回结果:

makefile 复制代码
翻译结果: J'aime développer des applications.

1.1.3 使用消息对象

LangChain 提供了类型安全的消息对象,日常开发中也常使用这种方式:

python 复制代码
from langchain.messages import HumanMessage, AIMessage, SystemMessage

conversation = [
    SystemMessage("你是一个有帮助的助手,专门将英语翻译成法语。"),
    HumanMessage("翻译:我喜欢编程。"),
    AIMessage("J'aime la programmation."),
    HumanMessage("翻译:我喜欢构建应用程序。")
]

response = deepseek_llm.invoke(conversation)
print(f"翻译结果: {response.content}")

消息类型说明:

  • SystemMessage:系统提示词,设定助手的角色和行为
  • HumanMessage:用户消息,表示用户的输入
  • AIMessage:助手消息,表示模型的响应
  • ToolMessage:工具消息,用于工具调用的结果返回

1.2 带 RunnableConfig 的调用

invoke 支持传入 config 参数来控制执行行为、埋点追踪、元数据管理:

python 复制代码
response = deepseek_llm.invoke(
    "介绍一下 LangChain",
    config={
        "run_name": "langchain_introduction",     # 自定义运行名称
        "tags": ["introduction", "demo"],         # 标签,用于分类和过滤
        "metadata": {"user_id": "123"}            # 自定义元数据
    }
)

print(f"响应内容: {response.content}")
print(f"Token 使用: {response.usage_metadata}")

返回结果:

yaml 复制代码
响应内容: 我们来全面介绍一下 LangChain。

### 什么是 LangChain?
**LangChain 是一个用于开发由大语言模型(LLM)驱动的应用程序的开源框架。...略

Token 使用: {'input_tokens': 7, 'output_tokens': 1000, 'total_tokens': 1007, 'input_token_details': {'cache_read': 0}, 'output_token_details': {'reasoning': 188}}

config 参数说明:

  • run_name:为此特定调用标识,出现在日志和追踪中
  • tags:标签被子调用继承,用于调试工具中的过滤和组织
  • metadata:自定义键值对,用于跟踪额外上下文
  • callbacks:监控和响应执行事件的回调处理器

1.3 invoke 的适用场景

  • ✅ 快速问答、单次任务处理
  • ✅ 需要完整响应后再处理的场景
  • ✅ 对实时性要求不高的请求
  • ❌ 长文本生成(用户等待时间过长)
  • ❌ 需要实时反馈的交互场景

二、stream 流式输出

2.1 基础流式输出

stream() 返回一个生成器,逐块产生输出,显著改善长响应的用户体验:

python 复制代码
full = None
for chunk in deepseek_llm.stream("天空是什么颜色的?"):
    full = chunk if full is None else full + chunk
    print(chunk.content, end="", flush=True)

print(f"\n完整消息: {full.content}")
print(f"内容块: {full.content_blocks}")

流式输出特点:

  • 返回多个 AIMessageChunk 对象,每个包含部分输出文本
  • 每个 chunk 可以通过累加方式组合成完整消息
  • 提供实时反馈,用户体验更好

输出示例:

erlang 复制代码
天空天空通常是天空通常是蓝色的天空通常是蓝色的...
完整消息: 天空通常是蓝色的...

2.2 流式输出的累加处理

python 复制代码
full_message = None
chunk_count = 0

for chunk in deepseek_llm.stream("用三个词描述人工智能"):
    full_message = chunk if full_message is None else full_message + chunk
    chunk_count += 1
    print(f"块 #{chunk_count}: {chunk.content}")

print(f"\n总计 {chunk_count} 个块")
print(f"最终内容: {full_message.content}")

返回结果:

makefile 复制代码
块 #80: 学习
块 #81: 、
块 #82: 推理
块 #83: 、
块 #84: 适应
块 #85: 
块 #86: 

总计 86 个块
最终内容: 学习、推理、适应

2.3 高级流式事件监听

astream_events() 可以流式输出语义事件,简化基于事件类型的过滤:

python 复制代码
import asyncio

async def stream_events_demo():
    async for event in deepseek_llm.astream_events("你好"):
        if event["event"] == "on_chat_model_start":
            print(f"输入: {event['data']['input']}")

        elif event["event"] == "on_chat_model_stream":
            chunk = event['data']['chunk']
            print(f"Token: {chunk.text}", end="", flush=True)

        elif event["event"] == "on_chat_model_end":
            print(f"\n完整消息: {event['data']['output'].text}")

asyncio.run(stream_events_demo())

返回结果:

yaml 复制代码
输入: 你好
Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: Token: 你好Token: !Token: 很高兴Token: 见到Token: 你Token: !Token: 😊Token: 

Token: 我是Token: DeepToken: SeToken: ekToken: ,Token: 一个Token: 由Token: 深度Token: 求Token: 索Token: 公司Token: 创造的Token: AIToken: 助手Token: 。Token: 我可以Token: 帮你Token: 解答Token: 问题Token: 、Token: 提供Token: 建议Token: 、Token: 处理Token: 文件Token: 、Token: 进行Token: 创作Token: ,Token: 或者Token: 只是Token: 陪你Token: 聊Token: 聊天Token: 。Token: 有什么Token: 我可以Token: 帮Token: 你的Token: 吗Token: ?Token: 无论是Token: 学习Token: 、Token: 工作Token: 还是Token: 生活Token: 上的Token: 问题Token: ,Token: 都可以Token: 随时Token: 告诉我Token: !Token: Token: 
完整消息: 你好!很高兴见到你!😊
​
我是DeepSeek,一个由深度求索公司创造的AI助手。我可以帮你解答问题、提供建议、处理文件、进行创作,或者只是陪你聊聊天。有什么我可以帮你的吗?无论是学习、工作还是生活上的问题,都可以随时告诉我!

事件类型说明:

  • on_chat_model_start:模型调用开始
  • on_chat_model_stream:流式输出单个 token
  • on_chat_model_end:模型调用结束

2.4 "Auto-streaming" 自动流式机制

LangChain 支持在非显式调用流式方法时自动启用流式模式。当使用 invoke() 但检测到整体应用在流式运行时,LangChain 会自动切换到内部流式模式,通过 on_llm_new_token 事件实时输出 token,在 LangGraph Agents 中特别有用。

Auto-streaming 的优势: 代码保持简洁,使用 invoke() 即可;在需要时自动启用流式输出;无需手动切换调用方式。

2.5 stream vs invoke 对比

特性 invoke stream
返回方式 一次性返回完整 AIMessage 逐块返回 AIMessageChunk
用户体验 长响应需要等待 实时反馈,体验更好
适用场景 短问答、后台任务 长文本生成、实时对话
内存占用 较高(需缓存完整响应) 较低(逐块处理)
复杂度 简单直接 需要处理累加逻辑

2.6 stream 的适用场景

  • ✅ 长文本生成(文章、报告、代码)
  • ✅ 实时对话、聊天机器人
  • ✅ 需要即时反馈的用户交互
  • ✅ 大批量内容的流式处理
  • ❌ 需要完整响应才能处理的业务逻辑
  • ❌ 简单的短问答(增加不必要的复杂度)

三、batch 批量处理

3.1 基础批量调用

batch() 可以并行处理多个独立请求,较大地提升处理性能,同时有助于降低调用成本:

python 复制代码
import time

questions = [
    "为什么鹦鹉有五颜六色的羽毛?",
    "飞机是如何飞行的?",
    "什么是量子计算?"
]

print(f"批量处理 {len(questions)} 个问题...")
start_time = time.time()

responses = deepseek_llm.batch(questions)

end_time = time.time()
print(f"批量处理完成,耗时: {end_time - start_time:.2f} 秒")

for i, response in enumerate(responses, 1):
    print(f"\n问题 {i} 响应:")
    print(f"内容: {response.content[:100]}...")
    print(f"Token 使用: {response.usage_metadata}")

返回结果:

yaml 复制代码
批量处理 3 个问题...
批量处理完成,耗时: 14.29 秒

问题 1 响应:
内容: 鹦鹉五颜六色的羽毛是自然选择和性选择共同作用的结果,背后有多种生物学原因:

1. **吸引配偶(性选择)**:鲜艳的羽毛是健康、强壮和优良基因的信号。雌性鹦鹉往往更喜欢羽毛色泽鲜艳的雄性,因为这意味...
Token 使用: {'input_tokens': 12, 'output_tokens': 729, 'total_tokens': 741, 'input_token_details': {'cache_read': 0}, 'output_token_details': {'reasoning': 339}}
​
问题 2 响应:
内容: 飞机之所以能飞上天空,核心在于 **四股力量** 的平衡与相互作用,以及机翼的巧妙设计。简单概括就是:**机翼"切"开空气,制造压力差,产生升力**。
​
下面我们分步拆解,就像看一部飞机的"飞行说明书...
Token 使用: {'input_tokens': 9, 'output_tokens': 1000, 'total_tokens': 1009, 'input_token_details': {'cache_read': 0}, 'output_token_details': {'reasoning': 272}}

问题 3 响应:
内容: 量子计算是一种利用量子力学原理(如叠加和纠缠)进行信息处理的新型计算范式。与经典计算机使用比特(0或1)不同,量子计算机使用**量子比特(qubit)**。量子比特可以同时处于0和1的叠加态,这使得量...
Token 使用: {'input_tokens': 8, 'output_tokens': 875, 'total_tokens': 883, 'input_token_details': {'cache_read': 0}, 'output_token_details': {'reasoning': 208}}

3.2 batch vs 单独调用性能对比

python 复制代码
questions = [
    "什么是人工智能?",
    "什么是机器学习?",
    "什么是深度学习?"
]

# 单独调用
print("单独调用方式:")
start_time = time.time()
individual_responses = []
for question in questions:
    response = deepseek_llm.invoke(question)
    individual_responses.append(response)
individual_time = time.time() - start_time
print(f"耗时: {individual_time:.2f} 秒")

# batch 调用
print("\nbatch 调用方式:")
start_time = time.time()
batch_responses = deepseek_llm.batch(questions)
batch_time = time.time() - start_time
print(f"耗时: {batch_time:.2f} 秒")
​
print(f"\n性能提升: {(individual_time - batch_time) / individual_time * 100:.1f}%")

性能对比结果:

makefile 复制代码
单独调用方式:
耗时: 42.44 秒

batch 调用方式:
耗时: 15.11 秒

性能提升: 64.4%

3.3 batch_as_completed 实时响应

batch_as_completed() 可以在单个输入完成时立即返回,无需等待整个批次完成:

python 复制代码
questions = [
    "简述 Python 的特点",
    "简述 JavaScript 的特点",
    "简述 Go 的特点"
]

print("实时处理批量响应:")
response_count = 0

for response in deepseek_llm.batch_as_completed(questions):
    response_count += 1
    print(f"\n响应 #{response_count} 完成:")
    idx, responseMsg = response
    print(f"内容: {responseMsg.content[:80]}...")
    print(f"Token: {responseMsg.usage_metadata}")

print(f"\n总计处理 {response_count} 个响应")

返回结果:

yaml 复制代码
响应 #1 完成:
内容: Python 具有以下主要特点:

- **简单易学**:语法简洁清晰,接近自然语言,适合初学者快速上手。
- **高级语言**:自动管理内存,提供丰富的数据结...
Token: {'input_tokens': 8, 'output_tokens': 344, 'total_tokens': 352, 'input_token_details': {'cache_read': 0}, 'output_token_details': {'reasoning': 56}}

响应 #2 完成:
内容: JavaScript 是一种动态、弱类型、基于原型的脚本语言,主要用于 Web 开发,其核心特点包括:

1. **动态类型**:变量类型在运行时确定,无需显式...
Token: {'input_tokens': 8, 'output_tokens': 351, 'total_tokens': 359, 'input_token_details': {'cache_read': 0}, 'output_token_details': {'reasoning': 90}}

响应 #3 完成:
内容: Go(又称 Golang)是由 Google 开发的静态强类型、编译型语言,主要特点包括:

1. **简洁易学**:语法简洁(无继承、泛型等复杂概念),代码风...
Token: {'input_tokens': 8, 'output_tokens': 398, 'total_tokens': 406, 'input_token_details': {'cache_read': 0}, 'output_token_details': {'reasoning': 86}}

batch_as_completed 的优势:

  • 无需等待整个批次完成
  • 优先处理快速完成的任务
  • 提供更好的用户体验
  • 适用于响应时间差异较大的场景

3.4 带 config 的批量调用

python 复制代码
prompts = [
    "写一个关于春天的句子",
    "写一个关于夏天的句子",
    "写一个关于秋天的句子"
]

responses = deepseek_llm.batch(
    prompts,
    config={
        "run_name": "creative_writing_batch",
        "tags": ["creative", "seasons"]
    }
)

for i, response in enumerate(responses, 1):
    print(f"句子 {i}: {response.content}")

返回结果:

markdown 复制代码
句子 1: 好的,这里有几句关于春天的句子,希望能触动你:

1.  风里带着些新翻的泥土的气息,混着青草味儿,还有各种花的香,都在微微润湿的空气里酝酿。
2.  春天是属于懒洋洋的午后,和一整个下午晒不完的太阳。
3.  柳树在晨光里抽了新芽,细细的,嫩嫩的,像谁在风里绣着淡青色的线。
4.  春天是打翻了的调色盘,绿了枝头,粉了桃腮,黄了菜花,也暖了人心。
句子 2: # 关于夏天

夏风推着蝉鸣撞进窗棂,碎成一地颤动的光影,我和影子在午后的地板上跳着没有节拍的双绳,影子矮了一寸,热浪便偷偷爬高一尺,直到风累了,蝉哑了,我们才停下来,坐在光与影的边界,听屋檐下的风铃敲打自己------它以为摇响的每一声,都能撬动天梯,想要爬上夏天最热的那朵云。
句子 3: 一片落叶飘下,恰似秋天在信笺上轻轻写下的金色记忆,带着泥土的安静和天空的澄澈,仿佛提醒我们------万物都在按时长大,慢慢变老,而生活却如这静美的时节,在呼吸之间绽放着最温柔的深情。时光在此刻像是一本翻了很久的书,终于安静下来,让人忍不住停顿,聆听季节翻页的细响。

3.5 batch 的适用场景

  • ✅ 批量数据处理(文档分析、内容生成)
  • ✅ 多任务并发处理
  • ✅ 成本优化(批量请求可能享受折扣)
  • ✅ 离线任务、定时任务
  • ❌ 实时交互场景
  • ❌ 需要上下文依赖的连续对话

四、异步调用模型(ainvoke、astream、abatch)

4.1 异步编程基础

LangChain 1.x 完整支持异步调用方式,对应的三种异步API为:ainvokeastreamabatch

Python 异步编程核心概念:

  • async def:定义异步函数
  • await:等待异步操作完成
  • asyncio:Python 异步编程标准库
  • asyncio.run():运行异步函数的入口

异步 vs 同步的本质区别:

  • 同步调用:阻塞等待,一次处理一个任务
  • 异步调用:不阻塞,可同时处理多个任务

4.2 三种异步调用方式快速入门

4.2.1 ainvoke 异步调用

python 复制代码
import asyncio
from my_llm import deepseek_llm

async def ainvoke_demo():
    """异步调用示例"""
    response = await deepseek_llm.ainvoke("为什么鹦鹉会说话?")
    print(f"响应内容: {response.content}")
    print(f"Token 使用: {response.usage_metadata}")

# 运行异步函数
asyncio.run(ainvoke_demo())

返回结果:

css 复制代码
响应内容: 鹦鹉能"说话",其实并不是它们在像人类一样理解语言的含义并主动交流,而是一种**高度发达的模仿能力**。这背后有几个关键原因:

1.  **独特的生理结构**:鹦鹉拥有很特殊的发声器官------**鸣管*...
Token 使用: {'input_tokens': 9, 'output_tokens': 805, 'total_tokens': 814, 'input_token_details': {'cache_read': 0}, 'output_token_details': {'reasoning': 310}}

ainvoke 的特点:

  • 异步执行,不阻塞事件循环
  • 适合单次异步请求场景
  • 语法与 invoke 类似,只需加 await

4.2.2 astream 异步流式输出

python 复制代码
async def astream_demo():
    """异步流式输出示例"""
    print("异步流式输出: ", end="", flush=True)
    
    full_response = None
    chunk_count = 0
    async for chunk in deepseek_llm.astream("天空是什么颜色的?"):
        full_response = chunk if full_response is None else full_response + chunk
        chunk_count += 1
        print(chunk.content, end="", flush=True)
    
    print(f"\n\n总计 {chunk_count} 个输出块")

asyncio.run(astream_demo())

返回结果:

markdown 复制代码
异步流式输出: 天空的颜色并不是固定不变的,它取决于光线、大气成分和观察角度等多种因素。下面从几个常见角度来解释:

1. **晴朗白天的天空**:通常是**蓝色**。这是因为太阳光穿过大气层时,波长较短的蓝光(和紫光)更容易被空气分子和微小颗粒散射到四面八方,而我们的眼睛对蓝光更敏感,所以看到蓝色的天空。

2. **日出和日落时**:天空呈现**橙红色、红色或紫色**。此时太阳光斜射穿过更厚的大气层,蓝光被大量散射掉,而波长较长的红光、橙光能穿透并到达我们的眼睛,照亮云层和天空。

3. **阴天或多云时**:天空呈现**灰色或白色**。厚厚的云层(由水滴或冰晶组成)会均匀散射所有波长的可见光,导致光线混合成白色或灰色,显得阴沉。

4. **雾霾或沙尘天气**:天空可能呈**灰黄色、灰白色**。污染物或沙尘粒子散射光线,改变了光的颜色,常让天空变得浑浊。

5. **雨后的天空**:有时会出现**彩虹**,这是阳光被雨滴折射、反射后分解出的七色光带。

6. **在高海拔或外太空**:如果没有大气层,天空是**黑色**的,因为光线不再被散射,只有太阳和其他恒星直接发出的光。

7. **特殊现象**:比如极光(绿色、粉色等)或火山喷发后的天空(可能呈暗红色),则属于大气光学现象。

**总结**:我们最熟悉的"蓝色"只是晴天时大气散射的结果。天空的颜色其实是一张由天气、时间、地点和环境共同绘制的动态画卷。如果想知道某个具体时刻的颜色,可以描述一下当时的天气或场景哦!😊

总计 585 个输出块

astream 的特点:

  • 异步实时输出,支持并发处理
  • 使用 async for 进行迭代
  • 特别适合长文本生成的异步场景

4.2.3 abatch 异步批量调用

python 复制代码
async def abatch_demo():
    """异步批量调用示例"""
    questions = [
        "什么是人工智能?",
        "什么是机器学习?",
        "什么是深度学习?"
    ]
    
    print(f"异步批量处理 {len(questions)} 个问题...")
    start_time = time.time()
    
    responses = await deepseek_llm.abatch(questions)
    
    batch_time = time.time() - start_time
    print(f"批量处理完成,耗时: {batch_time:.2f} 秒")
    
    for i, response in enumerate(responses, 1):
        print(f"\n问题 {i} 响应:")
        print(f"内容: {response.content[:80]}...")

asyncio.run(abatch_demo())

返回结果:

makefile 复制代码
异步批量处理 3 个问题...
批量处理完成,耗时: 13.64 秒

问题 1 响应:
内容: 人工智能(Artificial Intelligence,简称AI)是计算机科学的一个分支,旨在让机器模拟、延伸或扩展人类智能。简单来说,就是让计算机像人一样学...

问题 2 响应:
内容: 这是一个很好的问题!我们来深入浅出地聊聊什么是机器学习。

简单来说,**机器学习就是让计算机"自己学习"的技术,而不是由人类一步一步编写死板的指令。**

想...

问题 3 响应:
内容: 这是一个非常核心的问题。简单来说,**深度学习是机器学习的一个子领域**,它通过模拟人脑的神经网络结构,让计算机从大量数据中自动学习复杂的模式与特征。

为了让...

abatch 的特点:

  • 异步并发处理多个请求
  • 充分利用异步的性能优势
  • 适合高并发批量处理场景

4.3 同步 vs 异步性能对比

并发场景性能测试:

python 复制代码
import asyncio
import time

async def performance_comparison():
    """同步 vs 异步性能对比"""
    
    tasks = [
        "简述 Python 的特点",
        "简述 JavaScript 的特点",
        "简述 Go 的特点"
    ]

    # 顺序执行(模拟同步调用)
    print("\n顺序执行(模拟同步调用):")
    start_time = time.time()

    sequential_results = []
    for task in tasks:
        response = await deepseek_llm.ainvoke(task)  # 顺序等待
        sequential_results.append(response)

    sequential_time = time.time() - start_time
    print(f"耗时: {sequential_time:.2f} 秒")

    # 并发执行(异步优势)
    print("\n并发执行(异步并发调用):")
    start_time = time.time()

    # 创建并发任务
    concurrent_tasks = [deepseek_llm.ainvoke(task) for task in tasks]
    concurrent_results = await asyncio.gather(*concurrent_tasks)

    concurrent_time = time.time() - start_time
    print(f"耗时: {concurrent_time:.2f} 秒")

    print(f"\n性能提升: {(sequential_time - concurrent_time) / sequential_time * 100:.1f}%")
    print("异步调用在并发场景下性能优势明显!")

asyncio.run(performance_comparison())

性能对比结果:

makefile 复制代码
顺序执行(模拟同步调用):
耗时: 23.43 秒

并发执行(异步并发调用):
耗时: 5.31 秒

性能提升: 77.3%
异步调用在并发场景下性能优势明显!

4.4 异步调用的适用场景

适合异步调用:

  • Web 应用后端:FastAPI、aiohttp 等
  • 高并发 API 服务:需要同时处理多个请求
  • 实时流式数据处理:长时间运行的流式任务
  • 并发模型调用:同时调用多个模型或工具
  • I/O 密集型任务:网络请求、数据库操作等

适合同步调用:

  • 简单脚本和工具:命令行应用、数据处理脚本
  • 单次任务:原型开发、测试调试
  • 批处理任务:定时任务、数据导入导出
  • 学习演示:代码示例、教学场景

混合使用策略:

python 复制代码
# 可以在同一应用中混合使用同步和异步调用
class HybridModelHandler:
    def __init__(self, model):
        self.model = model
    
    # 简单场景使用同步调用
    def simple_query(self, prompt):
        return self.model.invoke(prompt)
    
    # 并发场景使用异步调用  
    async def concurrent_queries(self, prompts):
        tasks = [self.model.ainvoke(p) for p in prompts]
        return await asyncio.gather(*tasks)

一些个人经验:

  • 简单场景:同步调用更直观,开发效率较高
  • 高并发场景:异步调用性能优势比较明显,资源利用率较高
  • 灵活选择:可以根据具体场景在应用中混合使用

五、调用方式选择

5.1 场景对比

场景 常用方式 特点
简单问答 invoke 简单直接,无需复杂逻辑
长文本生成 stream 实时反馈,用户体验较好
批量数据处理 batch 并发处理,性能较高
实时对话 stream 低延迟,即时响应
后台任务 batch 批量处理,成本优化
短平快的单次请求 invoke 开发效率较高
需要完整响应才能处理的逻辑 invoke 简化逻辑,避免复杂性
多任务并发 batch 并发性能较好

5.2 性能对比

维度 invoke stream batch 异步调用
开发复杂度 ⭐⭐⭐ ⭐⭐ ⭐⭐⭐⭐
响应速度 ⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐ ⭐⭐⭐⭐⭐
用户体验 ⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐ ⭐⭐⭐⭐
资源效率 ⭐⭐ ⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐⭐⭐
并发能力 ⭐⭐ ⭐⭐⭐ ⭐⭐⭐⭐⭐
适用范围 ⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐⭐⭐

5.3 场景选择参考

markdown 复制代码
是否需要实时反馈?
├─ 是 → 是否长文本生成?
│   ├─ 是 → stream
│   └─ 否 → invoke(短对话)
└─ 否 → 是否批量处理?
    ├─ 是 → batch
    └─ 否 → invoke

六、总结

本篇,和大家分享了 LangChain 1.x 的模型调用方式:同步调用(invokestreambatch)和异步调用(ainvokeastreamabatch),以及各自的适用场景和实践经验

核心要点回顾:

  1. invoke 同步调用:简单直接的单次调用,适合快速问答和后台任务
  2. stream 流式输出:实时反馈的用户体验优化,适合长文本生成和实时对话
  3. batch 批量处理:并发提升性能,适合批量数据处理和成本优化
  4. 异步调用模型:高并发场景下性能优势比较明显,适合 Web 应用和 API 服务

选择建议:

  • 开发效率优先:invoke(简单场景)
  • 用户体验优先:stream(长文本、实时对话)
  • 性能和成本优先:batch(批量处理)
  • 高并发场景:异步调用(Web 服务、API)

个人体会:

  • 同步调用简单直观,能满足大多数场景需求
  • 异步调用在并发场景下性能提升比较明显(实测可达 60%+)
  • 实际开发中可以根据应用特点灵活选择,甚至混合使用
  • LangChain 1.x 在这块提供了比较完整的同步和异步 API 支持

下一篇:工具调用实战|让模型具备执行能力 涉及工具定义、绑定、执行循环、服务端工具使用等核心内容

相关推荐
喵叔哟3 小时前
第二周概述
人工智能·langchain
meilindehuzi_a3 小时前
远程 MCP 项目实战:LangChain 连接高德地图、Chrome DevTools 与文件系统
人工智能·langchain·chrome devtools
uncle_ll3 小时前
LangChain 实战指南:回调系统、自定义组件与有状态对话全落地
langchain·llm·embedding·agent·大模型开发·rag
码云骑士8 小时前
61-LangChain-vs-LlamaIndex-选型对比-功能矩阵-混用实践
python·线性代数·矩阵·langchain
2601_963671688 小时前
零基础实战:用 LangChain 搭建本地 RAG 知识库系统
langchain
可涵不会debug9 小时前
从向量嵌入到复杂 Agent:LLM、LangChain、LangGraph 完整科普
langchain·嵌入模型·langgraph
怕浪猫9 小时前
第13章 评估与评测:如何衡量Agent的好坏
langchain·openai·ai编程
Linging_249 小时前
基于Langchain得AI Agent相关知识学习
人工智能·学习·langchain
艾莉丝努力练剑1 天前
【AI面试】AI八股文
人工智能·ai·面试·langchain·八股文