【langchain学习】使用 langchain 构建复杂逻辑的 FewShotPromptTemplate 处理自然语言问题

在自然语言处理中,处理复杂的推理问题需要考虑多步推理、条件判断以及上下文信息。本文将展示如何使用 LangChain 创建一个带有复杂逻辑的 FewShotPromptTemplate,并结合语义相似性示例选择器来选择最相关的示例以生成更加智能的响应。

1. 导入必要的库

首先,我们导入 LangChain 的核心库 PromptTemplateFewShotPromptTemplate,以及用于示例选择的相关库。

from langchain_core.prompts import PromptTemplate
from langchain_core.prompts import FewShotPromptTemplate
from langchain_chroma import Chroma
from langchain_core.example_selectors import SemanticSimilarityExampleSelector
from langchain_community.embeddings import HuggingFaceEmbeddings
from config import acge_text_embedding

2. 创建基本的提示模板

PromptTemplate 是 LangChain 中的一个基本组件,用于定义提示的格式。在这里,我们创建了一个简单的模板,其中包括问题和答案的占位符。

example_prompt = PromptTemplate.from_template("Question: {question}\n{answer}")

3. 定义复杂逻辑的示例数据

examples = [
    {
        "question": "温格高是2023年环法冠军吗?",
        "answer": """
需要后续问题来回答吗: 是的。
后续问题: 温格高曾经获得过环法冠军吗?
中间答案: 是的,温格高曾获得2022年和2023年环法冠军。
后续问题: 温格高在2023年赢得的是什么比赛?
中间答案: 温格高在2023年赢得了环法比赛。
所以最终答案是: 是的
""",
    },
    {
        "question": "温格高在哪一年首次赢得环法冠军,并且他的主要竞争对手是谁?",
        "answer": """
需要后续问题来回答吗: 是的。
后续问题: 温格高第一次赢得环法冠军是在哪一年?
中间答案: 温格高在2022年第一次赢得环法冠军。
后续问题: 在2022年的比赛中,谁是温格高的主要竞争对手?
中间答案: 温格高的主要竞争对手是塔德伊·波加查(Tadej Pogačar)。
所以最终答案是: 2022年,主要竞争对手是塔德伊·波加查
""",
    },
    {
        "question": "温格高是哪个国家的车手,他曾经参加过奥运会吗?",
        "answer": """
需要后续问题来回答吗: 是的。
后续问题: 温格高的国籍是什么?
中间答案: 温格高是丹麦的车手。
后续问题: 温格高是否曾代表丹麦参加过奥运会?
中间答案: 不,温格高没有参加过奥运会。
所以最终答案是: 温格高是丹麦车手,但没有参加过奥运会。
""",
    },
    {
        "question": "温格高和塔德伊·波加查在环法比赛中的历史交锋情况如何?",
        "answer": """
需要后续问题来回答吗: 是的。
后续问题: 温格高和塔德伊·波加查在环法比赛中有过几次直接对决?
中间答案: 他们在2021年、2022年和2023年环法比赛中有过直接对决。
后续问题: 在这些对决中,谁赢得了更多的冠军?
中间答案: 温格高在2022年和2023年赢得了冠军,而塔德伊·波加查在2021年赢得了冠军。
所以最终答案是: 温格高和塔德伊·波加查有过三次对决,其中温格高赢得了两次。
""",
    },
    {
        "question": "温格高在2023年环法赛中是否赢得了所有山地赛段的胜利?",
        "answer": """
需要后续问题来回答吗: 是的。
后续问题: 温格高在2023年环法赛中是否表现出色?
中间答案: 是的,温格高在多个山地赛段中表现出色。
后续问题: 温格高是否赢得了所有山地赛段的胜利?
中间答案: 不,温格高赢得了大部分山地赛段,但不是全部。
所以最终答案是: 温格高在2023年表现出色,但并没有赢得所有山地赛段的胜利。
""",
    },
]

4. 生成包含复杂逻辑示例的提示词

我们使用 FewShotPromptTemplate 来创建一个包含复杂逻辑示例的提示词。这个模板将根据我们提供的示例和用户输入的问题生成最终的提示

prompt = FewShotPromptTemplate(
    examples=examples,
    example_prompt=example_prompt,
    suffix="Question: {input}",
    input_variables=["input"],
)

print(prompt.invoke({"input": "温格高是哪个国家的车手?"}).to_string())

输出结果:

Question: 温格高是哪个国家的车手?

需要后续问题来回答吗: 是的。
后续问题: 温格高的国籍是什么?
中间答案: 温格高是丹麦的车手。
所以最终答案是: 丹麦

5. 结合语义相似性选择器选择相关示例

为了让模型根据输入问题选择最相关的示例,我们可以使用 SemanticSimilarityExampleSelector。该选择器基于语义相似性选择最适合的示例。

example_selector = SemanticSimilarityExampleSelector.from_examples(
    examples,
    HuggingFaceEmbeddings(model_name=acge_text_embedding),
    Chroma,
    k=1,
)

6. 测试示例选择器

我们可以测试一下示例选择器,看看它能否为给定的问题找到最相关的示例。

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

输出结果:

与输入最相似的示例: 温格高和塔德伊·波加查在环法比赛中的历史交锋情况如何?

answer: 
需要后续问题来回答吗: 是的。
后续问题: 温格高和塔德伊·波加查在环法比赛中有过几次直接对决?
中间答案: 他们在2021年、2022年和2023年环法比赛中有过直接对决。
后续问题: 在这些对决中,谁赢得了更多的冠军?
中间答案: 温格高在2022年和2023年赢得了冠军,而塔德伊·波加查在2021年赢得了冠军。
所以最终答案是: 温格高和塔德伊·波加查有过三次对决,其中温格高赢得了两次。

