Langchain中的消息

1.消息概述

目前基本所有的大模型API都与openai API兼容,具体来说请求和应答的格式与openai的保持一致,以deepseek为例(其他大模型仅仅是模型名不同),一个聊天请求的具体数据格式如下:

{

"model": "deepseek-chat",

"messages": [

{"role": "system", "content": "You are a helpful assistant."},

{"role": "user", "content": "Hello!"}

],

"stream": false

}

在请求数据中messages承载了用户和大模型交互的业务数据,messages列表可以很长,其中包括用户请求、大模型应答以及对大模型的人格设定。

在Langchain中的消息就是以上messages的具体实现,其中包括了大模型的输入和输出数据,携带与大模型交互时表示对话状态所需的内容和元数据。LangChain提供了一种标准消息类型,适用于所有大模型,从而确保无论调用使用何种大模型,对于调用者来说都是一样的。

一条消息由如下三部分构成:

1)role:表示消息的类型,共有四种,分别是user,system,assistant和tool

2)content:消息中的具体内容

3)metadata:消息的元数据,比如消息ID,词元使用情况等

2.调用大模型

下面说明一下如何调用大模型,首先初始化一个大模型:

from langchain_openai import ChatOpenAI

llm = ChatOpenAI(

model = 'qwen-plus',

api_key = "sk-*",

base_url = "https://dashscope.aliyuncs.com/compatible-mode/v1")

2.1直接调用

最简单的情况,直接调用大模型,比如:

response = llm.invoke("你是一个陕西的唐诗大家,请用陕西话改写送元二使安西").content

print(response)

此时,调用时传入的消息跟openai API的数据格式不同,但langchain在调用大模型时会自动修改为:

{

"model": "deepseek-chat",

"messages": [

{"role": "user", "content": "你是一个陕西的唐诗大家,请用陕西话改写送元二使安西"}

],

"stream": false

}

输出如下:

哎呀,元二老弟!你这就要走咧?唉,莫说这话,让咱老哥给你整一首送行的诗,用咱长安土话谝一谝,才带劲!

渭城朝雨浥轻尘,

客舍青青柳色新。

劝君更进一杯酒,

西出阳关无故人。

咱用陕西话谝一遍:

渭城个早晨下咧场小雨,把土都沾住了,不扬片片;

客栈墙外头个柳树绿茵茵滴,嫩生生滴,刚发芽么!

老哥我再敬你一碗酒,你得喝了------

出了阳关往西去,再想寻个熟人谝个闲传,都没咧啊!

唉,元二啊元二,路上慢些走,到了安西莫忘了给老哥捎个信儿。咱这酒可是从曲江池边老铺子打滴,一口下去,满嘴都是长安味儿!

2.2自己组织消息

根据openai API的消息格式,自己组装消息,再调用大模型,具体如下:

messages = [

{"role": "system", "content": "你是一个陕西的唐诗大家"},

{"role": "user", "content": "请用陕西话改写送元二使安西"},

]

response = llm.invoke(messages).content

print(response)

2.3使用langchain的消息

使用langchain中的系统的消息类组织请求数据,然后调用大模型,具体如下:

from langchain.messages import SystemMessage, HumanMessage

messages = [

SystemMessage("你是一个陕西的唐诗大家"),

HumanMessage("请用陕西话改写送元二使安西"),

]

response = llm.invoke(messages).content

print(response)

3.消息详解

在openai API的role包括三种:user,assistant和system。分别表示用户输入、大模型应答和角色定位说明。langchian中于此对应的分别有三种的不同的消息类型:HumanMessage,AIMessage和SystemMessage,同时为了支持大模型的function calling,增加了一种消息类型ToolMessage,封装函数调用结果相关数据。

3.1SystemMessage

SystemMessage表示设定模型行为的初始指令集,可以用来定义模型角色、设定回复的强调,还可以对于应答的格式进行约束。

