利用Prompt工程为LLM提升推理能力

利用Prompt工程为LLM提升推理能力

  • 基于策略的推理详解
  • ReAct: 推理与行动
  • 思维链:逐步解决问题
  • 反思:深入分析和自我审查
  • 与代理架构的集成
  • 实际应用
  • 代码附录

众所周知,一个精心设计的Prompt能够显著增强大型语言模型(LLMs)的推理能力,助力AI应用更高效地解决实际问题。本文将深入探讨如何通过有效的Prompt工程技术,实现这一目标。【⭐文章结尾附全部代码⭐】

有效的Prompt工程技术对于帮助大型语言模型(LLMs)产生更可靠、结构化且推理严谨的回答至关重要。通常,这些Prompt技术都是基于以下几个关键原则写出来的:

  • 任务分解:将复杂任务细分为更小、更易管理的步骤,帮助LLMs更系统地进行信息处理,减少错误,提升逻辑一致性。
  • 清晰格式:制定明确的输出结构,引导LLMs有序组织思路,以更易懂的方式呈现信息。
  • 自我反思:鼓励LLMs回顾自身推理过程,有助于发现潜在错误,考量多元观点。
  • 情境模拟:设定特定框架,如“利弊分析”或“多角度考量”,助力模型从不同维度解决问题。

这些原则构成了我们编写Prompt的基石,每种策略都充分发挥了LLMs的不同能力,确保回答的一致性和可靠性。

基于策略的推理详解

虽然白板的LLM也可以直接处理任务,但是要是想让LLM有高级推理能力的话,就需要设计结构化的解决问题方法。为此,我们首先定义了一个策略模式父类,进而派生出多种推理策略。接下来,让我们一探究竟:

class ExecutionStrategy(ABC):
    @abstractmethod
    def build_prompt(self, task: str, instruction: Optional[str] = None) -> str:
        """Build the prompt according to the strategy."""
        pass
 
    @abstractmethod
    def process_response(self, response: str) -> str:
        """Process the LLM response according to the strategy."""
        pass

这个抽象的父类为实现各种推理策略提供了基础。每种策略都提供了一种独特的方法来:

  • 构建问题解决过程;
  • 分解复杂任务;
  • 组织代理的思考过程;
  • 确保对问题进行彻底考虑。

下面让我们更深入地看看三种不同的技术:ReAct、思维链和反思。

ReAct: 推理与行动

ReAct策略(Reasoning和Action)实现了一个思考、行动和观察三个行为的循环执行,这样可以使LLM的决策过程变得清晰且可追溯。下面是实现代码:

class ReactStrategy(ExecutionStrategy):
    def build_prompt(self, task: str, instruction: Optional[str] = None) -> str:
        base_prompt = """Approach this task using the following steps:
1) Thought: Analyze what needs to be done
2) Action: Decide on the next action
3) Observation: Observe the result
4) Repeat until task is complete
 
Follow this format for your response:
Thought: [Your reasoning about the current situation]
Action: [The action you decide to take]
Observation: [What you observe after the action]
... (continue steps as needed)
Final Answer: [Your final response to the task]
 
Task: {task}"""

这个策略确保了:

  • 明确推理:每一步思考过程都表达得清晰明了。
  • 行动导向:决策与具体行动紧密相连。
  • 迭代优化:通过循环观察和调整,逐步完善解决方案。

思维链:逐步解决问题

思维链策略将复杂问题分解成可管理的步骤,使推理过程更加透明和可验证。下面是它的工作原理:

class ChainOfThoughtStrategy(ExecutionStrategy):
    def build_prompt(self, task: str, instruction: Optional[str] = None) -> str:
        base_prompt = """Let's solve this step by step:
 
Task: {task}
 
Please break down your thinking into clear steps:
1) First, ...
2) Then, ...
(continue with your step-by-step reasoning)
 
Final Answer: [Your conclusion based on the above reasoning]"""

