找回密码
 立即注册
首页 业界区 业界 Oracle AI:使用SQL来实现融合检索和整个RAG流程 ...

Oracle AI:使用SQL来实现融合检索和整个RAG流程

缢闸 6 天前
RAG 都不用写程序了吗?
是的,Oracle 总是习惯把简单留给用户,目前已支持通过一条 SQL 就能实现基础的 RAG 需求。
本文就来深入剖析下这样的一条SQL,并展现下输出效果。
01|实现逻辑

这里先引用最近 AI 大会上的一张图,非常清晰地展现了实现逻辑:
1.jpeg

从图片中可以看到,真的是就用这么一条SQL完成了RAG的整个流程。
02|技术拆解

虽然对于暴露给用户只有这么一条SQL,但实际上这条SQL里面调用了很多库内的函数,用户自然可以不关注,但作为技术从业者还是需要理解一下的。
① 用户问题向量化

将用户输入的问题向量化,这里直接调用 vector_embedding() 函数。
Embedding模型可以直接使用已经导入Oracle库内的onnx格式模型,比如我这里使用的是 BGE_BASE,SQL 就类似这样:
  1. select vector_embedding(BGE_BASE USING :question_text AS DATA)
复制代码
② 执行向量搜索

vector_distance() 函数
查询对应的库内文本信息,依据库内文本信息的向量 和 用户问题的向量 比较结果,选TOP N的记录出来。
实践动手时就会发现,图中有个细节是不对的,估计是工作人员的笔误。
具体在 vector_distance() 函数里面多写了 SELECT,实际应该去掉,正确SQL类似如下:
  1. select content from t_history
  2.     order by vector_distance(v, vector_embedding(BGE_BASE USING :question_text AS DATA))
  3.     FETCH APPROX FIRST 5 ROWS ONLY
复制代码
注:

  • 笔者这里是Oracle 23.7的测试环境,以笔者这个版本的实际测试的结果为准
  • 本文所有测试都改成笔者实际测试使用的一张表t_history
③ 组合LLM提示词

将自定义的提示词 + 用户的问题 + TOP N的记录作为上下文 组合成整体的LLM提示词。
  1. WITH TOP5 AS (select content from t_history where type = 'English'
  2.     order by vector_distance(v, vector_embedding(BGE_BASE USING :question_text AS DATA))
  3.     FETCH APPROX FIRST 5 ROWS ONLY),
  4. LLM_PROMPT AS (
  5.     SELECT (
  6.         'Answer this question using the following context,' || CHR(10) || CHR(10) ||
  7.         'QUESTION: ' || :question_text || CHR(10) || CHR(10) ||
  8.         'CONTEXT: ' || CHR(10) || CHR(10) ||
  9.         LISTAGG(content, CHR(10))
  10.     ) AS prompt_text
  11.     FROM TOP5
  12. )
复制代码
注:

  • 这里使用 || 巧妙的拼接了所有需要的内容
  • 使用 LISTAGG(content, CHR(10)) 函数将多行 content 数据合并成单个字符串
  • 谓词条件 type = 'English' 代表只关注 t_history 表中这个类型相关的内容
④ 获得LLM回复结果

最终调用 dbms_vector_chain.utl_to_generate_text() 获取LLM的最终回答。
理想情况下,只需要在上一步的SQL基础上,再加一段:
  1. select dbms_vector_chain.utl_to_generate_text(prompt_text, json(:LLM_paras)) as answer
  2. from LLM_PROMPT;
复制代码
不过研究发现,这里的 dbms_vector_chain 是一个包,utl_to_generate_text 是包中的一个函数,遗憾的是目前还不能支持国内模型API直接调用。
03|照猫画虎

理解了上面的技术,我们只需要解决一个国内模型API的调用问题,就可以解决很多国内的RAG需求了。
所以这里先尝试自定义一个函数来实现:CHAT_LLM(),功能很简单就是实现调用deepseek官方的api来交互。
下面我们就模拟一个用户需求:
首先,用户已经通过系统记录了日常工作、学习内容;
现在要求实现以下需求:

  • 支持用户输入自然语言描述问题
  • 我们根据问题向量检索到最相关的前5条记录内容,并支持过滤指定分类
  • 程序自动构造组合的提示词
  • 用最终的提示词请求LLM获取最终结果
本质还是直接模仿开头的那张片子来具体实现,只需要:
最终SQL如下:
  1. WITH TOP5 AS (select content from t_history where type = 'English'
  2.     order by vector_distance(v, vector_embedding(BGE_BASE USING :question_text AS DATA))
  3.     FETCH APPROX FIRST 5 ROWS ONLY),
  4. LLM_PROMPT AS (
  5.     SELECT (
  6.         'Answer this question using the following context,' || CHR(10) || CHR(10) ||
  7.         'QUESTION: ' || :question_text || CHR(10) || CHR(10) ||
  8.         'CONTEXT: ' || CHR(10) || CHR(10) ||
  9.         LISTAGG(content, CHR(10))
  10.     ) AS prompt_text
  11.     FROM TOP5
  12. )select CHAT_LLM(prompt_text) as Answer from LLM_PROMPT;
复制代码
可以先在SQL命令行下测试效果:
  1. -- 首先定义变量
  2. VARIABLE question_text VARCHAR2(100);
  3. -- 给变量赋值
  4. BEGIN
  5.   :question_text := '总结有关日常对话的英文对话';
  6. END;
  7. /
  8. -- 完整的显示配置(新增SET ESCAPE OFF)
  9. SET ESCAPE OFF
  10. SET LINESIZE 32767
  11. SET PAGESIZE 0
复制代码
04|最终效果

因为TOP5格式还有点显示问题在调试ing,所以这里先用TOP1的内容输出效果展示下:
2.jpeg

实话讲思路虽然很简单,但是自定义的函数对模型返回的格式处理还是相当头疼,即便有AI辅助也是被折腾的焦头烂额。
关于自定义的CHAT_LLM函数内容本文就先不贴了,因为调试过程中发现功能实现简单,但是细节处理还是需要太多考量的,建议等官方函数支持国内LLM,或者未来测试相对稳定了笔者再跟大家分享后续吧。

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册