为 SWIRL 做出贡献的完整指南 🌌 漩涡 你好,开发人员, Swirl  团队 创建了这个令人惊叹的指南,其中包含所有相关信息,适合任何想要通过添加 SearchProviders、连接器和处理器来扩展 Swirl 的人。 
这让您轻松为 Swirl 做出贡献。立即加入 Swirl,开启开源之旅。我们还将参与 Hacktoberfest 活动,为贡献者提供 Swag 奖品。奖品价值最高可达 100 美元, 详情请点击 此处的博客查看。 
请参阅下面这篇文章,了解有关 Swirl 的更多信息。 
在GitHub 上给 Swirl 点个赞 。 
  目录   先决条件 
 本地安装最新的 Python,3.11 或更高版本  
 %  python 
Python  3.11 . 1  ( v3 . 11.1 : a7a450f84a ,  Dec   6  2022 ,  15 : 24 : 06 )  [ Clang  13.0 . 0  ( clang - 1300.0 . 29.30 )]  on  darwin 
Type  " help " ,  " copyright " ,  " credits "  or  " license "  for  more  information . 
  
   
    
     Enter fullscreen mode
       
   
    
     Exit fullscreen mode
       
   
  
 
 Redis 安装并运行 Swirl 安装在本地(不在 Docker 中)并正在运行  
 % python swirl.py status* :6379 -b  0.0.0.0 -p  8000 swirl_server.asgi:application
  
   
    
     Enter fullscreen mode
       
   
    
     Exit fullscreen mode
       
   
  
 
  背景:了解 Swirl 搜索工作流程 简而言之: 
🕐 每个搜索提供程序并行执行 
🕐 结束并行处理 
有关更多信息,请参阅 开发人员指南工作流概述 。 
  创建 SearchProvider SearchProvider 是 Connector 的配置。因此,要连接到给定源,首先请验证它是否支持您已有的 Connector。(有关如何创建新 Connector 的信息,请参阅下一教程。) 
例如,如果尝试使用类似 URL 查询网站 https://host.com/?q=my+query+here并返回 JSON 或 XML,请创建一个新的 SearchProvider 并配置 RequestsGet 连接器,如下所示: 
 复制任意 Google PSE SearchProviders  
修改 url和 query_template以构造查询 URL。使用上面的示例: 
 { 
        " url " :  " https://host.com/ " , 
        " query_template " :  " {url}?q={query_string} " , 
} 
  
   
    
     Enter fullscreen mode
       
   
    
     Exit fullscreen mode
       
   
  
 
要了解有关查询和 URL 参数的更多信息,请参阅 开发人员指南 。 
 如果网站提供分页结果或按日期(以及相关性)对结果进行排序的功能,请使用 PAGE=和 DATE_SORT查询映射通过 Swirl 添加对这些功能的支持。  
有关更多信息,请参阅 用户指南的查询映射部分: 
 在浏览器中打开查询 URL 并查看 JSON 响应。  
如果使用 Visual Studio Code,请右键单击粘贴的 JSON 并选择 Format Document使其更易于阅读。 
 确定结果列表以及找到和检索到的结果数量。将这些 JSON 路径放入响应映射 (response_mappings) 中。然后,确定用于从结果映射 (result_mappings) 中结果列表的每个项目中提取 Swirl 默认字段 title、 body、 url和 date_published的JSON 路径 author,其中 Swirl 字段名称位于左侧,源 JSON 路径位于右侧。  
例如: 
 
        " response_mappings " :  " FOUND=searchInformation.totalResults,RETRIEVED=queries.request[0].count,RESULTS=items " , 
        " result_mappings " :  " url=link,body=snippet,author=displayLink,cacheId,pagemap.metatags[*].['og:type'],pagemap.metatags[*].['og:site_name'],pagemap.metatags[*].['og:description'],NO_PAYLOAD " , 
  
   
    
     Enter fullscreen mode
       
   
    
     Exit fullscreen mode
       
   
  
 
 根据服务要求添加凭证。  
使用的格式取决于凭证的类型。详情请参阅: 用户指南凭证部分 
 添加合适的标签,可用于描述来源或其所知道的内容。  
不允许使用空格;好的标签在查询中使用时是清晰明显的,例如 company:tesla或 news:openai。 
有关标签的更多信息,请参阅: 组织 SearchProviders 
 回顾一下完成的SearchProvider:  
 