如下代码,设定模型为熟悉springcloud框架的Java专家,然后让他生成断路保护器的代码,具体如下:

messages = [

system_msg,

HumanMessage("如何创建一个短路保护器?")

]

response = llm.invoke(messages)

print(response.content)

输出为:

在 Spring Cloud 微服务架构中,短路保护(Circuit Breaker)通常使用 **Resilience4j** 或旧版的 **Hystrix**(已停更)。推荐使用 Resilience4j,它是轻量、函数式、高性能的容错库。

下面是一个使用 **Resilience4j + Spring Boot + OpenFeign** 的短路保护器示例:


✅ 1. 添加依赖(`pom.xml`)

```xml

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-starter-circuitbreaker-resilience4j</artifactId>

</dependency>

```


✅ 2. 启用 Feign 和 CircuitBreaker

```java

@SpringBootApplication

@EnableFeignClients

public class Application {

public static void main(String[] args) {

SpringApplication.run(Application.class, args);

}

}

```


✅ 3. 创建 Feign Client

```java

@FeignClient(name = "userClient", url = "https://api.example.com")

public interface UserClient {

@GetMapping("/users/{id}")

String getUser(@PathVariable("id") Long id);

}

```


✅ 4. 使用 `CircuitBreakerFactory` 包装调用

```java

@Service

public class UserService {

@Autowired

private UserClient userClient;

@Autowired

private CircuitBreakerFactory circuitBreakerFactory;

public String getUserWithFallback(Long id) {

CircuitBreaker circuitBreaker = circuitBreakerFactory.create("userCB"); // 名称唯一

return circuitBreaker.run(

() -> userClient.getUser(id),

throwable -> getFallback(id, throwable)

);

}

private String getFallback(Long id, Throwable throwable) {

return "Fallback: User service is down (" + throwable.getMessage() + ")";

}

}

```


✅ 5. 配置 `application.yml`

```yaml

resilience4j.circuitbreaker:

instances:

userCB:

failureRateThreshold: 50

minimumNumberOfCalls: 5

waitDurationInOpenState: 5s

slidingWindowSize: 10

```

> 当失败率达到 50%(如 10 次中有 5 次失败),断路器进入 `OPEN` 状态,停止请求 5 秒后尝试恢复(半开状态)。


✅ 工作原理简述:

  • **CLOSED**:正常调用。

  • **OPEN**:失败过多,直接短路,返回 fallback。

  • **HALF_OPEN**:等待期过后尝试恢复调用。


✅ 可选:使用注解方式(更简洁)

引入 `@CircuitBreaker` 注解:

```java

@CircuitBreaker(name = "userCB", fallbackMethod = "getFallback")

public String getUser(Long id) {

return userClient.getUser(id);

}

public String getFallback(Long id, CallNotPermittedException ex) {

return "Service unavailable, using fallback.";

}

```

需确保开启注解支持(Spring Cloud CircuitBreaker 支持)。


总结

✅ 推荐组合:

**Spring Boot + OpenFeign + Resilience4j (via Spring Cloud CircuitBreaker)**

优点:

  • 轻量、易配置

  • 支持熔断、降级、监控(集成 Micrometer)

  • 官方推荐替代 Hystrix

需要我加上监控(如 Prometheus + Grafana)示例吗?

如果不设定角色,让大模型完成同样的任务呢?

messages = [#把SystemMessage去掉

HumanMessage("如何创建一个短路保护器?")

]

response = llm.invoke(messages)

print(response.content)

输出结果肯定不如人意,具体如下:

创建一个短路保护器(Short-Circuit Protector)的目的是在电路发生短路时迅速切断电流,防止设备损坏或火灾。以下是几种常见且实用的方法来实现短路保护,适用于不同应用场景:


一、基本原理

短路是指电流绕过正常负载,直接从正极流向负极,导致电流急剧上升。短路保护器通过检测异常大电流并快速断开电路来实现保护。

