“ 既要积极拥抱,又要保持清醒。”
GenAI(生成式AI)这两年很火,现在几乎所有的技术论坛,包括架构师论坛,都在聊GenAI。很显然,大部分企业也有把GenAI应用到企业的冲动。
笔者通过实践以及与负责GenAI平台开发的厂商交流,有一些新的洞见,在这里跟大家分享一下,希望能帮助大家在企业应用时避些坑。
这是一个全新的领域,大家都在探索过程中,欢迎大家一起进行交流,互通有无。
01
—
理解GenAI的核心原理
随着ChatGPT 3.5在2022年11月发布,GenAI(生成式AI)一夜爆火,热度持续到今天。要理解GenAI能在企业如何应用,首先要理解GenAI的核心原理。
对To C的场景来说,GenAI“效果炸裂”,因为用户对结果的准确性并不那么在乎,就像电商的商品推荐,推荐错了(比如你买了某件商品,它继续给你推荐该商品,明明你短期内不再需要了)你也就忽视或者当作笑话做谈资。
大语言模型(下面统一简称“大模型”)的胡诌,对于个人用户来说也是如此。
但对于To B或在企业内应用来说,大模型仅仅是一切的开始。要得到可信、合规的结果,还有大量细致、繁琐的工作要做,包括多个模型的结合使用以及模型与其它传统技术的结合。
这里有一个70%靠数据、20%靠算力、10%靠模型的说法。也就是说,大模型的能力在企业应用中的占比其实并没有那么高。
和传统AI技术一样,数据的质量和有效处理对于最终的效果依然起着决定性的作用。
算力也是必须考虑的因素。企业内部所拥有的GPU数量肯定有限,租用云厂商的算力资源也涉及到高昂的费用问题。
模型相当于一个容器,它的大小就是这个容器的尺寸。模型越大,调用时所需要的GPU资源特别是显存的要求越大。
通用大模型就是往这个容器里投喂各个领域的数据训练而成。如果要解决的问题在某个垂直领域里,而这个领域在某个通用大模型中的训练数据只占10%,显然不如使用领域数据专门训练过的相对小的模型性价比高。这里的性价比除了指对GPU特别是显存的要求会降低外,应用处理的速度也会更快,提升用户体验。
大语言模型的训练或微调,是应试教育的过程,核心目标是让它具备解决不同问题的能力。投喂什么样的数据,它就能解决什么范围的问题。
但直接使用通过训练好或微调好的模型解决问题,是“背题”的过程。还要通过RAG或匹配调用AI Agent等组合拳,让它能有效地从内部最新的知识库或接口找到最合适的内容,才是“解题”的过程。
02
—
GenAI在企业的典型应用
基于GenAI的能力和核心原理,在企业中的典型应用有:
企业内部知识问答机器人
当用户对企业某个产品或服务有疑问或者需要支持时,一个解决方案就是有一个问答机器人能根据企业内部知识先自动回应用户。
这里涉及到的问题是,不管是通用大模型还是垂直领域模型,训练它的数据都是通用知识,而不是企业特有的知识。
这里有两个解决方案:微调和RAG。
微调就是在原有大模型的基础上,利用企业内部数据对模型进行再训练。但这个过程需要有足够的GPU资源进行训练,当企业内部数据有更新时,可能也需要重新训练。正如前面所述,使用通过微调的模型解决问题,是“背题”的过程。这种方式成本较高,内容时效性较差。
所以,在这个场景里,更合适的技术是RAG。
RAG全称Retrieval-Augmented Generation,是一种结合了检索(Retrieval)和生成(Generation)的人工智能模型,它旨在通过从大量数据中检索相关信息来增强生成任务的性能。
其中Embedding是RAG的典型过程。
Embedding的原理是把知识库的内容进行向量化,保存在向量数据库中。当用户提出问题或提示时,Embedding模型会把它转化成向量,然后通过向量相似度匹配,找出最接近的内容返回给LLM回答用户。
和微调的“背题”过程不同,通过RAG,能有效地从内部最新的知识库找到最合适的内容,是“解题”的过程。
代码助手
Github Copilot推出后,AI编程也火了起来。它可以根据文档、提示或注释自动生成示例代码、给现有代码提出优化建议、生成测试用例等。很多企业把代码助手视为提升开发效率的灵丹妙药。
AI Agent
AI Agent听起来很神,好像能有很多助手帮忙自动完成一些事务。下面是一段AI Agent的代码,可以帮助揭开它神秘的面纱。
import json
import openai
import requests
from datetime import datetime, timedelta
s = requests.Session()
s.verify=False
openai.requestssession = s
openai.api_base = '{}'
openai.api_key = "xxx"
functions = [
{
"name": "current_date",
"description": "Use this function to return current date, this is helpful. Output is a str that the formatting is like '1900-01-01'.",
"parameters": None
},
{
"name": "send_mail",
"description": "Use this function to send mail, this is helpful. Output should be a fully JSON schema.",
"parameters": {
"type": "object",
"properties": {
"to_list": {
"type": "list[str]",
"description": "mail box to receive the email, formatting example, ['abc@qq.com', '123@qq.com']"
},
"bcc_list": {
"type": "list[str]",
"description": "mail box to be BCC when send the email, default value is [], formatting example, ['abc@qq.com', '123@qq.com']"
},
"cc_list": {
"type": "list[str]",
"description": "mail box to be CC when send the email, default value is [], formatting example, ['abc@qq.com', '123@qq.com']"
},
"subject": {
"type": "string",
"description": "email subject/title"
},
"email_content": {
"type": "string",
"description": "email contents/body, it is a html formatting, but remove following labels: <html></html> and <body></body>"
}
},
"required": ["to_list", "bcc_list", "cc_list", "subject", "email_content"]
}
}
]
def current_date(any):
return datetime.now().strftime("%Y-%m-%d")
def send_mail(conf):
r = requests.post(
url='{API URL for sending mail}',
headers={"ccstoken":openai.api_key},
json = {
"to_list": conf.get('to_list'),
"bcc_list": conf.get('bcc_list') or [],
"cc_list": conf.get('cc_list') or [],
"subject": conf.get('subject'),
"email_content": conf.get('email_content')
},
verify=False
)
print(r.json())
这段代码解决的问题是,如果大模型是私有部署的,没有联网。当有用户问到一些实时的问题,比如今天是几号,今天天气如何,这类看似简单,但是“超纲”的问题,大模型就会傻眼。正如前面所说的,大模型是“背题”,这些问题的答案不在它的“记忆”里。
这个时候,我们就可以通过调用AI Agent来解决。如代码所示,当被问到“今天是几号”时,它会调用系统的命令返回信息给大模型进行回答。同理,当被问到“今天天气如何”时,相应的实现方法是调用可用的天气信息API返回信息给大模型进行回答。
代码中也有通过对话发邮件的示例。
这段代码最核心的是每个Agent的description字段。系统正是通过用户输入提示的内容匹配Agent的description的语义来确定调用哪个 Agent的。
通过提示工程规范文档
企业内部有很多文档规范,包括对执行计划书写的要求,比如内容要完整、具体、有逻辑顺序、可执行等。这些规范往往是以自然语言描述。在过去,要检查文档是否符合规范,需要人工对每一份文档进行审核,费时费力,也很难确保真的检查过。
通过提示工程,可以把这些具体要求的描述和文档内容一起投喂给LLM,从而让LLM判别文档内容是否满足要求,以下是一个例子:
《年度销售报告》规范性检查
目标文档
• 文档名称:《年度销售报告》
• 文档目的:总结过去一年的销售业绩,并为未来的销售策略提供数据支持。
规范要求
文档结构:应包含以下部分:封面、目录、摘要、正文(包括市场分析、销售数据分析、竞争对手分析、销售策略)、结论、附录。
格式规范:正文使用12号Times New Roman字体,1.5倍行距,各章节标题使用加粗和合适的字号,图表应有清晰的标题和来源标注。
数据准确性:报告中的数据应准确无误,来源可靠,对于关键数据提供相应的图表或图形以便于理解。
语言和风格:保持正式和客观的语言风格,避免使用第一人称,确保术语的一致性。
03
—
GenAI落地的注意事项
合规要求的满足
很多企业对AI使用场景和模型的选择都有严格的合规要求。更糟糕的是,由于GenAI属于新鲜事物,企业的合规审查流程可能还处在演讲过程中。团队在落地时可能会遇到,技术探索和实施只花了20%的时间与精力,其余80%用在过审上。
问答机器人知识库的投喂技巧
首先,团队需要对内部文档的内容进行审核,确保它是有效的、更新的。Garbage In,Garbage Out,我们可以想象如果文档内容质量不高或者不更新,机器人肯定不会给用户带来有价值的回答。
其次,实践中发现,使用RAG时,用作Embedding的知识库也有投喂技巧。
要想提升问题与回答的匹配度,有些时候甚至需要把常见问题写在对应文档中,也就是谜面要写在谜底中。
另外,如果把过多、主题分散的文档做Embedding,可能会干扰匹配的准确度。
比方说,以企业内部云平台服务为例,如果用了内部操作文档做Embedding,希望用户对企业内云服务的基础问题问答机器人可以通过匹配这些内部操作文档得到解答。
但如果同时把各个云产品的通用文档也做Embedding,试图扩充问答机器人的知识量和让它对通用问题也能有回答能力,很可能会导致用户问一些内部操作的问题时,机器人匹配到通用文档的概率更高,从而输出不合适的回复。因为那些通用文档的量远远大于内部操作文档,降低了内部操作文档被匹配的概率。
另外,用户在提问时,也需要包含更多的上下文来提高匹配度。比如,Embedding的文档中包含了某个负责运维的同事的值班电话。如果问题是“XX的电话是多少”,问答机器人大概率不会提供正确回复。但如果问题改成“XX服务的XXX的值班电话是多少”时,问答机器人能正确回答的概率会大大提高。
代码助手带来的挑战
企业对使用代码助手还是比较谨慎的。
一方面,很多代码助手都是由云厂商提供,企业使用时会担心把自己的代码,也是企业的核心知识产权放到云上,有泄漏风险。
对于这个问题,可以运用IDE的代码助手插件连接到私有部署的大模型实现,由于整个环境在隔离的无互联网访问的内网中,可以避免代码泄漏的问题。
另一方面,使用代码Copilot对程序员提出了更高的要求,程序员必须有能力读懂和验证生成的代码的有效性和质量,否则给企业带来的不是效率,而是风险。如何高效地验证生成代码的有效性是一个课题。
提示需要不断优化
前面提到的通过提示工程进行文档规范检查,也不是一蹴而就的。
首先,我们要建立好预期。通过LLM的提示工程,我们只是把大量文档的初筛完成。我们的目标是让机器处理大量的、低价值的工作,把少量的、高价值的工作留给人类。它的准确率肯定不是100%的。我们希望它能把80%大差不差的文档过滤掉,留下20%进行人工审核。
其次,提示需要不断优化,通过其反馈的结果,不断调整提示提高它的准确率。
04
—
总结
GenAI被媒体/自媒体吹得神乎其神,但要在企业落地,还需要对适合的场景进行大量的落地工作。在合规监管、内容生成的准确性和有效性方面,都有很多需要注意的地方和技巧。作为一种新鲜事物,我们既要积极拥抱,也要保持清醒,确保它用在合适的地方。
05
—
番外
谨慎起见,我请了Kimi帮忙分析这篇文章内容的准确性(节选):
根据您提供的文件内容,这篇文章对GenAI的原理和应用进行了较为详细的描述,整体上没有明显的错误。文章从多个角度分析了GenAI在企业应用中的注意事项,包括理解GenAI的核心原理、企业典型应用场景、以及落地时的注意事项等。
总的来说,文章内容没有发现对GenAI原理和应用的错误描述,而是提供了一个较为全面和深入的分析。当然,随着人工智能技术的快速发展,对GenAI的理解和应用也在不断进步和更新,因此保持对最新研究和技术动态的关注是非常重要的。
觉得文章不错,顺手点个“点赞”、“在看”或转发给朋友们吧。
相关阅读:
笔者参与翻译的《可解释AI实战》正在热卖中
关于作者
关注公众号看其它原创作品
坚持原创高质量软件交付相关文章
觉得好看,点个“点赞”、“在看”或转发给朋友们,欢迎你留言。