{ 
        " name " :  " My New SearchProvider " , 
        " connector " :  " RequestsGet " , 
        " url " :  " https://host.com/ " , 
        " query_template " :  " {url}?q={query_string} " , 
        " query_processors " :  [ 
            " AdaptiveQueryProcessor " 
        ], 
        " query_mappings " :  "" , 
        " result_processors " :  [ 
            " MappingResultProcessor " , 
            " CosineRelevancyResultProcessor " 
        ], 
        " response_mappings " :  " FOUND=jsonpath.to.number.found,RETRIEVED=jsonpath.to.number.retrieved,RESULTS=jsonpath.to.result.list " , 
        " result_mappings " :  " url=link,body=snippet,author=displayLink,NO_PAYLOAD " , 
        " credentials " :  " bearer=your-bearer-token-here " , 
        " tags " :  [ 
            " MyTag " 
        ] 
    } 
  
   
    
     Enter fullscreen mode
       
   
    
     Exit fullscreen mode
       
   
  
 
 
  前往 Swirl 页面 localhost:8000/swirl/searchproviders/,必要时请登录。将页面底部的表单设置为 RAW 模式,并粘贴 SearchProvider 代码。然后点击 POST。SearchProvider 将会重新加载。 
 
 
  前往 Galaxy  localhost:8000/galaxy/,使用之前创建的标签进行搜索。结果应该会在大致相同的时间内再次出现。 
 
 
  创建连接器 在 Swirl 中,连接器负责加载 SearchProvider,然后构建和传输对特定类型服务的查询,然后保存响应 - 通常是结果列表。 
:info:考虑使用您最喜欢的编码 AI 来生成连接器,方法是将连接器基类和有关您尝试查询的 API 的信息传递给它。 
:info: 如果您尝试向返回 JSON 或 XML 格式的端点发送 HTTP/S 请求,则无需创建连接器。只需 创建一个 SearchProvider 来配置 Swirl 内置的 RequestsGet 连接器即可。 
要创建新的连接器: 
 
  创建一个新文件,例如 swirl/connectors/my_connector.py
 
 
  复制连接器的样式 ChatGPT作为起点,或者 BigQuery将其作为数据库的目标。 
 
 
 
class  MyConnector ( Connector ): def  __init__ ( self ,  provider_id ,  search_id ,  update ,  request_id = '' ): 
        self . system_guide  =  MODEL_DEFAULT_SYSTEM_GUIDE 
        super (). __init__ ( provider_id ,  search_id ,  update ,  request_id ) 
  
   
    
     Enter fullscreen mode
       
   
    
     Exit fullscreen mode
       
   
  
 
在 init 类中,加载并持久化连接和查询服务所需的所有内容。以 ChatGPT 连接器为例。 
 导入 Python 包以连接到服务。ChatGPT 连接器使用 openai 包,例如:  
 import  openai 
  
   
    
     Enter fullscreen mode
       
   
    
     Exit fullscreen mode
       
   
  
 
 修改execute_search方法以连接到服务。  
从 ChatGPT 连接器中可以看到,它首先加载 OpenAI 凭证,然后构建提示,通过发送提示 openai.ChatCompletion.create(),然后存储响应。 
 
    def  execute_search ( self ,  session = None ): logger . debug ( f " { self } : execute_search() " ) if  self . provider . credentials : 
            openai . api_key  =  self . provider . credentials 
        else : 
            if  getattr ( settings ,  ' OPENAI_API_KEY ' ,  None ): 
                openai . api_key  =  settings . OPENAI_API_KEY 
            else : 
                self . status  =  " ERR_NO_CREDENTIALS " 
                return prompted_query  =  "" 
        if  self . query_to_provider . endswith ( ' ? ' ): 
            prompted_query  =  self . query_to_provider 
        else : 
            if  ' PROMPT '  in  self . query_mappings : 
                prompted_query  =  self . query_mappings [ ' PROMPT ' ]. format ( query_to_provider = self . query_to_provider ) 
            else : 
                prompted_query  =  self . query_to_provider 
                self . warning ( f ' PROMPT not found in query_mappings! ' ) if  ' CHAT_QUERY_REWRITE_GUIDE '  in  self . query_mappings : 
            self . system_guide  =  self . query_mappings [ ' CHAT_QUERY_REWRITE_GUIDE ' ]. format ( query_to_provider = self . query_to_provider ) if  not  prompted_query : 
            self . found  =  0 
            self . retrieved  =  0 
            self . response  =  [] 
            self . status  =  " ERR_PROMPT_FAILED " 
            return 
        logger . info ( f ' CGPT completion system guide: { self . system_guide }  query to provider :  { self . query_to_provider } ' ) 
        self . query_to_provider  =  prompted_query 
        completions  =  openai . ChatCompletion . create ( 
            model = MODEL , 
            messages = [ 
                { " role " :  " system " ,  " content " :  self . system_guide }, 
                { " role " :  " user " ,  " content " :  self . query_to_provider }, 
            ], 
            temperature = 0 , 
        ) 
        message  =  completions [ ' choices ' ][ 0 ][ ' message ' ][ ' content ' ]  # FROM API Doc
 
        self . found  =  1 
        self . retrieved  =  1 
        self . response  =  message . replace ( " \n\n " ,  "" ) return 
  
   
    
     Enter fullscreen mode
       
   
    
     Exit fullscreen mode
       
   
  
 