这种方法提供了:

  • 线性进展:通过步骤化推进复杂问题。
  • 清晰联系:步骤与结论之间逻辑清晰。
  • 易于验证:推理过程更简单易懂。
  • 深度理解:更好地把握结论的来龙去脉。

反思:深入分析和自我审查

反思策略增加了一个元认知层,鼓励代理检查自己的假设并考虑替代方法。代码如下:

class ReflectionStrategy(ExecutionStrategy):
    def build_prompt(self, task: str, instruction: Optional[str] = None) -> str:
        base_prompt = """Complete this task using reflection:
 
Task: {task}
 
1) Initial Approach:
   - What is your first impression of how to solve this?
   - What assumptions are you making?
 
2) Analysis:
   - What could go wrong with your initial approach?
   - What alternative approaches could you consider?
 
3) Refined Solution:
   - Based on your reflection, what is the best approach?
   - Why is this approach better than the alternatives?"""

与代理架构的集成

这些策略通过工厂模式和策略设置器,与代理架构实现了无缝集成。

class Agent:
    @property
    def strategy(self) -> Optional[ExecutionStrategy]:
        return self._strategy
 
    @strategy.setter
    def strategy(self, strategy_name: str):
        """Set the execution strategy by name."""
        self._strategy = StrategyFactory.create_strategy(strategy_name)

执行流程包含了所选策略:

def execute(self, task: Optional[str] = None) -> str:
        if task is not None:
            self._task = task
        
        messages = self._build_messages()
        
        try:
            response = client.chat.completions.create(
                model=self._model,
                messages=messages
            )
            
            response_content = response.choices[0].message.content
            
            # Process response through strategy if set
            if self._strategy:
                response_content = self._strategy.process_response(response_content)

实际应用

下面以一个实际的例子,展示如何在实际中使用这些策略:

task = """一位同学想成为全职剧本杀DM,他有如下限制条件:

        预算:100元
        限时:10天
        他们应该如何完成这个白日梦?"""

print("\n===ReAct Strategy ===")
agent.strategy = "ReactStrategy"
agent.task = task
response = agent.execute()
print("\nResponse:")
print(response)

print("\n===Chain of Thought Strategy ===")
agent.strategy = "ChainOfThoughtStrategy"
agent.task = task
response = agent.execute()
print("\nResponse:")
print(response)

print("\n===Reflection Strategy ===")
agent.strategy = "ReflectionStrategy"
agent.task = task
response = agent.execute()
print("\nResponse:")
print(response)

三种策略的效果如下所示:

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在实际应用中,这些策略展现了显著优势:

  • 灵活选择:针对不同任务,灵活选用适宜的推理方法。
  • 一致格式:无论采用何种策略,输出都保持结构化。
  • 清晰路径:问题解决过程记录透明,易于追踪。
  • 策略对比:方便评估同一问题的不同解决方法。

代码附录

from abc import abstractmethod, ABC
from typing import Optional, List, Dict

from openai import OpenAI


class ExecutionStrategy(ABC):
    @abstractmethod
    def build_prompt(self, task: str, instruction: Optional[str] = None) -> str:
        """Build the prompt according to the strategy."""
        pass

    @abstractmethod
    def process_response(self, response: str) -> str:
        """Process the LLM response according to the strategy."""
        pass


class ReactStrategy(ExecutionStrategy):
    def build_prompt(self, task: str, instruction: Optional[str] = None) -> str:
        base_prompt = """Approach this task using the following steps:
                        1) Thought: Analyze what needs to be done
                        2) Action: Decide on the next action
                        3) Observation: Observe the result
                        4) Repeat until task is complete
                        
                        Follow this format for your response:
                        Thought: [Your reasoning about the current situation]
                        Action: [The action you decide to take]
                        Observation: [What you observe after the action]
                        ... (continue steps as needed)
                        Final Answer: [Your final response to the task]
                        
                        Task: {task}"""
        if instruction:
            base_prompt += f"\nAdditional Instruction: {instruction}"

        return base_prompt.format(task=task)

    def process_response(self, response: str) -> str:
        """Process the LLM response according to the strategy."""
        return response


