langchain 基础
langchain 基础
基于langchain 0.3
提示词模板
from langchain.chains.summarize.map_reduce_prompt import prompt_template
from langchain_core.prompts import PromptTemplate
prompt_template =PromptTemplate.from_template("tell me who is {him}")
result = prompt_template.invoke({"him":"kobe"})
print(result)
大多数LLM应用程序不会直接将用户输入传递到LLM中。通常,它们会将用户输入添加到一个更大的文本片段中,
称为提示模板,该模板提供了有关特定任务的附加上下文。
基础会话
from http.client import responses
from openai import OpenAI
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage,SystemMessage
import os
from pyexpat.errors import messages
load_dotenv()
api_key=os.getenv("OPENAI_API_KEY")
model =ChatOpenAI(api_key=api_key,model="gpt-4.1-mini")
messages=[
SystemMessage(content="turn the sentence to chinese"),
HumanMessage(content="Apple"),
]
response=model.invoke(messages)
print(response)
Parser
但我们发现返回的结果包含了不少我们不需要的内容,通过Parser可以将其过滤掉
from http.client import responses
from langchain_core.output_parsers import StrOutputParser
from openai import OpenAI
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage,SystemMessage
import os
from pyexpat.errors import messages
load_dotenv()
api_key=os.getenv("OPENAI_API_KEY")
model =ChatOpenAI(api_key=api_key,model="gpt-4.1-mini")
messages=[
SystemMessage(content="turn the sentence to chinese"),
HumanMessage(content="Apple"),
]
parser =StrOutputParser()
response=model.invoke(messages)
print(parser.invoke(response))
链式调用
但这样似乎还是有点麻烦,langchain提供了|
来实现链式调用
from http.client import responses
from langchain_core.output_parsers import StrOutputParser
from openai import OpenAI
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage,SystemMessage
import os
from pyexpat.errors import messages
load_dotenv()
api_key=os.getenv("OPENAI_API_KEY")
model =ChatOpenAI(api_key=api_key,model="gpt-4.1-mini")
parser =StrOutputParser()
chain=model|parser
messages=[
SystemMessage(content="turn the sentence to chinese"),
HumanMessage(content="Apple"),
]
print(chain.invoke(messages))
stream
这样写只需要一次调用
上面我们学习的都是invoke
下面来学习下stream
** stream 方法**
流式返回:实时返回模型生成的部分内容,不等待完整响应
实现方式:使用迭代器,每生成一小段内容就立即返回
使用场景:
实现打字效果,增强用户体验
处理长回复时提供即时反馈
需要渐进式处理响应的场景
实际使用:
from http.client import responses
from langchain_core.output_parsers import StrOutputParser
from openai import OpenAI
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage,SystemMessage
import os
from pyexpat.errors import messages
load_dotenv()
api_key=os.getenv("OPENAI_API_KEY")
messages=[
SystemMessage(content="turn the sentence to chinese"),
HumanMessage(content="Apple"),
]
chunks =[]
model =ChatOpenAI(api_key=api_key,model="gpt-4.1-mini")
for chunk in model.stream(messages):
chunks.append(chunk)
print(chunk.content,end="|",flush=True)
invoke 方法
完整返回:等待模型完成整个生成过程,一次性返回完整结果
实现方式:阻塞调用,直到获得完整响应
使用场景:
需要完整结果才能进行后续处理
简单的问答交互
作为链式处理的标准方法
异步调用:
from http.client import responses
import asyncio
from langchain_core.output_parsers import StrOutputParser
from openai import OpenAI
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage,SystemMessage
import os
from pyexpat.errors import messages
load_dotenv()
api_key=os.getenv("OPENAI_API_KEY")
messages = [
SystemMessage(content="you are master of ai"),
HumanMessage(content="what is ai agent"),
]
chunks = []
model = ChatOpenAI(api_key=api_key, model="gpt-4.1-mini")
async def async_stream () :
async for chunk in model.astream(messages):
chunks.append(chunk)
print(chunk.content,flush=True)
asyncio.run(async_stream())
json格式
使用JsonOutputParser() 使输出格式化为json格式
from http.client import responses
import asyncio
from langchain_core.output_parsers import StrOutputParser, JsonOutputParser
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage,SystemMessage
import os
from pyexpat.errors import messages
load_dotenv()
api_key=os.getenv("OPENAI_API_KEY")
messages = [
SystemMessage(content="you are master of ai and you answer must be json"),
HumanMessage(content="what is ai agent"),
]
chunks = []
model = ChatOpenAI(api_key=api_key, model="gpt-4.1-mini")
chain = model| JsonOutputParser()
async def async_stream () :
async for chunk in chain.astream(messages):
chunks.append(chunk)
print(chunk,flush=True)
asyncio.run(async_stream())
打印当前事件
from http.client import responses
import asyncio
from langchain_core.output_parsers import StrOutputParser, JsonOutputParser
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage,SystemMessage
import os
from pyexpat.errors import messages
load_dotenv()
api_key=os.getenv("OPENAI_API_KEY")
messages = [
SystemMessage(content="you are a computer programmer"),
HumanMessage(content="hello"),
]
model = ChatOpenAI(api_key=api_key, model="gpt-4.1-mini")
async def async_stream () :
async for event in model.astream_events(messages):
print(event,flush=True)
asyncio.run(async_stream())
fewshot
Few-shot 是指在提示中提供少量示例,帮助模型更好地理解任务。LangChain 中的 FewShotPromptTemplate 会将这些示例、示例模板和输入拼接成最终提示
我们来看一个例子
from langchain_core.prompts import PromptTemplate
from langchain_core.prompts import FewShotPromptTemplate
examples = [
{
"question": "谁活得更长,穆罕默德·阿里还是艾伦·图灵?",
"answer": """
是否需要后续问题:是的。
后续问题:穆罕默德·阿里去世时多大年纪?
中间答案:穆罕默德·阿里去世时74岁。
后续问题:艾伦·图灵去世时多大年纪?
中间答案:艾伦·图灵去世时41岁。
所以最终答案是:穆罕默德·阿里
""",
},
{
"question": "克雷格斯列表的创始人是什么时候出生的?",
"answer": """
是否需要后续问题:是的。
后续问题:克雷格斯列表的创始人是谁?
中间答案:克雷格斯列表的创始人是克雷格·纽马克。
后续问题:克雷格·纽马克是什么时候出生的?
中间答案:克雷格·纽马克于1952年12月6日出生。
所以最终答案是:1952年12月6日
""",
},
{
"question": "乔治·华盛顿的外祖父是谁? {input}",
"answer": """
是否需要后续问题:是的。
后续问题:乔治·华盛顿的母亲是谁?
中间答案:乔治·华盛顿的母亲是玛丽·波尔·华盛顿。
后续问题:玛丽·波尔·华盛顿的父亲是谁?
中间答案:玛丽·波尔·华盛顿的父亲是约瑟夫·波尔。
所以最终答案是:约瑟夫·波尔
""",
},
{
"question": "《大白鲨》和《皇家赌场》的导演都来自同一个国家吗?",
"answer": """
是否需要后续问题:是的。
后续问题:《大白鲨》的导演是谁?
中间答案:《大白鲨》的导演是史蒂文·斯皮尔伯格。
后续问题:史蒂文·斯皮尔伯格来自哪个国家?
中间答案:美国。
后续问题:《皇家赌场》的导演是谁?
中间答案:《皇家赌场》的导演是马丁·坎贝尔。
后续问题:马丁·坎贝尔来自哪个国家?
中间答案:新西兰。
所以最终答案是:不是
""",
},
]
example_prompt = PromptTemplate.from_template("问题:{question}\n{answer}")
prompt = FewShotPromptTemplate(
examples=examples,
example_prompt=example_prompt,
suffix="问题:{input}",
input_variables=["input"],
)
print(
prompt.invoke({"input": "乔治·华盛顿的父亲是谁?"}).to_string()
)
其中 example_prompt 是例子模板
我们通过这个提示词模板构建FewShotPromptTemplate,
suffix="问题:{input}",
是后缀模板,他会在实力之后将问题拼接进去,形成最终的提示词
通过few_shot来选取最似答案
from langchain_chroma import Chroma
from langchain_core.example_selectors import SemanticSimilarityExampleSelector
from langchain_core.prompts import PromptTemplate
from langchain_openai import OpenAIEmbeddings
from dotenv import load_dotenv
import os
# 先安装Visual C++ 14.0,如果install没有报错,需要先执行pip uninstall langchain-chroma
# 再执行pip install langchain-chroma
# error: Microsoft Visual C++ 14.0 or greater is required. Get it with "Microsoft C++ Build Tools": https://visualstudio.microsoft.com/visual-cpp-build-tools/
# [end of output]
# https://visualstudio.microsoft.com/zh-hans/visual-cpp-build-tools/
examples = [
{
"question": "谁活得更长,穆罕默德·阿里还是艾伦·图灵?",
"answer": """
是否需要后续问题:是的。
后续问题:穆罕默德·阿里去世时多大年纪?
中间答案:穆罕默德·阿里去世时74岁。
后续问题:艾伦·图灵去世时多大年纪?
中间答案:艾伦·图灵去世时41岁。
所以最终答案是:穆罕默德·阿里
""",
},
{
"question": "克雷格斯列表的创始人是什么时候出生的?",
"answer": """
是否需要后续问题:是的。
后续问题:克雷格斯列表的创始人是谁?
中间答案:克雷格斯列表的创始人是克雷格·纽马克。
后续问题:克雷格·纽马克是什么时候出生的?
中间答案:克雷格·纽马克于1952年12月6日出生。
所以最终答案是:1952年12月6日
""",
},
{
"question": "乔治·华盛顿的外祖父是谁?",
"answer": """
是否需要后续问题:是的。
后续问题:乔治·华盛顿的母亲是谁?
中间答案:乔治·华盛顿的母亲是玛丽·波尔·华盛顿。
后续问题:玛丽·波尔·华盛顿的父亲是谁?
中间答案:玛丽·波尔·华盛顿的父亲是约瑟夫·波尔。
所以最终答案是:约瑟夫·波尔
""",
},
{
"question": "《大白鲨》和《皇家赌场》的导演都来自同一个国家吗?",
"answer": """
是否需要后续问题:是的。
后续问题:《大白鲨》的导演是谁?
中间答案:《大白鲨》的导演是史蒂文·斯皮尔伯格。
后续问题:史蒂文·斯皮尔伯格来自哪个国家?
中间答案:美国。
后续问题:《皇家赌场》的导演是谁?
中间答案:《皇家赌场》的导演是马丁·坎贝尔。
后续问题:马丁·坎贝尔来自哪个国家?
中间答案:新西兰。
所以最终答案是:不是
""",
},
]
load_dotenv()
api_key=os.getenv("OPENAI_API_KEY")
example_selector = SemanticSimilarityExampleSelector.from_examples(
# 这是可供选择的示例列表。
examples,
# 这是用于生成嵌入的嵌入类,用于衡量语义相似性。
OpenAIEmbeddings(api_key=api_key),
# 这是用于存储嵌入并进行相似性搜索的 VectorStore 类。
Chroma,
# 这是要生成的示例数量。
k=1,
)
# 选择与输入最相似的示例。
question = "《大白鲨》的导演是谁?"
selected_examples = example_selector.select_examples({"question": question})
print(f"与输入最相似的示例: {question}")
for example in selected_examples:
print("\n")
for k, v in example.items():
print(f"{k}: {v}")