上星期我发布了一篇用llama_index制作文档机器人的文章,感兴趣的朋友不少。于是,这周我多花了一些时间研究它,将一些运用上的常见问题记录了下来。

从本文开始,笔者将会让GPT更多地参与到文字撰写中。

GPT:在本文中,咱们将深入评论llama_index的运用,并供给一些关键的留意事项,以保证你可以成功完结你的方针。请坐稳,放松自己,准备好进入llama_index的令人兴奋的国际吧!

笔者:倒也没有那么令人兴奋……

1.两个留意事项

调试:检查实际发送给GPT的内容

GPT:调试是运用任何技术的过程中都必须考虑到的重要步骤。在llama_index中,你可能会好奇它真正传给GPT模型的文字是什么。这样可以协助你更好地了解llama_index和GPT模型之间的交互,并保证它们之间的通讯是正确的。

gpt-index.readthedocs.io/en/latest/g…

LLM模型的挑选

GPT:当你开始看log时,会意识到它query时默认运用的大预言模型是text-davinci-002模型。假如你想要选用gpt-3.5-turbo模型,你需求进行一些修正。

gpt-index.readthedocs.io/en/latest/g…

2.llama_index运作流程、怎么进行更复杂的查询(要点)

GPT:在第一篇文章中,咱们介绍了GPTSimpleVectorIndex将一切文档作为一个接连的文本进行查询。其流程大概是这样的:

+-----------+      +-----------------+     +-------------+
|  相关文档  | ——>  | Embedding API   | ——> | VectorIndex |
+-----------+      +-----------------+     +-------------+
                                                  |
                                ------------------+
                                |
                                V
+-----------+                +-------+     +--------------+
|  用户问题  | ——---------->  | Query | ——> |    GPT API   |
+-----------+                +-------+     +--------------+
                                               |
                                               |
                                               V
                                           +--------+
                                           | Answer |
                                           +--------+

笔者:图像得很好。留意其中VectorIndex可以被存到磁盘,不需求每次都创立。

GPT:但是,假如你的资料库许多,一个vecIndex可能不够用,你可以创立多个Index,并用不同的方法安排你的文档。llama_index官方供给了一个示例来协助你完结这个方针:

gpt-index.readthedocs.io/en/latest/h…

笔者:对,这个示例有两个难点:

不同的index(索引方法)

笔者:官方供给的几个典型Index如下:

gpt-index.readthedocs.io/en/latest/g…

图中只画了query操作的步骤,而且看起来也比较难了解,你可以加上我的总结来服用:

●ListIndex:query一个listIndex时,它会按照顺序,逐个对它的子index进行query操作。每一次答案都会对前一个答案进行refine操作(GPT优化)。

+-----------+      +-----------------+     +-------------+
|  相关文档  | ——>  |   多个子Index   | ——> |  ListIndex  |
+-----------+      +-----------------+     +-------------+
                                                  |
                                ------------------+
                                |
                                V
+-----------+                +-------+     +----------------+   +----------------+   +---------------+  
|  用户问题  | ——---------->  | Query | ——> | 子Index调query |-->| 子Index调query |-->| 子Index调query |  
+-----------+                +-------+     +----------------+   +----------------+   +---------------+  
                                               |                     |                     |        
                                               V                     V                     V        
                                           +--------+         +---------------+        +----------------+         
                                           | Answer | ---->   | 新旧Answer一同 |  ----> | 新旧Answer一同 |   
                                           |        |         |    让GPT优化   |        |    让GPT优化   |
                                           +--------+         +---------------+        +----------------+   
                                                                                             |        
                                                                                             V        
                                                                                          +-------+ 
                                                                                          | Answer|
                                                                                          +-------+ 

●KeywordTableIndex:创立index时,会先提取一切子index的内容的关键词;到了query这个TableIndex时,会将疑问句里的关键词提取出来,然后对子index的关键词进行匹配。拿出一切匹配的子index,逐个进行query。然后像List一样,会逐个进行refine操作(对子index提取关键词、对问题提取关键词的算法都有三个:正则、RAKE、问GPT)

