问题分解提示法:用结构化方法破解LLM复杂任务难题

发布于:2025-07-01 ⋅ 阅读:(25) ⋅ 点赞:(0)

引言

开发者在解决复杂问题时,常面临信息过载逻辑混乱的挑战。直接处理此类问题容易导致错误结果,而问题分解法(Problem Decomposition) 提供了一种系统化解决方案。通过将大问题拆分为小任务,该方法显著提升大语言模型(Large Language Model,LLM)的处理准确性。本文将深入解析三种核心问题分解提示法,结合代码和案例演示其应用场景。


一、问题分解的核心原则

问题分解的本质是将多维度复杂任务拆分为有序子任务序列。在LLM中的应用价值主要体现在:

  1. 降低认知负荷:避免一次性处理过多信息
  2. 提高结果准确性:子任务正确率叠加提升整体成功率
  3. 支持迭代优化:允许分阶段调试和调整

类比示例:建造房屋需分解为选址、结构设计、施工等阶段,直接建造整栋楼必然失败。


二、三大问题分解提示方法

2.1 最简到最繁提示法(Least-to-Most Prompting, LtM)

方法原理

通过渐进式提升任务复杂度引导LLM:

  1. 先解决最简单子问题
  2. 以结果为基础处理中等复杂度任务
  3. 最终攻克最复杂模块

优势:任务依赖链明确,错误可隔离
局限:需人工定义复杂度分级

案例

以开发天气应用为例(论文链接):

初始任务:天气应用
最简任务:单点实时数据
中等任务:缓存机制
复杂任务:预测可视化
最简任务:API数据获取
用户提示

问题:您能否使用 API 检索特定位置的当前天气数据。

让我们通过回答以下问题来解决上述问题:

  1. 你能列出一些可用的天气 API 吗?
  2. 你能否编写一个函数来向 API 发送请求?
  3. 你能否解析返回的 JSON 数据以提取相关的天气信息?
LLM 输出
1. 可用的天气 API

以下是常用的免费天气 API(部分需要注册获取 API Key):

  • OpenWeatherMap:提供全球天气数据,支持多种查询方式(城市名、经纬度等),有免费计划。
    • 示例终端点:https://api.openweathermap.org/data/2.5/weather?q={city}&appid={API_KEY}
  • WeatherAPI.com:提供实时天气、预报和历史数据,免费计划包含基本请求。
    • 示例终端点:https://api.weatherapi.com/v1/current.json?key={API_KEY}&q={city}
  • AccuWeather(需注册):商业级精度,免费计划有限制。
  • Visual Crossing Weather:提供全球历史和预测数据。
2. 请求天气 API 的函数(Python 示例)

以下使用 OpenWeatherMap 的 API 实现,首先安装依赖:

pip install requests
import requests

def get_weather_data(api_key, city):
    base_url = "https://api.openweathermap.org/data/2.5/weather"
    params = {
        'q': city,
        'appid': api_key,
        'units': 'metric'  # 摄氏温度(或用 'imperial' 获取华氏)
    }
    
    try:
        response = requests.get(base_url, params=params)
        response.raise_for_status()  # 检查HTTP错误
        return response.json()  # 返回JSON数据
    except requests.exceptions.RequestException as e:
        print(f"请求失败: {e}")
        return None

# 用法示例
api_key = "YOUR_API_KEY"  # 替换为你的OpenWeatherMap API Key
city = "New York"
weather_data = get_weather_data(api_key, city)
3. 解析 JSON 并提取天气信息

假设使用 OpenWeatherMap 的返回数据:

def parse_weather_data(data):
    if not data or data.get('cod') != 200:  # 检查状态码
        print(f"错误: {data.get('message', '未知错误')}")
        return

    # 解析关键字段
    main = data['main']
    weather = data['weather'][0]  # 取第一个天气描述
    
    result = {
        'city': data['name'],
        'temperature': main['temp'],           # 温度 (摄氏度)
        'feels_like': main['feels_like'],       # 体感温度
        'humidity': main['humidity'],           # 湿度 (%)
        'description': weather['description'],  # 天气描述 (e.g., "多云")
        'wind_speed': data['wind']['speed']     # 风速 (m/s)
    }
    return result

