llama_index文档机器人使用注意事项和操作流程

释放双眼,带上耳机,听听看~!
本文介绍了使用llama_index文档机器人时的注意事项和操作流程,包括调试和LLM模型的选择,以及如何进行更复杂的查询。

上周我发布了一篇用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 = []  
for node in res.source_nodes:  
    if node.similarity != None:  
        refDoc.append(f'(相似度{node.similarity}) https://puerts.github.io/docs/puerts' + node.doc_id) # 此处我提前将文档路径设为了doc_id,你也可以设在extra_info里
        
print("n".join([  
    responseByGPT,  
    "related Doc",  
    "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运作的核心。

更多的有缘再写吧。

本网站的内容主要来自互联网上的各种资源,仅供参考和信息分享之用,不代表本网站拥有相关版权或知识产权。如您认为内容侵犯您的权益,请联系我们,我们将尽快采取行动,包括删除或更正。
AI教程

ChatGPT: 一个开发人员的利器

2023-12-9 10:54:14

AI教程

同态加密(Paillier算法)原理及应用场景分析

2023-12-9 11:07:14

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索