+-----------+      +-----------------+     +------------------+     +-------------------+
|  相关文档  | ——>  |   多个子Index   | ——> |  提取各自的关键词  | ——> | KeyWordTableIndex |
+-----------+      +-----------------+     +------------------+     +-------------------+
                                                                            |
                                --------------------------------------------+
                                |
                                V
+-----------+                +-------+     +---------------------+
|  用户问题  | ——---------->  | Query | ——> | 提取用户问题的keyword|
+-----------+                +-------+     +---------------------+
                                |               |
                                V               |
                        +----------------+      |
                        | 找出一切keyword| <-----|
                        | 符合的子index  |
                        +----------------+
                                |
                                V
                    +----------------+   +---------------+    +----------------+   +---------------+                                           
                    | 子Index调query |-->| 子Index调query | -->| 子Index调query |-->| 子Index调query |                                           
                    |                |   |               |    |                |   |               |                                           
                    +----------------+   +---------------+    +----------------+   +---------------+                                           
                       |                     |                     |                     |        
                       V                     V                     V                     V        
                   +--------+         +---------------+        +---------------+        +----------------+         
                   | Answer | ---->   | 新旧Answer一同 |  ----> | 新旧Answer一同 | ---->  | 新旧Answer一同 |
                   |        |         |    让GPT优化   |        |    让GPT优化   |        |    让GPT优化   |
                   +--------+         +---------------+        +---------------+        +----------------+
                                                                                              |
                                                                                              V
                                                                                           +-----------+
                                                                                           | 终究Answer|
                                                                                           +-----------+

●TreeIndex:创立index时,会先找GPT提取一切子index的总结内容。到了用户query阶段,会将这些index的总结词发给GPT,让GPT挑选其中的几个节点,然后query所选中的节点,得到终究成果。

+-----------+      +-----------------+     +--------------------------+     +-------------------+
|  相关文档  | ——>  |   多个子Index   | ——> | 找GPT总结它们内容(summary) | ——> |     TreeIndex     |
+-----------+      +-----------------+     +--------------------------+     +-------------------+
                                                                                   |
                                ---------------------------------------------------+
                                |
                                V
+-----------+                +-------+
|  用户问题  | ——---------->  | Query |
+-----------+                +-------+
                                |         
                                V         
                        +-------------------+
                        | 询问GPT,哪n个节点 | 
                        | 的summary最匹配问题 |
                        +--------------------+
                                |
                                V
                    +----------------+   +---------------+    +----------------+   +---------------+                                           
                    | 子Index调query |-->| 子Index调query | -->| 子Index调query |-->| 子Index调query |                                           
                    |                |   |               |    |                |   |               |                                           
                    +----------------+   +---------------+    +----------------+   +---------------+                                           
                       |                     |                     |                     |        
                       V                     V                     V                     V        
                   +--------+         +---------------+        +---------------+        +----------------+         
                   | Answer | ---->   | 新旧Answer一同 |  ----> | 新旧Answer一同 | ---->  | 新旧Answer一同 |
                   |        |         |    让GPT优化   |        |    让GPT优化   |        |    让GPT优化   |
                   +--------+         +---------------+        +---------------+        +----------------+
                                                                                              |
                                                                                              V
                                                                                           +-----------+
                                                                                           | 终究Answer|
                                                                                           +-----------+

像ListIndex和TableIndex,都有一个特色:假如子index的数量会不停增长,那么在用户提问时,你无法控制终究会产生多少次query。笔者以为假如你的运用实时性要求较高,尽量不要滥用它们。只要在表达确认长度的编排联系的时分,query次数是可控的,就可以用他们。

别的。上图中多个answer兼并优化这一个阶段称为“response合成”阶段,图里画的是 create and refine 方法,llama_index别的还供给了tree_summarize方法,这里就不赘述了。

ComposableGraph

笔者:比如中说到的另一个可能比较困惑的东西:ComposableGraph,个人觉得比较恰当的了解是:index之间的嵌套只代表它们的父子联系,假如你希望你的查询是递归进行的,就要用ComposableGraph。

