最近刷到一个脱口秀,表演者调侃自己的领导最近把AI看成"全能员工"或"终极救星",甚至还没用过就信仰上头。
于是跟风投资建设了一套企业内部AI平台,搭建好之后呢,兴奋无比地给AI甩了一堆材料,然后就跟往常对人类员工布置任务一样,跟AI讲,"你给我弄下。"
结果AI自然get不到领导的真实意图,究竟是要弄啥嘞,只能一通胡乱输出。
其实呢,AI确实很强大,但前提是:你得会用、会说清楚你的目标、会给清晰的数据或上下文。
那如今AI应用的真实场景是什么样的呢?
今天我们就聊一个AI应用中的真实案例,小小的揭露下AI的神秘面纱。
最近在测试AI文生SQL的场景中,遇到因数据日期格式不符合最佳实践的情况,导致AI无法直接得到预期结果。
这类问题比较典型,因为各种各样的原因,即便在很多客户的生产环境中也广泛存在,就是在业务表中的某个时间类型的字段,对应的数据类型设置不符合规范,经常被错误设置为字符串数据类型,从而导致一些潜在问题。
下面我们就来模拟下这个场景。
注意:本文并不是标准答案,因为实际场景可能涉及更多的细节和个性化设置,所以本文只是提供一个调试思路,当大家未来遇到类似问题时,参考使用。
构造测试表,插入7条典型的测试数据,代表常见场景:
SQL
--创建测试表,指定日期格式为varchar2,模拟客户环境
create Table test (id number, delivery_date varchar2(20), content varchar2(50));
--插入几行测试数据
insert into test values (1,'20250722','normal');
insert into test values (2,'20250511','normal');
insert into test values (3,'20250518','normal');
insert into test values (4,null,'null值');
insert into test values (5,' ','space空格'); --模拟数据质量问题"空格"
insert into test values (6,'20250230','非法日期');--模拟数据质量问题
insert into test values (7,'20251301','非法日期');--模拟数据质量问题
--delete from test where id=6; --删除2月30号非法日期(测试过程中会用到)
--delete from test where id=7; --删除13月1号非法日期
commit;
这里也可以看到,因为字段不是date时间数据类型,如果程序逻辑再处理不当或有bug,后台表中就可能存在被插入任意非法值,导致一系列的数据质量问题。
SQL
select id, length(delivery_date), content from test;
可以看到,如果是null值(正常),length长度也是null,如果是错误的space空格这种,长度就是1:
SQL
--ORA-01840: 输入值对于日期格式不够长。 "input value not long enough for date format"
select to_date(' ','yyyymmdd') from dual;
--注意:null值不算有问题,因为null值不会报错,返回也是null:
select to_date(null,'yyyymmdd') from dual;
--针对空格的workaround,使用trim函数,这样也会返回null:
select to_date(trim(' '),'yyyymmdd') from dual;
这类数据其实相对比较好过滤,比如通过length函数来过滤,只取length(delivery_date) = 8
的数据即可。
SQL
--过滤掉长度不为8的无效数据
select * from test where length(delivery_date) = 8;
--严谨角度也可以加入trim,过滤掉极端场景,比如恰好有8个空格的情况..
select * from test where length(trim(delivery_date)) = 8;
但是,另外一些符合长度8的非法日期,依然存在,
比如这里模拟构建的2个非法日期,分别都会报错,而且可以看到错误描述非常精细,具体区别到究竟是月份无效还是月份中没有这一天,如下:
SQL
--ORA-01839: 指定月份的日期无效。 "date not valid for month specified"
SELECT TO_DATE('20230230', 'YYYYMMDD') FROM dual;
--因为你传入的字符串,年份和月份是合法的,但对应的日期 在该月中并不存在。
--ORA-01843: 指定的月份无效。 "An invalid month was specified."
SELECT TO_DATE('20251301', 'YYYYMMDD') FROM dual;
--因为你传入的字符串,经过解析后发现 月份部分不是 01~12 的有效值。
如果我们使用简单过滤规则,比如限定月份和天数的合法数值:
sql
select * from test
where length(delivery_date) = 8
and SUBSTR(delivery_date,5,2) BETWEEN '01' AND '12'
AND SUBSTR(delivery_date,7,2) BETWEEN '01' AND '31'
不过上述过滤其实不够严谨,例如没有对年份检查,同时也仅能过滤类似13月这种明显错误数据。
如果使用正则表达式来过滤(这里多校验了年份):
SQL
select * from test
where length(delivery_date) = 8
AND REGEXP_LIKE(delivery_date, '^(19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])$')
正则表达式中虽然加了年份过滤,也把20251301
这种明显违法范围值的无效数据就会被过滤掉了,但是像20250230
这种特殊的情况,表面上满足定义的基本规律,但因为2月份压根就没有30号,所以就依然存在漏洞。
这个当然也可以写复杂规则来过滤,但过滤起来就比较麻烦了,这也是为何强烈建议要用date数据类型存储时间格式数据的原因之一。
下面我们来具体测试AI文生SQL场景下这类问题的影响:
场景:要求查询2025年上半年的数据
自然语言转成SQL,LLM默认过滤时间基本都会使用标准的to_date()
函数操作,这也是情理之中,符合正常情况下的最佳实践。但是因为我们这里的时间是字符串存储的,属于非正常情况,可能会因此报各种错误信息:
SQL
--使用to_date函数来过滤时间列,查询2025年上半年的数据:
--该查询会报错:ORA-01840: 输入值对于日期格式不够长
select * from test
where TO_DATE(delivery_date, 'YYYYMMDD') >= TO_DATE('20250101','YYYYMMDD') and to_date(delivery_date,'YYYYMMDD') < to_date('20250701','YYYYMMDD')
此时,如果想继续查询,就需要添加各种过滤限制条件,比如:
sql
--报错变成:ORA-01839: 指定月份的日期无效
--这是因为表中还有20250230这样的非法日期没过滤掉,但如果没有这条数据,就可以成功执行了:
select * from test
where TO_DATE(delivery_date, 'YYYYMMDD') >= TO_DATE('20250101','YYYYMMDD') and to_date(delivery_date,'YYYYMMDD') < to_date('20250701','YYYYMMDD')
and length(delivery_date) = 8
AND REGEXP_LIKE(delivery_date, '^(19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])$')
而一般使用字符串定义日期格式的用户,通常对应的程序也都是直接使用字符串来比较时间的:
SQL
--这样虽然不会报错,但是例如20250230这样的非法日期数据,也会被查询出来
--只能依靠程序来控制不要输入此类非法数据
select * from test
where delivery_date >= '20250101' and delivery_date < '20250701'
现在问题就明朗了,要么还是选择to_date方式,要额外增加各种过滤条件,要么干脆直接选择字符比较。
二者各有利弊,前者写法复杂,但会校验日期格式,如果有非法日期问题还是会报错;后者是直接出结果,不会过多考虑数据是否正确的问题。
而至于如何让AI文生SQL按你的实际场景生成想要的SQL,本质就是通过提示词工程。好的文生SQL软件会提供非常灵活的各种配置选项,来应对适配各类复杂场景,最终在相互配合下就可以做到相对精确的影响到LLM的处理行为逻辑,从而生成符合实际用户需求的SQL并执行得到预期结果。
另外通过这个典型场景也可以切身领悟到,就算AI再强大,但对那些让人类实际工作都踩过坑的事情,对于AI来说同样是挑战,你不跟他通过"提示词"交流说清楚具体是个啥情况,对于特定场景下那些稀奇古怪的弯弯绕它一样无法理解。
所以呢,AI虽然厉害,但也不必迷信AI,有了它,工作效率的确是大大提升了,但我们依然还是要面临处理很多意料之外的事情,这其实也是我们人类身处于这个丰富多彩的现实世界的魅力所在。