如何添加示例到提示中进行查询分析

在我们的查询分析变得越来越复杂时,LLM(大型语言模型)可能难以理解在某些场景下到底应该如何响应。为了提升性能,我们可以在提示中添加示例来指导LLM。在本文中,我们将演示如何为我们构建的LangChain YouTube视频查询分析器添加示例。

技术背景介绍

随着查询分析的复杂度增加,LLM可能无法准确识别用户意图并生成对应的高质量查询。通过在提示中添加具体示例,我们可以向模型提供引导,帮助其更好地理解用户需求并生成更加准确的查询。

核心原理解析

提示示例(Prompt Examples)是一种通过在提示中添加具体输入和期望输出的方式,来指导LLM如何处理特定类型的问题。这种方法能够显著提升模型在特定任务上的表现。

代码实现演示

环境设置

先安装所需的依赖库:

# 安装依赖
# %pip install -qU langchain-core langchain-openai

设置环境变量,我们使用OpenAI的服务:

import getpass
import os

os.environ["OPENAI_API_KEY"] = getpass.getpass()

# 可选,取消注释以使用LangSmith跟踪运行
# os.environ["LANGCHAIN_TRACING_V2"] = "true"
# os.environ["LANGCHAIN_API_KEY"] = getpass.getpass()

定义查询模式

我们定义一个模型来表示查询的结构,包括一个主查询和多个子查询:

from typing import List, Optional
from langchain_core.pydantic_v1 import BaseModel, Field

sub_queries_description = """\
如果原始问题包含多个不同的子问题,或者有更通用的相关问题需要回答以回答原始问题,请列出所有相关的子问题。
确保此列表全面并涵盖原始问题的所有部分。即使子问题中存在冗余也没关系。
确保子问题越具体越好。"""

class Search(BaseModel):
    query: str = Field(..., description="应用于视频转录本的主要相似性搜索查询。")
    sub_queries: List[str] = Field(default_factory=list, description=sub_queries_description)
    publish_year: Optional[int] = Field(None, description="视频发布年份")

生成查询提示

我们将结合LangChain构建提示模板和查询分析链:

from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.runnables import RunnablePassthrough
from langchain_openai import ChatOpenAI

system = """你是将用户问题转换为数据库查询的专家。
你可以访问一个包含关于构建LLM应用程序的教程视频的数据库。
给定一个问题,返回一系列优化以检索最相关结果的数据库查询。

如果有你不熟悉的缩写或词语,不要试图重新措辞。"""

prompt = ChatPromptTemplate.from_messages(
    [
        ("system", system),
        MessagesPlaceholder("examples", optional=True),
        ("human", "{question}"),
    ]
)
llm = ChatOpenAI(model="gpt-3.5-turbo-0125", temperature=0)
structured_llm = llm.with_structured_output(Search)
query_analyzer = {"question": RunnablePassthrough()} | prompt | structured_llm

添加示例并调整提示

我们添加一些示例以指导模型如何处理复杂的查询:

examples = []

question = "What's chat langchain, is it a langchain template?"
query = Search(
    query="What is chat langchain and is it a langchain template?",
    sub_queries=["What is chat langchain", "What is a langchain template"],
)
examples.append({"input": question, "tool_calls": [query]})

question = "How to build multi-agent system and stream intermediate steps from it"
query = Search(
    query="How to build multi-agent system and stream intermediate steps from it",
    sub_queries=[
        "How to build multi-agent system",
        "How to stream intermediate steps from multi-agent system",
        "How to stream intermediate steps",
    ],
)
examples.append({"input": question, "tool_calls": [query]})

question = "LangChain agents vs LangGraph?"
query = Search(
    query="What's the difference between LangChain agents and LangGraph? How do you deploy them?",
    sub_queries=[
        "What are LangChain agents",
        "What is LangGraph",
        "How do you deploy LangChain agents",
        "How do you deploy LangGraph",
    ],
)
examples.append({"input": question, "tool_calls": [query]})

更新提示模板和链以包含这些示例:

import uuid
from typing import Dict
from langchain_core.messages import (
    AIMessage,
    BaseMessage,
    HumanMessage,
    SystemMessage,
    ToolMessage,
)

def tool_example_to_messages(example: Dict) -> List[BaseMessage]:
    messages: List[BaseMessage] = [HumanMessage(content=example["input"])]
    openai_tool_calls = []
    for tool_call in example["tool_calls"]:
        openai_tool_calls.append(
            {
                "id": str(uuid.uuid4()),
                "type": "function",
                "function": {
                    "name": tool_call.__class__.__name__,
                    "arguments": tool_call.json(),
                },
            }
        )
    messages.append(
        AIMessage(content="", additional_kwargs={"tool_calls": openai_tool_calls})
    )
    tool_outputs = example.get("tool_outputs") or [
        "You have correctly called this tool."
    ] * len(openai_tool_calls)
    for output, tool_call in zip(tool_outputs, openai_tool_calls):
        messages.append(ToolMessage(content=output, tool_call_id=tool_call["id"]))
    return messages

example_msgs = [msg for ex in examples for msg in tool_example_to_messages(ex)]

query_analyzer_with_examples = (
    {"question": RunnablePassthrough()}
    | prompt.partial(examples=example_msgs)
    | structured_llm
)

让我们测试更新后的查询分析器:

query_analyzer_with_examples.invoke(
    "what's the difference between web voyager and reflection agents? do both use langgraph?"
)

结果分析

通过添加示例,我们可以看到查询结构得到了进一步的分解,生成了更精确的子查询。此外,通过更多的提示工程和示例调整,我们可以进一步提升查询生成的质量。

应用场景分析

这种方法特别适用于需要精确查询生成的场景,如文档检索、技术问题解答等。通过提供示例,我们可以大大提升LLM在这些特定任务上的表现。

实践建议

  1. 示例多样化:提供多种类型的示例,以涵盖可能的查询场景。
  2. 持续优化:根据实际使用效果,持续优化示例和提示。
  3. 功能测试:在更新提示和示例后,进行充分的功能测试以确保效果。

结束语:如果遇到问题欢迎在评论区交流。

你可能感兴趣的:(windows,python,linux)