class ChainOfThoughtStrategy(ExecutionStrategy):
    def build_prompt(self, task: str, instruction: Optional[str] = None) -> str:
        base_prompt = """Let's solve this step by step:

                        Task: {task}
                        
                        Please break down your thinking into clear steps:
                        1) First, ...
                        2) Then, ...
                        (continue with your step-by-step reasoning)
                        
                        Final Answer: [Your conclusion based on the above reasoning]"""
        if instruction:
            base_prompt += f"\nAdditional Instruction: {instruction}"

        return base_prompt.format(task=task)

    def process_response(self, response: str) -> str:
        """Process the LLM response according to the strategy."""
        return response


class ReflectionStrategy(ExecutionStrategy):
    def build_prompt(self, task: str, instruction: Optional[str] = None) -> str:
        base_prompt = """Complete this task using reflection:

                        Task: {task}
                        
                        1) Initial Approach:
                           - What is your first impression of how to solve this?
                           - What assumptions are you making?
                        
                        2) Analysis:
                           - What could go wrong with your initial approach?
                           - What alternative approaches could you consider?
                        
                        3) Refined Solution:
                           - Based on your reflection, what is the best approach?
                           - Why is this approach better than the alternatives?"""
        if instruction:
            base_prompt += f"\nAdditional Instruction: {instruction}"

        return base_prompt.format(task=task)

    def process_response(self, response: str) -> str:
        """Process the LLM response according to the strategy."""
        return response


class StrategyFactory:
    """Factory class for creating execution strategies."""

    _strategies = {
        'ReactStrategy': ReactStrategy,
        'ChainOfThoughtStrategy': ChainOfThoughtStrategy,
        'ReflectionStrategy': ReflectionStrategy
    }

    @classmethod
    def create_strategy(cls, strategy_name: str) -> ExecutionStrategy:
        """Create a strategy instance based on the strategy name."""
        strategy_class = cls._strategies.get(strategy_name)
        if not strategy_class:
            raise ValueError(f"Unknown strategy: {strategy_name}")
        return strategy_class()

    @classmethod
    def available_strategies(cls) -> List[str]:
        """Return a list of available strategy names."""
        return list(cls._strategies.keys())


class Agent:
    def __init__(self, name: str, system_prompt: str, instruction: str, api_key: str, url: str, model_name: str):
        self.task = None
        self.name = name
        self.system_prompt = system_prompt
        self.instruction = instruction
        self._strategy = None
        self.model_name = model_name
        self.client = OpenAI(
            api_key=api_key,
            base_url=url
        )

    @property
    def strategy(self) -> Optional[ExecutionStrategy]:
        return self._strategy

    @strategy.setter
    def strategy(self, strategy_name: str):
        """Set the execution strategy by name."""
        self._strategy = StrategyFactory.create_strategy(strategy_name)

    def execute(self, task: Optional[str] = None) -> str:
        if task is not None:
            self.task = task

        messages = self._build_messages()

        try:
            completion = self.client.chat.completions.create(
                model=self.model_name,
                messages=messages
            )

            response_content = completion.choices[0].message.content

            if self._strategy:
                response_content = self._strategy.process_response(response_content)

            return response_content
        except Exception as e:
            return f"An error occurred: {str(e)}"

    def _build_messages(self) -> List[Dict[str, str]]:
        messages = [{"role": "system", "content": self.system_prompt}]

        if self.instruction:
            messages.append({
                "role": "user",
                "content": f"Global Instruction: {self.instruction}"
            })

        current_task = self._strategy.build_prompt(self.task, self.instruction)

        if current_task:
            messages.append({"role": "user", "content": current_task})

        return messages


system_prompt = """你是一个分析解决问题的助手。你擅长分解复杂的问题并解释你的思维过程。你的解释透彻、有逻辑、清晰。"""
instruction = "确保你的回答清晰、详细、结构合理。始终保持以中文回答。"
url = "https://open.bigmodel.cn/api/paas/v4/"
api_key = "xxx"

