为 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
__S_W_I_R_L__2_._6__________________________________________________________
Service: redis...RUNNING, pid:31012
Service: django...RUNNING, pid:31014
Service: celery-worker...RUNNING, pid:31018
PID TTY TIME CMD
31012 ttys000 0:20.11 redis-server * :6379
31014 ttys000 0:12.04 /Library/Frameworks/Python.framework/Versions/3.11/Resources/Python.app/Contents/MacOS/Python /Library/Frameworks/Python.framework/Versions/3.11/bin/daphne -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:
$ setup-vector-db
$ migrate-data
$ configure-indexes
# Just this:
$ curl https://raw.githubusercontent.com/swirlai/swirl-search/main/docker-compose.yaml -o docker-compose.yaml
Enter fullscreen mode
Exit fullscreen mode
💡 您可以用 SWIRL 构建什么?
团队的真实例子……
文章来源:https://dev.to/swirl/your-full-guide-to-contributing-to-swirl-256f