最近一直用LLM解决各种各样的问题,感觉已经脱离不了LLM了。每次使用LLM解决一个之前解决不了的问题,或者大大提升我的工作效率的时候,我内心都小小会激动一下。我想这是只通过看文章或只是研究AI理论感受不到的小确幸。我也因此更加确信LLM是一个技术变革,它会带来了一些技术范式的改变,非常期待它的进一步发展。
分享一个最近在实际业务中使用LLM解决传统技术解决不了的小问题(或者说之前解决门槛和成本非常高),以及整个过程的感受。
需求
最近业务上有一个需要文本检测和信息提取的功能,就是要从聊天上下文中获取用户意图和信息。比如用户聊天内容的意图是什么,以及提取聊天内容中出现的用户当前位置和年龄信息等等。
传统技术方案
团队中的一个同学尝试用规则去实现。他的思路是用分词算法去分词,然后按关键字去匹配,再分割出认为是对应信息的字符串。这种方法一看就不灵,因为没有上下文,很容易误判或者检测不出来。
比如下边的聊天内容:
用户:我在深圳上班的时候才24岁。
这句话中既没有用户的当前位置信息,也没有当前的年龄信息,但是如果你用关键字“我在”和“岁”去匹配,可能会匹配出位置“深圳”和年龄“24”,但这并不是用户当前的位置和年龄信息,属于误判。
再举个上下文相关的例子:
用户A:我不年轻了,都34了,不知道还能干几年。
用户B:我也差不多,就比你小一岁。
这样的场景用规则是无法识别出用户B的年龄信息的。
LLM方案尝试
我一看,觉得这个场景适合用LLM解决。我写了个简单的prompt,用百度最新的ernie-bot-4尝试了下,发现效果不错。当时没有多想,就开始动手把百度的ernie-bot-4 接进来了。
但是,接进来容易,实测起来发现问题不少:LLM幻觉导致的误判,prompt过长导致的成本,以及用户输入的敏感字符导致触发LLM的安全规则等等。
接下来的一周,我一直在努力去解决这些问题,目标是达到业务要求的95%的准确率并且把成本降下来。在经历几次都差点要放弃的情况下,终于达到在控制成本的前提下接近95%的准确率。优化过程中用了很多技巧:用词准确性优化,特殊关键词语(比如:让我们一步一步思考等等),符号分割,关键字突出,输出格式优化,结构化prompt,COT,few shot,问题拆解等等。
总结
回想从demo验证到最终优化到满足业务要求的过程,有几点感悟:
首先,prompt是使用LLM解决问题的关键。怎么写prompt,用什么prompt框架会大大影响LLM解决问题的准确率。prompt中的用词的准确,词出现的位置,few shot,COT等都能影响LLM的输出结果。
第二,prompt优化非常考验经验和思路,这也是很多人在尝试LLM后最终放弃,并得出LLM是个玩具的结论的原因。我在优化过程中也几次想要放弃,因为LLM是一个黑箱,我也不确定持续优化下去能不能达到最终的要求。这给人非常大的不安全感,真正的业务开发中需要承担比较大业务压力和可能失败的风险。
第三,用LLM解决问题跟使用传统技术解决问题有点不一样。使用prompt解决问题的关键是准确描述需求,然后不断地去调优prompt,而且基于现在的LLM的能力基本无法做到100%准确。这跟上边的第二点相关,传统技术方案是非常确定的。
第四,虽然现在也没有人能解释清楚LLM为什么会出现涌现的能力,也无法用数学证明它100%正确。但是它确实能解决我们之前无法解决的一些问题(或者解决起来门槛和成本极高)。既然有用,那我们可以先用起来。我们不要排斥它,我们要承认它具备一些可以非常方便使用的特有的能力,比如语义理解,一定的常识智能,情绪判断等等。最重要的是,LLM目前还在快速发展中,非常值得期待。
同时,我们目前也不要神化LLM。LLM目前确实还是有不少缺陷,比如成本,幻觉,响应时间,数学能力差等等。
prompt分享
下边是解决方案中用到的一个根据聊天上下文获取年龄信息的prompt的草稿,给大家参考一下。我这里相当于把llm当作一个接口来用,所以输入是josn字符串,输出也是json字符串,主要是方便跟传统程序对接,感兴趣的可以尝试一下:
# Role
你是一个通过分析聊天对话内容准确地计算出"我的年龄"的年龄计算器。## Backgrounds
- 与不同的陌生人聊天对话中经常会出现询问问我年龄的情况。
- 从"我"对自己年龄的描述中分析出"我的年龄"。## Workflows
1.从 input json对象中读取 "year" 字段,获取"今年年份"。
2.通过"今年年份"和"msgs"消息中我对年龄的描述,计算出"我的年龄"。## Constraints
- 描述年龄的数字是"大于等于70"时,表示"19"开头的"出生年份"。
- 描述年龄的数字是"0开头"时,表示"20"开头的"出生年份"。
- 年龄="今年年份" - "出生年份",减法计算通过调用 python 命令完成。
- 描述年龄的数字是"大于等于16" 且 "小于等于50"时,即[16,50]时,数字即"我的年龄"。
- 如果信息不足于准确地计算出具体的年龄,"我的年龄"为0。
- 避免误判,严格按照给定规则进行计算。
- 只有是对"我"年龄询问的回答的数字才是"我的年龄"## Skills
- 文本分析和理解的能力。
- 1000 以内 加减算术的能力。## Examples
###
input:
{
"year":2020,
"msgs":[
{
"A": "你几岁?",
"我": "9 5 的"
},
{
"B": "你多大了?",
"我": "2 7了"
},
{
"C": "你的号码发我下",
"我": "19"
},
{
"D": "你今年几岁了?",
"我": "我 97 的"
},
{
"E": "你哪年的?",
"我": "02年的"
},
{
"F": "你今年几岁了?",
"我": "24"
}
]
}
output:
{
"year":2020,
"ages":[
"年龄询问并回答出生年,2020-1995=25(25)",
"年龄询问并直接回答(27)",
"非年龄询问(0)",
"年龄询问并回答出生年,2020-1997=23(23)",
"年龄询问并回答出生年,2020-2002=18(18)",
"年龄询问并直接回答(24)"
]
}
###
input:
{
"year":2024,
"msgs":[
{
"A": "你多大?",
"我": "我三十一"
},
{
"B": "我比你年轻",
"我": "你97的?"
},
{
"C": "我比你小",
"我": "你24了?"
},
{
"D": "我30岁",
"我": "我比你小3岁"
},
{
"E": "你发下你的号码",
"我": "34"
},
{
"F": "你多大?",
"我": "我03年的"
}
]
}
output:
{
"year":2024,
"ages":[
"年龄询问并直接回答(31)",
"没有我的年龄信息(0)",
"没有我的年龄信息(0)",
"推算我的年龄,30-3=27(27)"
"非年龄询问(0)",
"年龄询问并回答出生年,2024-2003=21(21)"
]
}
##### 注意
- 只有明确地描述"我的"出生年份或年龄时才推算"我的年龄"。
- 疑问句,询问句都不能推算"我的年龄"。
- 对方的年龄,即"你的年龄" 不予以计算。
- 只有是对"我"年龄询问的回答的数字才是"我的年龄",其他情况年龄默认为 0。
- **不输出analyse, 但分析过程请严格按照analyse分析**。## Goals
让我们一步一步思考,严格遵循 Constraints,一条一条地根据 analyse 的分析过程准确地计算出"我的年龄",**严格按照格式**输出json对象output。###
input:
{
"year":2023,
"msgs":[
{
"A": "我比你大",
"我": "你今年30了?"
},
{
"B": "我25,你多大?",
"我": "我比你大3岁"
},
{
"C": "你多大?",
"我": "你呢?你97的?"
},
{
"E": "你的号码是?",
"我": "我18"
},
{
"F": "你多大了?",
"我": "23"
},
{
"G": "你多大?",
"我": "我93年的"
}
]
}
output:
我目前正在开发一款基于自研的LLM agent framework 的智能客服产品,它具有意图引导、信息收集、情绪安抚、LUI与GUI 完美融合、打通公司内部与外部数据孤岛、人工接管、数据分析与洞察、异常监控等功能。
欢迎对智能客服产品、AI应用落地,或者是prompt学习和调优,LLM应用开发感兴趣的朋友加我微信,一起交流,共同前行。