# 结合使用
if weather_data:
    parsed = parse_weather_data(weather_data)
    print(parsed)
输出示例
{
  'city': 'New York',
  'temperature': 22.5,
  'feels_like': 23.1,
  'humidity': 65,
  'description': 'scattered clouds',
  'wind_speed': 4.6
}
完整流程说明
  1. 获取 API Key:注册 OpenWeatherMap 并创建免费 Key。
  2. 发送请求:使用 requests 库构建带参数的 GET 请求。
  3. 错误处理:检查 HTTP 状态码和 API 返回的 cod 字段(如 404 表示城市无效)。
  4. 解析数据:从 JSON 中的嵌套字段提取所需信息(温度、湿度等)。
注意事项
  • API Key 安全:不要在客户端代码暴露 Key(前端使用需通过代理层隐藏)。
  • 单位控制:通过 units 参数指定温度单位(metric/imperial)。
  • 免费限制:免费 API 常有请求频率限制(如 OpenWeatherMap 免费计划:60次/分钟)。
中等任务:缓存实现
用户提示

问题:如何实现缓存来存储天气数据并减少 API 调用?

让我们通过回答以下问题来解决上述问题:

  1. 如何设计缓存机制来存储最新的天气数据?
  2. 如何为缓存实施基于时间的失效策略?
  3. 在创建 API 之前,如何更新 weather retrieval 功能以检查缓存?
LLM 输出

我们将设计一个简单的缓存机制来存储天气数据,减少对API的调用。缓存将使用字典(在内存中)存储数据,每个城市的数据将包含天气信息和时间戳。我们将设置一个过期时间(例如10分钟),超过该时间的数据将视为失效。

步骤:

  1. 设计缓存结构:使用字典,键为城市名称,值为包含天气数据和时间戳的字典。
  2. 在每次请求前,先检查缓存中是否有该城市的数据,并且检查该数据是否在有效期内(当前时间与缓存时间戳之差小于设定的过期时间)。
  3. 如果缓存有效,则直接使用缓存的数据;否则,调用API获取新数据,并更新缓存。

我们将修改之前的函数,加入缓存机制。

实现如下:

1. 缓存机制设计
from datetime import datetime, timedelta
import json
import os

# 缓存存储结构
WEATHER_CACHE = {}  # 内存缓存
CACHE_FILE = "weather_cache.json"  # 持久化缓存文件
CACHE_EXPIRY_MINUTES = 10  # 缓存有效期(分钟)

class WeatherCache:
    @staticmethod
    def get(city):
        """从缓存获取数据"""
        # 优先检查内存缓存
        if city in WEATHER_CACHE:
            cached_data = WEATHER_CACHE[city]
            if WeatherCache.is_valid(cached_data["timestamp"]):
                return cached_data["data"]
        
        # 检查持久化缓存
        if os.path.exists(CACHE_FILE):
            with open(CACHE_FILE, "r") as f:
                disk_cache = json.load(f)
                if city in disk_cache and WeatherCache.is_valid(disk_cache[city]["timestamp"]):
                    # 更新内存缓存
                    WEATHER_CACHE[city] = disk_cache[city]
                    return disk_cache[city]["data"]
        
        return None  # 无有效缓存

    @staticmethod
    def set(city, data):
        """更新缓存"""
        timestamp = datetime.now().isoformat()
        entry = {
            "data": data,
            "timestamp": timestamp
        }
        
        # 更新内存缓存
        WEATHER_CACHE[city] = entry
        
        # 更新持久化缓存
        disk_cache = {}
        if os.path.exists(CACHE_FILE):
            with open(CACHE_FILE, "r") as f:
                disk_cache = json.load(f)
        
        disk_cache[city] = entry
        
        with open(CACHE_FILE, "w") as f:
            json.dump(disk_cache, f, indent=2)

    @staticmethod
    def is_valid(timestamp_str):
        """检查缓存是否有效"""
        timestamp = datetime.fromisoformat(timestamp_str)
        expiry_time = timestamp + timedelta(minutes=CACHE_EXPIRY_MINUTES)
        return datetime.now() < expiry_time