常用元件包括:

  • 保险丝(Fuse)

  • 断路器(Circuit Breaker)

  • 自恢复保险丝(PPTC)

  • 电子式保护电路(如使用MOSFET + 电流检测)


二、简单方案:使用保险丝

**材料**:

  • 保险丝(根据电路额定电流选择,例如1A、5A等)

  • 保险丝座(可选)

**步骤**:

  1. 将保险丝串联在电源正极线路中。

  2. 当电流超过保险丝额定值时,内部金属熔断,断开电路。

  3. 短路排除后需更换保险丝。

✅ 优点:成本低、可靠

❌ 缺点:一次性使用,需手动更换


三、进阶方案:自恢复保险丝(PPTC)

**材料**:

  • PPTC(聚合物正温度系数器件),如Polyswitch

**连接方式**:

  • 与保险丝一样,串联在主电路中。

**工作原理**:

  • 正常电流下电阻很小。

  • 短路时电流过大 → 温度升高 → PPTC电阻急剧增大 → 切断电流。

  • 故障排除后自动恢复导通。

✅ 优点:可重复使用,适合消费电子产品

❌ 缺点:响应速度较慢,不适合高精度应用


四、智能电子短路保护电路(推荐DIY)

使用电子元件构建一个可调、快速响应的保护电路。

示例电路:基于MOSFET + 运放/比较器

**所需元件**:

  • N沟道MOSFET(如IRF540N)------作为开关

  • 电流检测电阻(低阻值,如0.1Ω/1W)

  • 运算放大器或比较器(如LM358)

  • 齐纳二极管或稳压源(参考电压)

  • 继电器或驱动电路(可选)

  • 电容、电阻若干

工作流程:

  1. 电流流过检测电阻,产生压降(V = I × R)。

  2. 放大该电压信号,送入比较器。

  3. 比较器将采样电压与设定阈值比较。

  4. 若超过阈值(表示短路),输出信号关闭MOSFET,切断电源。

  5. 可加入延时或锁定机制防止误触发。

简化版本(带自锁保护):

```plaintext

电源+ → 电流检测电阻 → MOSFET漏极

负载

电源-

控制逻辑:

当检测到过流 → 触发三极管或比较器 → 关断MOSFET栅极电压 → 断开电路

```

✅ 优点:响应快、可调节、可复位

❌ 缺点:设计复杂,需调试


五、模块化解决方案(适合初学者)

使用现成的保护模块更安全便捷:

  1. **电子保险丝模块**(eFuse Module)

  2. **过流保护IC** 如:

  • TI TPS2592xx(支持过流、过压保护)

  • ON Semi NIS5110

  • Maxim MAX1757x

这些芯片集成检测、控制和保护功能,只需外围少量元件即可实现高性能短路保护。


六、注意事项

  1. **匹配额定值**:保护器的额定电压/电流必须大于等于系统需求。

  2. **响应时间**:短路应在几毫秒内被切断。

  3. **散热设计**:大电流下检测电阻和MOSFET需良好散热。

  4. **安全隔离**:高压系统需注意绝缘与隔离。

  5. **测试验证**:可在低压小电流下模拟短路测试保护功能。


总结:如何选择?

| 场景 | 推荐方案 |

|------|----------|

| 家用电器、简单电路 | 保险丝或PPTC |

| 可充电设备(如电池) | PPTC + 电压保护 |

| 工业/精密设备 | 电子保护电路或专用eFuse IC |

| DIY实验 | LM358 + MOSFET + 检测电阻 |


如果你提供具体的应用场景(如:12V直流电源、电机驱动、锂电池供电等),我可以为你定制一个详细的电路图和元件清单。

3.2HumanMessage

HumanMessage代表用户的输入,可以是文本、图片、音频或者视频。还可以包含元数据,比如:

human_message = HumanMessage(

content="请解释一下薛定谔的猫!",

name="bob",

id="123",

)

