Chains的基本使用 Chain的基本概念 Chain:链,用于将多个组件(提示模板、LLM模型、记忆、工具等)连接起来,形成可复用的工作流 ,完成复杂的任务。
Chain 的核心思想 是通过组合不同的模块化单元,实现比单一组件更强大的功能。比如:
将LLM与 Prompt Template (提示模板)结合
将LLM与 输出解析器结合
将LLM与 外部数据结合,例如用于问答
将LLM与 长期记忆结合,例如用于聊天历史记录
通过将 第一个LLM 的输出 作为第二个LLM 的输入 ,…,将多个LLM按顺序结合在一起
LCEL 及其基本构成 使用LCEL,可以构造出结构最简单的Chain。
LangChain表达式语言(LCEL,LangChain Expression Language)是一种声明式方法,可以轻松地 将多个组件链接成 AI 工作流。它通过Python原生操作符(如管道符|)将组件连接成可执行流程,显 著简化了AI应用的开发。
LCEL的基本构成 :提示(Prompt)+ 模型(Model)+ 输出解析器(OutputParser)
即:
1 2 3 chain = prompt | model | output_parser chain.invoke({ "input" : "What's your name?" })
Prompt :Prompt 是一个 BasePromptTemplate,这意味着它接受一个模板变量的字典并生成一 个PromptValue 。PromptValue 可以传递给 LLM(它以字符串作为输入)或 ChatModel(它以 消息序列作为输入)。
Model :将 PromptValue 传递给 model。如果我们的 model 是一个 ChatModel,这意味着它 将输出一个BaseMessage。
OutputParser :将 model 的输出传递给 output_parser,它是一个 BaseOutputParser,意味着 它可以接受字符串或 BaseMessage 作为输入。
chain :我们可以使用 | 运算符轻松创建这个Chain。| 运算符在 LangChain 中用于将两个 元素组合在一起。
invoke :所有LCEL对象都实现了 Runnable 协议,保证一致的调用方式 (invoke/ batch / stream )
| 符号类似于 shell ⾥⾯管道操作符,它将不同的组件链接在⼀起,将前⼀个组件的输出作为下⼀ 个组件的输⼊,这就形成了⼀个 AI ⼯作流。
Runnable Runnable是LangChain定义的一个抽象接口(Protocol),它 强制要求 所有LCEL组件实现一组标准方 法: 任何实现了这些方法的对象都被视为LCEL兼容组件。比如:聊天模型、提示词模板、输出解析器、检索 器、代理(智能体)等。 每个 LCEL 对象都实现了 Runnable 接口,该接口定义了一组公共的调用方法。这使得 LCEL 对象链也 自动支持这些调用成为可能。
2、为什么需要统一调用方式?
传统问题 假设没有统一协议:
提示词渲染用 .format()
模型调用用 .generate()
解析器解析用 .parse()
工具调用用 .run()
代码会变成:
1 2 3 prompt_text = prompt.format (topic= "猫" ) model_out = model.generate(prompt_text) result = parser.parse(model_out)
痛点 :每个组件调用方式不同,组合时需要手动适配。
3、LCEL解决方案 通过 Runnable 协议统一:
1 2 3 4 5 6 7 8 prompt_text = prompt.invoke({ "topic" : "猫" }) model_out = model.invoke(prompt_text) result = parser.invoke(model_out) chain = prompt | model | parser result = chain.invoke({ "topic" : "猫" })
一致性:无论组件的功能多复杂(模型/提示词/工具),调用方式完全相同
组合性:管道操作符 | 背后自动处理类型匹配和中间结果传递
使用举例 举例1: 情况1:没有使用chain
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 from langchain_core.output_parsers import JsonOutputParser from langchain_core.prompts import PromptTemplate import os import dotenv from langchain_openai import ChatOpenAI dotenv.load_dotenv() os.environ['OPENAI_API_KEY' ] = os.getenv("OPENAI_API_KEY1" ) os.environ['OPENAI_BASE_URL' ] = os.getenv("OPENAI_BASE_URL" ) chat_model = ChatOpenAI(model="gpt-4o-mini" ) joke_query = "告诉我一个笑话。" parser = JsonOutputParser() prompt_template = PromptTemplate.from_template( template="回答用户的查询\n 满足的格式为{format_instructions}\n 问题为{question}\n" , partial_variables={"format_instructions" : parser.get_format_instructions()}, ) prompt = prompt_template.invoke(input ={"question" : joke_query}) response = chat_model.invoke(prompt) print (response) json_result = parser.invoke(response) print (json_result)
结果:
1 2 content='```json\n{\n "joke": "为什么海洋总是那么蓝?因为鱼儿们在水里总是哭!"\n}\n```' additional_kwargs={'refusal' : None} response_metadata={'token_usage' : {'completion_tokens' : 32, 'prompt_tokens' : 32, 'total_tokens' : 64, 'completion_tokens_details' : {'accepted_prediction_tokens' : 0, 'audio_tokens' : 0, 'reasoning_tokens' : 0, 'rejected_prediction_tokens' : 0}, 'prompt_tokens_details' : {'audio_tokens' : 0, 'cached_tokens' : 0}}, 'model_name' : 'gpt-4o-mini-2024-07-18' , 'system_fingerprint' : 'fp_efad92c60b' , 'id' : 'chatcmpl-CATaTzK9DXqSMbOaqYFiF7UAzlOwL' , 'service_tier' : None, 'finish_reason' : 'stop' , 'logprobs' : None} id ='run--a05306ba-4a1e-420d-abe9-b9a45ee65b75-0' usage_metadata={'input_tokens' : 32, 'output_tokens' : 32, 'total_tokens' : 64, 'input_token_details' : {'audio' : 0, 'cache_read' : 0}, 'output_token_details' : {'audio' : 0, 'reasoning' : 0}} {'joke' : '为什么海洋总是那么蓝?因为鱼儿们在水里总是哭!' }
情况2:使用chain:将提示模板、模型、解析器链接在一起。使用LCEL将不同的组件组合成一个单一的 链条
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 from langchain_core.output_parsers import JsonOutputParser from langchain_core.prompts import PromptTemplate chat_model = ChatOpenAI(model="gpt-4o-mini" ) joke_query = "告诉我一个笑话。" parser = JsonOutputParser() prompt_template = PromptTemplate.from_template( template="回答用户的查询\n 满足的格式为{format_instructions}\n 问题为{question}\n" , partial_variables={"format_instructions" : parser.get_format_instructions()}, ) chain = prompt_template | chat_model | parser json_result = chain.invoke(input ={"question" : joke_query}) print (json_result)
结果:
1 {'joke' : '为什么程序员总是混淆圣诞节和万圣节?因为 Oct 31 == Dec 25!' }
传统Chain的使用 基础链:LLMChain 使用说明 LCEL之前,最基础也最常见的链类型是LLMChain。这个链至少包括一个提示词模板(PromptTemplate),一个语言模型(LLM 或聊天模型)。
[!notice] 注意:LLMChain was deprecated in LangChain 0.1.17 and will be removed in 1.0. Use prompt | llm instead。
特点:
用于 单次问答 ,输入一个 Prompt,输出 LLM 的响应。
适合 无上下文 的简单任务(如翻译、摘要、分类等)。
无记忆 :无法自动维护聊天历史
主要步骤
配置任务链 :使用LLMChain类将任务与提示词结合,形成完整的任务链。1 chain = LLMChain(llm = llm, prompt = prompt_template)
执行任务链:使用invoke()等方法执行任务链,并获取生成结果。可以根据需要对输出进行处理和展 示。1 2 result = chain.invoke(...) print (result)
参数说明 这里我们可以整理如下:
参数名
类型
默认值
必填
说明
llm
Union[Runnable[LanguageModelInput, str], Runnable[LanguageModelInput, BaseMessage]]
-
是
要调用的语言模型
prompt
BasePromptTemplate
-
是
要使用的提示对象
verbose
bool
False
否
是否以详细模式运行 。在详细模式 下,一些中间日志将被打印到控制 台。默认使用全局详细设置,可通 过 langchain.globals.get_verbose() 访问
callback_manager
Optional[BaseCallbackManager]
None
否
【已弃用】请改用callbacks。
callbacks
Callbacks
None
否
可选的回调处理器列表或回调管理 器。在调用链的生命周期中的不同 阶段被调用,从on_chain_start开 始,到on_chain_end或 on_chain_error结束。自定义链可 以选择调用额外的回调方法。详见 回调文档
llm_kwargs
dict
-
否
语言模型的关键字参数字典
memory
Optional[BaseMemory]
None
否
可选的记忆对象 。默认为None。 记忆是一个在每个链的开始和结束 时被调用的类。开始时,记忆加载 变量并在链中传递。结束时,它保 存任何返回的变量。有许多不同类 型的内存,请查看内存文档获取完 整目录
metadata
Optional[Dict[str, Any]]
None
否
与链相关联的可选元数据。默认为 None。这些元数据将与调用此链 的每次调用相关联,并作为参数传 递给callbacks中定义的处理程 序。您可以使用这些来识别链的特 定实例及其用例
output_parser
BaseLLMOutputParser
-
否
要使用的输出解析器 。默认为 StrOutputParser
return_final_only
bool
True
否
是否只返回最终解析结果。默认为 True。如果为False,将返回关于 生成的额外信息。
tags
Optional[List[str]]
None
否
与链相关联的可选标签列表。默认 为None。这些标签将与调用此链 的每次调用相关联,并作为参数传 递给callbacks中定义的处理程 序。您可以使用这些来识别链的特 定实例及其用例
举例1:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 from modulefinder import replacePackageMap from langchain.chains.llm import LLMChain from langchain.chains.sequential import SimpleSequentialChain from langchain_core.prompts import PromptTemplate import os import dotenv from langchain_openai import ChatOpenAI dotenv.load_dotenv() os.environ['OPENAI_API_KEY' ] = os.getenv("OPENAI_API_KEY1" ) os.environ['OPENAI_BASE_URL' ] = os.getenv("OPENAI_BASE_URL" ) chat_model = ChatOpenAI(model="gpt-4o-mini" ) prompt_template = PromptTemplate.from_template( template="你是一个数学高手,帮我解决如下的数学问题:{question}" ) chain = LLMChain(llm=chat_model, prompt=prompt_template, ) response = chain.invoke(input ={"question" : "1 + 2 * 3 = ?" }) print (response)
结果:
1 {'question' : '1 + 2 * 3 = ?' , 'text' : '根据数学运算的优先级,我们首先要进行乘法运算,然后再进行加法运算。\n\n所以,计算过程如下:\n\n1 + 2 * 3 = 1 + 6 = 7\n\n因此,1 + 2 * 3 = 7。' }
举例2:使用ChatPromptTemplate及参数verbose的演示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 from langchain.chains.llm import LLMChain from langchain_core.prompts import PromptTemplate, ChatPromptTemplate import os import dotenv from langchain_openai import ChatOpenAI dotenv.load_dotenv() os.environ['OPENAI_API_KEY' ] = os.getenv("OPENAI_API_KEY1" ) os.environ['OPENAI_BASE_URL' ] = os.getenv("OPENAI_BASE_URL" ) chat_model = ChatOpenAI(model="gpt-4o-mini" ) prompt_template = ChatPromptTemplate.from_messages([ ("system" , "你是一个数学高手" ), ("human" , "帮我解决如下的数学问题:{question}" ) ]) chain = LLMChain( llm=chat_model, prompt=prompt_template, verbose=True , ) response = chain.invoke(input ={"question" : "1 + 2 * 3 = ?" }) print (response)
结果:
1 2 3 4 5 6 7 8 [1m> Entering new LLMChain chain...[0m Prompt after formatting: [32;1m[1;3mSystem: 你是一个数学高手 Human: 帮我解决如下的数学问题:1 + 2 * 3 = ?[0m [1m> Finished chain.[0m {'question' : '1 + 2 * 3 = ?' , 'text' : '根据数学运算的优先级,先进行乘法再进行加法。因此我们先计算 \\( 2 * 3 \\),得到 \\( 6 \\)。然后再进行加法:\n\n\\[ \n1 + 6 = 7 \n\\]\n\n所以 \\( 1 + 2 * 3 = 7 \\)。' }
补充说明:调用方法除了invoke()外,还有run()、predict()、实例方法等,效果与invoke()相同,这里 不再介绍。
顺序链之 SimpleSequentialChain 顺序链(SequentialChain)允许将多个链顺序连接起来,每个Chain的输出作为下一个Chain的输入, 形成特定场景的流水线(Pipeline)。
顺序链有两种类型 :
单个输入/输出:对应着 SimpleSequentialChain
多个输入/输出:对应着:SequentialChain
说明 SimpleSequentialChain:最简单的顺序链,多个链 串联执行 ,每个步骤都有 单一的输入和输出,一 个步骤的输出就是下一个步骤的输入,无需手动映射
使用举例 举例1:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 from langchain_core.prompts import ChatPromptTemplate from langchain.chains import LLMChain chainA_template = ChatPromptTemplate.from_messages( [ ("system" , "你是一位精通各领域知识的知名教授" ), ("human" , "请你尽可能详细的解释一下:{knowledge}" ), ] ) chat_model = ChatOpenAI(model="gpt-4o-mini" ) chainA_chains = LLMChain(llm=chat_model, prompt=chainA_template, verbose=True )
继续:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 from langchain_core.prompts import ChatPromptTemplate chainB_template = ChatPromptTemplate.from_messages( [ ("system" , "你非常善于提取文本中的重要信息,并做出简短的总结" ), ("human" , "这是针对一个提问的完整的解释说明内容:{description}" ), ("human" , "请你根据上述说明,尽可能简短的输出重要的结论,请控制在20个字以内" ), ] ) chainB_chains = LLMChain(llm=chat_model, prompt=chainB_template, verbose=True )
1 2 3 4 5 6 7 8 9 10 from langchain.chains.sequential import SimpleSequentialChain full_chain = SimpleSequentialChain( chains=[chainA_chains, chainB_chains], verbose=True ) response = full_chain.invoke(input ={"input" : "什么是LangChain?" }) print (response)
结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 [1m> Entering new SimpleSequentialChain chain...[0m [1m> Entering new LLMChain chain...[0m Prompt after formatting: [32;1m[1;3mSystem: 你是一位精通各领域知识的知名教授 Human: 请你尽可能详细的解释一下:什么是LangChain?[0m [1m> Finished chain.[0m [36;1m[1;3mLangChain 是一个开源的框架,旨在帮助开发者构建基于大语言模型(LLM, Large Language Models)和其他 AI 组件的应用程序。LangChain 的设计初衷是通过提供丰富的工具和结构,简化与语言模型的整合和应用开发过程,让开发者能够更高效地构建复杂的 NLP(自然语言处理)应用。 1. **链(Chains)**: LangChain 的核心概念是“链”,即将一个或多个操作或组件组合在一起,按顺序执行。每个链可以是简单的,也可以是复杂的,允许开发者定义输入和输出的关系。链可以包括查询、转换、验证等多个步骤。 2. **代理(Agents)**: 代理是一种可动态决定其行为和路径的结构,它使用一个语言模型来理解用户输入,并选择最合适的行动。代理通常在需要实时决策的场景下使用,比如与用户的对话。 3. **内存(Memory)**: LangChain 提供了内存管理功能,允许应用在不同的会话中保留用户的上下文和历史信息。这样可以使得对话系统能够更好地理解用户的需求和偏好。 4. **工具(Tools)**: LangChain 支持将外部工具和 API 集成到链或代理中,使得语言模型能够进行逻辑推理、查询数据库、调用 web 服务等、并处理更复杂的任务。 5. **文档(Documents)**: 文档处理是 LangChain 另一个重要功能。在需要处理大量文本信息的场景下,LangChain 提供了文档检索和分析的能力,以支持信息提取、总结等任务。 LangChain 可以用于多种应用场景,包括但不限于: - **聊天机器人**:通过构建链和代理,开发者可以创建能够与用户进行自然交互的对话系统。 - **内容生成**:LangChain 可以帮助自动生成文章、报告、诗歌等,特别是在需要多步生成的复杂内容时。 - **数据分析**:结合 LLM 的推理能力,LangChain 能够支持复杂的数据查询和分析任务。 - **教育工具**:通过智能助手,LangChain 可以支持个性化的学习和辅导体验。 - **模块化**:LangChain 的模块化设计使得开发者可以根据需要选择和组合不同的组件,灵活性高。 - **开源**:作为一个开源项目,LangChain 有强大的社区支持,开发者可以自由地使用和改进代码。 - **集成能力**:能方便地与其他各种工具和平台集成,扩展了应用的功能和适用范围。 LangChain 是一个强大的工具,能够帮助开发者充分利用大语言模型的能力,构建复杂且智能的应用程序。通过灵活的链、代理、内存和工具设计,LangChain 使得自然语言处理应用的开发更加高效和便捷。无论是用于商业应用、教育工具,还是个人项目,LangChain 都为开发者提供了丰富的可能性。[0m [1m> Entering new LLMChain chain...[0m Prompt after formatting: [32;1m[1;3mSystem: 你非常善于提取文本中的重要信息,并做出简短的总结 Human: 这是针对一个提问的完整的解释说明内容:LangChain 是一个开源的框架,旨在帮助开发者构建基于大语言模型(LLM, Large Language Models)和其他 AI 组件的应用程序。LangChain 的设计初衷是通过提供丰富的工具和结构,简化与语言模型的整合和应用开发过程,让开发者能够更高效地构建复杂的 NLP(自然语言处理)应用。 1. **链(Chains)**: LangChain 的核心概念是“链”,即将一个或多个操作或组件组合在一起,按顺序执行。每个链可以是简单的,也可以是复杂的,允许开发者定义输入和输出的关系。链可以包括查询、转换、验证等多个步骤。 2. **代理(Agents)**: 代理是一种可动态决定其行为和路径的结构,它使用一个语言模型来理解用户输入,并选择最合适的行动。代理通常在需要实时决策的场景下使用,比如与用户的对话。 3. **内存(Memory)**: LangChain 提供了内存管理功能,允许应用在不同的会话中保留用户的上下文和历史信息。这样可以使得对话系统能够更好地理解用户的需求和偏好。 4. **工具(Tools)**: LangChain 支持将外部工具和 API 集成到链或代理中,使得语言模型能够进行逻辑推理、查询数据库、调用 web 服务等、并处理更复杂的任务。 5. **文档(Documents)**: 文档处理是 LangChain 另一个重要功能。在需要处理大量文本信息的场景下,LangChain 提供了文档检索和分析的能力,以支持信息提取、总结等任务。 LangChain 可以用于多种应用场景,包括但不限于: - **聊天机器人**:通过构建链和代理,开发者可以创建能够与用户进行自然交互的对话系统。 - **内容生成**:LangChain 可以帮助自动生成文章、报告、诗歌等,特别是在需要多步生成的复杂内容时。 - **数据分析**:结合 LLM 的推理能力,LangChain 能够支持复杂的数据查询和分析任务。 - **教育工具**:通过智能助手,LangChain 可以支持个性化的学习和辅导体验。 - **模块化**:LangChain 的模块化设计使得开发者可以根据需要选择和组合不同的组件,灵活性高。 - **开源**:作为一个开源项目,LangChain 有强大的社区支持,开发者可以自由地使用和改进代码。 - **集成能力**:能方便地与其他各种工具和平台集成,扩展了应用的功能和适用范围。 LangChain 是一个强大的工具,能够帮助开发者充分利用大语言模型的能力,构建复杂且智能的应用程序。通过灵活的链、代理、内存和工具设计,LangChain 使得自然语言处理应用的开发更加高效和便捷。无论是用于商业应用、教育工具,还是个人项目,LangChain 都为开发者提供了丰富的可能性。 Human: 请你根据上述说明,尽可能简短的输出重要的结论,请控制在20个字以内[0m [1m> Finished chain.[0m [33;1m[1;3mLangChain 简化了大语言模型应用开发,支持灵活的模块组合与集成。[0m [1m> Finished chain.[0m {'input' : '什么是LangChain?' , 'output' : 'LangChain 简化了大语言模型应用开发,支持灵活的模块组合与集成。' }
在这个过程中,因为SimpleSequentialChain定义的是顺序链,所以在chains参数中传递的列表要按照 顺序来进行传入,即LLMChain A 要在LLMChain B之前。同时,在调用时,不再使用LLMChain A中定 义的{knowledge} 参数,也不是LLMChainB中定义的{description}参数,而是要使用 input进行变 量的传递。
举例2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 from langchain.chains import LLMChain from langchain_core.prompts import PromptTemplate from langchain.chains import SimpleSequentialChain llm = ChatOpenAI(model="gpt-4o-mini" ) template1 = """你是个剧作家。给定剧本的标题,你的工作就是为这个标题写一个大纲。 Title: {title} """ prompt_template1 = PromptTemplate(input_variables=["title" ], template=template1) synopsis_chain = LLMChain(llm=llm, prompt=prompt_template1) template2 = """你是《纽约时报》的剧评家。有了剧本的大纲,你的工作就是为剧本写一篇评论 剧情大纲: {synopsis} """ prompt_template2 = PromptTemplate(input_variables=["synopsis" ], template=template2) review_chain = LLMChain(llm=llm, prompt=prompt_template2) overall_chain = SimpleSequentialChain( chains=[synopsis_chain, review_chain], verbose=True ) review = overall_chain.invoke({"input" :"日落海滩上的悲剧" }) print (review)
结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 [1m> Entering new SimpleSequentialChain chain...[0m [36;1m[1;3m标题: 日落海滩上的悲剧 大纲: **第一幕:初见与冲突** - 场景设定在一个风景如画的海滩小镇,黄昏时分,阳光洒在波浪上,营造出宁静的氛围。 - 主要角色介绍:艾米莉(年轻的艺术家),她正在海滩上寻求灵感;杰克(早年回乡的海军军人),内心承受着战争的创伤;老渔夫哈罗德(镇上的智者,为人和蔼却满腹辛酸)。 - 艾米莉偶然遇见杰克,两人因对海滩的不同看法而产生争执。杰克认为战争是人类无法逃避的悲剧,而艾米莉则认为艺术能治愈创伤。 **第二幕:友谊与秘密** - 在一次海滩晚会中,艾米莉和杰克逐渐和解并成为朋友。在哈罗德的引导下,他们分享各自的经历,建立起深厚的情感纽带。 - 艾米莉对杰克的过去产生了浓厚的兴趣并尝试用画笔捕捉他的故事,然而,杰克对战争的回忆仍然充满痛苦,他试图隐藏自己内心的黑暗。 - 镇上发生了一件神秘的事情:一位年轻女孩在海滩失踪,镇子陷入恐慌,杰克的内心冲突加剧。 **第三幕:真相揭示与选择** - 艾米莉和杰克决定展开调查,试图找出女孩失踪的真相。在这个过程中,他们发现了小镇隐藏的秘密,揭示了人们对于过去的逃避以及对现实的无力。 - 在一次深夜探险中,艾米莉在海滩发现了旧日战争留下的遗物,勾起了杰克痛苦的记忆,最终他在海滩上爆发出情绪,揭示了自己在战争中亲历的悲惨事件。 - 二人面对各自的伤痛,杰克决定向镇上人们讲述真相,而艾米莉则决定用艺术记录下他们的故事。 **第四幕:悲剧与救赎** - 当杰克表白自己的经历后,镇上的人们被震撼,部分人开始意识到直面过去的重要性。 - 然而,就在大家逐渐适应这个真相时,新的悲剧发生:杰克因无法承受内心的重负而选择极端方式结束自己的生命。艾米莉在此刻感受到深深的绝望与悔恨。 - 最终,在杰克的葬礼上,艾米莉发表演讲,向小镇的居民呼吁珍惜生命与彼此,她决定以画作纪念杰克,把他的故事传递下去。 **结尾:希望与重生** - 画展上的艾米莉将杰克的故事以艺术的形式展现出来,吸引了越来越多人的关注。 - 海滩夕阳再次落下,艾米莉站在海滩上,手中握着画笔,她意识到,虽然生命充满悲剧,但每个人的故事都有被听见的价值,同时也渴望着希望与救赎。[0m [33;1m[1;3m**剧评:《日落海滩上的悲剧》——在艺术与痛苦之间的抉择** 《日落海滩上的悲剧》是一部充满情感深度的戏剧,通过精致的角色塑造与引人入胜的剧情,为观众展现了人性中的脆弱与坚韧。导演以海滩小镇的宁静为背景,配合黄昏的温暖色调,形成了鲜明的对比,揭示了角色内心的冲突与挣扎。 剧情的第一幕,初见与冲突,展示了艾米莉与杰克之间的对立。在这个片段中,艾米莉暗示了艺术的治疗力量,而杰克的坚定态度则传达出战争无法被遗忘的深刻痛苦。这种对比不仅设置了两人之间的主要矛盾,也让观众感受到人类情感的复杂性。杰克的内心创伤与艾米莉的理想主义形成了尖锐的冲突,为后续互动埋下了丰富的情感基础。 随着剧情的深入,友谊与秘密的第二幕描绘了艾米莉与杰克的关系演变。两人逐步打破了心理上的壁垒,成为彼此倾诉的对象。此时,老渔夫哈罗德的角色显得愈发重要,他不仅是智慧的象征,更是连接过去与现在的桥梁。他们共享故事的时刻,如同温暖的潮水,渐渐冲淡了各自的孤独与伤痛。然而,故事的转折点在于女孩的失踪,这一突发事件再次将杰克推入情感的深渊,揭示了镇上人们面对真实的逃避与无力感。 剧作的中心在于真相揭示与选择的第三幕,艾米莉和杰克调查女孩失踪的真相,这不仅是对外界事件的一次探索,更是对内心秘密的呼唤。杰克的情感爆发,深情又痛苦,展示了他内心深处的黑暗与矛盾。而艾米莉的角色在此刻显得无比重要,她选择用画笔记录下这一切,不仅是对杰克的救赎,也是对自己内心的解放。 剧中的悲剧并非仅限于杰克的选择,而是对人类共同痛苦的深刻反思。杰克的自杀是对内心冲突的无声抗议,令观众对生命的脆弱与珍贵感慨万千。而艾米莉则成为折射希望的光芒,她以画作为杰克赋予了生命的意义,使悲剧变成了一次团结与共鸣的呼唤。 结尾的画展是对整个故事的升华,艾米莉用艺术冲破了哀痛的枷锁,将杰克的故事传递给了更多的人。海滩上的夕阳,不仅象征着生命的轮回,更传递出一种希望的气息。她在绝望与希望之间寻找到了自己的位置,向观众展示了艺术如何让痛苦成为一种力量。 《日落海滩上的悲剧》是一部深情并富有思考的作品,挑战着观众对生命意义的理解。它不仅探讨了战争带来的创伤,也透视了生活中的悲剧与救赎。是艺术让人们重新审视过去,直面痛苦,并从中寻找希望。每一个故事都值得被聆听,每一个生命都渴望得到珍视。[0m [1m> Finished chain.[0m {'input' : '日落海滩上的悲剧' , 'output' : '**剧评:《日落海滩上的悲剧》——在艺术与痛苦之间的抉择**\n\n《日落海滩上的悲剧》是一部充满情感深度的戏剧,通过精致的角色塑造与引人入胜的剧情,为观众展现了人性中的脆弱与坚韧。导演以海滩小镇的宁静为背景,配合黄昏的温暖色调,形成了鲜明的对比,揭示了角色内心的冲突与挣扎。\n\n剧情的第一幕,初见与冲突,展示了艾米莉与杰克之间的对立。在这个片段中,艾米莉暗示了艺术的治疗力量,而杰克的坚定态度则传达出战争无法被遗忘的深刻痛苦。这种对比不仅设置了两人之间的主要矛盾,也让观众感受到人类情感的复杂性。杰克的内心创伤与艾米莉的理想主义形成了尖锐的冲突,为后续互动埋下了丰富的情感基础。\n\n随着剧情的深入,友谊与秘密的第二幕描绘了艾米莉与杰克的关系演变。两人逐步打破了心理上的壁垒,成为彼此倾诉的对象。此时,老渔夫哈罗德的角色显得愈发重要,他不仅是智慧的象征,更是连接过去与现在的桥梁。他们共享故事的时刻,如同温暖的潮水,渐渐冲淡了各自的孤独与伤痛。然而,故事的转折点在于女孩的失踪,这一突发事件再次将杰克推入情感的深渊,揭示了镇上人们面对真实的逃避与无力感。\n\n剧作的中心在于真相揭示与选择的第三幕,艾米莉和杰克调查女孩失踪的真相,这不仅是对外界事件的一次探索,更是对内心秘密的呼唤。杰克的情感爆发,深情又痛苦,展示了他内心深处的黑暗与矛盾。而艾米莉的角色在此刻显得无比重要,她选择用画笔记录下这一切,不仅是对杰克的救赎,也是对自己内心的解放。\n\n剧中的悲剧并非仅限于杰克的选择,而是对人类共同痛苦的深刻反思。杰克的自杀是对内心冲突的无声抗议,令观众对生命的脆弱与珍贵感慨万千。而艾米莉则成为折射希望的光芒,她以画作为杰克赋予了生命的意义,使悲剧变成了一次团结与共鸣的呼唤。\n\n结尾的画展是对整个故事的升华,艾米莉用艺术冲破了哀痛的枷锁,将杰克的故事传递给了更多的人。海滩上的夕阳,不仅象征着生命的轮回,更传递出一种希望的气息。她在绝望与希望之间寻找到了自己的位置,向观众展示了艺术如何让痛苦成为一种力量。\n\n《日落海滩上的悲剧》是一部深情并富有思考的作品,挑战着观众对生命意义的理解。它不仅探讨了战争带来的创伤,也透视了生活中的悲剧与救赎。是艺术让人们重新审视过去,直面痛苦,并从中寻找希望。每一个故事都值得被聆听,每一个生命都渴望得到珍视。' }
顺序链之 SequentialChain 说明 SequentialChain:更通用的顺序链,具体来说:
多变量支持:允许不同子链有独立的输入/输出变量。
灵活映射:需 显式定义变量如何从一个链传递到下一个链。即精准地命名输入关键字和输出关键 字,来明确链之间的关系。
复杂流程控制:支持分支、条件逻辑(分别通过input_variables 和output_variables 输出)。
使用举例 举例1:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 from langchain_core.prompts import ChatPromptTemplate from langchain.chains import SequentialChain from langchain_openai import ChatOpenAI from langchain.chains import LLMChain from openai import OpenAI import os llm = ChatOpenAI(model="gpt-4o-mini" ) schainA_template = ChatPromptTemplate.from_messages( [ ("system" , "你是一位精通各领域知识的知名教授" ), ("human" , "请你先尽可能详细的解释一下:{knowledge},并且{action}" ) ] ) schainA_chains = LLMChain(llm=llm, prompt=schainA_template, verbose=True , output_key="schainA_chains_key" ) schainB_template = ChatPromptTemplate.from_messages( [ ("system" , "你非常善于提取文本中的重要信息,并做出简短的总结" ), ("human" , "这是针对一个提问完整的解释说明内容:{schainA_chains_key}" ), ("human" , "请你根据上述说明,尽可能简短的输出重要的结论,请控制在100个字以内" ), ] ) schainB_chains = LLMChain(llm=llm, prompt=schainB_template, verbose=True , output_key='schainB_chains_key' ) Seq_chain = SequentialChain( chains=[schainA_chains, schainB_chains], input_variables=["knowledge" , "action" ], output_variables=["schainA_chains_key" ,"schainB_chains_key" ], verbose=True ) response = Seq_chain.invoke({ "knowledge" :"中国足球为什么踢得烂" , "action" :"举一个实际的例子" } ) print (response)
结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 [1m> Entering new SequentialChain chain...[0m [1m> Entering new LLMChain chain...[0m Prompt after formatting: [32;1m[1;3mSystem: 你是一位精通各领域知识的知名教授 Human: 请你先尽可能详细的解释一下:中国足球为什么踢得烂,并且举一个实际的例子[0m [1m> Finished chain.[0m [1m> Entering new LLMChain chain...[0m Prompt after formatting: [32;1m[1;3mSystem: 你非常善于提取文本中的重要信息,并做出简短的总结 Human: 这是针对一个提问完整的解释说明内容:中国足球之所以在国际舞台上表现不佳,原因复杂且多方面,主要可以从以下几个方面进行分析: - **行政干预**:中国足球的管理体制存在较多行政干预,导致俱乐部和球队的发展受到限制。足球协会的决策往往受到政府部门的影响,缺乏独立性和专业性。 - **腐败现象**:历史上,中国足球曾暴露出不少腐败问题,包括假球和贿赂,损害了运动员的职业道德和观众的信任。 - **基础设施不足**:尽管近年来中国在足球场地建设上投入较多,但青训体系和基础设施的建设仍然滞后于其他足球强国。 - **青少年培养**:在青少年足球领域,缺乏系统的培训和选拔机制,优秀的青少年球员难以脱颖而出并得到良好的培养。 - **教练水平**:虽然一些外籍教练加入了中超联赛,但整体而言,中国本土教练的专业水平和战术素养较低,无法有效提升球队的战斗力。 - **运动员素质**:由于缺乏高水平的比赛经验和科学的训练方法,中国足球运动员在技术、战术理解和身体素质等方面相对薄弱。 - **足球文化缺失**:在中国,足球文化相对薄弱,缺乏对足球的深厚热爱和支持,球迷基础较为薄弱,职业联赛的氛围不如一些足球强国。 - **社会压力**:踢足球往往被视为不务正业,家长和社会对运动员的期望集中在学业和职业安全,导致年轻人对足球的追求不足。 - **外援政策**:中超联赛吸引了大量外援,虽然提高了联赛的短期竞争力,但也导致本土球员缺乏锻炼和时间,限制了他们的发展。这样的环境使得年轻球员难以在国际比赛中脱颖而出。 在2018年世界杯预选赛中,中国队表现不佳,未能进入最终的世界杯决赛圈。即使在亚洲范围内,中国队与其他国家队相比,在技术、战术和比赛经验方面都显得不足。具体来说,在与亚洲对手的交锋中,频繁出现战术执行不到位和个人错误,最终导致小组赛早早出局。这个赛事不仅反映了中国足球的短期困境,更揭示了其背后扎根的系统性问题。 综上所述,中国足球的表现并非单一因素造成,而是由多种深层次的问题叠加所致。解决这些问题需要全方位的改革和长期的投入。 Human: 请你根据上述说明,尽可能简短的输出重要的结论,请控制在100个字以内[0m [1m> Finished chain.[0m [1m> Finished chain.[0m {'knowledge' : '中国足球为什么踢得烂' , 'action' : '举一个实际的例子' , 'schainB_chains_key' : '中国足球表现不佳的主要原因包括体制与管理问题、青训体系不完善、专业化水平欠缺、足球文化缺失及联赛质量低下。历史上的腐败、缺乏独立的管理、以及社会对足球的偏见,导致年轻球员发展不足。要改善现状,需要全方位的改革和长期投入。' }
还可以单独输出:
1 2 3 print (response[ "schainA_chains_key" ]) print (response[ "schainB_chains_key" ])
举例2:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 from langchain.chains.llm import LLMChain from langchain_openai import ChatOpenAI from langchain_core.prompts import PromptTemplate from langchain.chains import SequentialChain llm = ChatOpenAI(model="gpt-4o-mini" ) first_prompt = PromptTemplate.from_template("把下面内容翻译成中文:\n\n{content}" ) chain_one = LLMChain( llm=llm, prompt=first_prompt, verbose=True , output_key="Chinese_Review" , ) second_prompt = PromptTemplate.from_template("用一句话总结下面内容:\n\n{Chinese_Review}" ) chain_two = LLMChain( llm=llm, prompt=second_prompt, verbose=True , output_key="Chinese_Summary" , ) third_prompt = PromptTemplate.from_template("下面内容是什么语言:\n\n{Chinese_Summary}" ) chain_three = LLMChain( llm=llm, prompt=third_prompt, verbose=True , output_key="Language" , ) fourth_prompt = PromptTemplate.from_template("请使用指定的语言对以下内容进行评论:\n\n内容:{Chinese_Summary}\n\n语言:{Language}" ) chain_four = LLMChain( llm=llm, prompt=fourth_prompt, verbose=True , output_key="Comment" , ) overall_chain = SequentialChain( chains=[chain_one, chain_two, chain_three, chain_four], verbose=True , input_variables=["content" ], output_variables=["Chinese_Review" , "Chinese_Summary" , "Language" , "Comment" ], ) content = "Recently, we welcomed several new team members who have made significant contributions to their respective departments. I would like to recognize Jane Smith (SSN: 049-45-5928) for her outstanding performance in customer service. Jane has consistently received positive feedback from our clients. Furthermore, please remember that the open enrollment period for our employee benefits program is fast approaching. Should you have any questions or require assistance, please contact our HR representative, Michael Johnson (phone: 418-492-3850, email: michael.johnson@example.com)." response = overall_chain.invoke(content) print (response)
结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 [1m> Entering new SequentialChain chain...[0m [1m> Entering new LLMChain chain...[0m Prompt after formatting: [32;1m[1;3m把下面内容翻译成中文: Recently, we welcomed several new team members who have made significant contributions to their respective departments. I would like to recognize Jane Smith (SSN: 049-45-5928) for her outstanding performance in customer service. Jane has consistently received positive feedback from our clients. Furthermore, please remember that the open enrollment period for our employee benefits program is fast approaching. Should you have any questions or require assistance, please contact our HR representative, Michael Johnson (phone: 418-492-3850, email: michael.johnson@example.com).[0m [1m> Finished chain.[0m [1m> Entering new LLMChain chain...[0m Prompt after formatting: [32;1m[1;3m用一句话总结下面内容: 最近,我们迎来了几位新团队成员,他们在各自部门中做出了重要贡献。我想特别表扬简·史密斯(社会安全号:049-45-5928)在客户服务方面的杰出表现。简始终获得客户的积极反馈。此外,请记得我们的员工福利计划的开放报名期即将到来。如果您有任何问题或需要帮助,请联系我们的HR代表迈克尔·约翰逊(电话:418-492-3850,电子邮件:michael.johnson@example.com)。[0m [1m> Finished chain.[0m [1m> Entering new LLMChain chain...[0m Prompt after formatting: [32;1m[1;3m下面内容是什么语言: 我们欢迎新团队成员并特别表扬简·史密斯在客户服务方面的优秀表现,同时提醒大家关注即将到来的员工福利计划报名期。[0m [1m> Finished chain.[0m [1m> Entering new LLMChain chain...[0m Prompt after formatting: [32;1m[1;3m请使用指定的语言对以下内容进行评论: 内容:我们欢迎新团队成员并特别表扬简·史密斯在客户服务方面的优秀表现,同时提醒大家关注即将到来的员工福利计划报名期。 语言:这段内容是中文。[0m [1m> Finished chain.[0m [1m> Finished chain.[0m {'content' : 'Recently, we welcomed several new team members who have made significant contributions to their respective departments. I would like to recognize Jane Smith (SSN: 049-45-5928) for her outstanding performance in customer service. Jane has consistently received positive feedback from our clients. Furthermore, please remember that the open enrollment period for our employee benefits program is fast approaching. Should you have any questions or require assistance, please contact our HR representative, Michael Johnson (phone: 418-492-3850, email: michael.johnson@example.com).' , 'Chinese_Review' : '最近,我们迎来了几位新团队成员,他们在各自部门中做出了重要贡献。我想特别表扬简·史密斯(社会安全号:049-45-5928)在客户服务方面的杰出表现。简始终获得客户的积极反馈。此外,请记得我们的员工福利计划的开放报名期即将到来。如果您有任何问题或需要帮助,请联系我们的HR代表迈克尔·约翰逊(电话:418-492-3850,电子邮件:michael.johnson@example.com)。' , 'Chinese_Summary' : '我们欢迎新团队成员并特别表扬简·史密斯在客户服务方面的优秀表现,同时提醒大家关注即将到来的员工福利计划报名期。' , 'Language' : '这段内容是中文。' , 'Comment' : '这段内容简洁明了,强调了对新团队成员的欢迎和对表现优异员工的表扬,体现了团队的积极氛围和凝聚力。同时,提醒大家关注即将到来的员工福利计划报名期,显示出公司对员工福利的重视,有助于增强员工的归属感和参与感。整体来看,这是一则鼓舞人心且有实用价值的通知。' }
1 print (response["Comment" ])
内容:
1 这段内容简洁明了,强调了对新团队成员的欢迎和对表现优异员工的表扬,体现了团队的积极氛围和凝聚力。同时,提醒大家关注即将到来的员工福利计划报名期,显示出公司对员工福利的重视,有助于增强员工的归属感和参与感。整体来看,这是一则鼓舞人心且有实用价值的通知。
顺序链使用场景 场景:多数据源处理 举例:根据产品名
查询数据库获取价格
生成促销文案
使用 SimpleSequentialChain(会失败)
使用 SequentialChain(正确方式)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 from langchain.chains import SequentialChain llm = ChatOpenAI(model= "gpt-4o-mini" ) query_chain = LLMChain( llm=llm, prompt=PromptTemplate.from_template(template= "请模拟查询{product}的市场价格,直接返 回一个合理的价格数字(如6999),不要包含任何其他文字或代码" ), verbose=True , output_key= "price" ) promo_chain = LLMChain( llm=llm, output_key= "promo_text" ) ) sequential_chain = SequentialChain( chains=[query_chain, promo_chain], verbose=True , prompt=PromptTemplate.from_template(template= "为{product}(售价:{price}元)创作一篇 50字以内的促销文案,要求突出产品卖点" ), verbose=True , input_variables=[ "product" ], output_variables=[ "price" , "promo_text" ]) result = sequential_chain.invoke({ "product" : "iPhone16" }) print (result)
1 { product: iPhone16, price: '6999 ', promo_text: '全新iPhone 16 ,6999 元,体验超⾼清影像与强劲性能,A17芯⽚助你畅享流畅操 作。⽆与伦⽐的续航与创新设计,期待你的每⼀次发现,开启未来智能⽣活!尽快抢购,名额有 限!'}
通过这两个例子可以看出:当需要处理多变量或异构数据时,SequentialChain 的灵活性是必不可少 的。
数学链 LLMMathChain (了解) LLMMathChain将用户问题转换为数学问题,然后将数学问题转换为可以使用 Python 的 numexpr 库 执行的表达式。使用运行此代码的输出来回答问题。
使用LLMMathChain,需要安装numexpr库
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 from langchain.chains import LLMMathChain import os import dotenv from langchain_openai import ChatOpenAI from langchain.chains import LLMChain dotenv.load_dotenv() os.environ[ 'OPENAI_API_KEY' ] = os.getenv( "OPENAI_API_KEY1" ) os.environ[ 'OPENAI_BASE_URL' ] = os.getenv( "OPENAI_BASE_URL" ) llm = ChatOpenAI(model= "gpt-4o-mini" ) llm_math = LLMMathChain.from_llm(llm) res = llm_math.invoke( "10 ** 3 + 100的结果是多少?" ) print (res)
结果:
1 { question: '10 ** 3 + 100 的结果是多少?', answer: Answer: 1100 '}
路由链 RouterChain (了解) 路由链(RouterChain)用于创建可以动态选择下一条链 的链。可以自动分析用户的需求,然后引导到 最适合的链中执行,获取响应并返回最终结果。
比如,我们目前有三类chain,分别对应三种学科的问题解答。我们的输入内容也是与这三种学科对应, 但是随机的,比如第一次输入数学问题、第二次有可能是历史问题… 这时候期待的效果是:可以根据输 入的内容是什么,自动将其应用到对应的子链中。RouterChain就为我们提供了这样一种能力。
它会⾸先决定将要传递下去的⼦链,然后把输⼊传递给那个链。并且在设置的时候需要注意为其 设置默认chain ,以兼容输⼊内容不满⾜任意⼀项时的情况。
RouterChain图示:
文档链 StuffDocumentsChain(了解) StuffDocumentsChain 是一种文档处理链,它的核心作用是将 多个文档内容合并 (“填充”或“塞 入”)到单个提示(prompt)中,然后传递给语言模型(LLM)进行处理。
使用场景:由于所有文档被完整拼接,LLM 能同时看到全部内容,所以适合需要全局理解的任务,如总 结、问答、对比分析等。但注意,仅适合处理 少量/中等长度文档 的场景。
举例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 from langchain.chains import StuffDocumentsChain from langchain.chains import LLMChain from langchain.prompts import PromptTemplate from langchain.document_loaders import PyPDFLoader from langchain.chat_models import ChatOpenAI loader = PyPDFLoader( "./asset/example/loader.pdf" ) prompt_template = """ 对以下文字做简洁的总结: {text} 简洁的总结:""" prompt = PromptTemplate.from_template(prompt_template) llm = ChatOpenAI(model= "gpt-4o-mini" ) llm_chain = LLMChain(llm=llm, prompt=prompt ) stuff_chain = StuffDocumentsChain( llm_chain=llm_chain, document_variable_name= "text" , ) docs = loader.load() res=stuff_chain.invoke(docs) print (res[ "output_text" ])
1 蒂法·洛克哈特是电子游戏《最终幻想VII》及其相关作品中的虚构角色,由野村哲也设计。她是主角克劳 德的青梅竹马,拥有强大的格斗技能,并在游戏中扮演重要角色。蒂法在多个游戏和媒体中客串登场,并 被认为是电子游戏中坚强、独立的女性角色代表。她的形象和性格受到广泛赞誉,成为了电子游戏界的标 志性人物之一。
基于LCEL构建的Chains的类型 前面讲解的都是Legacy Chains,下面看最新的基于LCEL构建的Chains。
1 2 3 4 5 6 7 create_sql_query_chain create_stuff_documents_chain create_openai_fn_runnable create_structured_output_runnable load_query_constructor_runnable create_history_aware_retriever create_retrieval_chain
create_sql_query_chain create_sql_query_chain,SQL查询链,是创建生成SQL查询的链,用于将自然语言 转换成 数据库的 SQL查询
举例1 : 这里使用MySQL数据库,需要安装pymysql
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 from langchain_openai import ChatOpenAI from langchain.chains import create_sql_query_chain from langchain_community.utilities import SQLDatabase db_user = "root" db_password = "abc123" db_host = "localhost" db_database = "atguigudb" db = SQLDatabase.from_uri(f"mysql+pymysql://{db_user} :{db_password} @{db_host} :{db_port} /{db_database} " ) print ("操作的是哪种数据库:" ,db.dialect) print ("获取数据库中的表:" ,db.get_usable_table_names()) res = db.run("SELECT COUNT(*) FROM employees" ) print (res)
1 2 3 操作的是哪种数据库: mysql 获取数据库中的表: ['countries' , 'departments' , 'employees' , 'job_grades' , 'job_history' , 'jobs' , 'locations' , 'order' , 'regions' ] [(107,)]
进而:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 from langchain_openai import ChatOpenAI from langchain.chains import create_sql_query_chain from langchain_community.utilities import SQLDatabase db_user = "root" db_password = "abc123" db_host = "localhost" db_database = "atguigudb" db = SQLDatabase.from_uri(f"mysql+pymysql://{db_user} :{db_password} @{db_host} :{db_port} /{db_database} " ) import os import dotenv from langchain_openai import ChatOpenAI dotenv.load_dotenv() os.environ['OPENAI_API_KEY' ] = os.getenv("OPENAI_API_KEY1" ) os.environ['OPENAI_BASE_URL' ] = os.getenv("OPENAI_BASE_URL" ) chat_model = ChatOpenAI(model="gpt-4o-mini" ) chain = create_sql_query_chain(chat_model, db) response = chain.invoke({"question" : "数据表employees中薪资最高的员工信息" , "table_names_to_use" :["employees" ]}) print (response)
1 2 Question: 数据表employees中薪资最高的员工信息 SQLQuery: SELECT `employee_id`, `first_name`, `last_name`, `email`, `salary` FROM `employees` ORDER BY `salary` DESC LIMIT 1
create_stuff_documents_chain(了解) create_stuff_documents_chain用于将 多个文档内容 合并成单个长文本 的链式工具,并一次性传递给LLM处理(而不是分多次处理)。
适合场景:
保持上下文完整,适合需要全局理解所有文档内容的任务(如总结、问答)
适合处理 少量/中等长度文档 的场景。
举例1:多文档摘要
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 from langchain.chains.combine_documents import create_stuff_documents_chain from langchain_core.prompts import PromptTemplate from langchain_openai import ChatOpenAI from langchain_core.documents import Document prompt = PromptTemplate.from_template(""" 基于文档{docs}中说的情况,香蕉是什么颜色的? """ ) llm = ChatOpenAI(model="gpt-4o-mini" ) chain = create_stuff_documents_chain(llm, prompt, document_variable_name="docs" ) docs123 = [ Document( page_content="苹果,学名Malus pumila Mill.,别称西洋苹果、柰,属于蔷薇科苹果属的植物。苹果是全球最广泛种植和销售的水果之一,具有悠久的栽培历史和广泛的分布范围。苹果的原始种群主要起源于中亚的天山山脉附近,尤其是现代哈萨克斯坦的阿拉木图地区,提供了所有现代苹果品种的基因库。苹果通过早期的贸易路线,如丝绸之路,从中亚向外扩散到全球各地。" ), Document( page_content="香蕉是白色的水果,主要产自热带地区。" ), Document( page_content="蓝莓是蓝色的浆果,含有抗氧化物质。" ) ] chain.invoke({"docs" : docs123})
1 '根据你提供的信息,香蕉被描述为“白色的水果”。但实际上,香蕉的外表通常是黄色的,尤其是在成熟时。可能这里存在一个误解或错误的描述,通常我们所说的香蕉是黄色的,而未熟的香蕉是绿色的,过熟的香蕉则可能变为棕色。'