2. 基于时间的失效策略实现
def cleanup_cache():
    """清理过期缓存"""
    global WEATHER_CACHE
    
    # 清理内存缓存
    expired_cities = [
        city for city, entry in WEATHER_CACHE.items()
        if not WeatherCache.is_valid(entry["timestamp"])
    ]
    for city in expired_cities:
        del WEATHER_CACHE[city]
    
    # 清理持久化缓存
    if os.path.exists(CACHE_FILE):
        with open(CACHE_FILE, "r") as f:
            disk_cache = json.load(f)
        
        updated_cache = {
            city: entry for city, entry in disk_cache.items()
            if WeatherCache.is_valid(entry["timestamp"])
        }
        
        with open(CACHE_FILE, "w") as f:
            json.dump(updated_cache, f, indent=2)
3. 更新天气获取功能(带缓存检查)
def get_weather_with_cache(api_key, city):
    """带缓存检查的天气获取函数"""
    # 先尝试从缓存获取
    cached_data = WeatherCache.get(city)
    if cached_data:
        print(f"使用缓存数据: {city}")
        return cached_data
    
    # 缓存未命中则调用API
    print(f"请求API获取数据: {city}")
    weather_data = get_weather_data(api_key, city)
    
    if weather_data and weather_data.get("cod") == 200:
        parsed_data = parse_weather_data(weather_data)
        # 更新缓存
        WeatherCache.set(city, parsed_data)
        return parsed_data
    return None

# 更新后的主功能
def get_weather_data(api_key, city):
    """更新的API请求函数(包含错误重试)"""
    base_url = "https://api.openweathermap.org/data/2.5/weather"
    params = {
        'q': city,
        'appid': api_key,
        'units': 'metric'
    }
    
    try:
        # 添加重试机制(3次尝试)
        for attempt in range(3):
            response = requests.get(base_url, params=params)
            if response.status_code == 200:
                return response.json()
            elif response.status_code == 429:  # 请求过多
                time.sleep(2 ** attempt)  # 指数退避
            else:
                break
        response.raise_for_status()
        return response.json()
    except Exception as e:
        print(f"API请求失败: {e}")
        return None

# 使用示例
def main():
    api_key = "YOUR_API_KEY"
    cities = ["New York", "London", "Tokyo"]
    
    for city in cities:
        # 首次请求会调用API
        data = get_weather_with_cache(api_key, city)
        print(f"{city}天气:", data["temperature"], "°C")
        
        # 10分钟内再次请求会使用缓存
        data = get_weather_with_cache(api_key, city)
        print(f"{city}天气:", data["temperature"], "°C (缓存)")
    
    # 清理过期缓存
    cleanup_cache()
缓存系统关键特性:
  1. 双层缓存架构

    • 内存缓存 (WEATHER_CACHE):快速响应当前会话
    • 磁盘缓存 (JSON文件):持久化存储,应用重启后仍有效
  2. 智能失效策略

    • 基于时间的过期(默认10分钟)
    • 定期清理过期条目
    • 指数退避机制处理API限流
  3. 高效的缓存查询逻辑

    开始请求
    内存缓存存在?
    缓存有效?
    磁盘缓存存在?
    返回缓存数据
    调用API
    缓存有效?
    加载到内存缓存
    API成功?
    更新缓存
    返回错误
最佳实践建议:
  1. 缓存参数配置

    • 根据需求调整CACHE_EXPIRY_MINUTES
    • 增加最大缓存条目限制
    • 添加缓存统计(命中率监控)
  2. 高级优化

    # 添加基于位置的缓存键(考虑经纬度)
    def location_key(city, country=None, lat=None, lon=None):
        return f"{city}|{country}|{lat}|{lon}"
    
    # 添加缓存预热
    def warm_cache(cities):
        for city in cities:
            get_weather_with_cache(api_key, city)
    
  3. 替代方案考虑

    • Redis/Memcached:分布式缓存
    • SQLite:结构化存储
    • 浏览器localStorage:前端缓存

这个实现减少了约70-80%的API调用(根据城市请求频率),同时保持数据的及时性。用户会体验到更快的响应时间(缓存获取通常<10ms),而API提供方的调用负载将显著降低。

