Qwen-Agent
一个智能体用于理解包含百万字词的文档,使用了支持8k上下文的模型,但效果超过RAG和长序列原生模型。智能体包含三个复杂度级别,每一层都建立在前一层的基础上。
官方介绍:https://qwenlm.github.io/zh/blog/qwen-agent-2405/
代码库:https://github.com/QwenLM/Qwen-Agent
Qwen-Agent博客写的长上下文共有三种方案:
- RAG检索
- 分块阅读
- 逐步推理
目前官方开源仓库只实现了RAG检索和分块阅读,逐步推理这里核心问题是怎么认定用户输入需要拆解,如何拆解的问题。
RAG检索简单的使用用户问题进行分词,利用BM25去做评分。优点是速度快。缺点也很明显:,虽然在调用RAG之前利用模型把用户输入转换成了中英文版本的关键词,但简单拆分关键词的方式并不具备信息提取的能力。如果你需要对一个代码仓库问一些问题,用户输入通常是对代码逻辑的总结,很难在代码关键词中对其有所匹配。
分块阅读利用了LLM对chunk进行了理解,来判断与用户的输入是否匹配,并提取chunk中与用户输入匹配的关键句子,再将它与用户输入一起进行分词,进行BM25比较,此种方案可以较好地提取出相关片段。由于文档中的每个chunk都需要去调用模型,对模型资源消耗较大,速度也会慢。
级别一:检索
处理100万字上下文的一种朴素方法是简单采用增强检索生成(RAG)。 RAG将上下文分割成较短的块,每块不超过512个字,然后仅保留最相关的块在8k字的上下文中。 挑战在于如何精准定位最相关的块。经过多次尝试,我们提出了一种基于关键词的解决方案:
- 步骤1:指导聊天模型将用户查询中的指令信息与非指令信息分开。例如,将用户查询
"回答时请用2000字详尽阐述,我的问题是,自行车是什么时候发明的?请用英文回复。"
转化为{"信息": ["自行车是什么时候发明的"], "指令": ["回答时用2000字", "尽量详尽", "用英文回复"]}
。 - 步骤2:要求聊天模型从查询的信息部分推导出多语言关键词。例如,短语
"自行车是什么时候发明的"
会转换为{"关键词_英文": ["bicycles", "invented", "when"], "关键词_中文": ["自行车", "发明", "时间"]}
。 - 步骤3:运用BM25这一传统的基于关键词的检索方法,找出与提取关键词最相关的块。
用户上传一个文件,输入问题
入口:agent.run
[{'content': [{'text': '什么是边际效应'}, {'file': 'C:\\Users\\xxx\\AppData\\Local\\Temp\\gradio\\d2681ab00e4fd866a28ee9d03db613e30e800773\\薛兆丰经济学讲义xg.pdf'}], 'name': 'user', 'role': 'user'}]
构建知识库,组装prompt
入口:assistant._prepend_knowledge_prompt / memory._run
构建知识库过程中查询语句拆分
、生成关键词
等步骤需要利用LLM,代码中准备了中英文两份prompt,可以由前端选择一种语言,或者根据用户输入的问题中是否包含中文来判断。
- 优化用户提问内容,提取关键词
使用的是SplitQueryThenGenKeyword策略,先将用户输入的内容分解成内容和指令两个部分,接着生成内容的中英文关键字。
- split_query._run:
这一步可以考虑用大点的模型来做,少量样本也需要丰富下
请提取问题中的可以帮助检索的重点信息片段和任务描述,以JSON的格式给出:{{"information": ["重点信息片段1", "重点信息片段2"], "instruction": ["任务描述片段1", "任务描述片段2"]}}。
如果是提问,则默认任务描述为:回答问题
Question: MMDET.UTILS是什么
Result: {{"information": ["MMDET.UTILS是什么"], "instruction": ["回答问题"]}}
Observation: ...
Question: 总结
Result: {{"information": [], "instruction": ["总结"]}}
Observation: ...
Question: 要非常详细描述2.1 DATA,2.2 TOKENIZATION,2.3 ARCHITECTURE。另外你能把这篇论文的方法融合进去吗
Result: {{"information": ["2.1 DATA,2.2 TOKENIZATION,2.3 ARCHITECTURE"], "instruction": ["要非常详细描述", "另外你能把这篇论文的方法融合进去吗"]}}
Observation: ...
Question: 帮我统计不同会员等级的业绩
Result: {{"information": ["会员等级的业绩"], "instruction": ["帮我统计"]}}
Observation: ...
Question: 什么是边际效应
Result:
这里调用模型的代码处理应该是有问题,qwen-agent代码返回:'{"information": ["什么是边际效应'
,实际模型返回:{{"information": ["边际效应是什么"], "instruction": ["回答问题"]}}
。
- gen_keyword._run
用第一步修改后的query去提取关键词。
请提取问题中的关键词,需要中英文均有,可以适量补充不在问题中但相关的关键词。关键词尽量切分为动词、名词、或形容词等单独的词,不要长词组(目的是更好的匹配检索到语义相关但表述不同的相关资料)。关键词以JSON的格式给出,比如{{"keywords_zh": ["关键词1", "关键词2"], "keywords_en": ["keyword 1", "keyword 2"]}}
Question: 这篇文章的作者是谁?
Keywords: {{"keywords_zh": ["作者"], "keywords_en": ["author"]}}
Observation: ...
Question: 解释下图一
Keywords: {{"keywords_zh": ["图一", "图 1"], "keywords_en": ["Figure 1"]}}
Observation: ...
Question: 核心公式
Keywords: {{"keywords_zh": ["核心公式", "公式"], "keywords_en": ["core formula", "formula", "equation"]}}
Observation: ...
Question: 什么是边际效应
Keywords:
返回:
{'content': '{"keywords_zh": ["边际效应", "边际", "效应"], "keywords_en": ["marginal effect", "marginal", "effect"]}', 'role': 'assistant'}
- 调用
retrieval
工具
入口:agent._call_tool / retrieval.call
将输入的文件进行分块(parser_page_size默认是500),然后利用混合检索,查找出一部分与关键词最相关的分页(max_ref_token默认值4000)
工具在qwen_agent.tools下,使用@register_tool注解去注册工具,Memory类构造器给自己加了两个tool: retrieval, doc_parser
组装的quey: ‘{“keywords_zh”: [“边际效应”, “边际”, “效应”], “keywords_en”: [“marginal effect”, “marginal”, “effect”], “text”: “什么是边际效应”}’
工具利用tools.storage在workspace/tools/<tool_name>
存储处理完的内容。
-
调用doc_parser.call解析文件
解析完成后会存储到workspace/tools/doc_parser
下,下次就直接从文件读取返回了。- 使用simple_doc_parser.call,解析文档的内容并计算token,存到`workspace/tools/simple_doc_parser,pdf解析目前没有用ocr,直接把图片忽略掉了。目前解析比较慢,后续看看是不是要改成多线程解析。
- 如果文档总token小于max_ref_token,则将整个文档返回。否则则需要对文档进行分块操作。
- 遍历Page与Page中的content,加入到chunk中。每个chunk会以[page: x]开头
- 当新的content加入后大于chunk size时,则会开启一个新的chunk,并将旧chunk中最后一页的内容放到新的chunk中,以保持语义的连续性。
- 如果一页的内容超过了chunk size,则用句号对语句进行拆分sentence,overlap从后往前取能取的最大部分(固定的150),接着拼当前页剩下的内容。
-
调用hibird_search.search进行混合检索
入口为hybrid_search.sort_by_scores
,使用settings.DEFAULT_RAG_SEARCHERS,目前默认:[‘keyword_search’, ‘front_page_search’],对query进行评分并重排序。- 提取关键词,除了模型提取的关键词外,还会将处理后的query进行分词,最后关键词为:[‘边际效应’, ‘边际’, ‘效应’, ‘marginal effect’, ‘margin’, ‘effect’, ‘边际效应’]
- 使用keyword_search对chunk内容进行分词(会过滤一些词,像我,你,怎么这,那个之类的),再利用bm25计算评分后,进行排序。
- 使用front_page_search提取固定内容的chunk(目前取的是前2页),分支设置成无穷大。
- 将多个搜索者的score求和后重排序,取topK,填充到max_ref_token(默认4000)后结束。
- 格式化知识库
## 来自 {source} 的内容:
```
{content}
```
调用模型
[{'role': 'system', 'content': '# 知识库\n\n## 来自 [文件](薛兆丰经济学讲义xg.pdf) 的内容:\n\n```\n[page: 1]\n[page: 2]\n薛兆丰经济学讲义\n\n薛兆丰 著\n 中信出版集团\n\n[page: 3]\n版权信息\nC O P Y R I G H T\n\n书名:薛兆丰经济学讲义\n 作者:薛兆丰\n\n出版社:中信出版社·华夏盛轩\n\n出版时间:2018.6\n\nISBN:978-7-5086-8551-9\n\n本书由北京华夏盛轩图书有限公司授权得到APP电子版制作与发行\n\n版权所有·侵权必究\n\n[page: 4]\n我的愿望是,\n 每个中国人都能体验经济学带来的乐趣,\n 具备经济学思维。\n\n【如果您想加入读书群和全国书友交流,加V信:\n209993658】\n关注微信公众号:njdy668(名称:奥丁弥米尔)\n免费领取16本心里学系列,10本思维系列的电子书,\n15本沟通演讲口才系列\n20本股票金融,16本纯英文系列,创业,网络,文学,哲学系以及纯\n英文系列等都可以在公众号上寻找。\n公众号“书单”书籍都可以免费下载。\n公众号经常推荐书籍!\n我收藏了10万本以上的电子书,需要任何书都可以这公众号后台留\n言!\n看到第一时间必回! \n奥丁弥米尔:一个提供各种免费电子版书籍的公众号,\n提供的书都绝对当得起你书架上的一席之地!\n总有些书是你一生中不想错过的!\n【更多新书公众号首发:njdy668 (名称:奥丁弥米尔)】\n\n[page: 5]\n前言\n每个人的经济学\n\n从2010年起,我每年都在北京大学讲授《经济学原理》,学生常常\n\n告诉我:“没想到经济学是这样的!”“经济学原来这么有趣!”“其实我\n\n\n...\n\n[page: 5]\n前言\n每个人的经济学\n\n从2010年起,我每年都在北京大学讲授《经济学原理》,学生常常\n\n告诉我:“没想到经济学是这样的!”“经济学原来这么有趣!”“其实我\n\n上过很多次经济学课,但这次很不一样。”\n 我知道他们不是客气,我自己就是在亲身经历过经济学带来的震撼\n 和快感后,才渴望把它再传递出去的。\n 经济学之所以有如此魅力,原因在于它是以研究陌生人的互动规律\n 为己任的学问。人的认知和判断,至今主要还是靠直觉和短距离的人际\n 关系来驱动,但人的身体和际遇,却早已置于大规模的陌生人的精妙协\n 作之中。\n 这两者的巨大反差,使得很多聪明绝顶的社会达人,对复杂社会关\n 系和经济运行规律的理解,仍然停留在幼稚的阶段。一个人在自己的专\n 业领域可以非常成功,但要理解现代社会的运行机制,还需要学习另外\n 一种智慧。\n\n美国总统特朗普为了振兴美国经济,提出了“买美国货、雇美国\n\n人”的口号,但他自己却把工厂设在中国,连竞选宣传品都是在中国生\n\n产的。当记者问他为什么如此分裂时,他诚实地回答:“我可是个商\n\n人!”\n\n[page: 6]\n是的,他是一位极其成功的商人,但在领悟“买美国货、雇美国\n\n\n...\n\n[page: 138]\n多少劳动,都是没有价值的。显然,主观价值论能够更好地指导生产,\n 减少浪费。\n 主观价值论由于有更好的解释力,能更好地指导生产,所以得到了\n\n许多经济学家的大力支持。这些经济学家往往都声称自己是“个人主义\n\n的主观价值论者”。\n 思考题\n 有哪件物品,市场上的价格很低,而你对它的个人估值却是非常高\n 的?\n\n[page: 139]\n第027讲 | 边际革命\n\n需求定律中,还涉及一个非常重要的概念——边际。边际这个概念\n\n有多重要?过去近20年的时间里,我一直给报纸杂志写经济学专栏,为\n 了写得清楚明了,我尽可能避开经济学术语,避开了其实也还能把话说\n\n清楚,但有一个经济学术语,怎么避都避不开,这个术语就是“边际”。\n 实际上,整个经济学的思维都是关于边际的。经济学早期的时候是\n 一种哲学的思辨,而今天是一种科学的范式。这两者之间转变的一个重\n 要节点,就是边际概念的产生。\n 引入边际概念的是奥地利学派,这个贡献太大了,以至于没有人再\n 提起这是奥地利学派的贡献,因为大家都觉得现代经济学当然是建立在\n 边际的概念之上的。\n 在前面提到科斯定律时我说过,不是因为科斯聪明,而是因为我们\n 糊涂,因为科斯思想很重要的渊源是他在读大学本科时看过的一本经济\n\n学入门教科书——《政治经济学常识》(The Common Sense of Political\n\nEconomy , 1910),而科斯的贡献其实也没有超出这本书中讲解的边际\n 概念的范围。\n 在现实生活中,边际的概念有着广泛的应用。\n 钻石与水的故事\n\n[page: 140]\n亚当·斯密曾经提出一个经典的问题:“水对于人的生命来说是非常\n 重要的,但是水的价格却非常低。钻石对人的生命来说,一点用处都没\n\n有,但是钻石却非常贵,这是为什么?”\n 是钻石给人带来的幸福大,还是水给人带来的幸福大?要回答这个\n\n问题,就必须用到“边际”的概念。\n 何谓边际\n\n\n...\n\n[page: 140]\n亚当·斯密曾经提出一个经典的问题:“水对于人的生命来说是非常\n 重要的,但是水的价格却非常低。钻石对人的生命来说,一点用处都没\n\n有,但是钻石却非常贵,这是为什么?”\n 是钻石给人带来的幸福大,还是水给人带来的幸福大?要回答这个\n\n问题,就必须用到“边际”的概念。\n 何谓边际\n\n那么到底什么叫边际?边际就是“新增”带来的“新增”。\n 例如,边际成本就是每新增一个单位产品所需要付出的新增成本;\n 边际收入是每多卖一个产品能够带来的新增收入;边际产量是每新增一\n 份投入所带来的新增产量;边际效用是每消耗一个单位的商品所能带来\n 的新增享受。\n\n“新增”带来的“新增”,就叫边际。\n\n明白了“边际”的概念,接下来就可以理解经济学当中最重要的原理\n\n——边际效用递减定律了。这个定律说的是,在单位时间内,随着人们\n 消耗的某种商品的数量不断增加,消耗这种商品所能带来的新增享受迟\n 早都会下降。\n 讲个故事你就明白了。美国的罗斯福总统,是美国历史上唯一一位\n\n连任四届的总统。当他第四次当选总统以后,有位记者就问他:“第四\n\n次当选总统是什么感受?”罗斯福没有当场回答他的问题,而是请这位\n 记者吃三明治。\n\n[page: 141]\n吃第一块三明治的时候,这位记者觉得这是总统请客,无上的荣\n 耀,吃得很舒服;吃第二块的时候就感觉平平了;吃第三块的时候,已\n 经很难下咽了。当罗斯福把第四块三明治放到这位记者面前时,罗斯福\n\n说:“你把这第四块三明治吃下去,你刚才问我的问题,我就不用回答\n\n\n...\n\n[page: 141]\n吃第一块三明治的时候,这位记者觉得这是总统请客,无上的荣\n 耀,吃得很舒服;吃第二块的时候就感觉平平了;吃第三块的时候,已\n 经很难下咽了。当罗斯福把第四块三明治放到这位记者面前时,罗斯福\n\n说:“你把这第四块三明治吃下去,你刚才问我的问题,我就不用回答\n\n了,你自己会有亲身感受。”\n 这就是边际效用递减的规律,它指的是每多消耗一个单位的商品,\n 所能带来的新增的享受在递减。例如我们吃东西的时候,食物带给我们\n 的边际效用,通常都是递减的。\n 边际效用与边际成本趋同\n 明白了边际效用递减定律,我们就能进一步理解,为什么通过追求\n 边际效用和边际成本的平衡,就能够使得总收益最大化了。\n 首先,边际效用和边际成本是一组成对的概念。例如,我们吃馒\n 头,馒头带给我们的效用在递减,但与此同时,我们每吃一块馒头,都\n 要付出一定的成本,要为馒头付钱。由于边际效用是在递减的,所以总\n 会有这么一个时刻,多吃一口馒头所带来的边际效用,会低于我们为吃\n 这一口馒头所付的边际成本。当这一刻来临时,继续吃馒头就得不偿失\n 了。这时我们就会停止吃馒头。也就是说,这时候我们只有把钱用到别\n 的地方去,才能获得比吃馒头更高的边际效用。\n\n一般来说,当我们把口袋里有限的钱,按“边际效用等于边际成\n\n本”的原则,分别用来购买不同的产品时,我们从这些不同的产品那里\n 获得的总收益,就会达到最大。\n\n[page: 142]\n到此,我们就已掌握了足够的思想工具,来回答斯密提出的问题\n\n——“到底是钻石给人带来的幸福大,还是水给人带来的幸福大”。\n 斯密说得没错,水才是人们真正的必需品。当我们花钱的时候,我\n 们花的第一个铜板是用来买水的,因为它是必需品;第二个铜板,也是\n\n\n...\n\n[page: 142]\n到此,我们就已掌握了足够的思想工具,来回答斯密提出的问题\n\n——“到底是钻石给人带来的幸福大,还是水给人带来的幸福大”。\n 斯密说得没错,水才是人们真正的必需品。当我们花钱的时候,我\n 们花的第一个铜板是用来买水的,因为它是必需品;第二个铜板,也是\n\n买水;第三个、第四个,还是买水……当第一千个铜板还是用来买水的\n 时候,这时水带给我们的边际效用已经相当低了。这时候,我们会动一\n 个念头:第一千零一个铜板,能不能买一点点钻石?\n 那一个铜板买来的一点点钻石,能够很好地满足我们的虚荣心。于\n 是我们就把第一千零一个铜板用来买钻石,因为用这个铜板买来的钻\n 石,比用它买来的水效用更大。也就是说,在边际上,水和钻石给人带\n 来的幸福是一样的。\n 当我们一个一个铜板分别在水和钻石上分摊的时候,其实是在遵循\n 一个原则,那就是确保水带给我们的边际效用跟钻石带来的边际效用相\n 等。\n 每个人都应当是边际平衡的高手\n 资源是有限的,如何最有效地利用有限的资源,使其获得\n\n...\n\n[page: 179]\n(The Use of Knowledge in Society, 1945)的文章。\n\n这篇文章有多重要?2011年《美国经济评论》庆祝创刊100周年,\n 请了世界上顶级的经济学家,在这本发表了无数文章的期刊里挑选出最\n\n经典的20篇论文,而这篇文章就是其中之一。\n 重温边际平衡的概念\n 在这篇文章里,哈耶克首先说,经济体系要解决的问题,不是边际\n 平衡的问题。我们前面讲过边际的概念,也讲过边际平衡的概念。边际\n 就是新增带来的新增,比如多花一元钱多带来的收益。\n 边际平衡说的是,我们手上的钱有限,每一元钱应该花在给我们带\n 来收益最大的那件商品上。钱一点点花出去,最后我们在每一种商品上\n 得到的边际效用就是平衡的。这样,我们手上有限的钱,买到的商品、\n 给我们带来的效用,就能够达到最大化。这就是边际平衡的概念。\n 经济学教科书一直关心的,往往是如何平衡边际的问题,也就是怎\n 么才能让我们每项活动的边际成本,跟它的边际收益相等的问题。如果\n 能做到边际成本等于边际收益,那么个人的总收益就能够达到最大。\n\n[page: 180]\n经济体系要解决的首要难题\n 但是哈耶克却力排众议,开门见山就说,经济体系要解决的问题,\n 不是边际平衡的问题。他说边际平衡是小问题,经济体系要解决的是应\n 付变化的问题。\n 人类社会跟自然界一个根本的区别是:自然界是循环往复的,而人\n 类社会每天都在接受各种各样的冲击。哈耶克说,如果人类社会仅仅是\n 要解决边际平衡问题的话,那实施什么样的社会制度,最终的结果都是\n 一样的。计划经济也可以,市场经济也可以。因为我们可以从不断试错\n 的过程中,发现我们应该如何计划未来的生产。\n 如果这个世界每天都像太阳系一样周而复始,人口是不变的,需求\n\n\n...\n\n[page: 464]\n思考题\n 一位女病人在长期接受了医院的输血以后患上了艾滋病。当然根据\n 汉德公式,我们会想医院应该负有责任。但是问题在于,这个案件发生在1987年,那一年人类才刚刚发现有\n 艾滋病这回事。在这以前整个医学界是不知道有艾滋病存在的,在这种\n 情况下,医院或者血液的提供者是否应该承担责任呢?为什么?\n第089讲 | 监管要看边际效应\n\n我们上一讲介绍的汉德公式中有三个变量:避免意外的成本、产生\n 意外的概率、意外所产生的损失。如果避免意外所付的成本低于意外发\n 生的概率乘以意外发生以后产生的损失(预计的损失),那么具有避免\n 意外义务的人就应该承担责任。\n 在实际的侵权法当中,责任的分摊不是黑白分明,而是有灰色过渡\n 带的。针对责任的强弱不同,还存在一些典型的不同比例的责任分摊类\n 型,包括疏忽责任、严格责任、连带责任等。\n\n生产商的“严格责任”\n\n1944年,美国发生过一宗跟可口可乐相关的案子(Escola v.Coca\n\nCola Bottling co. Fresno , 1944)。可口可乐公司给一家餐厅送了几箱玻\n\n璃瓶装的可口可乐,这家餐厅把这些可口可乐放在炎热的室外足足36个\n 小时。当餐厅的一位女服务员把这些可口可乐放进冰箱时,其中一瓶发\n 生了爆炸,女服务员被炸伤。\n 女服务员要求可口可乐公司赔偿,但根据当时的法律,原告必须提\n 出证据证明可口可乐公司在生产过程中存在疏忽。在一审时,陪审团一\n\n致认为,可口可乐公司有疏忽。但可口可乐公司不服,它说:“我们的\n 生产过程一直是这样,我们生产和送货都有严格的程序,没有证据证明\n 我们存在疏忽。而且这几箱可口可乐已经交付给客人,在客人那里放了\n\n\n...\n\n[page: 555]\n另外一批经济学家认为,通货膨胀的原因只有一个,那就是钱发多\n 了,解决的方案也只有一个,很简单,就是少印钱,严格控制货币发行\n 量。思考题\n 通货膨胀只不过是货币数量不断地增加而已,而货币本身只不过是\n 一个记账的符号,如果每个人的工资、收入、支出都加一个零的话,那\n 对真实生活会有影响吗?为什么?\n第106讲 | 通货膨胀的过程\n\n通货膨胀对我们的真实生活有很大的影响,这种影响表现在多个方\n 面。\n 通货膨胀的坎蒂隆效应\n 如果政府每多印一批钞票,都用直升机在整个国家平均撒下去,每\n 个人得到的货币增量都一样,而且所有商品和服务的标价也同时灵敏地\n 做出调整,那么货币增发对我们的真实生活不会有影响。\n 但现实生活中新增的货币总是通过某个出口逐渐流向社会的,这个\n 流动的过程需要一段时间,货币对整个经济生活的影响是不均匀的,这\n 时它对人们的决策和行动就会产生影响。\n 这种货币要经过一段时间才逐渐在整个社会里摊匀的现象被称为坎\n\n蒂隆效应(Cantillon Effect)。经济学家哈耶克曾经这样描述过,他说\n 这种效应更像我们把一种黏性液体,例如蜂蜜,倒入一个容器时发生的\n 现象:\n 这个液体会有扩散到整个瓶底表面的趋势,但是液体流动、扩散会\n 有一个过程,刚开始时,蜂蜜倒下去会有一个小小的隆起,而这个隆起\n 会慢慢地向外扩散,即使我们不再往里倒更多的蜂蜜,要达到完全持平\n 的表面仍然需要一段时间。\n\n\n...\n\n[page: 642]\n到底一个市场是竞争的还是垄断的,不\n 能简单地数那些市场上已经出现的正在经营的竞争者的数量,而应该去\n 看那些潜在的竞争者,看他们进入市场到底会不会遇到人为设置的行政\n 障碍。只要存在这个障碍,那么不论市场上现有的竞争者有多少,这都\n 是一个封闭的市场,一个垄断的市场,一个缺乏竞争的市场;如果没有\n这样的限制,人们可以随意进出,那不管看得见的竞争者数目是多少,\n 它都是一个充分竞争的市场。\n 我们要看到潜在的供给和潜在的需求。供应者和需求者之间没有本\n 质的区别,我们要看到供应者和需求者这两种角色会随着价格的变化而\n 转化。\n 我们还要看到私人的支出和政府支出之间的替代关系。政府支出会\n 产生乘数的效应,能够刺激经济的发展。我们会看到官方举办的大型体\n 育活动对旅游业的刺激,会看到大型基建工程对原材料生产的刺激,也\n 能看到大规模的再就业工程对人们生活的改善。但同样重要的是,我们\n 要问政府花的这些钱、用的这些资金、调动的这些资源,如果落到私人\n 的手上,让私人来使用的话,是不是也能够产生乘数效应?会不会产生\n 更好的、更高的乘数效应?\n\n能分辨原因和结果的才是地道的\n\n在经济学里有一个重要的分支发展得非常蓬勃,叫计量经济学,它\n 专门研究不同变量之间的关系。而在这些关系当中,很重要的一种叫相\n 关性关系。我们通过大数据的分析方法,只要发现一种情况的发生伴随\n 着另外一种情况的发生,我们就说它们之间有相关性,而有相关性的事\n 件之间可能同时也存在着因果性。\n 假设男艺术家大多留着长头发,这时候长头发和艺术气质之间就存\n 在着相关性。但这相关性并不意味着因果性,你忽然想当艺术家了,把\n\n```'}, {'role': 'user', 'content': [{'text': '什么是边际效应'}, {'file': 'C:\\Users\\liuzhenghua-jk\\AppData\\Local\\Temp\\gradio\\e755ac6f4c3305c85879ce1f44fa9ea84791d895\\薛兆丰经济学讲义xg.pdf'}], 'name': 'user'}]
级别二:分块阅读
RAG检索方法很快速,但常在相关块与用户查询关键词重叠程度不足时失效,导致这些相关的块未被检索到、没有提供给模型。尽管理论上向量检索可以缓解这一问题,但实际上效果有限。 为了解决这个局限,我们采用了一种暴力策略来减少错过相关上下文的几率:
- 步骤1:对于每个512字块,让聊天模型评估其与用户查询的相关性,如果认为不相关则输出
"无"
, 如果相关则输出相关句子。这些块会被并行处理以避免长时间等待。 - 步骤2:然后,取那些非
"无"
的输出(即相关句子),用它们作为搜索查询词,通过BM25检索出最相关的块(总的检索结果长度控制在8k上下文限制内)。 - 步骤3:最后,基于检索到的上下文生成最终答案,这一步骤的实现方式与通常的RAG相同。
入口:parallel_doc_qa._run,流程如下:
用户输入问题与文档
[{'content': [{'text': '怎么构建docker镜像'}, {'file': 'C:\\Users\\xxx\\AppData\\Local\\Temp\\gradio\\5941ee43e2a46480d1d5a9bf4d92e95faf4ee914\\第七模块云原生docker运维.pdf'}], 'name': 'user', 'role': 'user'}]
将文档分成chunk
跟之前的方案一致,入口:parallel_doc_qa._parse_and_chunk_files
使用LLM评估chunk与用户查询的相关性(并行执行,默认是2n+1),生成相关的句子
入口:ParallelDocQAMember._run
prompt也根据语言区分了中英文,由system prompt和user prompt组成
system prompt
您是一个擅长文档问答的专家,可以根据文档内容回答用户问题。
# 任务描述:
请仔细阅读所给的文档片段,并根据其内容回答问题。
您需要判断文档的内容是否可以回答问题,不要强行回答。如果可以回答,答案必须严格遵循文档内容,即使与事实不符。
如果答案与事实不符,直接给出答案,不要做解释。
# 回答规则:
- 请使用与文档材料相同的语言回答问题。
- 评估文档是否含有足够信息回答问题。无关时不要回答。
- 如果问题能被回答,你的回答必须严格遵循文档内容,即使与事实不符。一定不要做多余解释。
- 如果问题能被回答,直接引用文档的相关信息保证答案准确、完整,并追求简洁。
- 当文档中只有少量信息与问题相关时,重点关注这部分信息,这种情况下一定回答。
# 回答格式:
回答的内容请以JSON的格式给出。
## 示例:
当文档内容无关时:
{{"res": "none", "content": "{no_response}"}},
Observation: ...
当文档内容可回答,且文档为中文时:
{{"res": "ans", "content": "你的答案"}}
Observation: ...
当文档内容可回答,且文档为英文时:
{{"res": "ans", "content": "[Your Answer]"}}
Observation: ...
user prompt
# 文档:
{ref_doc}
# 问题:
{instruction}
请根据回答规则,给出你的回答:
取出相关句子,通过BM25检索出最相关的块
入口:parallel_doc_qa._retrieve_according_to_member_responses
- 对结果进行按索引重排序,过滤掉Content为None的句子,将片段用\n\n拼接起来
- 如果token数量不大于MAX_RAG_TOKEN_SIZE(4500),则将相关内容拼接到用户输入内容后面一起生成关键词
{"keywords_zh": ["构建", "docker", "镜像", "Dockerfile", "FROM", "MAINTAINER", "RUN", "ADD", "ENV", "CMD", "docker build", "docker commit"], "keywords_en": ["build", "docker", "image", "Dockerfile", "FROM", "MAINTAINER", "RUN", "ADD", "ENV", "CMD", "docker build", "docker commit"]}
- 调用RAG检索(使用的keyword_search)
- keyword_search使用bm25对关键词和chunk进行相似度匹配。
- 关键词除了模型生成的keywords之外,还会对用户的query进行分词(删除一些事实无关的东西,如我、你之类的代词,疑问词等)
- 如果上一步因为上下文长度原因没有把相关句子一起给模型生成关键词,则这一步会将相关内容加入query,进行分词得到关键词。
- 最终得到的评分片段按相关度进行组合,与之前的RAG检索逻辑相同。