【LangChain】LangChain2-基础概念P1-输入控制与输出解析

article/2025/8/28 15:11:39

欢迎来到啾啾的博客🐱。
记录学习点滴。分享工作思考和实用技巧,偶尔也分享一些杂谈💬。
有很多很多不足的地方,欢迎评论交流,感谢您的阅读和评论😄。

目录

  • 引言
  • 基础代码
    • LangChain python官方文档
  • 输出可控性
    • 结构化输入输出:提示模板Prompt Templates
    • 输出解析器 Output Parsers(输出解析器)

引言

在上一篇LangChain入门中,我们已经了解到了可以使用LangChain的langchain_deepseek组件与DeepSeek进行对话。
但DeepSeek并没有提供如OpenAI一样的诸多参数来解决AI使用的问题,如控制随机性的temperature,控制重复(质量和新颖度)的presence_penalty和frequency_penalty。

关于参数在之前常见AI参数讲解有介绍过。

那AI的诸多问题要怎么解决呢?要怎么控制大模型(AI)呢?
常见问题如下:
![[【LangChain】LangChain基础概念-2.png]]

我们应该使用“直接修改大模型本身”之外的方案来解决问题(不现实)。
比如,LangChain。
LangChain不仅仅通过简单传递参数给 LLM API来解决问题,它还抽象了一系列组件来提供问题的解决方案。使用LangChain,可以讲不同大模型API封装成统一、易于调用的形式。

需要快速回顾和看懂Python的Java程序员可以看一下我之前写的Python快速入门

基础代码

上一篇入门中有与DeepSeek联网搜索对话的代码,这里放一个对话基础代码。

我本地是没有问题的(狗头)。有问题随时交流。

在DeepSeek官网购买获取API-KEY后替换到代码中。