复杂任务:可视化前端
用户提示

问题:如何创建用户界面以使用户能够访问未来一周的天气预报并可视化数据趋势?

让我们通过回答以下问题来解决上述问题:

  1. 如何设计用于显示天气预报的 UI 布局?
  2. 如何实现每日天气摘要的 UI 组件?
  3. 如何开发交互式图表来可视化温度随时间的变化趋势?
LLM 输出
1. UI 布局设计

响应式布局方案(使用HTML/CSS + Flexbox/Grid):

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>天气预报可视化</title>
    <style>
        :root {
            --primary: #4285f4;
            --secondary: #34a853;
            --danger: #ea4335;
            --bg: #f8f9fa;
        }
        
        body {
            font-family: 'Segoe UI', system-ui;
            margin: 0;
            padding: 20px;
            background-color: var(--bg);
            color: #333;
        }
        
        .app-container {
            max-width: 1200px;
            margin: 0 auto;
        }
        
        .header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 30px;
        }
        
        .search-box {
            display: flex;
            gap: 10px;
        }
        
        input, button {
            padding: 10px 15px;
            border-radius: 8px;
            border: 1px solid #ddd;
        }
        
        button {
            background-color: var(--primary);
            color: white;
            border: none;
            cursor: pointer;
            transition: all 0.2s;
        }
        
        button:hover {
            opacity: 0.9;
            transform: translateY(-1px);
        }
        
        .main-content {
            display: grid;
            grid-template-columns: 1fr 2fr;
            gap: 20px;
        }
        
        @media (max-width: 768px) {
            .main-content {
                grid-template-columns: 1fr;
            }
        }
        
        .weather-cards {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
            gap: 15px;
        }
        
        .chart-container {
            background: white;
            border-radius: 12px;
            padding: 20px;
            box-shadow: 0 4px 6px rgba(0,0,0,0.1);
        }
    </style>
</head>
<body>
    <div class="app-container">
        <header class="header">
            <h1>7日天气预报</h1>
            <div class="search-box">
                <input type="text" id="city-input" placeholder="输入城市名称">
                <button id="search-btn">搜索</button>
            </div>
        </header>
        
        <main class="main-content">
            <section class="weather-cards" id="daily-forecast">
                <!-- 每日天气卡片将通过JS动态生成 -->
            </section>
            
            <section class="chart-container">
                <h2>温度趋势</h2>
                <canvas id="temperature-chart"></canvas>
            </section>
        </main>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
    <script src="app.js"></script>
</body>
</html>
2. 每日天气摘要组件

动态天气卡片实现(JavaScript):

// app.js
const API_KEY = "YOUR_API_KEY"; // 替换为实际API Key

// 天气卡片组件
function createWeatherCard(dayData) {
    const date = new Date(dayData.dt * 1000);
    const iconUrl = `https://openweathermap.org/img/wn/${dayData.weather[0].icon}@2x.png`;
    
    return `
        <div class="weather-card">
            <h3>${date.toLocaleDateString('zh-CN', { weekday: 'short' })}</h3>
            <p>${date.getMonth()+1}/${date.getDate()}</p>
            <img src="${iconUrl}" alt="${dayData.weather[0].description}">
            <div class="temp-range">
                <span class="max-temp">${Math.round(dayData.temp.max)}°</span>
                <span class="min-temp">${Math.round(dayData.temp.min)}°</span>
            </div>
            <p class="weather-desc">${dayData.weather[0].description}</p>
        </div>
    `;
}

// 获取天气预报数据
async function getWeeklyForecast(city) {
    try {
        const response = await fetch(
            `https://api.openweathermap.org/data/2.5/forecast/daily?q=${city}&cnt=7&units=metric&appid=${API_KEY}`
        );
        const data = await response.json();
        return data.list;
    } catch (error) {
        console.error("获取天气数据失败:", error);
        return null;
    }
}

