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}")

posted @ 2025-05-27 00:54  折翼的小鸟先生  阅读(16)  评论(0)    收藏  举报