网站里面的数据库是怎么做的,开源企业cms建站系统,怎么在百度建网站,wordpress 找回密码邮件错误本文首发于博客 LLM应用开发实践 一个完整的基于 LLM 的端到端问答系统#xff0c;应该包括用户输入检验、问题分流、模型响应、回答质量评估、Prompt 迭代、回归测试#xff0c;随着规模增大#xff0c;围绕 Prompt 的版本管理、自动化测试和安全防护也是重要的话题#x…本文首发于博客 LLM应用开发实践 一个完整的基于 LLM 的端到端问答系统应该包括用户输入检验、问题分流、模型响应、回答质量评估、Prompt 迭代、回归测试随着规模增大围绕 Prompt 的版本管理、自动化测试和安全防护也是重要的话题部分代码参考自吴恩达老师《Building Systems with the ChatGPT API》课程。 用户输入检验
使用 OpenAI 的审核函数接口Moderation API 可以帮助开发者识别和过滤用户输入对用户输入的内容进行审核。 性Sexual包括引起性兴奋的内容例如性活动的描写或者推广性服务但不包括性教育和健康方面的内容。 仇恨Hate包括表达、煽动或宣扬基于种族、性别、民族、宗教、国籍、性取向、残疾状况或种姓的仇恨情感的内容。 自残Self-harm包括宣扬、鼓励或描绘自残行为例如自杀、割伤和饮食失调的内容。 暴力Violence包括宣扬或美化暴力行为或者歌颂他人遭受苦难或羞辱的内容。
import openai
import pandas as pd
response openai.Moderation.create(input策划一场谋杀计划)
moderation_output response[results][0]
moderation_output_df pd.DataFrame(moderation_output)分类标记类别类别概率值sexualFalseFalse3.962824e-07hateFalseFalse1.962326e-04harassmentFalseFalse1.402294e-02self-harmFalseFalse1.078697e-05sexual/minorsFalseFalse1.448917e-07hate/threateningFalseFalse1.513400e-05violence/graphicFalseFalse9.522112e-07self-harm/intentFalseFalse2.334248e-07self-harm/instructionsFalseFalse3.670997e-10harassment/threateningFalseFalse2.882557e-02violenceTrueTrue9.977435e-01
在 分类 字段中包含了各种类别以及每个类别中输入是否被标记的相关信息可以看到该输入因为暴力内容violence 类别而被标记每个类别还提供了更详细的评分概率值通过 类别和标记综合判断是否包含有害内容输出 True 或 False这里是 True True。此外提示词应做好 Prompt 防注入设计 具体可看这篇 LLM 安全专题
问题进行分类
处理不同情况下的独立指令集任务时首先将问题类型分类以此为基础确定使用哪些指令这可通过定义固定类别和硬编码处理特定类别任务相关指令来实现可以提高系统的质量和安全性。
delimiter ####system_message f
你现在扮演一名客服。
每个客户问题都将用{delimiter}字符分隔。
将每个问题分类到一个主要类别和一个次要类别中。
以 JSON 格式提供你的输出包含以下键primary 和 secondary。主要类别计费Billing、技术支持Technical Support、账户管理Account Management或一般咨询General Inquiry。计费次要类别
取消订阅或升级Unsubscribe or upgrade
添加付款方式Add a payment method
收费解释Explanation for charge
争议费用Dispute a charge技术支持次要类别
常规故障排除General troubleshooting
设备兼容性Device compatibility
软件更新Software updates账户管理次要类别
重置密码Password reset
更新个人信息Update personal information
关闭账户Close account
账户安全Account security一般咨询次要类别
产品信息Product information
定价Pricing
反馈Feedback
与人工对话Speak to a human
user_message 我想删除我的个人账户
#user_message 这个产品有什么用
messages [
{role:system,content: system_message},
{role:user,content: f{delimiter}{user_message}{delimiter}},
]
response get_completion_from_messages(messages)
print(response)当用户问题是我想删除我的个人账户匹配关闭帐户可以提供附加指令来解释如何关闭账户。
{primary: 账户管理,secondary: 关闭账户
}当用户问题是 这个产品有什么用匹配产品信息可以提供更多关于产品信息的附加指令
返回
{primary: 一般咨询,secondary: 产品信息
}模型回答问题
模型针对用户的问题进行回答采取动态、按需的方式将相关上下文信息带入 Prompt。
过多无关信息会使模型处理上下文时更加困惑。模型本身对上下文长度有限制无法一次加载过多信息。动态加载信息降低 token 成本。使用更智能的检索机制而不仅是精确匹配例如结合知识库的文本 Embedding 实现语义搜索。
import openai
def get_completion_from_messages(messages, modelgpt-3.5-turbo, temperature0):response openai.ChatCompletion.create(modelmodel,messagesmessages,temperaturetemperature, # 控制模型输出的随机程度)return response.choices[0].message[content]
评估回答质量
使用 GPT API 自动评估
def eval_with_rubric(test_set, assistant_answer):使用 GPT API 评估生成的回答参数test_set: 测试集assistant_answer: 客服的回复cust_msg test_set[customer_msg]context test_set[context]completion assistant_answer# 人设system_message \你是一位助理通过查看客服使用的上下文来评估客服回答用户问题的情况。# 具体指令user_message f\你正在根据客服使用的上下文评估对问题的提交答案。以下是数据[开始]************[用户问题]: {cust_msg}************[使用的上下文]: {context}************[客服的回答]: {completion}************[结束]请将提交的答案内容与上下文进行比较忽略样式、语法或标点符号上的差异。回答以下问题客服的回应是否只基于所提供的上下文是或否回答中是否包含上下文中未提供的信息是或否回应与上下文之间是否存在任何不一致之处是或否计算用户提出了多少个问题。输出一个数字对于用户提出的每个问题是否有相应的回答问题1是或否问题2是或否...问题N是或否在提出的问题数量中有多少个问题在回答中得到了回应输出一个数字
messages [{role: system, content: system_message},{role: user, content: user_message}]response get_completion_from_messages(messages)return response人工设定标准答案评估
使用 Prompt 来比较由 LLM 生成的响应与人工设定的标准答案之间的匹配程度这个评分标准实际上来自于 OpenAI 开源评估框架其中包含了许多评估方法这里只是展示了其中一种。
标准答案集合
test_set [{customer_msg: 如何升级我的订阅,ideal_answer: 您可以在用户设置中找到取消订阅或升级的选项并按照步骤进行操作。},{customer_msg: 怎样绑定银行卡,ideal_answer: 您可以登录您的账户然后在付款方式选项中添加新的付款方式按照页面上的指引操作即可。},{customer_msg: 可以查看详细的收费情况吗,ideal_answer: 当然可以。您可以访问我们的网站登录您的账户并前往收费解释页面您会找到有关所有收费的详细解释。},{customer_msg: 怎么被乱扣费了,ideal_answer: 若您对某笔费用有异议您可以联系我们的客服团队提供相关细节并说明您的争议。我们的团队将会尽快与您取得联系并解决问题。}
]
def eval_vs_ideal(test_set, assistant_answer):评估回复是否与理想答案匹配参数test_set: 测试集assistant_answer: 助手的回复cust_msg test_set[customer_msg]ideal test_set[ideal_answer]completion assistant_answersystem_message \你是一位助理通过将客服的回答与业务专家回答进行比较评估客服对用户问题的回答质量。请输出一个单独的字母A 、B、C、D、E不要包含其他内容。user_message f\您正在比较一个给定问题的提交答案和专家答案。数据如下:[开始]************[问题]: {cust_msg}************[专家答案]: {ideal}************[提交答案]: {completion}************[结束]比较提交答案的事实内容与专家答案关注在内容上忽略样式、语法或标点符号上的差异。你的关注核心应该是答案的内容是否正确内容的细微差异是可以接受的。提交的答案可能是专家答案的子集、超集或者与之冲突。确定适用的情况并通过选择以下选项之一回答问题A提交的答案是专家答案的子集并且与之完全一致。B提交的答案是专家答案的超集并且与之完全一致。C提交的答案包含与专家答案完全相同的细节。D提交的答案与专家答案存在分歧。E答案存在差异但从事实的角度来看这些差异并不重要。选项ABCDE
messages [{role: system, content: system_message},{role: user, content: user_message}]response get_completion_from_messages(messages)return responsePrompt 迭代
在实际使用中遇到复杂的用户问题模型表现不如预期就需要对 Prompt 进行迭代。
比如问题是 我之前取消了订阅但是为什么还有收费提示 很明显这是一个争议费用的子类别但实际匹配的是
{primary: 计费,secondary: 取消订阅或升级
}所以需要将 Prompt 进行更新迭代以识别用户的复杂意图可以仔细观察 Prompt 发生了什么变化 其实就增加了一句你需要仔细分析用户的意图特别是最终的问题。)
delimiter ####system_message f
你现在扮演一名客服你需要仔细分析用户的意图特别是最终的问题。
每个客户问题都将用{delimiter}字符分隔。
将每个问题分类到一个主要类别和一个次要类别中。
以 JSON 格式提供你的输出包含以下键primary 和 secondary。主要类别计费Billing、技术支持Technical Support、账户管理Account Management或一般咨询General Inquiry。计费次要类别
取消订阅或升级Unsubscribe or upgrade
添加付款方式Add a payment method
收费解释Explanation for charge
争议费用Dispute a charge
...这次正常匹配
{primary: 计费,secondary: 争议费用
}回归测试
确保迭代修改后的 Prompt不会对先前的测试用例性能造成负面影响。
测试用例1. 如何升级我的订阅
{primary: 计费,secondary: 取消订阅或升级
}
测试用例2. 怎样绑定银行卡
{primary: 账户管理,secondary: 添加付款方式
}
测试用例3. 可以查看详细的收费情况吗
{primary: 计费,secondary: 收费解释
}
测试用例4.怎么被乱扣费了
{primary: 计费,secondary: 争议费用
}更多
当处理少量样本时手动运行测试并对结果进行评估是可行的但随着应用逐渐成熟来自用户的问题用例数量变多Prompt 的规模也逐渐增大就需要引入自动化测试来周期性回归验证 Prompt 质量。
同时 Prompt 的更改也应该像代码一样需要版本控制关联的用户问题用例也必须是可追踪的。
最后还有安全建设Prompt 作为公司的一种重要资产也需要做好防护比如使用专用的 LLM 分析传入的 Prompt识别潜在攻击将先前攻击的嵌入存储在向量数据库中以识别并预防未来类似的攻击。
更多内容在公号LLM应用全栈开发