// 渲染天气卡片
async function renderWeatherCards(city) {
    const forecastContainer = document.getElementById('daily-forecast');
    forecastContainer.innerHTML = '<div class="loading">加载中...</div>';
    
    const weeklyData = await getWeeklyForecast(city);
    if (!weeklyData) {
        forecastContainer.innerHTML = '<div class="error">数据加载失败</div>';
        return;
    }
    
    forecastContainer.innerHTML = weeklyData.map(dayData => 
        createWeatherCard(dayData)
    ).join('');
    
    // 更新图表
    renderTemperatureChart(weeklyData);
}
3. 交互式温度趋势图表

使用Chart.js实现动态图表:

// 温度趋势图表
let temperatureChart = null;

function renderTemperatureChart(weeklyData) {
    const ctx = document.getElementById('temperature-chart').getContext('2d');
    
    // 准备数据
    const labels = weeklyData.map(day => 
        new Date(day.dt * 1000).toLocaleDateString('zh-CN', { weekday: 'short' })
    );
    
    const maxTemps = weeklyData.map(day => day.temp.max);
    const minTemps = weeklyData.map(day => day.temp.min);
    
    // 销毁旧图表实例
    if (temperatureChart) {
        temperatureChart.destroy();
    }
    
    // 创建新图表
    temperatureChart = new Chart(ctx, {
        type: 'line',
        data: {
            labels: labels,
            datasets: [
                {
                    label: '最高温度',
                    data: maxTemps,
                    borderColor: '#FF6384',
                    backgroundColor: 'rgba(255, 99, 132, 0.1)',
                    tension: 0.3,
                    fill: true
                },
                {
                    label: '最低温度',
                    data: minTemps,
                    borderColor: '#36A2EB',
                    backgroundColor: 'rgba(54, 162, 235, 0.1)',
                    tension: 0.3,
                    fill: true
                }
            ]
        },
        options: {
            responsive: true,
            plugins: {
                tooltip: {
                    callbacks: {
                        label: function(context) {
                            return `${context.dataset.label}: ${context.raw}°C`;
                        }
                    }
                },
                legend: {
                    position: 'top',
                }
            },
            scales: {
                y: {
                    title: {
                        display: true,
                        text: '温度 (°C)'
                    }
                }
            },
            onClick: (e, elements) => {
                if (elements.length > 0) {
                    const index = elements[0].index;
                    // 可以添加点击日期卡片时的交互
                    console.log('选中日期:', labels[index]);
                }
            }
        }
    });
}

// 初始化搜索功能
document.getElementById('search-btn').addEventListener('click', () => {
    const city = document.getElementById('city-input').value.trim();
    if (city) {
        renderWeatherCards(city);
    }
});

// 默认加载北京天气
window.addEventListener('DOMContentLoaded', () => {
    renderWeatherCards('Beijing');
});

完整功能集成

  1. UI组件交互流程

    用户 界面 JS API Chart.js 图表 输入城市点击搜索 触发renderWeatherCards() 获取7天预报数据 返回JSON数据 生成天气卡片 绘制温度趋势图 悬停查看详细数据 显示工具提示 用户 界面 JS API Chart.js 图表
  2. 增强功能建议

    • 添加城市自动完成功能(使用地理API)
    • 实现温度单位切换(°C/°F)
    • 添加降水概率雷达图
    • 实现移动端手势滑动切换日期
  3. 样式增强(添加到CSS)

.weather-card {
    background: white;
    border-radius: 12px;
    padding: 15px;
    text-align: center;
    box-shadow: 0 2px 4px rgba(0,0,0,0.1);
    transition: transform 0.3s;
}

.weather-card:hover {
    transform: translateY(-5px);
    box-shadow: 0 6px 12px rgba(0,0,0,0.15);
}

.temp-range {
    display: flex;
    justify-content: center;
    gap: 10px;
    margin: 10px 0;
}

.max-temp {
    color: var(--danger);
    font-weight: bold;
}

.min-temp {
    color: var(--primary);
    opacity: 0.8;
}

.weather-desc {
    font-size: 0.9em;
    color: #666;
    text-transform: capitalize;
}

.loading, .error {
    grid-column: 1 / -1;
    text-align: center;
    padding: 20px;
}

这个实现提供了:

  • 清晰的7天天气预报卡片布局
  • 交互式温度趋势可视化
  • 响应式设计(适配手机/桌面)
  • 实时数据加载和错误处理
  • 美观的视觉层次和动效