ChatGPT 依赖于 OpenAI API 密钥,该密钥通过 .env 文件提供给 Swirl。要遵循此模式,请在 .env 中创建新值,然后修改 swirl_server/settings.py以将其加载为 Django 设置,并设置合理的默认值。 
 修改该 normalize_response()方法以存储原始响应。实际上,这只不过是将结果对象写成 Python 列表并将其存储在 self.results:  
 
    def  normalize_response ( self ): logger . debug ( f " { self } : normalize_response() " ) self . results  =  [ 
                { 
                ' title ' :  self . query_string_to_provider , 
                ' body ' :  f ' { self . response } ' , 
                ' author ' :  ' CHATGPT ' , 
                ' date_published ' :  str ( datetime . now ()) 
            } 
        ] return 
  
   
    
     Enter fullscreen mode
       
   
    
     Exit fullscreen mode
       
   
  
 
如果 self.response 已经是一个 python 列表,则无需执行此操作。 
 将新连接器添加到 swirl/connectors/__init__.py 
 from  swirl.connectors.my_connector  import  MyConnector 
  
   
    
     Enter fullscreen mode
       
   
    
     Exit fullscreen mode
       
   
  
 
 重启 Swirl  
 % python swirl.py restart core
  
   
    
     Enter fullscreen mode
       
   
    
     Exit fullscreen mode
       
   
  
 
 创建一个 SearchProvider 来配置新的连接器,然后按照创建 SearchProvider 教程 中的说明将其添加到 Swirl 安装中 。  
不要忘记有用的标签,以便您在准备测试时可以轻松定位新的连接器。 
要了解有关开发连接器的更多信息,请参阅 开发人员指南 。 
  创建查询处理器 QueryProcessor 是在预查询或查询处理过程中执行的一个阶段。两者的区别在于,预查询处理应用于所有 SearchProvider,而查询处理由每个 SearchProvider 单独执行。在这两种情况下,目标都是修改发送给部分或全部 SearchProvider 的查询。 
注意:如果您只想使用查找表或正则表达式重写查询,请 考虑 使用 QueryTransformations
要创建新的 QueryProcessor: 
 
  创建一个新文件,例如 swirl/processors/my_query_processor.py
 
 
  复制 GenericQueryProcessor该类作为起点,然后重命名: 
 
 
 
class  MyQueryProcessor ( QueryProcessor ): type  =  ' MyQueryProcessor ' def  process ( self ): 
        # TO DO: modify self.query_string, and return it 
         return  self . query_string  +  '  modified ' 
  
   
    
     Enter fullscreen mode
       
   
    
     Exit fullscreen mode
       
   
  
 
保存模块。 
 将新模块添加到 swirl/processors/__init__.py 
 
from  swirl.processors.my_processor  import  MyQueryProcessor 
  
   
    
     Enter fullscreen mode
       
   
    
     Exit fullscreen mode
       
   
  
 
 将新模块添加到 Search.pre_query_processing 管道或至少一个 SearchProvider.query_processing 管道:  
SearchProvider: 
 
        " query_processors " :  [ 
            " AdaptiveQueryProcessor " , 
            " MyQueryProcessor " 
        ], 
  
   
    
     Enter fullscreen mode
       
   
    
     Exit fullscreen mode
       
   
  
 
Search: 
 
  { 
        " query_string " :  " news:ai " , 
        " pre_query_processors " :  [ 
          " MyQueryProcessor " 
        ], 
  } 
  
   
    
     Enter fullscreen mode
       
   
    
     Exit fullscreen mode
       
   
  
 
 重启 Swirl  
 % python swirl.py restart core
  
   
    
     Enter fullscreen mode
       
   
    
     Exit fullscreen mode
       
   
  
 
 前往 Galaxy http://localhost:8000/swirl/search/?q=some+query 
