零基础构建智能客服机器人:OpenAI Chat 格式与 OrderBot 完整教程(附代码)
摘要
大语言模型不仅可以完成单轮任务,还能通过“聊天格式”(Chat Format)构建多轮对话的自定义聊天机器人。本文基于 OpenAI 官方课程,深入讲解 Chat Completion API 中的三种消息角色(system、user、assistant),以及如何利用系统消息设定机器人的行为、个性和知识。你将亲手构建一个披萨餐厅点餐机器人 OrderBot:自动收集用户订单、询问尺寸/配料/配送方式、生成结构化 JSON 摘要。同时,我们会探讨对话上下文管理、temperature 参数的选择,并提供完整的 Python 代码示例(包括 Panel 图形界面)。读完本文,你就能为自己的业务场景打造专属 AI 助手。
适用人群 / 前置知识
适用人群:希望构建对话式 AI 应用的开发者、产品经理、创业者;对 ChatGPT 背后 API 感兴趣的学习者。
前置知识:Python 基础;OpenAI API 调用基础(本系列前几篇);了解 JSON 格式。
引言:从单轮到多轮——聊天机器人的核心
你已经在 ChatGPT 网页界面中和 AI 聊过天。但你有没有想过,如何为你的业务构建一个定制化的聊天机器人?比如一个能自动接单的披萨店助手、一个能回答产品问题的客服、或者一个能帮你安排日程的私人助理?
OpenAI 的 Chat Completion API 正是为此设计的。它支持多轮对话,并允许开发者通过 系统消息(system message) 来控制机器人的行为、语气和知识。本文将带你从零开始,构建一个功能完整的点餐机器人 OrderBot。
一、理解 Chat Format:三种消息角色
在 Chat Completion API 中,输入是一个消息列表,每条消息包含 role 和 content。主要有三种角色:
| 角色 | 说明 | 示例 |
|---|---|---|
| system | 设定助手的行为、个性、规则。用户不可见,相当于“幕后指令”。 | “你是一个像莎士比亚一样说话的助手。” |
| user | 用户发送的消息。 | “给我讲个笑话。” |
| assistant | 模型生成的消息。在多轮对话中,之前的 assistant 消息可以作为历史输入。 | “为什么鸡过马路?为了到另一边去。” |
基础示例:莎士比亚风格的助手
import openai
import os
from dotenv import load_dotenv, find_dotenv
_ = load_dotenv(find_dotenv())
openai.api_key = os.getenv('OPENAI_API_KEY')
def get_completion_from_messages(messages, model="gpt-3.5-turbo", temperature=0):
response = openai.ChatCompletion.create(
model=model,
messages=messages,
temperature=temperature,
)
return response.choices[0].message["content"]
messages = [
{"role": "system", "content": "You are an assistant that speaks like Shakespeare."},
{"role": "user", "content": "tell me a joke"},
{"role": "assistant", "content": "Why did the chicken cross the road?"},
{"role": "user", "content": "I don't know"}
]
response = get_completion_from_messages(messages, temperature=1)
print(response)
# 输出示例:To get to the other side, fair sir or madam. It is an old and classic that never fails.
二、上下文管理:模型不会“记住”历史
重要概念:每次 API 调用都是无状态的。模型不会自动记住之前的对话。如果你希望模型引用之前说过的话,你必须把整个对话历史作为消息列表传入。
错误示例:不提供历史
messages = [
{"role": "system", "content": "You are a friendly chatbot."},
{"role": "user", "content": "Yes, can you remind me what is my name?"}
]
response = get_completion_from_messages(messages)
print(response)
# 模型无法回答,因为它不知道名字
正确做法:提供上下文
messages = [
{"role": "system", "content": "You are a friendly chatbot."},
{"role": "user", "content": "Hi, my name is Isa"},
{"role": "assistant", "content": "Hi Isa! It's nice to meet you. How can I help?"},
{"role": "user", "content": "Yes, can you remind me what is my name?"}
]
response = get_completion_from_messages(messages)
print(response)
# 输出:Your name is Isa.
这就是所谓的上下文窗口——你每次调用都需要把相关的对话历史塞进去。上下文越长,消耗的 token 越多,成本也越高。
三、实战:构建 OrderBot 披萨点餐机器人
我们将构建一个自动点餐机器人,它能够:
- 问候顾客
- 收集订单(披萨尺寸、配料、配菜、饮料)
- 询问自取或外送
- 确认订单并生成 JSON 摘要
3.1 定义系统消息(核心指令)
系统消息是机器人的“大脑”。我们在这里指定菜单、规则和风格。
context = [
{"role": "system", "content": """
You are OrderBot, an automated service to collect orders for a pizza restaurant.
You first greet the customer, then collects the order, and then asks if it's a pickup or delivery.
You wait to collect the entire order, then summarize it and check for a final time if the customer wants to add anything else.
If it's a delivery, you ask for an address.
Finally you collect the payment.
Make sure to clarify all options, extras and sizes to uniquely identify the item from the menu.
You respond in a short, very conversational friendly style.
The menu includes:
pepperoni pizza 12.95, 10.00, 7.00
cheese pizza 10.95, 9.25, 6.50
eggplant pizza 11.95, 9.75, 6.75
fries 4.50, 3.50
greek salad 7.25
Toppings:
extra cheese 2.00, mushrooms 1.50, sausage 3.00, canadian bacon 3.50, AI sauce 1.50, peppers 1.00
Drinks:
coke 3.00, 2.00, 1.00
sprite 3.00, 2.00, 1.00
bottled water 5.00
"""}
]
3.2 构建交互界面(使用 Panel 库)
为了演示方便,我们使用 Panel 创建一个简单的文本输入界面。你也可以用 Gradio、Streamlit 或直接命令行。
import panel as pn
pn.extension()
panels = [] # 存储显示内容
def collect_messages(_):
prompt = inp.value_input
inp.value = ''
context.append({'role': 'user', 'content': f"{prompt}"})
response = get_completion_from_messages(context)
context.append({'role': 'assistant', 'content': f"{response}"})
panels.append(pn.Row('User:', pn.pane.Markdown(prompt, width=600)))
panels.append(pn.Row('Assistant:', pn.pane.Markdown(response, width=600, style={'background-color': '#F6F6F6'})))
return pn.Column(*panels)
inp = pn.widgets.TextInput(value="Hi", placeholder='Enter text here...')
button_conversation = pn.widgets.Button(name="Chat!")
interactive_conversation = pn.bind(collect_messages, button_conversation)
dashboard = pn.Column(
inp,
pn.Row(button_conversation),
pn.panel(interactive_conversation, loading_indicator=True, height=300),
)
dashboard
运行后,你会看到一个聊天界面。输入“Hi”,机器人会问候你并开始点餐流程。
3.3 模拟一次完整的点餐对话
以下是在界面中可能发生的对话(手动演示):
- User: Hi, I would like to order a pizza.
- Assistant: Great! What pizza would you like? We have pepperoni, cheese, and eggplant.
- User: How much are they?
- Assistant: Pepperoni: $12.95 (large), $10.00 (medium), $7.00 (small). Cheese: $10.95/$9.25/$6.50. Eggplant: $11.95/$9.75/$6.75.
- User: I’ll have a medium eggplant pizza.
- Assistant: Any toppings? Extra cheese $2.00, mushrooms $1.50, etc.
- User: No toppings.
- Assistant: Anything else? Sides or drinks?
- User: Yes, fries. Small.
- Assistant: Small fries $3.50. Anything else?
- User: That’s all.
- Assistant: Is this for pickup or delivery?
- User: Delivery. My address is 123 Main St.
- Assistant: Great. Your total is $13.25. How would you like to pay?
- User: Credit card.
- Assistant: Order confirmed. Thank you!
3.4 生成订单摘要(JSON)
在对话结束后,我们可以让模型从上下文中提取订单信息,生成结构化的 JSON,方便后端系统处理。
# 复制当前上下文并添加一个“摘要”指令
messages = context.copy()
messages.append({
"role": "system",
"content": """
Create a JSON summary of the previous food order.
Itemize the price for each item.
The fields should be:
1) pizza (include size)
2) list of toppings
3) list of drinks (include size)
4) list of sides (include size)
5) total price
"""
})
summary = get_completion_from_messages(messages, temperature=0)
print(summary)
输出示例:
{
"pizza": {"type": "eggplant", "size": "medium", "price": 9.75},
"toppings": [],
"drinks": [],
"sides": [{"item": "fries", "size": "small", "price": 3.50}],
"total_price": 13.25
}
这个 JSON 可以直接发送给订单处理系统或数据库。
四、temperature参数在对话中的选择
- 低temperature(0~0.3):输出确定、一致。适合订单收集、客服回答固定问题。我们的 OrderBot 在收集订单时建议使用低temperature,避免随机推荐不存在的商品。
- 中temperature(0.5~0.7):有一定多样性,适合闲聊机器人,让回答不那么机械。
- 高temperature(0.8~1.0):创意性强,可能偏离主题。用于头脑风暴或娱乐场景。
在 OrderBot 的示例中,我们在收集订单时使用 temperature=0,但在生成摘要时也使用 temperature=0 以确保结构化输出稳定。
五、常见问题与注意事项
1. 上下文长度限制:GPT-3.5-Turbo 上下文窗口为 4096 tokens,GPT-4 有 8K/32K 版本。长对话会消耗大量 token,注意成本。
2. 系统消息不是“记忆”:系统消息只是初始指令,不会自动记录对话历史。你必须手动把历史消息加入每次调用。
3. 用户消息中的敏感信息:如果你的机器人会收集地址、付款信息,务必遵循数据安全规范,不要记录或泄露。
4. 机器人自称 AI:最好让机器人明确告知用户它是 AI,避免误导(如示例中的署名或自我介绍)。
5. 处理异常输入:用户可能输入不相关或恶意内容。你可以在系统消息中加入“如果用户询问菜单之外的内容,礼貌地拒绝”等规则。
六、扩展:自定义角色与知识
你可以轻松修改系统消息,让机器人扮演不同角色:
- IT 支持机器人:系统消息包含常见问题和排查步骤。
- 心理陪伴机器人:系统消息设定为“温暖、共情、不提供医疗建议”。
- 语言学习伙伴:系统消息要求只使用目标语言对话,并在必要时纠正语法。
总结
| 核心概念 | 说明 |
|---|---|
| 三种角色 | system(设定行为)、user(用户输入)、assistant(模型回复) |
| 上下文管理 | 每次调用需传入完整对话历史,模型无状态 |
| 系统消息 | 控制机器人的个性、知识、规则,用户不可见 |
| OrderBot 实战 | 披萨点餐机器人:收集订单、确认配送、生成 JSON |
| temperature 参数 | 低temperature用于确定性任务,高temperature用于创意对话 |
通过本文的学习,你已经掌握了 OpenAI Chat Completion API 的核心用法,并亲手构建了一个可交互的点餐机器人。你可以将这个框架应用到自己的业务场景中——只需修改系统消息和菜单,就能得到一个全新的定制机器人。
下一步,你可以尝试为机器人添加更多功能:集成支付接口、调用外部 API 查询库存、或者使用函数调用(Function Calling)来执行具体操作。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐
所有评论(0)