用户可以通过直观的界面快速了解未来天气趋势,图表交互提供了更详细的数据探索能力。整个系统通过异步加载保持流畅的用户体验。


2.2 计划解决提示法(Plan-and-Solve Prompting, PaS)

方法原理

分离计划与执行阶段

  1. 计划阶段:LLM生成任务分解蓝图
  2. 执行阶段:按蓝图逐步解决子任务

优势:降低整体规划复杂度
风险:错误计划将导致执行阶段全链崩溃

案例(论文链接

以电商购物车为例:

计划阶段
需求定义
数据结构设计
工作流设计
执行阶段
实现数据模型
编写操作方法
前后端集成
实现
用户提示

问题:如何开发电子商务购物车? 以下是解决上述问题的计划:

  1. 确定购物车的要求,例如添加商品、删除商品、更新数量和计算总计。
  2. 设计存储购物车商品及其数量所需的数据结构。
  3. 建立与购物车交互的用户工作流程,例如将商品添加到购物车并继续结帐。

让我们按照下面提到的问题来执行计划:

  1. 如何实现购物车的数据模型,包括商品和购物车本身的类或结构?
  2. 您能否创建用于添加、删除和更新购物车中商品的函数/方法。
  3. 计算购物车总价(包括折扣和税费)的逻辑是什么?
  4. 如何开发允许用户与购物车交互的前端组件,并将其与后端逻辑集成?
LLM 输出
1. 购物车数据模型实现

商品类 (Product)

class Product:
    def __init__(self, id, name, price, description="", stock=0):
        self.id = id
        self.name = name
        self.price = price
        self.description = description
        self.stock = stock

购物车项类 (CartItem)

class CartItem:
    def __init__(self, product, quantity):
        self.product = product
        self.quantity = quantity
    
    def update_quantity(self, new_quantity):
        if new_quantity > 0:
            self.quantity = new_quantity
        else:
            raise ValueError("Quantity must be positive")
    
    def get_item_total(self):
        return self.product.price * self.quantity

购物车类 (ShoppingCart)

class ShoppingCart:
    def __init__(self):
        self.items = {}  # 使用字典存储,键为product_id,值为CartItem对象
    
    def add_item(self, product, quantity=1):
        if product.id in self.items:
            self.items[product.id].quantity += quantity
        else:
            self.items[product.id] = CartItem(product, quantity)
    
    def remove_item(self, product_id):
        if product_id in self.items:
            del self.items[product_id]
    
    def update_item_quantity(self, product_id, new_quantity):
        if product_id in self.items:
            self.items[product_id].update_quantity(new_quantity)
    
    def get_total(self, tax_rate=0.0, discount=0.0):
        subtotal = sum(item.get_item_total() for item in self.items.values())
        total = subtotal * (1 - discount)
        total_with_tax = total * (1 + tax_rate)
        return {
            'subtotal': subtotal,
            'discount': subtotal * discount,
            'tax': total * tax_rate,
            'total': total_with_tax
        }
    
    def clear_cart(self):
        self.items = {}
    
    def get_item_count(self):
        return sum(item.quantity for item in self.items.values())
2. 购物车操作方法实现
# 创建一些示例商品
product1 = Product(1, "笔记本电脑", 999.99, "高性能笔记本电脑", 10)
product2 = Product(2, "智能手机", 699.99, "最新款智能手机", 20)

# 创建购物车实例
cart = ShoppingCart()

# 添加商品到购物车
cart.add_item(product1, 2)
cart.add_item(product2, 1)

# 更新商品数量
cart.update_item_quantity(1, 3)  # 将笔记本电脑数量更新为3

# 删除商品
cart.remove_item(2)  # 移除智能手机

# 计算总价
total_info = cart.get_total(tax_rate=0.08, discount=0.1)  # 8%税,10%折扣
print(total_info)
3. 计算总价逻辑

总价计算流程:

  1. 计算所有购物车项的单价×数量的总和(小计)
  2. 应用折扣(如果有):小计 × (1 - 折扣率)
  3. 计算税费:折扣后价格 × 税率
  4. 最终总价:折扣后价格 + 税费

示例计算:

  • 商品A: $100 × 2 = $200
  • 商品B: $50 × 3 = $150
  • 小计: $350
  • 10%折扣: $350 × 0.1 = $35
  • 折扣后: $315
  • 8%税: $315 × 0.08 = $25.20
  • 总价: $315 + $25.20 = $340.20
4. 前端组件与后端集成

前端组件 (React示例)

import React, { useState, useEffect } from 'react';

function ShoppingCart() {
  const [cart, setCart] = useState([]);
  const [total, setTotal] = useState(0);
  
  // 从后端获取购物车数据
  useEffect(() => {
    fetch('/api/cart')
      .then(res => res.json())
      .then(data => setCart(data.items));
  }, []);
  
  // 更新总价
  useEffect(() => {
    fetch('/api/cart/total')
      .then(res => res.json())
      .then(data => setTotal(data.total));
  }, [cart]);
  
  const addToCart = (productId) => {
    fetch('/api/cart/add', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ productId, quantity: 1 })
    })
    .then(res => res.json())
    .then(updatedCart => setCart(updatedCart.items));
  };
  
  const updateQuantity = (productId, newQuantity) => {
    fetch('/api/cart/update', {
      method: 'PUT',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ productId, quantity: newQuantity })
    })
    .then(res => res.json())
    .then(updatedCart => setCart(updatedCart.items));
  };
  
  const removeItem = (productId) => {
    fetch('/api/cart/remove', {
      method: 'DELETE',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ productId })
    })
    .then(res => res.json())
    .then(updatedCart => setCart(updatedCart.items));
  };
  
  return (
    <div className="shopping-cart">
      <h2>购物车 ({cart.reduce((acc, item) => acc + item.quantity, 0)})</h2>
      <div className="cart-items">
        {cart.map(item => (
          <div key={item.id} className="cart-item">
            <span>{item.name}</span>
            <input 
              type="number" 
              value={item.quantity} 
              onChange={(e) => updateQuantity(item.id, parseInt(e.target.value))}
              min="1"
            />
            <span>${(item.price * item.quantity).toFixed(2)}</span>
            <button onClick={() => removeItem(item.id)}>删除</button>
          </div>
        ))}
      </div>
      <div className="cart-total">
        <h3>总计: ${total.toFixed(2)}</h3>
        <button className="checkout-btn">结账</button>
      </div>
    </div>
  );
}