import os# 基础对话所需
from langchain_deepseek import ChatDeepSeek
from langchain_core.messages import SystemMessage, HumanMessage# 环境key
os.environ["DEEPSEEK_API_KEY"] = 'sk-xx'def get_deepseek_key():key = os.getenv('DEEPSEEK_API_KEY')if key is None:raise ValueError("DEEPSEEK_API_KEY not found in environment variables.")return key# --- LLM 初始化 ---
def create_deepseek_llm():api_key = get_deepseek_key()if not api_key:raise ValueError("没有ds key")return ChatDeepSeek(model = "deepseek-chat",temperature=0.1, # 低温度,更具备确定性max_tokens=1024, timeout=None,max_retries=2,api_key=api_key)def test_simple_llm_call():llm = create_deepseek_llm()# 封装消息# LangChain 支持的消息类型如下:# - 'human': 人类消息# - 'user': 用户消息# - 'ai': AI 消息# - 'assistant': 助手消息# - 'function': 函数消息# - 'tool': 工具消息# - 'system': 系统消息# - 'developer': 开发者消息messages = [("system","你是一个乐于助人的LangChain专家。"),("human","你好,请用一句话介绍LangChain。")]# 流式响应for chunk in llm.stream(messages):print(chunk.text(), end="")print("\n AI回答完了")# 单词响应# response = llm.invoke(messages)# print("AI:", response.content)if __name__ == '__main__':test_simple_llm_call()

LangChain python官方文档

https://python.langchain.com/docs/how_to/#prompt-templates

输出可控性

结构化输入输出:提示模板Prompt Templates

LangChain提供了组件 Prompt Templates(提示模板)用来"让你的指令更规范、灵活,并且可以动态地根据用户输入或上下文调整"。

# 导入提示模板
from langchain_core.prompts import ChatPromptTemplate, PromptTemplate

场景:我们创建一个LangChain专家的提示模板

import os# 基础对话所需
from langchain_deepseek import ChatDeepSeek
from langchain_core.messages import SystemMessage, HumanMessage# 提示模板
from langchain_core.prompts import ChatPromptTemplate, PromptTemplate# 环境key
os.environ["DEEPSEEK_API_KEY"] = 'sk-xx'def get_deepseek_key():key = os.getenv('DEEPSEEK_API_KEY')if key is None:raise ValueError("DEEPSEEK_API_KEY not found in environment variables.")return key# --- LLM 初始化 ---
def create_deepseek_llm():api_key = get_deepseek_key()if not api_key:raise ValueError("没有ds key")return ChatDeepSeek(model = "deepseek-chat",temperature=0.1, # 低温度,更具备确定性max_tokens=1024,timeout=None,max_retries=2,api_key=api_key)# --- 使用模板对话限定输入输出 ---
def create_langchain_teacher_template():# 创建基础对话模板 """ 我们能在一些消息的构建上看到这种使用消息对象的写法。但是实际上这不是推荐的简洁写法,应该直接使用元组。是的,这个写法不会被视为一个s-string模板,而是一个stringreturn ChatPromptTemplate.from_messages([SystemMessage(content="你是一个乐于助人的LangChain专家。"),HumanMessage(content="你好,我想问一个关于LangChain的问题: {actual_user_input}")])"""return ChatPromptTemplate.from_messages([("system", "你是一个乐于助人的LangChain专家。"),("human", "你好,我想问一个关于LangChain的问题: {actual_user_input}") # 确保这里是占位符])def test_simple_template_call():llm = create_deepseek_llm()user_question = "你好,请问LangChain组件Prompt Templates可以做什么?"prompt_template = create_langchain_teacher_template()messages = prompt_template.format_messages(actual_user_input=user_question)print("最终发送给 LLM 的消息:")for msg in messages:print(f"- 类型: {msg.type}, 内容: {msg.content}")print("\nAI开始回答")for chunk in llm.stream(messages):print(chunk.content, end="")print("\nAI回答完了")if __name__ == '__main__':test_simple_template_call()

Prompt Templates可以告诉LLM它应该扮演什么角色、提供上下文、引导输出。

这里需要注意的是,在使用ChatPromptTemplate.from_messages()方法创建ChatPromptTemplate实例时,使用元组消息而是不是使用消息对象。
(“human”, “…”) 语法糖在幕后为你做了更多的工作,将字符串自动识别和处理为模板。而直接使用 HumanMessage(content=“…”) 时,content 被视为最终内容,而不是一个待格式化的模板。

输出解析器 Output Parsers(输出解析器)

现在,我们已经了解了基本对话和使用提示词模板Prompt Templates来限制输出。有时候我们需要结构化的输出数据,比如JSON、列表等…
LangChain提供了Output Parsers(输出解析器)来解析大模型返回文本。

以Prompt Templates的代码为基础,我们导入类库,询问LangChain的3个优点

import os# 基础对话所需
from langchain_deepseek import ChatDeepSeek
from langchain_core.messages import SystemMessage, HumanMessage# 提示模板
from langchain_core.prompts import ChatPromptTemplate, PromptTemplate# 输出解析器
from langchain.output_parsers import CommaSeparatedListOutputParser# 链条
from langchain.chains import LLMChain, SimpleSequentialChain, SequentialChain# 环境key
os.environ["DEEPSEEK_API_KEY"] = 'sk-xx'def get_deepseek_key():key = os.getenv('DEEPSEEK_API_KEY')if key is None:raise ValueError("DEEPSEEK_API_KEY not found in environment variables.")return key# --- LLM 初始化 ---
def create_deepseek_llm():api_key = get_deepseek_key()if not api_key:raise ValueError("没有ds key")return ChatDeepSeek(model = "deepseek-chat",temperature=0.1, # 低温度,更具备确定性max_tokens=1024,timeout=None,max_retries=2,api_key=api_key)# --- 使用模板对话限定输入输出 ---
def create_langchain_teacher_template():return ChatPromptTemplate.from_messages([("system", "你是一个乐于助人的LangChain专家。"),("human", "你好,我想问一个关于LangChain的问题: {actual_user_input} \n\n {format_instructions}") # 确保这里是占位符])# --- 使用输出解析器解析输出 ---
def create_output_parser():return CommaSeparatedListOutputParser()def test_output_parser_with_template():llm = create_deepseek_llm()output_parser = create_output_parser()"""1.获取格式化指令对于 CommaSeparatedListOutputParser,它会是类似 "Your response should be a list of comma separated values, eg: `foo, bar, baz`""""format_instructions = output_parser.get_format_instructions()print(f"输出解析器的格式化指令: {format_instructions}")prompt_template = create_langchain_teacher_template()user_task = "请列出 LangChain 的3个主要优点。"# 2.格式化完整提示,包含用户任务和格式指令messages_for_llm = prompt_template.format_messages(actual_user_input=user_task,format_instructions=format_instructions)print("\n最终发送给 LLM 的消息 (包含格式指令):")for msg in messages_for_llm:print(f"- 类型: {msg.type}, 内容: {msg.content}")# 3. 调用LLM并获取原始文本输出print("\nAI开始生成原始文本 (等待 LLM 响应)...")ai_response_message = llm.invoke(messages_for_llm)raw_llm_output = ai_response_message.content # AIMessage对象的content属性是字符串print(f"LLM 返回的原始文本: '{raw_llm_output}'")# 4. 解析原始文本输出try:parsed_output = output_parser.parse(raw_llm_output)print("\n解析后的输出 (Python列表):")print(parsed_output)if isinstance(parsed_output, list):print("LangChain 的3个优点是:")for i,advantage in enumerate(parsed_output):print(f"{i}. {advantage.strip()}")except Exception as e:print(f"解析输出时出错: {e}")print("这通常意味着 LLM 的输出没有严格遵循格式化指令。")print("你可以尝试调整提示,或者使用更鲁棒的解析器/重试机制。")print("--- 结束测试:带输出解析器的模板调用 ---\n")if __name__ == '__main__':test_output_parser_with_template()

![[【LangChain】LangChain2-基础概念P1.png]]


http://www.hkcw.cn/article/PvhBjMHOqg.shtml

相关文章

在windows环境下安装Nmap并使用

Date: 2025-05-29 19:46:20 author: lijianzhan Nmap(简称:Network Mapper)是一款开源的网络扫描和嗅探工具包,Nmap主要作用是可以检测目标主机是否在线、主机端口开放情况、检测主机运行的服务类型及版本信息、检测操作系统与设备…

为什么我开始用 Data.olllo 做数据处理了?

之前我写过一篇文章,讲的是为什么我要做一个能打开 100GB CSV 的工具,叫 Data.olllo。 结果没想到,这篇文章不少人留言、私信我,问了一个类似的问题: “打开是解决了,那你用这个工具到底能干嘛&#xff1f…

通过远程桌面连接Windows实例提示“出现身份验证错误,无法连接到本地安全机构”错误怎么办?

本文介绍通过远程桌面连接Windows实例提示“出现身份验证错误无法连接到本地安全机构”错误的解决方案。 问题现象 通过本地电脑内的远程桌面连接Windows实例提示“出现身份验证错误,无法连接到本地安全机构”错误。 问题原因 导致该问题的可能原因如下&#x…

Spring未能自动解决循环依赖的问题

有过经验的同学应该都知道Spring能够自动解决循环依赖的问题,依靠的是它为单例池提供的三级缓存。如果你还不清楚三级缓存具体是怎么个解法的话,可以看一下这篇文章【图文详解】Spring是如何解决循环依赖的? 本文中的问题来源于我在开发项目…

RV1126 FFMPEG推流器理解

一.FFMPEG概念 概念:FFMPEG是一种音视频推流工具,把RV1126编码的视频,通过FFMPEG推流到流媒体服务器上,让大家都能访问和观看。为什么RV1126 编码的视频码流要利用 FFMPEG 框架推送到流媒体服务器,之前通过终端ffplay…

TeleAI发布TeleChat2.5及T1正式版,双双开源上线魔乐社区!

5月12日,中国电信开源TeleChat系列四个模型,涵盖复杂推理和通用问答的多个尺寸模型,包括TeleChat-T1-35B、TeleChat-T1-115B、TeleChat2.5-35B和TeleChat2.5-115B,实测模型性能均有显著的性能效果。TeleChat系列模型基于昇思MindS…

TMS320F28388D使用sysconfig配置IPC

第1章 配置IPC底层代码 使用IPC的动机: 我计划我的项目中要使用RS485,CANFD通信和EtherCAT通信,由于通信种类较多,而对于电机控制来说大部分数据都是重复的,并且有些数据可以很久才改变一次,所以我计划使…

Linux的线程同步

一、互斥锁(互斥量) 互斥锁是一种特殊的变量,有上锁(lock)和解锁(unlock)两种状态。 当处于解锁状态时,线程想获取该互斥锁,就可以获取不被阻塞,互斥锁变为…

.NET WinForm图像识别二维码/条形码

需求:图像识别出一张图片中的二维码或者条形码,并读取其中的内容。 一、安装ZXing.NET(此处建议使用0.14.0,高版本的不少地方进行优化,如果能处理好也可) Install-Package ZXing.Net 二、WinForm示例代码(含关键优化&#xff0…

理解教材意图轻松积累常见数列

教学感悟 以前在传授数列时只是机械的要求学生记住常见的数列,至于“哪些才算是常见的数列?这些数列是怎么来的”,心里比较糊涂,在有一次的教学中,偶然回忆起:函数教学时教材要求掌握一些常见的函数&#…

[预训练]Encoder-only架构的预训练任务核心机制

原创文章1FFN前馈网络与激活函数技术解析:Transformer模型中的关键模块2Transformer掩码技术全解析:分类、原理与应用场景3【大模型技术】Attention注意力机制详解一4Transformer核心技术解析LCPO方法:精准控制推理长度的新突破5Transformer模…

【大模型MCP】MCP 深度解析:AI 时代的「USB-C」接口——原理、对比、实战代码与行业落地

摘要 模型上下文协议 (Model Context Protocol, MCP) 诞生于 2024 年11月,由 Anthropic 牵头,在 2025-03-26 发布 1.0 正式规范。它以 JSON-RPC 2.0 消息结构承载于 WebSocket / SSE 等全双工传输之上,把「初始化 → 工具目录 → 调用 → 结…

超声波清洗机的作用是什么?使用超声波清洗机可以去除毛刺吗?

在现代制造业中,表面质量对产品的性能和外观至关重要。超声波清洗机作为一种高效的清洗工具,在去除表面污垢和缺陷方面发挥着关键作用。本文深圳科伟达将介绍超声波清洗机的作用,以及它是否能够有效去除毛刺。 超声波清洗机的作用&#xff1…

非常好看网站维护带倒计时模板+维护结束模板

非常好看网站维护带倒计时模板维护结束模板 网站维护带倒计时模板维护结束模板.zip - 蓝奏云

STM32F103_Bootloader程序开发05 - Keil修改生成文件的路径与文件名,自动生成bin格式文件

导言 通过Keil的相关配置,可以灵活地修改输出文件的保存路径及文件名称。在Bootloader程序开发过程中,合理配置输出文件对于后续固件升级和自动化脚本处理至关重要。完成路径和文件名配置后,还可以借助Keil自带的fromelf.exe工具,…

【MQ】消息队列的核心价值及技术选型

文章目录 一、什么是消息队列二、消息队列的核心功能三、主流消息队列技术对比ActiveMQ:逐渐淡出的老牌产品Kafka:大数据领域的王者RabbitMQ:企业级可靠选择Apache Pulsar:云原生时代的"新贵"NATS:轻量级消息…

本地部署消息代理软件 RabbitMQ 并实现外部访问( Windows 版本 )

RabbitMQ 是由 Erlang 语言开发的 消息中间件,是一种应用程序之间的通信方法。支持多种编程和语言和协议发展,用于实现分布式系统的可靠消息传递和异步通信等方面。 本文将详细介绍如何在 Windows 系统本地部署 RabbitMQ 并结合路由侠实现外网访问本…

如何在 Odoo 18 中创建 PDF 报告

如何在 Odoo 18 中创建 PDF 报告 Qweb 是 Odoo 强大的模板引擎,旨在轻松将 XML 数据转换为 HTML 文档。其功能特性包括基于属性的自定义、条件逻辑、动态内容插入及多样化的报告模板选项。这种多功能性使 Qweb 成为制作个性化、视觉吸引力强的报告、电子邮件和文档…

【面板数据】上市公司供应链网络地位数据(2001-2024年)

企业是产业链供应链的微观主体,其供应链网络布局是增强产业链供应链稳定性的重中之重,企业在供应链网络中的地位,已成为衡量其市场影响力和风险承受能力的重要指标。本次是上市公司供应链网络地位数据,数据年份为2001-2024年。 一…

EasyFileCount(文件查重工具) v3.0.5.1 便携版

EasyFileCount 是一款免费方便、快捷的文件管理软件,采用Java开发,主打一个清爽简洁、安全无害的使用体验,支持多盘高性能扫描。遍历扫描文件夹的速度还算比较快的,当然所谓的快慢取决于CPU、系统、硬盘种类、文件或文件夹的数量等…