response = llm.invoke([

human_message

]).content

print(response)

其中的name和id表示用户名和本消息的id,具体可以使用哪些元数据,需要查询对应的大模型文档。

3.3AIMessage

AIMessage是对调用大模型的输出结果封装,并且在langchain生态中使用。以下是直接调用大模型是的返回结果:

{

"choices": [

{

"message": {

"role": "assistant",

"content": "我是阿里云开发的一款超大规模语言模型,我叫通义千问。"

},

"finish_reason": "stop",

"index": 0,

"logprobs": null

}

],

"object": "chat.completion",

"usage": {

"prompt_tokens": 3019,

"completion_tokens": 104,

"total_tokens": 3123,

"prompt_tokens_details": {

"cached_tokens": 2048

}

},

"created": 1735120033,

"system_fingerprint": null,

"model": "qwen-plus",

"id": "chatcmpl-6ada9ed2-7f33-9de2-8bb0-78bd4035025a"

}

langchian基于以上标准应答封装AIMessage。

AIMessage可以包括多模态数据、工具调用数据和大模型提供商所提供的其他元数据,比如令牌使用情况。

以下代码输出大模型应答类型和数据:

response = llm.invoke("请简单解释一下黑暗森林法则,要求不超过100字")

print(type(response))

print(response)

输出如下:

<class 'langchain_core.messages.ai.AIMessage'>

content='黑暗森林法则是刘慈欣在《三体》中提出的宇宙文明生存理论:宇宙如黑暗森林,每个文明都是带枪的猎人,为自保必须隐藏自己,一旦发现其他文明,最安全的选择就是消灭对方,以防被先发制人。' additional_kwargs={'refusal': None} response_metadata={'token_usage': {'completion_tokens': 59, 'prompt_tokens': 22, 'total_tokens': 81, 'completion_tokens_details': None, 'prompt_tokens_details': {'audio_tokens': None, 'cached_tokens': 0}}, 'model_provider': 'openai', 'model_name': 'qwen-plus', 'system_fingerprint': None, 'id': 'chatcmpl-3f07af6a-dfb6-4611-9add-39b86554aef4', 'finish_reason': 'stop', 'logprobs': None} id='lc_run--11ed3caf-6f5f-4ccb-85d5-28836c4c928f-0' usage_metadata={'input_tokens': 22, 'output_tokens': 59, 'total_tokens': 81, 'input_token_details': {'cache_read': 0}, 'output_token_details': {}}

3.4ToolMessage

ToolMessage与是调用工具的结果,与大模型的工具调用(function calling)紧密相关,大模型的工具调用(function calling)是指根据上下文和大模型绑定的工具集选择需要调用的工具及参数。这些信息包括在大模型返回的AIMessage中。以下示例说明了大模型的function calling调用过程。

以下代码中声明了一个简单的加法工具,当对大模型提出整数加法的问题时,大模型会选择加法工具,并返回对应的参数,具体代码如下:

from langchain.tools import tool

@tool

def add(a: int, b:int)->int:

'''Add two numbers'''

return a + b

tools = [add,]

model = llm.bind_tools(tools)

ai_message = model.invoke("计算100+99")

查看大模型的响应数据:

ai_message

输出如下:

AIMessage(content='', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 27, 'prompt_tokens': 161, 'total_tokens': 188, 'completion_tokens_details': None, 'prompt_tokens_details': {'audio_tokens': None, 'cached_tokens': 0}}, 'model_provider': 'openai', 'model_name': 'qwen-plus', 'system_fingerprint': None, 'id': 'chatcmpl-7c6f01a6-03a1-4233-aab5-ab1b59206e4a', 'finish_reason': 'tool_calls', 'logprobs': None}, id='lc_run--2929ca49-979b-4e40-b44e-a93078fabde8-0', tool_calls=[{'name': 'add', 'args': {'a': 100, 'b': 99}, 'id': 'call_c872fc02b15f4285abf421', 'type': 'tool_call'}], usage_metadata={'input_tokens': 161, 'output_tokens': 27, 'total_tokens': 188, 'input_token_details': {'cache_read': 0}, 'output_token_details': {}})