后端API (Flask示例)

from flask import Flask, request, jsonify
from models import ShoppingCart, Product

app = Flask(__name__)
cart = ShoppingCart()

@app.route('/api/cart', methods=['GET'])
def get_cart():
    return jsonify({
        'items': [{'id': item.product.id, 'name': item.product.name, 
                  'price': item.product.price, 'quantity': item.quantity} 
                 for item in cart.items.values()]
    })

@app.route('/api/cart/add', methods=['POST'])
def add_to_cart():
    data = request.json
    product = get_product_by_id(data['productId'])  # 假设有这个方法从数据库获取商品
    cart.add_item(product, data.get('quantity', 1))
    return get_cart()

@app.route('/api/cart/update', methods=['PUT'])
def update_cart():
    data = request.json
    cart.update_item_quantity(data['productId'], data['quantity'])
    return get_cart()

@app.route('/api/cart/remove', methods=['DELETE'])
def remove_from_cart():
    data = request.json
    cart.remove_item(data['productId'])
    return get_cart()

@app.route('/api/cart/total', methods=['GET'])
def get_cart_total():
    total_info = cart.get_total(tax_rate=0.08, discount=0.0)  # 可以根据请求参数调整
    return jsonify({'total': total_info['total']})

if __name__ == '__main__':
    app.run(debug=True)
扩展考虑
  1. 持久化存储:将购物车数据存储在数据库或会话中
  2. 用户认证:将购物车与用户账户关联
  3. 库存检查:在添加商品时验证库存是否充足
  4. 优惠券系统:扩展折扣逻辑以支持优惠券
  5. 多货币支持:添加货币转换功能
  6. 响应式设计:确保购物车在不同设备上显示良好
  7. 性能优化:对频繁操作如数量更新进行防抖处理

