大家好,我是 AI 研习者轻寒。在之前的文章《解密AI客服:+打造智能客服新时代》中,我基于 + 实现了简易公众号的 AI 客服,主要是基于文本回答用户提出的问题,但缺陷在于无法回答文本之外的内容,且回答较为生硬,同时没有根据用户隔离会话。本文通过优化,使客服能够在回答业务问题之外,还能与用户闲聊,同时隔离用户会话的同时保留上下文缓存。
打造 AI 客服
是一个用于开发由语言模型驱动的应用程序的框架, 灵活的抽象和广泛的工具包使开发人员能够利用 LLM 的力量。由于其版本迭代的太快,作者也是在不断的探索。
AI 客服
AI 客服旨在提供实用的辅助和支持,通过与用户的互动,自动分析用户的输入的问题,并根据用户的需求响应适当的回答或建议。
AI 客服可以为企业提高高效、降低成本,通过快速响应以提升用户满意度,并减少人工客服的工作负担,如原本可能需要 10 人的客服团队,现在在 AI 的辅助下可能只需要 2 人就能胜任工作。
目前 AI 客服还没法完全自主解决所有问题,但如何提升 AI 客服解决问题的能力还有很多探索的空间,比如基于 实现日常客服(如售前、售后)流程阶段自动化,通过 的代理及工具可以和其他业务系统紧密结合,利用 的链可以对会话或阶段进行分析和评估等等。
基于文本问答的客服实现
这是之前实现简易 AI 客服,有兴趣的可以去看看:《解密AI客服:+打造智能客服新时代》。
功能优化
本文是基于前文的实现进行了优化。
检索问答优化优化概述
在之前的实现中使用了 , 是 中的一个模块,用于构建基于检索的问答系统。
的主要思想是先从文档库中检索出与问题相关的文档,基于相关性对候选答案进行排序和筛选,然后将这些文档和原始问题一起提供给语言模型,让语言模型根据这些上下文来生成答案。
本次优化使用 去实现, 用于构建会话式的检索问答代理。它会考虑会话的上下文信息,根据之前的问题并回答来改进当前问题的检索结果。相比单轮的 ,可以在会话的过程中不断改进检索性能。
的主要思想是先构建一个检索工具,可以对用户的问题进行检索,获取相关文档。然后构建一个会话式的代理,内部集成了检索工具。当用户提出一个问题时,代理首先用检索工具获取相关文档。然后将问题、相关文档以及之前的对话历史作为 ,提供给语言模型生成回答。这样可以利用检索结果增强语言模型的理解能力,生成更好的回答。
mory 是 中的一个组件,用于在会话问答系统中存储对话历史。它可以跟踪对话的上下文,在生成回复时提供给语言模型使用。
代码实现优化前
qa = RetrievalQA.from_chain_type(llm=ChatOpenAI(model_name='gpt-3.5-turbo-0613'), chain_type="stuff",
retriever=vector_store.as_retriever())
优化后
memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True, verbose=True)
qa = ConversationalRetrievalChain.from_llm(llm=ChatOpenAI(model_name='gpt-3.5-turbo-0613'), chain_type="stuff", memory=memory,
retriever=vector_store.as_retriever(),
condense_question_prompt=common_prompt,
verbose=True)
系统预设优化概述
系统提示预设可以让模型回答的更可控,通过自定义系统模板,可以让 AI 的回复更加符合交互场景的需要,提高用户体验。它为构建会话式问答系统提供了更多可定制性,比如让系统回复更加人性化,丰富系统和用户之间的交互形式,又如控制 AI 哪些可以回答,哪些不能回答。
把 .txt 存在在静态文件中,在 部署时,方便快速调试以及优化 。
代码实现
# 构建system_template.txt文件的路径
system_template_path = os.path.join(base_dir, 'static', 'system_template.txt')
with open(system_template_path, 'r') as file:
system_template = file.read()
common_prompt = PromptTemplate(
template=system_template,
input_variables=[]
)
利用代理实现自定义工具调用优化概述
有 的功能, 的代理也是类似,这里我们使用了 。
的代理可以根据用户的提问,结合工具的描述(描述是非常有用的)和自定义参数自动判断是否需要调用工具以及选择什么工具。
基于代理和工具我们还可以把业务和 GPT 模型能力完美的结合起来。
代码实现
这里把之前写的实时查询天气的工具集成了进来,方便测试。可以阅读之前的文章《基于实现实时查询天气》来学习如何实现自定义工具(工具即是函数或者接口能力)。
qa = ConversationalRetrievalChain.from_llm(llm=llm, chain_type="stuff", memory=memory,
retriever=vector_store.as_retriever(),
condense_question_prompt=common_prompt,
verbose=True)
realWeatherTool = RealWeatherTool()
tools = [
Tool(
name="xmhc",
func=qa.run,
description="当您需要回答小猫惠充客服相关问题时,包括话费充值、充值类型(快充/慢充)、到账时间、充值须知、充值规则、充值协议、活动规则、客服联系方式、联系客服等,"
"这非常有用。输入应该是一个完整的问题。",
verbose=True,
),
Tool(
name="RealWeatherTool",
func=realWeatherTool.run,
description=realWeatherTool.description,
verbose=True,
)
]
chat_prompt = OpenAIFunctionsAgent.create_prompt(
system_message=SystemMessage(content=system_template)
)
agent = OpenAIFunctionsAgent(llm=llm, tools=tools, prompt=chat_prompt, verbose=True)
agent_executor = AgentExecutor(agent=agent, tools=tools, memory=memory, verbose=True)
用户会话隔离及上下文存储优化概述
我们知道微信公众消息都是基于公众号用户的,所用我们可以采用 来作用用户唯一标识,以此来用于绘画隔离。
同时需要记录用户会话的上下文,这里我采用 redis 来缓存用户会话记录,后续还可以基于会话记录来做一个会话分析功能。
对会话上下文进行限制,以防超出模型最大 token。
代码实现
@app.route("/xmhc/kf", methods=['POST'])
def chat(): # put application's code here
# 接口请求参数
json_data = request.get_json()
userid = json_data['userid']
question = json_data['question']
# 获取当前用户历史会话内容
history_message = []
if redis_store.exists(userid):
history_message_str = redis_store.get(userid)
history_message = json.loads(history_message_str)
try:
answer = agent_executor.run({"input": question, "chat_history": history_message})
current_message = (question, answer)
# 缓存当前用户历史对话内容
history_message.append(current_message)
if len(history_message) > 10: # 对会话数进行限制
# 删除最旧的数据
history_message.pop(0)
# 将元组列表转换为JSON字符串
history_message_str = json.dumps(history_message)
redis_store.set(userid, history_message_str)
print(answer)
except InvalidRequestError:
# 调用模型请求失败,可能是额度不足或者请求频繁
return {
"err_code": -1,
"data_list": []
}
return {
"err_code": 0,
"data_list": [
{"content": answer}
]
}
成果演示
结尾
给了我很多的惊喜,它让开发 AI 应用变得简单。但它的生态还在不断扩展,版本不断迭代,所以我们只能不断的探索。关注公众号【码森林】~
理解新范式,拥抱新时代,把握新机会。