LangChain 是一款专为构建大语言模型(LLM)应用设计的 Python/JavaScript 开源框架,核心目标是解决 “只用原生 LLM API 开发复杂应用太繁琐” 的问题,让开发者能快速把 LLM(比如 ChatGPT、文心一言、智谱清言等)和外部资源(数据、工具、知识库)结合起来,搭建智能对话、问答机器人、数据分析、自动化工作流等应用。
1、先安装环境
conda create -n langchain python=3.11conda activate langchainpip install -U langchainpip install -U langchain-openai
2、一些简单的例子
from langchain_openai import ChatOpenAIimport osfrom langchain_core.messages import SystemMessage, HumanMessage, AIMessagechatLLM = ChatOpenAI(api_key=os.getenv("DASHSCOPE_API_KEY"),base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",model="qwen-plus", # 此处以qwen-plus为例,您可按需更换模型名称。模型列表:https://help.aliyun.com/zh/model-studio/getting-started/models# other params...)#简单示例def test1():messages = [{"role": "system", "content": "You are a helpful assistant."},{"role": "user", "content": "你是谁?"}]response = chatLLM.invoke(messages)print(response)#多轮对话def test2():messages = [SystemMessage(content="你是聚客AI大模型课的课程助理。"),HumanMessage(content="我是聚客AI学员,我叫小聚。"),AIMessage(content="欢迎!"),HumanMessage(content="我是谁?")]ret = chatLLM.invoke(messages)print(ret.content)#流式输出def test3():for token in chatLLM.stream("你是谁"):print(token.content, end="")# 程序入口:只有直接运行这个文件时,才执行游戏if __name__ == "__main__":test3()
3、模板格式限定相关的例子
from langchain_core.prompts import PromptTemplatefrom langchain_openai import ChatOpenAIimport osfrom pydantic import BaseModel, Fieldfrom langchain_core.prompts import (ChatPromptTemplate,HumanMessagePromptTemplate,SystemMessagePromptTemplate,)from langchain_core.output_parsers import JsonOutputParserfrom langchain_core.output_parsers import PydanticOutputParserchatLLM = ChatOpenAI(api_key=os.getenv("DASHSCOPE_API_KEY"),base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",model="qwen-plus", # 此处以qwen-plus为例,您可按需更换模型名称。模型列表:https://help.aliyun.com/zh/model-studio/getting-started/models# other params...)#模板替换def test1():template = PromptTemplate.from_template("给我讲个关于{subject}的笑话")print("===Template===")print(template)print("===Prompt===")print(template.format(subject='小明'))def test2():# 通过 Prompt 调用 LLMtemplate = PromptTemplate.from_template("给我讲个关于{subject}的笑话")ret = chatLLM.invoke(template.format(subject='小明'))# 打印输出print(ret.content)def test3():template = ChatPromptTemplate.from_messages([SystemMessagePromptTemplate.from_template("你是{product}的客服助手。你的名字叫{name}"),HumanMessagePromptTemplate.from_template("{query}")])prompt = template.format_messages(product="AI大模型课程",name="小林",query="你是谁")print(prompt)ret = chatLLM.invoke(prompt)print(ret.content)#从文件中加载def test4():template = PromptTemplate.from_file("G:\\AI\\workspace\\vscode\\202602\\prompt.txt", encoding="utf-8")print("===Template===")print(template)print("===Prompt===")print(template.format(topic='黑色幽默'))# 定义你的输出对象class Date(BaseModel):year: int = Field(description="Year")month: int = Field(description="Month")day: int = Field(description="Day")era: str = Field(description="BC or AD")#结构化输出def test5():# 定义结构化输出的模型structured_llm = chatLLM.with_structured_output(Date)template = """提取用户输入中的日期。用户输入:{query}"""prompt = PromptTemplate(template=template,)query = "2023年四月6日天气晴..."input_prompt = prompt.format_prompt(query=query)ret = structured_llm.invoke(input_prompt)print(ret)#输出指定格式的jsondef test6():json_schema = {"title": "Date","description": "Formated date expression","type": "object","properties": {"year": {"type": "integer","description": "year, YYYY",},"month": {"type": "integer","description": "month, MM",},"day": {"type": "integer","description": "day, DD",},"era": {"type": "string","description": "BC or AD",},},}# 定义结构化输出的模型structured_llm = chatLLM.with_structured_output(json_schema)template = """提取用户输入中的日期。用户输入:{query}"""prompt = PromptTemplate(template=template,)query = "2023年四月6日天气晴..."input_prompt = prompt.format_prompt(query=query)ret = structured_llm.invoke(input_prompt)print(ret)#JsonOutputParser指定输出格式def test7():parser = JsonOutputParser(pydantic_object=Date)prompt = PromptTemplate(template="提取用户输入中的日期。\n用户输入:{query}\n{format_instructions}",input_variables=["query"],partial_variables={"format_instructions": parser.get_format_instructions()},)query = "2023年四月6日天气晴..."input_prompt = prompt.format_prompt(query=query)output = chatLLM.invoke(input_prompt)print("原始输出:")print(output)print("解析后:")print(parser.invoke(output))#PydanticOutputParser指定输出格式def test8():parser = PydanticOutputParser(pydantic_object=Date)prompt = PromptTemplate(template="提取用户输入中的日期。\n用户输入:{query}\n{format_instructions}",input_variables=["query"],partial_variables={"format_instructions": parser.get_format_instructions()},)query = "2023年四月6日天气晴..."input_prompt = prompt.format_prompt(query=query)output = chatLLM.invoke(input_prompt)print("原始输出:")print(output)print("解析后:")print(parser.invoke(output))# 程序入口:只有直接运行这个文件时,才执行游戏if __name__ == "__main__":test8()
4、回调本地方法的一些例子
from langchain_openai import ChatOpenAIfrom langchain_core.messages import HumanMessageimport osimport jsonfrom langchain_core.tools import tool@tooldef add(a: int, b: int) -> int:"""Add two integers.Args:a: First integerb: Second integer"""return a + b@tooldef multiply(a: float, b: float) -> float:"""Multiply two integers.Args:a: First integerb: Second integer"""return a * bchatLLM = ChatOpenAI(api_key=os.getenv("DASHSCOPE_API_KEY"),base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",model="qwen-plus", # 此处以qwen-plus为例,您可按需更换模型名称。模型列表:https://help.aliyun.com/zh/model-studio/getting-started/models# other params...)#简单示例def test1():llm_with_tools = chatLLM.bind_tools([add, multiply])query = "3.5的4倍是多少?"messages = [HumanMessage(query)]output = llm_with_tools.invoke(messages)print(output)print("\n")print(json.dumps(output.tool_calls, indent=4))# 程序入口:只有直接运行这个文件时,才执行游戏if __name__ == "__main__":test1()
5、LCEL流式调用的一些例子
LCEL(LangChain Expression Language)是 LangChain 推出的声明式链式编程语法,核心目标是让开发者用极简的代码,把 LangChain 的各种组件(比如提示词、LLM、输出解析器)拼接成可执行的 “链”,而且自带异步、批处理、缓存等能力,不用自己写复杂的拼接逻辑。
可以把 LCEL 理解为:专门为 LangChain 组件设计的 “管道语法” —— 就像把不同功能的水管接在一起,数据从一端流入,经过各个组件处理后从另一端流出。
from langchain_core.prompts import ChatPromptTemplatefrom langchain_core.output_parsers import StrOutputParserfrom langchain_core.runnables import RunnablePassthroughfrom pydantic import BaseModel, Fieldfrom typing import List, Dict, Optionalfrom enum import Enumfrom langchain_openai import ChatOpenAIimport jsonimport osfrom langchain.chat_models import init_chat_model# 输出结构class SortEnum(str, Enum):data = 'data'price = 'price'class OrderingEnum(str, Enum):ascend = 'ascend'descend = 'descend'class Semantics(BaseModel):name: Optional[str] = Field(description="流量包名称", default=None)price_lower: Optional[int] = Field(description="价格下限", default=None)price_upper: Optional[int] = Field(description="价格上限", default=None)data_lower: Optional[int] = Field(description="流量下限", default=None)data_upper: Optional[int] = Field(description="流量上限", default=None)sort_by: Optional[SortEnum] = Field(description="按价格或流量排序", default=None)ordering: Optional[OrderingEnum] = Field(description="升序或降序排列", default=None)# Prompt 模板prompt = ChatPromptTemplate.from_messages([("system", "你是一个语义解析器。你的任务是将用户的输入解析成JSON表示。不要回答用户的问题。"),("human", "{text}"),])# 模型llm = ChatOpenAI(api_key=os.getenv("DASHSCOPE_API_KEY"),base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",model="qwen-plus", # 此处以qwen-plus为例,您可按需更换模型名称。模型列表:https://help.aliyun.com/zh/model-studio/getting-started/models# other params...)structured_llm = llm.with_structured_output(Semantics)# LCEL 表达式runnable = ({"text": RunnablePassthrough()} | prompt | structured_llm)# 直接运行ret = runnable.invoke("不超过100元的流量大的套餐有哪些")print(json.dumps(ret.model_dump(),indent = 4,ensure_ascii=False))
6、LangChain 与 LlamaIndex 的错位竞争
- LangChain 侧重与 LLM 本身交互的封装
- Prompt、LLM、Message、OutputParser 等工具丰富
- 在数据处理和 RAG 方面提供的工具相对粗糙
- 主打 LCEL 流程封装
- 配套 Agent、LangGraph 等智能体与工作流工具
- 另有 LangServe 部署工具和 LangSmith 监控调试工具
- LlamaIndex 侧重与数据交互的封装
- 数据加载、切割、索引、检索、排序等相关工具丰富
- Prompt、LLM 等底层封装相对单薄
- 配套实现 RAG 相关工具
- 同样配套智能体与工作流工具
- 提供 LlamaDeploy 部署工具,通过与三方合作提供过程监控调试工具