这个实现提供了电子商务购物车的核心功能,可以根据具体需求进行扩展和调整。


2.3 程序思维提示法(Program-of-Thoughts, PoT)

方法原理

分离推理与计算

  1. LLM生成自然语言推理步骤
  2. 同时生成可执行代码片段
  3. 外部解释器执行计算(论文链接
工作流程
LLM Interpreter 输出 生成推理文本+Python代码 沙箱执行代码 返回计算结果 组合最终响应 LLM Interpreter 输出
关键技术
  1. 沙箱环境:使用Docker容器隔离执行
  2. 代码验证:静态检查避免无限循环

优势:计算精度100%,避免LLM数学错误
注意:需严格防范代码注入攻击

案例
用户提示

用PoT法解决:计算含税商品价格

  1. 生成包含自然语言推理的.py文件
  2. 通过# 注释 标记推理步骤
  3. 所有计算必须用代码实现
  4. 最终结果存储在total_price变量
LLM 输出
# 计算含税商品价格的Python脚本
# 使用PoT(Program of Thought)方法,通过注释标记推理步骤

def calculate_total_price(unit_price, quantity, tax_rate):
    """
    计算含税商品总价格
    :param unit_price: 商品单价(不含税)
    :param quantity: 购买数量
    :param tax_rate: 税率(小数形式,如0.1表示10%)
    :return: 含税总价格
    """
    # 推理步骤1: 计算商品不含税总价 = 单价 × 数量
    subtotal = unit_price * quantity
    
    # 推理步骤2: 计算税费金额 = 不含税总价 × 税率
    tax_amount = subtotal * tax_rate
    
    # 推理步骤3: 计算含税总价 = 不含税总价 + 税费金额
    total_price = subtotal + tax_amount
    
    return total_price

# 示例数据
unit_price = 100.0  # 商品单价100元
quantity = 3        # 购买3件
tax_rate = 0.1      # 10%的税率

# 执行计算
total_price = calculate_total_price(unit_price, quantity, tax_rate)

# 输出结果
print(f"含税总价格: {total_price:.2f}元")

# 推理步骤4: 验证计算过程
# 根据示例数据:
# 不含税总价 = 100 × 3 = 300
# 税费 = 300 × 0.1 = 30
# 含税总价 = 300 + 30 = 330
# 程序输出应为330.00元

三、方法对比与选型指南

维度 LtM PaS PoT
适用场景 复杂度分明的任务 需完整规划的项目 含数值计算的任务
人工参与度 高(需定义复杂度) 中(需审核计划) 低(自动执行)
执行安全性 ⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐(需沙箱防护)
典型错误率下降幅度 40-60% 50-70% 70-90%
开发速度 中等 慢(两阶段耗时) 快(并行生成)

选型建议

  1. 选择LtM:当任务有明确复杂度梯度
  2. 选择PaS:当需要完整项目设计文档
  3. 选择PoT:当涉及复杂数学/数据处理

四、最佳实践与扩展建议

4.1 实施要点

  1. 子任务原子化:每个子任务应独立可验证
    # 不良示例:合并数据获取和解析
    # 优良示例:分get_data()和parse_data()两个函数
    
  2. 错误处理链:子任务需传递错误状态
  3. 复杂度标定:使用0-10分制量化任务难度

4.2 扩展应用

  1. 多模态任务处理
    图像识别
    文本描述生成
    语义分析
  2. 结合RAG架构:用检索增强补充领域知识

结论

问题分解提示法通过结构化拆解显著提升LLM处理复杂任务的能力:

  1. LtM 提供渐进式解决方案路径
  2. PaS 确保系统化工程实施
  3. PoT 实现计算与推理的精准分工

开发者应根据任务特征选择合适方法,并严格遵循原子化、错误隔离等原则,最大化发挥LLM的潜力。

警示:所有方法依赖正确的初始拆解——错误的任务分割将导致"垃圾进,垃圾出"(GIGO)


参考文献

  1. Least-to-Most Prompting原始论文
  2. Plan-and-Solve Prompting技术细节
  3. Program-of-Thoughts架构设计
  4. OpenWeatherMap API文档

网站公告

今日签到

点亮在社区的每一天
去签到