运行搜索;如果使用查询处理器,请务必指定相应的 SearchProvider。例如,如果您将 QueryProcessor 添加到带有标签“news”的 SearchProvider query_processing 管道,则查询将 http://localhost:8000/swirl/search/?q=news:some+query改为: 
结果应该在几秒钟内出现。在 messages代码块中应该会出现一条消息,表明新的 QueryProcessor 重写了查询: 
 MyQueryProcessor rewrote Strategy Consulting - Google PSE's query to: <modified-query> 
 
  
   
    
     Enter fullscreen mode
       
   
    
     Exit fullscreen mode
       
   
  
 
要了解有关编写处理器的更多信息,请参阅 开发人员指南 。 
  创建 ResultProcessor ResultProcessor 是每个 SearchProvider 在 Connector 检索到结果后执行的一个阶段。ResultProcessor 对结果进行操作,并根据需要对其进行转换,以供下游使用或呈现。 
GenericResultProcessor 和 MappingResultProcessor 阶段旨在规范化 JSON 结果。GenericResultProcessor 搜索与 Swirl 模式完全匹配的结果(如 SearchProvider 示例中所示),并将其复制过来。MappingResultProcessor 应用 result_mappings 来规范化结果,同样如上文 SearchProvider 示例中所示。通常,在这些阶段之后添加阶段是个好主意,除非 SearchProvider 需要以 Swirl 模式格式响应。 
要创建新的 ResultProcessor: 
 
  创建一个新文件,例如 swirl/processors/my_result_processor.py
 
 
  复制 GenericResultProcessor该类作为起点,然后重命名。不要忘记 init 。 
 
 
 class  MyResultProcessor ( ResultProcessor ): def  __init__ ( self ,  results ,  provider ,  query_string ,  request_id = '' ,  ** kwargs ): 
        super (). __init__ ( results ,  provider ,  query_string ,  request_id = request_id ,  ** kwargs ) 
  
   
    
     Enter fullscreen mode
       
   
    
     Exit fullscreen mode
       
   
  
 
 实现该 process()方法。这是唯一需要的。  
Process() 操作于 self.results,它将以 Python 列表格式包含来自给定 SearchProvider 的所有结果。修改结果列表中的项目,并报告更新的数量。 
     def  process ( self ): if  not  self . results : 
            return updated  =  0 
        for  item  in  self . results : 
            # TO DO: operate on each item and count number updated
             item [ ' my_field1 ' ]  =  ' test ' 
            updated  =  updated  +  1 # note: there is no need to save in this type of Processor
 
        # save modified self.results
         self . processed_results  =  self . results 
        # save number of updated
         self . modified  =  updated return  self . modified 
  
   
    
     Enter fullscreen mode
       
   
    
     Exit fullscreen mode
       
   
  
 
保存模块。 
 将新模块添加到 swirl/processors/__init__.py 
 from  swirl.processors.my_processor  import  MyResultProcessor 
  
   
    
     Enter fullscreen mode
       
   
    
     Exit fullscreen mode
       
   
  
 
 将新模块添加到至少一个 SearchProvider.result_processing 管道:  
         " result_processors " :  [ 
            " MappingResultProcessor " , 
            " MyResultProcessor " , 
            " CosineRelevancyResultProcessor " 
        ], 
         ... etc ... 
  
   
    
     Enter fullscreen mode
       
   
    
     Exit fullscreen mode
       
   
  
 
 重启 Swirl  
 % python swirl.py restart core
  
   
    
     Enter fullscreen mode
       
   
    
     Exit fullscreen mode
       
   
  
 
 前往 Galaxy http://localhost:8000/swirl/search/?q=some+query 
运行搜索;确保至少定位一个具有新 ResultProcessor 的 SearchProvider。 
例如,如果您将 ResultProcessor 添加到带有标签“news”的 SearchProvider result_processing 管道,则查询将需要 http://localhost:8000/swirl/search/?q=news:some+query代替上述内容。 
结果应该在几秒钟内出现。在 messages代码块中应该出现一条消息,表明新的 ResultProcessor 更新了多个结果,并且内容应该按预期进行修改。 
 MyResultProcessor updated 5 results from: MyConnector",
 
  
   
    
     Enter fullscreen mode
       
   
    
     Exit fullscreen mode
       
   
  
 
要了解有关编写处理器的更多信息,请参阅 开发人员指南 。 
  创建 PostResultProcessor PostResultProcessor 是所有 SearchProvider 返回结果后执行的一个阶段。它们会对给定查询的所有结果进行操作。 
