如何用好o1:用深度推理能力搞定复杂任务

193 阅读20分钟

最近学习了吴恩达和 OpenAI 联合出品的课程《Reasoning with o1》,有一些收获。简单来说,如果你的业务场景涉及到客服系统(客户服务解决方案)或一些复杂的流程管理(例如供应链管理、排障系统),并且你想借助 AI 的推理和规划能力来提升效率,那么你需要关注 o1 模型。

o1擅长拆解问题和深度推理,这就像在复杂的业务需求面前,我们不再只得到一个“看似正确”的结果,而是能跟随 o1 的思维过程,一步步理解它是如何得出答案的。这样一来,你可以更好地把 AI 的决策过程融入到自己的业务流程里,从而增强可控性和可靠性。

接下来,我将通过四个部分带大家了解 o1 的核心理念与一些实践案例,带你体验一下这位“思考型 AI”在工作中究竟能帮我们做些什么。

o1 的强大推理能力:为什么它能够深度思考

在经过一系列技术文章的分析,以及读完openAI去年发表的论文《Let’s Verify Step by Step》后,我归纳为以下几个关键技术点:

  • 强化学习 + 内化思维链
    想象一下,你在解一道复杂的数学题。如果你只会直接给出答案,而忽略思考过程,往往会出错或给出不完整的答案。但是如果能仔细分解题目、逐步推理,就更容易得出正确结论。

    o1 模型采用了内化思维链(Chain of Thought, CoT)的理念,让它能“分步骤思考”,就像优秀学生在考试时,一步步把解题过程写出来。通过强化学习,o1 能在解题前先模拟推理的过程,从而给出更有深度、更具解释性的答案。

  • 自我博弈:自己跟自己“下棋”
    除了思维链,o1 还有个独门秘籍——自我博弈(Self-Play)。o1 会一边生成答案,一边模拟另一个“批评者”来审查这个答案。如果发现逻辑漏洞,它会再次调整推理,直到得到最合乎逻辑的结论。这种“自己跟自己下棋”的方式,帮助 o1 不断自我优化,越来越可靠。

  • 过程监督 + 结果监督
    之前的大模型常常只关心“最后的答案对不对”,不怎么关注中间思路。o1 则采用过程监督和结果监督相结合的方式:

    过程监督:每一步推理都要过审(打标),类似于老师批改你解题步骤是否合规。
    结果监督:最终答案也要符合预期,如果过程中逻辑完美,但结果与目标不符,也不行。 这样的“双保险”监督机制,让 o1 在应对复杂任务时更加稳定、可信,真正做到把问题想透、答对。

通过案例看 o1 的任务规划能力

接下来,我们用一个具体案例来感受一下 o1 的“多步规划 + 执行”能力。想象你是电商运营经理,突然涌入大量新订单,需要尽快处理库存、供应商和发货等环节。这是一项包含多环节、多角色协同的复杂任务。

  1. 场景设定

    • 新订单处理:订单量猛增,手头资源有限。
    • o1做规划:给它提供客户需求、库存信息、供应商数据、运输选项和客户元数据等上下文。
    • GPT-4o执行:o1制定完执行方案后,GPT-4o负责一步步去“跑流程”,从而达到准确与效率的权衡。
  2. 定义约束和上下文

    • 库存(Inventory) :哪些产品有库存?
    • 订单(Order) :如果没库存或不够,需不需要向供应商下单?
    • 供应商(Suppliers) :谁提供原材料或成品?
    • 运输选项(Shipping Options) :如何根据时效和成本选出适合的运输方式?
    • 客户元数据(Customer Metadata) :不同客户可能有不同的“定制化”需求。

    o1 在规划时,需要综合考虑上述信息,像人类主管一样,思考“产品够吗?不够就下单供应商;下单后怎么安排物流?等等”。

  3. 构建计划的提示(Prompt)设计
    要让 o1 明确知道如何去规划,我们需要在 Prompt 中写清楚它的角色、它所拥有的工具,以及它需要达成的目标。比如:

    • 角色定义: 告诉 o1 —— 你是“供应链助理”,专门负责拆解任务和制定计划。
    • 任务说明: 让它知道自己必须逐步检查订单,判断库存,然后安排生产或物流。
    • 工具列表: 需要调用哪个函数去检查库存、哪个函数去获取订单状态、哪个函数去安排发货……都需要在提示里事先“告诉”它。
  4. 工具定义与执行
    在完成以上步骤后,有新任务过来时,o1会仔细思考后规划出详细的执行计划,例如:

# 订单履行计划

1. 获取新订单  
   - a. `fetch_new_orders()`

2. 逐一处理每个订单  
   - 对于新订单列表中的每个 `order`:
     a. 提取订单详情  
        - i. 从 `order` 中获取 `order_id``customer_id``destination` 以及包含各 `product` 和其 `quantity` 的 `products` 列表。

     b. 检查订单中每个产品的库存  
        - i. 针对 `products` 列表中的每个 `product`:
          - A. 调用 `get_inventory_status(product_id)` 并传入相应的 `product_id`。
          - B. 如果 `available_quantity >= required_quantity`:
            1. 分配库存  
               - a. `allocate_stock(order_id, product_id, required_quantity)`  
               - b. `update_inventory(product_id, -required_quantity)`
          - C. 否则:  
            1. 确定差额  
               - a. 计算 `deficit = required_quantity - available_quantity`
            2. 检查生产能力  
               - a. 调用 `check_production_capacity(time_frame='immediate')`
               - b. 如果 `production_capacity >= deficit`:  
                 i. 安排生产  
                    - A. `schedule_production_run(product_id, deficit, time_frame='immediate')`  
                    - B. *(无需调用 `update_inventory`,该函数会自动更新库存)*
                 ii. 分配新生产的库存  
                    - A. `allocate_stock(order_id, product_id, deficit)`  
                    - B. `update_inventory(product_id, -deficit)`
               - c. 否则:  
                 i. 向供应商订购额外零部件  
                    - A. 调用 `get_product_details(product_id)`  
                    - B. 确定满足 `deficit` 所需的 `component_ids` 和对应数量。  
                    - C. 调用 `check_available_suppliers()`  
                    - D. 对于可用的每个供应商:
                      1. 针对所需的每个 `component_id` 调用 `get_supplier_info(supplier_id)`。  
                      2. 如果该供应商能提供所需零部件:  
                         - a. `place_purchase_order(supplier_id, component_id, quantity_needed)`  
                         - b. 一旦下单成功,则跳出该供应商循环。  
                      3. 否则:  
                         - a. 继续检查下一个供应商。
                    - E. 通知客户可能存在的延迟  
                      - a. `send_order_update(customer_id, order_id, "您的订单正在处理。由于需求量大,部分商品可能会有所延迟。我们正尽最大努力为您尽快完成订单。")`

     c. 计算订单的运输选项  
        - i. 计算订单的 `total_weight` 和 `total_dimensions`。  
        - ii. 调用 `calculate_shipping_options(destination='Los Angeles', weight=total_weight, dimensions=total_dimensions)`  
        - iii. 选择最具成本效益且能及时送达的 `shipping_option`。

     d. 预定货运  
        - i. `book_shipment(order_id, carrier_id=selected_carrier, service_level=selected_service_level)`

     e. 通知客户订单状态  
        - i. `send_order_update(customer_id, order_id, "您的订单已发货,并正在前往洛杉矶配送中心的路上。")`