可以看到大模型返回的是AIMessage,同时数据中包括tool_calls就是需要调用的工具信息,具体如下:

{'name': 'add', 'args': {'a': 100, 'b': 99}, 'id': 'call_c872fc02b15f4285abf421', 'type': 'tool_call'}

调用工具,并生成ToolMessage,具体代码如下:

sum = add.invoke(ai_message.tool_calls[0]['args'])

tool_message = ToolMessage(

content=sum,

tool_call_id=ai_message.tool_calls[0]['id']

)

把前面的HumanMessage,AIMessage和ToolMessage组合后再次调用大模型:

messages = [

HumanMessage("计算100+99"),

ai_message,

tool_message]

response = model.invoke(messages)

response.content

大模型输出内容为:

100 + 99 的结果是 199。

4.消息内容说明

所有的消息类型都一个content属性,content没有强制类型要求,可以是字符串,可以是任意类型的数组,这是为了支持未遵循openai API格式的大模型而设计的。

同时angChain为文本、推理、引用、多模态数据、服务器端工具调用和其他消息内容提供了专用的内容类型。所有的消息类型还有一个content_blocks属性,content_blocks采用了明确的数据类型,实际是 content的另一种表示,content_blocks的类型包括text、reasoning、image、video、audio和file。

比如一个文本应答的content_blocks为:

{'type': 'text', 'text': '哎呀,元二老哥,你又要走咧?这回可是要去那安西都护府啊!我这个陕西娃,给你用咱关中的腔调,把王维这首诗重新谝一谝:\\n\\n渭城朝雨浥轻尘,\\n客舍青青柳色新。\\n劝君更尽一杯酒,\\n西出阳关无故人。\\n\\n咱陕西话咋说哩?听好咯------\\n\\n"渭城个早雨把土雾儿都压停当咧,\\n驿站里头柳树绿茵茵个新鲜劲儿。\\n老哥诶,再咥上这一杯烧酒,\\n出了阳关那达,可就冇人跟你谝闲传咧!"\\n\\n哎呀,说得我都恓惶咧。你看这渭水边上,杨柳依依,就像咱陕西婆姨编的花环。这酒是凤翔的西凤酒,辣得很,香得很!元二老哥,你这一走,怕是要翻过千山万壑,穿过戈壁滩,那达连个熟人都冇得。要不...咱俩再咥一碗?让这酒暖暖心窝子!\\n\\n(抹了把眼角)你说这长安城里头,咱们常在曲江池畔吟诗作对,如今你要去那西域,叫我咋想你唻...'}

相关推荐
小关会打代码15 小时前
LangChain最详细教程之Agents
langchain
钢蛋17 小时前
LangChain 框架架构解析:从核心到应用的完整生态
langchain·agent
钢蛋19 小时前
LangGraph 与 LangChain:关系与定位
langchain·agent
用户9125188677671 天前
一篇文章带你彻底搞懂langchain v1&langgraph v1中的Runtime和ToolRuntime
langchain
再会呀1 天前
[Ai Agent] 05 LangChain Agents 实战:从 ReAct 到带记忆的流式智能体
langchain·github
zhangbaolin1 天前
基于pypdf和chromadb构建向量库
langchain·chroma·分块·向量库·文件加载
Andy_shenzl3 天前
31、LangChain开发框架(八)-- LangChain 数据分析智能体实战
数据挖掘·数据分析·langchain·agent开发
liliangcsdn4 天前
如何结合langchain、neo4j实现关联检索问答
开发语言·python·langchain·neo4j
大模型教程4 天前
dify和Langchain-Chatchat有什么区别?
程序员·langchain·llm