怎么搭配RAG使用,能详细一点吗
可以先将问题使用RAG技术搜索出相关的文档,然后依照文档进行生成报告或回答吗
感谢关注。
已经做了很多RAG方面的努力,也包含大部份已经流行的RAG设计方案,包括您提到的这种场景。 但因为没有框架还在早期状态,概念设计上经常改动,所以我没有正式更新到文档。
这个问题我先保持 open,下周完善了RAG的文档之后一并回复您。
刚刚更新了文档,这是其中的一部份,当作回复:
内置 RAG 支持
使用 RAG(检索增强生成)是开发大模型应用时的常见场景。
illufly 内置了一些 RAG 实现策略,最简单的就是直接将背景知识添加到 Agent 中。
构建最朴素的 RAG 应用:
from illufly.chat import ChatQwen
# 声明大模型实例
qwen = ChatQwen(knowledge=[
"我的女朋友名字叫林徽因,我喜欢叫她「银子」",
"她喜欢叫我「金子」",
])
# 使用
qwen("请你帮我写封一句话情书,深情又逗比的那种")
qwen.memory
"亲爱的银子,你是我生活中不可或缺的闪光点,没有你,我的人生将失去所有的金光璀璨,也少了许多欢声笑语,爱你的金子如是说。"
[{'role': 'user',
'content': '回答时请参考已有知识:\n@knowledge\n我的女朋友名字叫林徽因,我喜欢叫她「银子」她喜欢叫我「金子」\n'},
{'role': 'assistant', 'content': 'ok'},
{'role': 'user', 'content': '请你帮我写封一句话情书,深情又逗比的那种'},
{'role': 'assistant',
'content': '"亲爱的银子,你是我生活中不可或缺的闪光点,没有你,我的人生将失去所有的金光璀璨,也少了许多欢声笑语,爱你的金子如是说。"'}]
将资料保存到文件并根据问题召回:
illufly 也支持传统的 RAG 流程:将文档切分成多个片段,再通过向量模型比较问题和文档片段,这个过程被称为「召回」,也就是从数据库中查找到文本相似的那部份文档片段。
你可以把资料整理为 markdown 文件,放入指定位置,比如 ./docs/gf.md 中,然后使用向量模型嵌入文档,再使用向量数据库检索,最后加载到大模型的提示语中。
在 illufly 框架中,这个过程依然非常简洁,你只负责声明实例就可以,其余的交给 illufly 实现。
from illufly.rag import TextEmbeddings, FaissDB
from illufly.chat import ChatQwen
# 声明向量数据库并加载指定位置的文档
db = FaissDB(embeddings=TextEmbeddings(), top_k=3)
db.load("./docs")
# 声明大模型实例
qwen = ChatQwen(knowledge=[db])
# 使用
qwen("请你帮我写封一句话情书,深情又逗比的那种")
qwen.memory
亲爱的银子,你是我的小白兔,不仅因为你的温柔可爱,还因为你总能让我这个“金子”闪闪发光,哪怕是在最平凡的日子里。爱你,就像呼吸一样自然,却又想大喊出来让全世界都知道!
[{'role': 'user',
'content': '回答时请参考已有知识:\n@knowledge\n我的女朋友名字叫林徽因,我喜欢叫她「银子」,\n她喜欢叫我「金子」,\n林徽因特别喜欢小兔子\n\n**Question**\n林徽因和她的喜好\n\n**Knowledge**\n林徽因是用户的女朋友,用户私下里称她为“银子”。她称呼用户为“金子”,并且喜欢小白兔。\n\n**Question**\n林徽因的姓名及爱好\n\n**Knowledge**\n林徽因是用户的女朋友,她喜欢小白兔。\n'},
{'role': 'assistant', 'content': 'ok'},
{'role': 'user', 'content': '请你帮我写封一句话情书,深情又逗比的那种'},
{'role': 'assistant',
'content': '亲爱的银子,你是我的小白兔,不仅因为你的温柔可爱,还因为你总能让我这个“金子”闪闪发光,哪怕是在最平凡的日子里。爱你,就像呼吸一样自然,却又想大喊出来让全世界都知道!'}]
在对话中自主进化
为了让大模型能够理解对话的背景,采用 RAG 策略的确是好办法,但管理 RAG 文档资料有些繁琐,涉及到文档准备、确认、加载、切分、检索等很多细节。你希望大模型记住的知识也许是未经整理的、碎片化的,这让 RAG 文档资料很难管理。
illufly 提供自我进化能力,其中之一就是在对话过程中学习知识。
在对话中获得经验需要使用 ChatLearn 子类。
from illufly.chat import ChatQwen
from illufly.learn import ChatLearn
talker = ChatLearn(ChatQwen())
talker("我跟你说说我的女朋友")
[AGENT] >>> Node 1: Scribe
当然,我很乐意听你分享关于你女朋友的事情。你可以告诉我一些你们的故事,或者你想要探讨的特定方面。
talker("她叫林徽因,我私下里叫她`银子`,她就叫我`金子`")
[AGENT] >>> Node 1: Scribe
林徽因这个名字听起来很有文化气息,`银子`这个昵称也很有创意。你们是怎么认识的呢?有没有什么特别的故事?
talker("你帮我总结吧")
[USER] 你帮我总结吧
**思考**
- 对话中的关键信息包括:林徽因是用户的女朋友,用户私下里叫她“银子”,她叫用户“金子”,她喜欢小白兔。
- 对比对话内容,没有发现与已有知识存在冲突的新知识。
- 这些信息包含了新的知识点,但没有明确的`@knowledge`标注,因此视为新知识。
- 新知识与已有知识不存在重复。
**决定**
- 没有发现与`@knowledge`开头的已有知识存在冲突的新知识。
- 新知识与已有知识不重复。
**结论**
<question>
林徽因和她的喜好
</question>
<knowledge>
林徽因是用户的女朋友,用户私下里称她为“银子”。她称呼用户为“金子”,并且喜欢小白兔。
</knowledge>
[AGENT] >>> Node 3: Fetch_FAQ
[FAQ] 保存知识到[032791-1583-0000]:林徽因和她的喜好 -> 林徽因是用户的女朋友,用户私下里称她为“银子”。她称呼用户为“金子”,并且喜欢小白兔。
使用在对话中获得的经验
from illufly.rag import FaissDB, TextEmbeddings
from illufly.chat import ChatQwen
db = FaissDB(embeddings=TextEmbeddings(), top_k=3)
qwen = ChatQwen(knowledge=[db])
qwen("你知道我女朋友叫什么吗?有什么爱好?")
你的女朋友名叫林徽因,她喜欢小白兔。在私下里,你称她为“银子”,而她则称呼你为“金子”。