笔者:别的,有了ComposableGraph之后,你给每个Index传递其参数的方法就得经过ComposableGraph.query函数的query_config参数,见下方代码。其中struct_id、index_struct_type都是用于挑选子index的。query_mode、query_kwargs则是要传递给它们的参数。

[
{
"index_struct_id":vectorIndex1.doc_id(),
"index_struct_type":"simple_dict",
"query_mode":"default",
"query_kwargs":{
"similarity_top_k":3
}
},
{
"index_struct_type":"simple_dict",
"query_mode":"default",
"query_kwargs":{
"similarity_top_k":1
}
    }
]

3. prompt

GPT:上文所说到的一些操作。比如query、refine、KeywordTable的提取关键字、TreeIndex的summary等操作,都需求请求GPT模型来完结。假如你想要更好地了解llama_index的作业原理,那么找到这些操作的prompt是十分重要的。在llama_index的代码中,你可以找到这些操作对应的prompt,

github.com/jerryjliu/l…

笔者:我在运用的过程中,遇到过一个Bug:在上文说到的ListIndex执行query操作后,在response合成时,gpt-3.5在前一个answer里得到了有用的东西,然后鄙人一次refine时,却变成这样的回来:“上文现已供给适宜的答案,不需求进行优化”。

究其原因,便是gpt-3.5-turbo没有遵循llama_index内置提示词的规则干事。所以,笔者只能经过自定义提示词的方法解决。

gpt-index.readthedocs.io/en/latest/h…

假如你用的是ComposableGraph,则可以在query_configs里传入。

别的,因为默认提示词是英文的,用于做中文产品时,有时你输入中文问题它会回答英文。也要经过该问题解决,只需求将它内部的default_prompt翻译一下即可。

4. 显现引证来源

GPT:将你的资料库整理成树形后。假如你正在开发问答类运用,那么出处引证功用就十分重要了。因为被GPT总结过后的内容很可能会丢掉一些信息,所以引证原始内容就变得尤为必要,new bing就有这个功用。在llama_index中,你可以很容易地找到它所运用的index,并从回来成果中获取它的内容。下面供给一个比如来协助你更好地了解怎么完结这个功用:假设你正在运用llama_index的query操作,得到了一个含有多个答案的回来成果。接下来,你可以经过检查每个答案所用到的index来确认哪个答案是正确的,然后运用index的内容作为出处引证。鄙人面的段落中,我将为你供给更多具体的指导和协助,以保证你可以成功完结出处引证功用。

res=graph.query('UsingAction怎么用?')
responseByGPT=str(res)  # 文字成果
refDoc=[]  
fornodeinres.source_nodes:  
ifnode.similarity!=None:  
        refDoc.append(f'(类似度{node.similarity})https://puerts.github.io/docs/puerts'+node.doc_id) # 此处我提早将文档路径设为了doc_id,你也可以设在extra_info里
print("\n".join([  
responseByGPT,  
"relatedDoc",  
"\n".join(refDoc)
]))

5. 总结

笔者:我在写这一篇的时分,chatgpt-plugin现已官宣了,其配套开源项目(相当于插件开发套件) openai/chatgpt-retrieval-plugin也现已发布。技术方案和llama_index共同。很显然这套提早搜索的方案,今后会是GPT定制的常态操作。所以理论上来说只要了解了llama_index,了解chatgpt-plugin就不难。

chatgpt-retrieval-pluginllama_index不一样的是,它只供给了vectorIndex的搜索方法(其实最有用的便是这个),而且它内部没有完结与GPT QA的操作 —— 在chatgpt-plugin线上运行时,这部分作业是运作在他们服务器的。所以它和llama_index并不彻底堆叠,他们是可以共存运用的。

另一个不一样的点:他们内置了一个简略的Rest服务器供给这个vector搜索服务,这样咱们可以用别的语言运用它,或是对接到别的LLM上。但更亮的是:会给这个Rest服务器生成十分利于GPT了解的自然语言API阐明文件,这是chatgpt-plugin运作的核心。

更多的有缘再写吧。