业务场景:办理流量包的智能客服

对话系统的基本模块

-
语音识别(ASR):将用户的语音输入转换为文本。 -
语义理解(NLU):利用大模型进行语义理解,解析用户意图。 -
对话管理(DM):包括状态跟踪(DST)和对话策略(Policy),管理对话的流畅进行。 -
自然语言生成(NLG):生成符合语境的回复文本。 -
语音合成(TTS):将文本回复转换为语音输出。
对话流程举例

-
用户:我要办理流量包。 -
智能客服:您好!请问您需要什么样的流量包?我们有经济套餐、畅游套餐、无限套餐和校园套餐。 -
用户:我想要一个流量大的。 -
智能客服:推荐您选择无限套餐,每月1000G流量,仅需300元。请问您需要办理吗? -
用户:是的,帮我办理吧。 -
智能客服:好的,您的无限套餐已办理成功。谢谢使用!
用Prompt实现DST不是唯一选择
-
优点:节省开发时间和成本,快速迭代。 -
缺点:调优过程复杂,需要通过大量动态例子进行调试和优化。
import openaiimport os# 加载 .env 文件from dotenv import load_dotenv, find_dotenv_ = load_dotenv(find_dotenv())# 从环境变量中获得你的 OpenAI Keyopenai.api_key = os.getenv('OPENAI_API_KEY')openai.api_base = os.getenv('OPENAI_API_URL')model = os.getenv('MODEL')# 基于 prompt 生成文本def get_completion(prompt, model=model):messages = [{"role": "user", "content": prompt}]response = openai.ChatCompletion.create(model=model,messages=messages,temperature=0,# 模型输出的随机性,0 表示随机性最小)return response.choices[0].message["content"]instruction = """你的任务是识别用户对手机流量套餐产品的选择条件。每种流量套餐产品包含三个属性:名称(name),月费价格(price),月流量(data)。根据对话上下文,识别用户在上述属性上的倾向。识别结果要包含整个对话的信息。"""# 输出描述output_format = """以JSON格式输出。1. name字段的取值为string类型,取值必须为以下之一:经济套餐、畅游套餐、无限套餐、校园套餐 或 null;2. price字段的取值为一个结构体 或 null,包含两个字段:(1) operator, string类型,取值范围:'<='(小于等于), '>=' (大于等于), '=='(等于)(2) value, int类型3. data字段的取值为取值为一个结构体 或 null,包含两个字段:(1) operator, string类型,取值范围:'<='(小于等于), '>=' (大于等于), '=='(等于)(2) value, int类型或string类型,string类型只能是'无上限'4. 用户的意图可以包含按price或data排序,以sort字段标识,取值为一个结构体:(1) 结构体中以"ordering"="descend"表示按降序排序,以"value"字段存储待排序的字段(2) 结构体中以"ordering"="ascend"表示按升序排序,以"value"字段存储待排序的字段只输出中只包含用户提及的字段,不要猜测任何用户未直接提及的字段。不要输出值为null的字段。"""# DO NOT OUTPUT NULL-VALUED FIELD!examples = """客服:有什么可以帮您用户:100G套餐有什么{"data":{"operator":">=","value":100}}客服:有什么可以帮您用户:100G套餐有什么客服:我们现在有无限套餐,不限流量,月费300元用户:太贵了,有200元以内的不{"data":{"operator":">=","value":100},"price":{"operator":"<=","value":200}}客服:有什么可以帮您用户:便宜的套餐有什么客服:我们现在有经济套餐,每月50元,10G流量用户:100G以上的有什么{"data":{"operator":">=","value":100},"sort":{"ordering"="ascend","value"="price"}}客服:有什么可以帮您用户:100G以上的套餐有什么客服:我们现在有畅游套餐,流量100G,月费180元用户:流量最多的呢{"sort":{"ordering"="descend","value"="data"},"data":{"operator":">=","value":100}}"""# input_text="哪个便宜"# input_text="无限量哪个多少钱"input_text = "流量最大的多少钱"context = f"""客服:有什么可以帮您用户:有什么100G以上的套餐推荐客服:我们有畅游套餐和无限套餐,您有什么价格倾向吗用户:{input_text}"""prompt = f"""{instruction}{output_format}{examples}{context}"""response = get_completion(prompt)print(response)
输出:
{"sort": {"ordering": "descend","value": "data"},"data": {"operator": ">=","value": 100}}
用Prompt实现NLU,用传统方法维护DST
-
优点:DST环节具有更高的可控性,可以结合业务经验设计状态更新机制,确保系统稳定可靠。 -
缺点:需要深入了解业务逻辑,设计合适的状态更新和冲突解决机制。
import openaiimport os# 加载 .env 文件from dotenv import load_dotenv, find_dotenv_ = load_dotenv(find_dotenv())# 从环境变量中获得你的 OpenAI Keyopenai.api_key = os.getenv('OPENAI_API_KEY')openai.api_base = os.getenv('OPENAI_API_URL')model = os.getenv('MODEL')# 任务描述instruction = """你的任务是识别用户对手机流量套餐产品的选择条件。每种流量套餐产品包含三个属性:名称(name),月费价格(price),月流量(data)。根据用户输入,识别用户在上述三种属性上的倾向。"""# 输出描述output_format = """以JSON格式输出。1. name字段的取值为string类型,取值必须为以下之一:经济套餐、畅游套餐、无限套餐、校园套餐 或 null;2. price字段的取值为一个结构体 或 null,包含两个字段:(1) operator, string类型,取值范围:'<='(小于等于), '>=' (大于等于), '=='(等于)(2) value, int类型3. data字段的取值为取值为一个结构体 或 null,包含两个字段:(1) operator, string类型,取值范围:'<='(小于等于), '>=' (大于等于), '=='(等于)(2) value, int类型或string类型,string类型只能是'无上限'4. 用户的意图可以包含按price或data排序,以sort字段标识,取值为一个结构体:(1) 结构体中以"ordering"="descend"表示按降序排序,以"value"字段存储待排序的字段(2) 结构体中以"ordering"="ascend"表示按升序排序,以"value"字段存储待排序的字段只输出中只包含用户提及的字段,不要猜测任何用户未直接提及的字段,不输出值为null的字段。"""examples = """便宜的套餐:{"sort":{"ordering"="ascend","value"="price"}}有没有不限流量的:{"data":{"operator":"==","value":"无上限"}}流量大的:{"sort":{"ordering"="descend","value"="data"}}100G以上流量的套餐最便宜的是哪个:{"sort":{"ordering"="ascend","value"="price"},"data":{"operator":">=","value":100}}月费不超过200的:{"price":{"operator":"<=","value":200}}就要月费180那个套餐:{"price":{"operator":"==","value":180}}经济套餐:{"name":"经济套餐"}"""input_text = "有没有便宜的套餐"# input_text = "有没有土豪套餐"# input_text = "办个200G的套餐"# input_text = "有没有流量大的套餐"# input_text = "200元以下,流量大的套餐有啥"# input_text = "你说那个10G的套餐,叫啥名字"prompt = f"""{instruction}{output_format}例如:{examples}用户输入:{input_text}"""# 基于 prompt 生成文本def get_completion(prompt, model=model):messages = [{"role": "user", "content": prompt}]response = openai.ChatCompletion.create(model=model,messages=messages,temperature=0,# 模型输出的随机性,0 表示随机性最小)return response.choices[0].message["content"]response = get_completion(prompt)print(response)
{"sort":{"ordering":"ascend","value":"price"}}