要创建新的 ResultProcessor: 
 
  创建一个新文件,例如 swirl/processors/my_post_result_processor.py
 
 
  复制下面的模板作为起点,然后重命名: 
 
 
 class  MyPostResultProcessor ( PostResultProcessor ): type  =  ' MyPostResultProcessor ' ############################################
 
    def  __init__ ( self ,  search_id ,  request_id  =  '' ): 
        return  super (). __init__ ( search_id ,  request_id = request_id ) ############################################
 
    def  process ( self ): updated  =  0 for  results  in  self . results : 
            if  not  results . json_results : 
                continue 
            for  item  in  results . json_results : 
                # TO DO: operate on each result item
                 item [ ' my_field2 ' ]  =  " test " 
                updated  =  updated  +  1 
            # end for
             # call results.save() if any results were modified
             if  updated  >  0 : 
                results . save () # end for
         ############################################
 
        self . results_updated  =  updated 
        return  self . results_updated 
  
   
    
     Enter fullscreen mode
       
   
    
     Exit fullscreen mode
       
   
  
 
修改 process()方法,对项目进行操作并保存每个结果集,如下所示。 
 将新模块添加到 swirl/processors/__init__.py 
 from  swirl.processors.my_post_result_processor  import  MyPostResultProcessor 
  
   
    
     Enter fullscreen mode
       
   
    
     Exit fullscreen mode
       
   
  
 
 将新模块添加到 Search.post_result_processing 管道:  
   { 
        " query_string " :  " news:ai " , 
        " post_result_processors " :  [ 
            " DedupeByFieldPostResultProcessor " , 
            " CosineRelevancyPostResultProcessor " , 
            " MyPostResultProcessor " 
        ], 
        ... etc ... 
    } 
  
   
    
     Enter fullscreen mode
       
   
    
     Exit fullscreen mode
       
   
  
 
 重启 Swirl  
 % python swirl.py restart core
  
   
    
     Enter fullscreen mode
       
   
    
     Exit fullscreen mode
       
   
  
 
 前往 Galaxy http://localhost:8000/swirl/search/?q=some+query 
运行搜索;确保至少定位一个具有新 PostResultProcessor 的 SearchProvider。 
例如,如果您向 post_result_processing带有标签“news”的搜索管道添加了 PostResultProcessor,则查询将需要 http://localhost:8000/swirl/search/?q=news:some+query代替上述内容。 
结果应该在几秒钟内出现。在 messages代码块中应该出现一条消息,表明新的 PostResultProcessor 更新了多个结果,并且内容应该按预期进行修改。 
 MyPostResultProcessor updated 10 results from: MySearchProvider
  
   
    
     Enter fullscreen mode
       
   
    
     Exit fullscreen mode
       
   
  
 
要了解有关编写处理器的更多信息,请参阅 开发人员指南 。 
  加入社区 在 GitHub 上给 Swirl 点个赞。 
 
  
  无需移动数据,即可进行 AI 搜索和 RAG 操作。从公司 100 多个应用的知识库中获取即时答案,同时确保数据安全。部署只需几分钟,无需数月。  
 
  
   
    
    
     
漩涡 
     
无需将数据移动到云端,即可为您的团队提供 ChatGPT 级搜索 
     
60 秒内将 RAG 与 One Drive 和 Microsoft 365 结合使用 提出问题 → 获取答案和来源 → 点击查看来源 
    
    在YouTube 上观看 
    使用 SWIRL 的团队每周平均可节省 7.5 小时的生产时间。 
    
    
    
     
🤔 为什么选择 SWIRL? 
     
避开复杂性,保持强大功能 
    
     
     
     
     
     
     
     
     
      
       
        
         
          
❌ 无 SWIRL 
          设置矢量数据库 移动数据 复杂的 ETL 管道 数周的基础设施工作 安全难题   
        
         
          
✅ 使用 SWIRL 
          一个docker命令 数据保留在原处 无需向量数据库 2分钟设置 企业级安全   
        
       
     
     
    
    
     
🚀 与众不同 
     
无向量 DB 戏剧 
     #  No need for:#  Just this:
      
       
        
         Enter fullscreen mode
           
       
        
         Exit fullscreen mode
           
       
      
     
    
     
💡 您可以用 SWIRL 构建什么? 团队的真实例子…… 
    
   
  
 
 
 
 
文章来源:https://dev.to/swirl/your-full-guide-to-contributing-to-swirl-256f