3. 处理积压订单  
   - a. 找出因库存或生产限制而未能完全分配的任何 `orders`。  
   - b. 针对每个积压的 `order`:
     - i. 提交所需零部件的采购订单  
       - A. 调用 `check_available_suppliers()`  
       - B. 针对所需的 `component_ids`,调用 `place_purchase_order(supplier_id, component_id, quantity_needed)`
     - ii. 通知客户订单积压  
       - A. `send_order_update(customer_id, order_id, "由于需求量大,您的订单目前处于积压状态。我们已经为所需零部件下单,一旦订单可以发货,我们会第一时间通知您。")`

4. 完成指令  
   - a. `instruct

可以看到,最后输出的是一份非常详细的订单处理规划,在不同的处理分支中应该调用哪些工具,如何处理逻辑判断进行了非常充分的描述。接下来,GPT-4o根据这份规划逐步执行,直到整个流程跑完。这个过程中,如果出现异常情况,模型还可以进行动态调整。最终,你会得到一个清晰的执行日志,告诉你哪个步骤成功了,哪个需要人工介入。

计划执行与反馈
o1 的多步规划能力,让业务负责人不再需要手动地去对接各种接口或时刻担心流程是否遗漏。它能自动拆解并找到合理顺序来完成复杂任务。对我们来说,这样的可扩展方案有很大价值:

  • 效率提升: 从人工手动规划到 AI 自动规划,大大节省时间。
  • 可控可查: 每一步的执行都有记录,更符合业务合规或审计需求。
  • 灵活适配: 场景变了或者需求升级了,只需要修改 Prompt 或函数列表,就能让 o1 适应新的流程。

化腐朽为神奇:Meta-Prompting技术

现在的企业通常已有一整套流程和规范文档,用来应对各种业务问题(比如客服系统如何回复、不同的故障如何定位和处理)。我们希望 AI 能深入理解这些文档,然后根据用户咨询或业务需求,自动生成准确的解决方案。这里,就用到一个关键技术——Meta-Prompting。

什么是 Meta-Prompting

Meta-Prompting 的核心思想是: 在执行任务之前,先让一个更智能的模型(比如 o1)去规划和设计针对另一模型(比如 4o)的指令或例程,让后者在执行时“更聪明”。就像你先为另外一个人写好行动指南,然后对方就能照着这份指南把事情办得妥妥的。看到这里明白了,其实刚才的规划能力也是应用的Meta-Prompting能力,只是规划属于动态能力,而这里要讲的从流程规范中去生成大模型执行文档属于静态能力。

还是拿具体的案例来分析,我们有一份客服政策,里面写着怎样处理航班取消或更改等业务的规则。目前业界最常用的AI客服是怎么做的:将客服策略相关的文档作为知识库嵌入到向量数据库中,接着通过RAG(检索增强)技术来应对客户的咨询,从文档中检索出相关的答案,再由大模型进行总结回复给客户。 这种方案的弊端是什么?它仅仅是信息检索,而非工作流,最终依然需要人去理解和操作。那是否有更好的办法呢?

还是拿航空公司的客服政策举例, 我们可以让o1去读取这份客服政策,生成一份初始的工作流,prompt可以这样设计:

是一位热心助人的助手,任务是将对外的帮助中心文章转换为对内部使用的、可由 LLM 程序执行的流程。  
使用此流程的 LLM 会阅读政策、回答来自客户的问题,并帮助推动案例走向解决。

请遵循以下指示:  
1. 仔细审核客户服务政策以确保每一步都被纳入其中。务必不要跳过任何步骤或政策。  
2. 将指示按照逻辑顺序组织成逐步操作,并使用指定的格式。  
3. 使用以下格式:  
   - 主要动作用数字编号(例如 1, 2, 3)。  
   - 子动作在其对应的主要动作下以字母分项列出(例如 1a, 1b)。  
     子动作应换行开始  
   - 用明确的“if...then...else”语句指定条件(例如,“如果该商品是在 30 天内购买的,那么……”)。  
   - 对于需要从客户获取更多信息的指示,以礼貌和专业的方式提示客户提供更多信息。  
   - 对于需要从外部系统获取数据的操作,在步骤中使用反引号书写需要调用的函数名称(例如,调用 `check_delivery_date`)。  
     - 如果某一步需要客服专员执行某项操作(例如,处理退款),则生成相应的函数调用(例如,调用 `process_refund`)。  
     - 只能使用下方定义的函数,不要使用新的函数。  
   - 如果有可以由助手替客户执行的操作,需包含对应的函数调用(例如,调用 `change_email_address`),并确保该函数已定义其用途和所需参数。  
     - 只能使用下方定义的函数,不要使用新的函数。  
   - 在结案之前,必须先询问是否还有其他需要协助的地方。  
   - 最后一步以调用 `case_resolution` 函数结束,这一步应始终是最终步骤。  
4. 确保合规性,确保所有步骤都符合公司政策、隐私法规和法律要求。  
5. 处理异常或升级,为超出标准政策范围的情形指定具体步骤。  
6. 确保覆盖所有情况,即政策中涵盖的所有条件都包含在此流程当中。  

重要:务必在返回的函数名称外加反引号,例如 `check_ticket_type`。不要包含函数的参数。  

以下是可用函数的 JSON 格式列表:  
TOOLS: {TOOLS}

请将下列客户服务政策转换为符合上述格式的流程,并确保它易于理解和可程序化执行。请确保仅使用所提供的函数,不要创建任何新的函数。

这里就开始化腐朽为神奇,通过o1,我们可以将一份给人看的文档转化为一份可以让4o等大模型准确执行的执行文档,从之前的咨询场景华丽转身为了可执行的工作流。我们来看通过o1生成的新的文档模式:

1. 验证客户身份
   - a. 调用 `verify_identity` 函数。

2. 了解客户需求
   - a. 调用 `ask_clarification` 函数,提示内容为:"您想要取消、改签还是咨询航班补偿事宜?"

3. 确定需求类型
   - a. 如果客户想要取消,则进入处理取消流程。
   - b. 如果客户想要改签,则进入处理改签流程。
   - c. 如果客户想要咨询补偿,则进入处理补偿请求流程。
   - d. 否则,调用 `ask_clarification` 函数,提示内容为:"请问您能提供更多关于需求的详细信息吗?"

4. 处理取消
   - a. 调用 `check_ticket_type` 函数。
   - b. 如果票种为可退款,则:
     - i. 如果在订票后 24 小时内取消,调用 `process_full_refund` 函数。
     - ii. 否则,调用 `check_fare_rules` 函数。
       - 如果符合部分退款条件,调用 `process_partial_refund` 函数。
       - 否则,调用 `process_full_refund` 函数。
   - c. 如果票种为不可退款,则:
     - i. 调用 `offer_flight_credit` 函数。
     - ii. 告知客户可能需支付相关罚金。
   - d. 否则,升级处理此案例。

5. 处理航空公司主动取消
   - a. 确定取消的原因。
   - b. 如果是天气原因,则:
     - i. 调用 `rebook_without_fee` 函数。
     - ii. 如果客户不接受改签,调用 `process_full_refund` 函数。
   - c. 如果是机械故障或运营调整,则:
     - i. 调用 `prioritize_missed_connections` 函数。
     - ii. 如果需要过夜住宿,调用 `offer_accommodation` 函数。
   - d. 否则,升级处理此案例。

6. 处理误机政策(No-Show)
   - a. 调用 `check_ticket_type` 函数。
   - b. 如果票种为不可退款,则:
     - i. 调用 `offer_flight_credit` 函数。
   - c. 如果票种为可退款,则:
     - i. 调用 `process_partial_refund` 函数,处理适用的税费部分。
   - d. 否则,升级处理此案例。

7. 处理改签
   - a. 调用 `check_ticket_type` 函数。
   - b. 如果改签为当日改签,则:
     - i. 如果票种为灵活票,调用 `process_change_no_fee` 函数。
     - ii. 如果票种为非灵活票,调用 `apply_change_fee` 函数,并告知客户票价差额。
   - c. 如果改签为提前改签,则:
     - i. 如果改签时间距起飞 7 天以内,调用 `apply_change_fee` 函数。
     - ii. 如果改签时间距起飞 7 天以外,根据票种调用 `apply_lesser_change_fee` 函数。
   - d. 否则,升级处理此案例。

8. 处理航空公司主动改签
   - a. 确定航班调整程度。
   - b. 如果改签为小幅变动(少于 2 小时),告知客户并在客户请求时提供替代选项。
   - c. 如果改签为大幅变动(2 小时及以上),则:
     - i. 调用 `rebook_without_fee` 函数。
     - ii. 如果客户不接受改签,调用 `process_full_refund` 函数。
     - iii. 作为替代方案,调用 `offer_flight_credit` 函数。
   - d. 否则,升级处理此案例。

9. 重新预订指南
   - a. 调用 `check_next_available_flight` 函数。
   - b. 如果找到可用航班,调用 `book_flight` 函数。
   - c. 如果没有合适的选项,调用 `check_interline_partners` 函数。
     - i. 如果找到联盟伙伴航班,调用 `book_interline_flight` 函数。
     - ii. 否则,告知客户并调用 `offer_flight_credit` 函数以提供航班额度。
   - d. 如果有更高舱位可用,调用 `offer_available_upgrades` 函数。
   - e. 如果适用,为无成人陪伴的未成年人调用 `prioritize_minors_rebooking` 函数。

10. 补偿及退款处理
    - a. 调用 `determine_refund_method` 函数。
    - b. 如果退款需退回原支付方式,调用 `process_refund` 函数。
    - c. 如果提供旅行额度,调用 `apply_travel_credit` 函数并加赠一定比例。
    - d. 对于补偿请求,调用 `check_compensation_eligibility` 函数。
      - i. 如果符合条件,通过调用 `offer_accommodation` 函数提供餐饮券或住宿。
    - e. 根据支付方式告知客户退款所需时间。

11. 处理特殊情况
    - a. 如果案例为医疗紧急状况,则:
      - i. 调用 `process_flexible_cancellation` 函数并提供医疗证明。
      - ii. 如果需更改航班,调用 `waive_change_fees` 函数并提供相关文件。
    - b. 如果案例为因丧事,则:
      - i. 调用 `apply_bereavement_flexibility` 函数并提供所需证明。
    - c. 如果处理团体订票,则:
      - i. 如果需要部分人取消,调用 `process_partial_group_cancellation` 函数。
      - ii. 如果需要更改乘客姓名,调用 `permit_name_change` 函数。
    - d. 如果涉及无成人陪伴的未成年人,则:
      - i. 调用 `arrange_supervision` 函数。
      - ii. 调用 `prioritize_minors_rebooking` 函数。
    - e. 否则,升级处理此案例。

12. 常见场景问答
    - a. 如果客户咨询联程航班受影响,调用 `prioritize_missed_connections` 函数。
    - b. 如果客户在取消后想升舱,调用 `offer_available_upgrades` 函数。
    - c. 如果客户需要更改目的地,调用 `process_destination_change` 函数。
    - d. 如果预订来自第三方,调用 `assist_third_party_booking` 函数。
    - e. 如果客户请求不便补偿,调用 `assess_compensation_request` 函数。
    - f. 如果客户心仪的航班已满员,则提供下一个可用航班并调用 `provide_alternative_options` 函数为其等待候补名单。
    - g. 否则,升级处理此案例。

13. 确认是否有其他需要
    - a. 向客户询问:"还有什么需要我为您协助的吗?"

14. 结案
    - a. 调用 `case_resolution` 函数。

请仔细体会下 原始文档 -> o1 -> 新文档,我相信你能够了解到其中的神奇之处。有了这份新的客服文档,接下来就轮到4o出马,它此时可以充当一个更加智能的AI客服去处理用户咨询。比如“帮我取消下周三的航班”“给我改到明天早上的航班”等。在航班客服这种场景,一般对准确率要求较高,所以我们还需进一步调优生成的指令流让4o能更准确的执行。首先我们准备一批离线训练样本来评估4o执行的准确性:

  • 成功率:多少询问或操作是正确的?
  • 错误率:有哪些地方回答不够准确?
  • 遗漏信息:有没有忘记询问关键信息?(如预订参考号、联系方式等)

收集完评估数据后,我们把这些错误反馈和原始例程再一次交给 o1。o1 会做什么呢?它会分析:

  • “为什么 4o 忘了问用户参考号?”
  • “哪一步骤描述得还不够清晰?”
  • “在哪些环节,4o 需要更详细的指令或更准确的参数说明?”

我们继续来看一下prompt应该如何设计:

### 说明
您是一名负责改进提供给客户服务 LLM 助手之指示质量的代理。  
您的任务是改进提供给 LLM 助手的指示,以便在遵循初始政策的同时,提高其在测试集上的准确性。

### 标准
- 分析现有指示和评估结果,了解哪些行为会导致失败。  
- 例如,如果 LLM 助手在需要的时候没有询问预订参考号,就应该在指示中添加一步,要求其询问预订参考号。  
- 改进指示,以解决评估结果中发现的不足。  
- 确保所做的修改符合原始政策。  
- 仅使用所提供的工具。  
- 尽最大努力使用所提供的函数,以确保 LLM 助手能够有效地处理客户服务请求,包括在必要时收集数据。  
- 如果当前格式效果不佳,可考虑使用基本的 XML(例如 `<step> <substep> <if> <case>`)或 Markdown 等替代格式。

您将获得以下 4 个项目:  
1) 客户服务代理的真实政策,其中包含关于如何处理航班取消和改签的详细指示。  
2) 可用函数的完整列表。  
3) 一个常规的指令集。  
4) 一个展示使用该常规指令集在测试集上评估结果的文件,其中包含以下列:  
   - request: 用户的初始请求。  
   - expected_function: 期待在对话结束时由 LLM 调用的函数。  
   - expected_input: 期待在对话结束时由 LLM 提供给该函数的输入。  
   - actual_function: LLM 在当前指令下最终调用的函数。  
   - actual_input: 基于当前指令,LLM 提供给函数的参数。  
   - transcript: 用户与 LLM 助手之间的对话记录。  
   - is_correct: 以 True/False 标注模型是否做出了正确响应。

您可能会获得一份编辑和评估的历史记录。您可以使用这份信息来了解之前尝试过哪些方法,以及哪些方法有效或无效。

### 数据
1. 原始政策
{flight_cancellation_policy}

2. 函数
{TOOLS}

### 结论
请返回改进后的政策,内容应与定义的 JSON 完全一致。请从 LLM 的回答中移除所有不属于政策的部分,不要创建额外的键。

有了这些分析,o1 随即给出一个新的、改进后的执行文档,经过多轮迭代及最终选优后,我们可以将生成的指令流在4o上执行的准确率进行大幅提升,最终得到一个非常稳定靠谱的AI客服。

写在最后

o1 的出现给了我们一个非常强大的思路:AI 不再只是“给答案”,而是可以像一个善于深度思考、反思、并不断迭代学习的同事。从“如何拆解复杂问题”到“如何将已有流程自动化或优化”,o1 都能为我们提供有价值的帮助。

如果你想要解决复杂业务流程:可以试试 o1 的多步规划能力,用它来“指挥”其他模型或系统执行具体任务。 如果你已经有成体系的流程和文档:那就可以运用 Meta-Prompting 技术,帮助“更弱”的模型按照你所需的方式更好地理解和执行这些流程。

更多内容,请关注作者公众号:

image.png