question: 温格高和塔德伊·波加查在环法比赛中的历史交锋情况如何?

7. 创建带有示例选择器的提示模板

最后,我们将示例选择器与 FewShotPromptTemplate 结合起来,生成一个动态的提示模板,可以根据输入自动选择最相关的示例。

prompt = FewShotPromptTemplate(
    example_selector=example_selector,
    example_prompt=example_prompt,
    suffix="Question: {input}",
    input_variables=["input"],
)

print(prompt.invoke({"input": "温格高在2023年环法赛中是否赢得了所有山地赛段的胜利?"}).to_string())

输出结果:

Question: 温格高在2023年环法赛中是否赢得了所有山地赛段的胜利?

需要后续问题来回答吗: 是的。
后续问题: 温格高在2023年环法赛中是否表现出色?
中间答案: 是的,温格高在多个山地赛段中表现出色。
后续问题: 温格高是否赢得了所有山地赛段的胜利?
中间答案: 不,温格高赢得了大部分山地赛段,但不是全部。
所以最终答案是: 温格高在2023年表现出色,但并没有赢得所有山地赛段的胜利。

通过这个博客,了解如何使用 LangChain 来创建和使用带有复杂逻辑的 FewShotPromptTemplate,并结合语义相似性示例选择器来处理自然语言问题。这种方法可以显著增强模型对复杂问题的理解能力,尤其是在提供多步推理和条件判断的情况下。

### LangChain Prompt Templates 的概述 LangChain 是一种用于构建语言模型应用程序的强大框架,其中 `Prompt Templates` 起到了核心作用。以下是关于 LangChain 中提示模板的相关介绍: #### 1. **String PromptTemplates** 这是最基础的一种提示模板形式,适用于简单的字符串操作场景。它允许开发者定义一个固定的字符串结构,并通过变量填充动态内容。 示例代码如下: ```python from langchain import PromptTemplate template = "What is a good name for a company that makes {product}?" prompt = PromptTemplate(input_variables=["product"], template=template) formatted_prompt = prompt.format(product="colorful socks") print(formatted_prompt) ``` 上述代码展示了如何利用 String PromptTemplates 创建并格式化提示语句[^1]。 --- #### 2. **ChatPromptTemplates** 这种类型的提示模板专为对话型应用设计,支持多轮交互以及复杂的消息处理逻辑。它可以组合多个消息组件(如人类提问、AI回复等),从而实现更自然流畅的对话体验。 下面是一个 ChatPromptTemplates 使用的例子: ```python from langchain.prompts.chat import ( ChatPromptTemplate, SystemMessagePromptTemplate, HumanMessagePromptTemplate, AIMessagePromptTemplate, ) system_template = "You are Qwen, an AI assistant who follows instructions extremely well." human_template = "{question}" ai_template = "The answer to your question is..." system_message_prompt = SystemMessagePromptTemplate.from_template(system_template) human_message_prompt = HumanMessagePromptTemplate.from_template(human_template) ai_message_prompt = AIMessagePromptTemplate.from_template(ai_template) chat_prompt = ChatPromptTemplate.from_messages([system_message_prompt, human_message_prompt, ai_message_prompt]) messages = chat_prompt.format_messages(question="How do I optimize my website?") for message in messages: print(message.content) ``` 此代码片段说明了如何配置系统角色、用户输入及 AI 输出的内容结构。 --- #### 3. **Few-Shot Learning with Examples** 为了进一步提升大语言模型的表现能力,“少样本学习”成为了一种常用策略。“Few-shot learning”的基本思路是在实际请求之前向模型展示若干示范案例,帮助其理解任务需求。 例如,当希望让模型生成特定风格的文章摘要时,可以通过以下方式设置 few-shot 提示模板: ```python from langchain.prompts.example_selector import LengthBasedExampleSelector from langchain.prompts.prompt import PromptTemplate from langchain.prompts.few_shot import FewShotPromptTemplate examples = [ {"input": "Apple", "output": "A fruit"}, {"input": "Carrot", "output": "A vegetable"} ] example_formatter_template = """Input: {input}\nOutput: {output}""" example_prompt = PromptTemplate( input_variables=["input", "output"], template=example_formatter_template ) dynamic_example_selector = LengthBasedExampleSelector(examples=examples, example_prompt=example_prompt, max_length=50) few_shot_prompt = FewShotPromptTemplate( example_selector=dynamic_example_selector, example_prompt=example_prompt, prefix="Classify the following items into categories.", suffix="\n\nInput: {new_input}\nOutput:", input_variables=["new_input"] ) final_prompt = few_shot_prompt.format(new_input="Banana") print(final_prompt) ``` 以上脚本演示了如何基于长度筛选合适的样例集合,并将其嵌入到最终提交给模型的任务描述之中[^3]。 --- #### 4. **自定义与扩展** 除了内置的标准功能外,LangChain 还提供了高度可定制化的接口,使得开发人员能够针对具体业务场景调整优化提示机制。比如引入外部数据源作为上下文补充材料;或者结合条件分支判断逻辑增强灵活性等等[^2]。 --- ### 总结 通过对 LangChain 提示模板的学习与实践,不仅可以简化日常工作中涉及的人工干预环节,而且有助于挖掘更大潜力释放出来的大规模预训练模型价值所在。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值