agent = Agent(
    name="难题粉碎机",
    system_prompt=system_prompt,
    instruction=instruction,
    api_key=api_key,
    url=url,
    model_name="glm-4-flash"
)

task = """一位同学想成为全职剧本杀DM,他有如下限制条件:

        预算:100元
        限时:10天
        他们应该如何完成这个白日梦?"""

print("\n===ReAct Strategy ===")
agent.strategy = "ReactStrategy"
agent.task = task
response = agent.execute()
print("\nResponse:")
print(response)

print("\n===Chain of Thought Strategy ===")
agent.strategy = "ChainOfThoughtStrategy"
agent.task = task
response = agent.execute()
print("\nResponse:")
print(response)

print("\n===Reflection Strategy ===")
agent.strategy = "ReflectionStrategy"
agent.task = task
response = agent.execute()
print("\nResponse:")
print(response)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/922454.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C#开发合集

用C#轻松搞定m3u8视频下载与合并 嘿,程序员们!今天咱们来聊聊如何用C#写个小程序,轻松下载和合并m3u8视频文件。没错,就是那种分段的流媒体视频。准备好了吗?让我们开始吧! 准备工作 在动手之前&#xf…

java框架Netty网络编程——问鼎篇

Netty进阶 粘包现象 案例 服务端代码 public static void main(String[] args) {NioEventLoopGroup bossGroupnew NioEventLoopGroup(1);NioEventLoopGroup workerGroupnew NioEventLoopGroup(2);try {ServerBootstrap serverBootstrap new ServerBootstrap();serverBootstr…

堤防安全监测系统方案

一、背景情况 堤防是开发利用水资源和防治水灾害的重要工程措施之一,对防洪、供水、生态、发电、航运等至关重要。我国现有堤防9.8万多座,其中大中型堤防4700多座、小型堤防9.4万座,80%以上修建于上世纪50至70年代。由于堤防管护力量薄弱&am…

模型减肥秘籍:模型压缩技术 知识蒸馏

教程链接:模型减肥秘籍:模型压缩技术-课程详情 | Datawhale 知识蒸馏:让AI模型更轻更快 在人工智能快速发展的今天,我们经常需要在资源受限的设备(如手机、IoT设备)上运行AI模型。但这些设备的计算能力和…

golang实现TCP服务器与客户端的断线自动重连功能

1.服务端 2.客户端 生成服务端口程序: 生成客户端程序: 测试断线重连: 初始连接成功

React表单联动

Ant Design 1、dependencies Form.Item 可以通过 dependencies 属性,设置关联字段。当关联字段的值发生变化时,会触发校验与更新。 一种常见的场景:注册用户表单的“密码”与“确认密码”字段。“确认密码”校验依赖于“密码”字段&#x…

springboot实战(16)(Validation参数校验冲突问题、分组校验、默认分组)

目录 一、注解NotNull与NotEmpty区别。 二、Validation提供的分组校验。(参数校验冲突问题) (1)基本介绍。 (2)实际案例。 (3)大模型提问提供的方法。 1、定义分组接口。 2、在字段上…

学Linux的第九天--磁盘管理

目录 一、磁盘简介 (一)、认知磁盘 (1)结构 (2)物理设备的命名规则 (二)、磁盘分区方式 MBR分区 MBR分区类型 扩展 GPT格式 lsblk命令 使用fdisk管理分区 使用gdisk管理分…

【ubuntu+win】Win10+Ubuntu22.04双系统给ubuntu系统中的某个分区进行扩容(从400G->800G)数据无损坏

给ubuntu已分区的部分进行扩容 1. 准备扩容的空间2.进入ubuntu系统进行卸载分区3.安装图形界面的安装包4.进行对分区扩容5. 重新挂载 我的情况是这式的(可以不看,直接看后面的): 刚开始买下电脑的时候,只装了一个 1T 的…

流式上传与分片上传的原理与实现

🚀 博主介绍:大家好,我是无休居士!一枚任职于一线Top3互联网大厂的Java开发工程师! 🚀 🌟 在这里,你将找到通往Java技术大门的钥匙。作为一个爱敲代码技术人,我不仅热衷…

Ettus USRP X410

总线连接器: 以太网 RF频率范围: 1 MHz 至 7.2 GHz GPSDO: 是 输出通道数量: 4 RF收发仪瞬时带宽: 400 MHz 输入通道数量: 4 FPGA: Zynq US RFSoC (ZU28DR) 1 MHz to 7.2 GHz,400 MHz带宽,GPS驯服OCXO,USRP软件无线电设备 Ettus USRP X410集…

oracle 19c RAC到单机ogg部署安装

源端(RAC)目标端(FS)IP192.168.40.30/31192.168.40.50数据库版本Oracle 19.3.0Oracle 19.3.0主机名hfdb30/hfdb31hfogg操作系统REHL7.6REHL7.6数据库实例hfdb1/hfdb2hfogg同步用户hfdb1hfdb1同步表testtestOGG版本19.1.0.0.419.1.…

现代密码学

概论 计算机安全的最核心三个关键目标(指标)/为:保密性 Confidentiality、完整性 Integrity、可用性 Availability ,三者称为 CIA三元组 数据保密性:确保隐私或是秘密信息不向非授权者泄漏,也不被非授权者使…

QT QGridLayout控件 全面详解

本系列文章全面的介绍了QT中的57种控件的使用方法以及示例,包括 Button(PushButton、toolButton、radioButton、checkBox、commandLinkButton、buttonBox)、Layouts(verticalLayout、horizontalLayout、gridLayout、formLayout)、Spacers(verticalSpacer、horizonta…

Adobe Illustrator 2024 安装教程与下载分享

介绍一下 下载直接看文章末尾 Adobe Illustrator 是一款由Adobe Systems开发的矢量图形编辑软件。它广泛应用于创建和编辑矢量图形、插图、徽标、图标、排版和广告等领域。以下是Adobe Illustrator的一些主要特点和功能: 矢量绘图:Illustrator使用矢量…

IDEA2023设置控制台日志输出到本地文件

1、Run->Edit Configurations 2、选择要输出日志的日志,右侧,IDEA2023的Logs在 Modify option 里 选中就会展示Logs栏。注意一定要先把这个日志文件创建出来,不然不会自动创建日志文件的 IDEA以前版本的Logs会直接展示出来 3、但是…

[UE5学习] 一、使用源代码安装UE5.4

一、简介 本文介绍了如何使用源代码安装编译UE5.4,并且新建简单的项目,打包成安卓平台下的apk安装包。 二、使用源代码安装UE5.4 注意事项: 请保证可以全程流畅地科学上网。请保证C盘具有充足的空间。请保证接下来安装下载的visual studi…

细说敏捷:敏捷四会之standup meeting

上一篇文章中,我们讨论了 敏捷四会 中 冲刺计划会 的实施要点,本篇我们继续分享敏捷四会中实施最频繁,团队最容易实施但往往也最容易走形的第二个会议:每日站会 关于每日站会的误区 站会是一个比较有标志性的仪式活动&#xff0…

10M和100M网口的编码及EMC影响

10M网口编码技术 10M网口,即10Base-T,采用的是曼彻斯特编码方法 。在这种编码中,“0”由“”跳变到“-”,而“1”由“-”跳变到“” 。这种编码方式的特点是信号的DC平衡,即信号在任何一段时间内的平均电压为零&#…

docker基本使用

参考视频: 参考视频https://www.bilibili.com/video/BV1e64y1F7pJ/?share_sourcecopy_web&vd_source8fc0c76c477d3db71f89fa5ae5b258c7 docker容器操作: 拉取镜像: 拉取官网ubuntu镜像 sudo docker pull ubuntu 运行镜像:…