智能体 Prompt Chaining 实战

230 阅读4分钟

什么是 Prompt Chaining?

Prompt Chaining (提示词链) 是由 Anthropic blog 提出的概念:

Prompt chaining decomposes a task into a sequence of steps, where each LLM call processes the output of the previous one. You can add programmatic checks (see "gate” in the diagram below) on any intermediate steps to ensure that the process is still on track.

www.anthropic.com/engineering…

When to use this workflow: This workflow is ideal for situations where the task can be easily and cleanly decomposed into fixed subtasks. The main goal is to trade off latency for higher accuracy, by making each LLM call an easier task.

www.anthropic.com/engineering…

简单的来说,提示词链就是用一套编排好的工作流,依次首尾相接执行大模型推理节点或程序调用节点。由于执行顺序的可控性,所以可以稳定的处理复杂的业务。

image.png

The prompt chaining workflow (anthropic.com)

可以说,只要能把一个任务拆分成有限、固定的多步来执行,并期望稳定的输出,就可适用于这种模式。它很像一个传统意义上的应用程序,只是把大模型当做了一个函数来对待。它是智能体较为常见的范式,广泛出现在各种搭建平台的样例上。我们用一个例子简述提示词链如何来应用

image.png

假设我们有这样一个智能体需求:

用户投诉处理任务:
1. 首先将用户投诉分类为【支付问题/物流问题/商品质量问题】
2. 从投诉文本中提取关键信息(订单号、问题类型、用户诉求)
3. 根据分类结果生成符合企业规范的客服回复模板

这个需求可以抽象成三次大模型调用:

1. 内容分类
2. 信息提取
3. 角色扮演
那么我们就可以设计一个这样的系统:

image.png

创建工具

分类、信息提取,都是大模型本身的能力,可以用 Prompt 或 Tool Calling 两种方式实现参数提取(无需程序逻辑参与)。这里我采用 Tool Calling 的方式 (较为简单稳定)。

分类器

@tool
def classify_complaint(complaint_type: str):
    """将用户投诉内容分类为【支付问题】、【物流问题】或【商品质量问题】
    Args:
        complaint_type: 问题分类 (值为【支付问题】、【物流问题】或【商品质量问题】的其中一项)
    """
    return {"投诉内容分类": complaint_type}

信息提取器

@tool
def extract_info(order_id: str, user_request: str):
    """ 根据用户投诉内容提取订单号和用户核心诉求转写
    Args:
        order_id: 订单号
        user_request: 用户核心诉求转写
    """
    return {"订单号": order_id, "用户核心诉求": user_request}

创建三个智能体

(工具通过 bind_tools 函数和大模型进行绑定)

内容分类

classify_prompt = {"role": "system", "content": "将用户投诉内容分类,如果调用工具,则无需输出内容"}
def classify_complaint_chatbot(state: State):
    return {"messages":[llm.bind_tools([classify_complaint]).invoke([classify_prompt] + state["messages"])]}

信息提取

extract_info_promp = {"role": "system", "content": "根据用户投诉内容提取订单号和用户核心诉求转写,如果调用工具,则无需输出内容"}
def extract_info_chatbot(state: State):
    return {"messages":[llm.bind_tools([extract_info]).invoke([extract_info_promp] + state["messages"])]}

角色扮演(智能客服)

def custmer_service_chatbot(state: State): 
    return { "messages": [llm.invoke([custmer_service_prompt] + state["messages"])]}

创建 LangGraph Nodes

graph_builder.add_node("classify_complaint_chatbot", classify_complaint_chatbot)
graph_builder.add_node("classify_complaint_tool", ToolNode([classify_complaint]))
graph_builder.add_node("extract_info_chatbot", extract_info_chatbot)
graph_builder.add_node("extract_info_tool", ToolNode([extract_info]))
graph_builder.add_node("custmer_service_chatbot", custmer_service_chatbot)

连接 LangGraph Nodes

graph_builder.add_edge(START, "classify_complaint_chatbot")
graph_builder.add_conditional_edges(
    "classify_complaint_chatbot",
    router_tools,
    {"tools": "classify_complaint_tool", END: "extract_info_chatbot"}
)
graph_builder.add_edge("classify_complaint_tool", "extract_info_chatbot")
graph_builder.add_conditional_edges(
    "extract_info_chatbot",
    router_tools,
    {"tools": "extract_info_tool", END: "custmer_service_chatbot"}
)
graph_builder.add_edge("extract_info_tool", "custmer_service_chatbot")
graph_builder.add_edge("custmer_service_chatbot", END)
graph = graph_builder.compile()

前端展现的 WebUI 有很多选择,这里我采用 Streamlit

image.png

可以看到程序如预期依次执行了内容分类、信息提取、整合回答。

局限性

Prompt Chaining 是迈向复杂智能体系统的第一步,用可控来消除模糊。但伴随而来的代价是自主性(autonomous)的下降,也会增大延迟和成本。

如果需求足够简单,用一步提示词即可;如果需求较为复杂,则需引入更多智能体的高级框架(后续更新笔记),Prompt Chaining 可以说是一套适用度广且较为平衡的方案。

image.png