知识库系统
1. 体系结构
说明:
最初版为了体系结构相对简单,微服务之间采用协同式交互方式.消息中间件作为微服务之间的沟通桥梁.且业务流转是协同自发的,后期随着业务的进一步拓展和复杂化再依据实际情况考虑编排式业务交互方式.
主要服务模块:
服务分为基础组件和业务服务两大类型,基础组件用于业务服务的注册,交互流转,数据缓存,数据持久化等.
基础组件 :
- kubernetes: 节点的管理,容器的部署,任务的调度,负债均衡,状态监控等.
- MQ 消息中间件集群 : 服务间异步通信的主要基础组件,最主要的提供异步交互能力,服务之间的关系解偶.
- 向量数据库集群 : 用于存储向量化以后的行业资料信息,在搜索时提供向量数据检索
业务服务 :
基础服务
- LLM Model Service Group( 大语言模型服务集群 ): 主要提供大语言模型的算法能力,包括行业知识文字的向量化,语言逻辑推理能力和内容总结生成等能力
- LLM Model Adapter Service( 大语言模型适配服务 ) : 适配不同的大语言模型系统接口,对外提供统一的调用接口
行业助手
- Ai Assistant Gateway( 行业助手网关 ): 该网关是行业助手系统的入口,承接内外交互的桥梁.网关必须启用断路器模式,防止过多请求导致系统过载.
知识库
- AI Search Service Gateway(AI 搜索网关 ): 该网关是整个智能搜索服务的入口,承接内外交互的桥梁.网关必须启用断路器模式,防止过多请求导致系统过载.
- AI Question Service(AI 问题服务 ): 主要通过大模型进行问题向量化,存储原始提问到Redis,投递搜索消息.
- AI Search Service(AI 搜索服务 ): 接受搜索任务消息,调用向量数据库进行搜索,根据相关规则进行结果过滤.发送搜索结果响应消息.
- AI Answer Service(AI 应答服务 ): 主要处理应答消息,将问题和答案提交到大模型服务进行整合.并将结果返回搜索网关.
- Document Service Gateway( 文档处理网关 ): 该网关是文档上传处理的入口,承接内外交互的桥梁.网关必须启用断路器模式,防止过多请求导致系统过载
- Document Process Service( 文档处理服务 ): 该服务主要负责文档的导入,读取,字符串分割,向量化和结果存储.
2. 工作流程
行业助手
1.通过将带有行业属性提示词的请求通过 Ai Assistant Gateway( 行业助手网关 ) 之后由负载均衡策略发送到 LLM Model Adapter Service( 大语言模型适配服务 )
2. LLM Model Adapter Service( 大语言模型适配服务 ) 将请求转换为已适配大模型服务的请求接口和协议.将结果整理之后通过网关返回.
知识库
a. 文档导入
- 文档上传和断路拦截,支持批量上传至 Document Service Gateway( 文档处理网关 ) ,该服务需要基于负载均衡策略选择合适的 Document Process Service( 文档处理服务 ) , 如果处理系统负载过高则启动断路器.
- Document Process Service( 文档处理服务 ) 将文档主要工作将文档进行加载,分割,将分割后的文字区块通过负载均衡策略调用对应的大模型算法服务转换为向量化嵌入.将向量化后的数据和原始文字数据存入向量数据库(VectorDataBase).
b. 知识搜索
- 用户搜索知识统一从AI Search Service Gateway(AI 搜索网关 ) 进入,该网关基于负载均衡策略选择AI Question Service(AI 问题服务 ) 来进行问题处理.当系统负载过高时启动断路器拒绝新进请求.
- AI Question Service(AI 问题服务 ) 收到请求后根据负载均衡策略调用大模型适配服务代理到对应的大模型服务进行问题向量化.将该问题和向量化的结果一并发送Search请求消息(包含问题向量化后的结果以及必要的字段如高速缓存的key)到MQ的RequestChannel.
- AI Search Service(AI搜索服务) 从RequestChannel中订阅到搜索消息,执行搜索任务,将搜索后的结果进行排序,保留符合阈值的结果.将搜索得到符合条件的原始文本一并发送到MQ的ResponseChannel.
- AI Answer Service(AI应答服务) 从ResponseChannel中订阅到搜索结果的响应消息和原始问题.将原始问题和结果通过负载均衡策略找到一个合适的大模型服务进行响应结果整理.最后根据消息中携带的网关服务器信息将最终响应消息发送到AI Search Service Gateway(AI 搜索网关 )
- AI Search Service Gateway(AI 搜索网关 ) 将最终结果响应匹配到请求会话,返回给前端客户.
3. 接口协议
行业助手
客户端 ->Ai Assistant Gateway( 行业助手网关 ) -> LLM Model Adapter Service( 大语言模型适配服务 )
协议接口
传输协议 | HTTP(POST) |
---|---|
URI PATH | /uran/lm/assistant |
Headers | Content-Type:application/json;charset=UTF-8 |
Version | v1.0 |
请求字段
名称 | 类型 | 是否必须 | 说明 |
---|---|---|---|
prompt | String | N | 提示词 |
question | String | Y | 问题 |
响应字段 ( 格式json)
名称 | 类型 | 是否必须 | 说明 |
---|---|---|---|
status | Int | Y | 状态码200为成功,其余为出错 |
message | String | Y | 当status=200为”success”, 其余为错误信息 |
data | Object | N | 返回有用的数据 |
+answer | String | N | 结果字符串 |
示例 :
请求
{
"prompt": "你现在是考拉AI能力专家,针对用户询问的关于AI能力相关特性作出回答",
"question": "烟火识别的准确率如何,是否适合工厂应用"
}
响应
{
"staus": 200,
"message": "success",
"data":{
"answer" : "烟火识别算法是考拉的成熟算法,准确率85%以上.工厂使用需要考虑光照因素影响,需要根据环境做强化训练"
}
}
知识库
知识库操作
添加 :
客户端 -> Document Service Gateway( 文档处理网关 ) -> Document Process Service(文档处理服务)
协议接口
传输协议 | HTTP(POST) |
---|---|
URI PATH | /uran/lm/documents |
Headers | Content-Type:application/json;charset=UTF-8 |
Version | v1.0 |
请求字段
名称 | 类型 | 是否必须 | 说明 |
---|---|---|---|
documents | ObjectArray | Y | 文档数组 |
+name | String | Y | 文档名 |
+type | String | Y | 文档类型,支持pdf, doc, txt, docx |
+url | String | Y | 文档url地址 |
+md5 | String | Y | 文档md5值,用于标识文档唯一性 |
repository | String | Y | 指定要插入的知识库 |
notifyUrl | String | Y | 通知文档处理状态地址 |
响应字段 ( 格式json)
名称 | 类型 | 是否必须 | 说明 |
---|---|---|---|
status | Int | Y | 状态码200为成功,其余为出错 |
message | String | Y | 当status=200为”success”, 其余为错误信息 |
data | Object | N | 返回有用的数据 |
示例 :
请求
{
"documents":[{ "name": "码极客算法白皮书", "type": "pdf",
"url": "http://xxxxxxxxxxxxxxx", "md5": "sfh8i3ss"}....]
"repository": "OsmagicAlgorithmSpec",
"notifyUrl": "http://xxxxxxxxxxxxxxx"
}
响应
{
"status": 200,
"message": "success"
}
通知文档处理状态 Document Process Service(文档处理服务)-> 客户端
协议接口
传输协议 | HTTP(POST) |
---|---|
URI PATH | /uran/lm/documents_status |
Headers | Content-Type:application/json;charset=UTF-8 |
Version | v1.0 |
请求字段
名称 | 类型 | 是否必须 | 说明 |
---|---|---|---|
documents | ObjectArray | Y | 文档数组 |
+name | String | Y | 文档名 |
+type | String | Y | 文档类型,支持pdf, doc, txt, docx |
+url | String | Y | 文档url地址 |
+md5 | String | Y | 该文档md5值 |
+status | Int | Y | 文档处理状态码200ok,其他失败 |
+message | String | Y | 文档成功OK,失败填写失败原因 |
repository | String | Y | 知识库名 |
响应字段 ( 格式json)
名称 | 类型 | 是否必须 | 说明 |
---|---|---|---|
status | Int | Y | 状态码200为成功,其余为出错 |
message | String | Y | 当status=200为”success”, 其余为错误信息 |
data | Object | N | 返回有用的数据 |
示例 :
请求
{
"documents":[{ "name": "码极客算法白皮书", "type": "pdf",
"url": "http://xxxxxxxxxxxxxxx", "md5": "sfh8i3ss", "status": 200, "message": "OK"}....]
"repository": "OsmagicAlgorithmSpec"
}
响应
{
"staus": 200,
"message": "success"
}
Document Process Service(文档处理服务)->LM Adapter Service( 大模型适配服务 )
协议接口
传输协议 | HTTP(POST) |
---|---|
URI PATH | /uran/lm/block_embedding |
Headers | Content-Type:application/json;charset=UTF-8 |
Version | v1.0 |
请求字段
名称 | 类型 | 是否必须 | 说明 |
---|---|---|---|
texts | Vector <String> |
Y | 分割后的文档块列表 |
响应字段 ( 格式json)
名称 | 类型 | 是否必须 | 说明 |
---|---|---|---|
status | Int | Y | 状态码200为成功,其余为出错 |
message | String | Y | 当status=200为”success”, 其余为错误信息 |
data | Object | N | 成功返回embedding好的数据 |
+embeddings | Vector[Vector <float> ] |
N | Embedding数据 |
示例 :
请求
{
"texts": ["Hi there!",
"Oh, hello!",
"What's your name?",
"My friends call me World",
"Hello World!"
]
}
响应
{
"staus": 200,
"message": "success",
"data":{
"embeddings" : [[0.3434, 0.12, 0.133....],
[0.8934, 0.81, 0.1111....],
[0.24346, 0.3434, 0.21....],
[....],
[....]
]
}
}
删除 :
删除文档 : 客户端 -> Document Service Gateway( 文档处理网关 ) -> Document Process Service(文档处理服务)
协议接口
传输协议 | HTTP(DELETE) |
---|---|
URI PATH | /uran/lm/documents |
Headers | Content-Type:application/json;charset=UTF-8 |
Version | v1.0 |
请求字段
名称 | 类型 | 是否必须 | 说明 |
---|---|---|---|
documents | StringArray | Y | 待删除的文档名数组 |
repository | String | Y | 指定所属的知识库 |
响应字段 ( 格式json)
名称 | 类型 | 是否必须 | 说明 |
---|---|---|---|
status | Int | Y | 状态码200为成功,其余为出错 |
message | String | Y | 当status=200为”success”, 其余为错误信息 |
data | Object | N | 返回有用的数据 |
示例 :
请求
{
"documents": ["码极客算法白皮书", "码极客算法报价单"...]
"repository": "OsmagicAlgorithmSpec",
}
响应
{
"staus": 200,
"message": "success"
}
删除库 : 客户端 -> Document Service Gateway( 文档处理网关 ) -> Document Process Service(文档处理服务)
协议接口
传输协议 | HTTP(DELETE) |
---|---|
URI PATH | /uran/llm/repositories |
Headers | Content-Type:application/json;charset=UTF-8 |
Version | v1.0 |
请求字段
名称 | 类型 | 是否必须 | 说明 |
---|---|---|---|
repositories | StringArray | Y | 待删除的库名数组 |
响应字段 ( 格式json)
名称 | 类型 | 是否必须 | 说明 |
---|---|---|---|
status | Int | Y | 状态码200为成功,其余为出错 |
message | String | Y | 当status=200为”success”, 其余为错误信息 |
data | Object | N | 返回有用的数据 |
请求问答系统
客户端 ->AI Search Service Gateway(AI 搜索网关 )
协议接口
传输协议 | HTTP(POST) |
---|---|
URI PATH | /uran/lm/question |
Headers | Content-Type:application/json;charset=UTF-8 |
Version | v1.0 |
请求字段
名称 | 类型 | 是否必须 | 说明 |
---|---|---|---|
messages | ObjectArrary | Y | 待搜索的问题集合 |
+role | String | Y | 角色user, assistant |
+content | String | Y | 搜索问题 |
+images | String | N | 图像url |
maxTokens | Int | Y | 限制最大token数 |
temperature | Float | Y | 想象力 |
model | String | Y | 模型名 |
repository | Object | N | 指定要搜索的知识库/如果没有则属于对话模式 |
+name | String | Y | 知识库名 |
+threshold | Float | Y | 搜索阈值 |
+topK | Int | Y | 指定搜索结果的topK |
background | String | N | 背景信息描述 |
响应字段 ( 流式text/event-stream )
名称 | 类型 | 是否必须 | 说明 |
---|---|---|---|
data | Object | Y | 返回产生的结果[DONE]表示完成 |
+choices | ObjectArray | Y | |
++delta | Object | Y | |
+++role/step/content | String | Y | role=assistant,step=当前正在发生进行的步骤, content=模型回复的消息 |
示例 :
请求
{
"maxTokens": 128,
"temperature": 0.7,
"messages": [
{
"role": "user",
"content": "请帮我描述下这个图片里的内容",
"images": "http://10.10.8.5:30601/storage/files/1669551431047143425.jpg"
}
],
"model": "koala-mm",
"repository": {
"repository": "铁塔高空监控",
"threshold": 0.5,
"topK": 2
},
"background" : "repository"
}
响应
data: { "choices": [{"delta": {"step": "正在解析图片内容"}}]}
data: { "choices": [{"delta": {"step": "正在检索知识库"}}]}
data: { "choices": [{"delta": {"step": "正在组织解决方案"}}]}
data: { "choices": [{"delta": {"role": "assistant"}}]}
data: { "choices": [{"delta": {"content": "火灾"}}]}
data: { "choices": ["delta": {"content": "发生"}}]}
AI Search Service Gateway(AI 搜索网关 )->AI Question Service(AI问题服务)
协议接口
传输协议 | HTTP(POST) |
---|---|
URI PATH | /uran/llm/question |
Headers | Content-Type:application/json;charset=UTF-8 |
Version | v1.0 |
请求字段
名称 | 类型 | 是否必须 | 说明 |
---|---|---|---|
messages | ObjectArrary | Y | 待搜索的问题集合 |
+role | String | Y | 角色user, assistant |
+content | String | Y | 搜索问题 |
+images | String | N | 图像url |
maxTokens | Int | Y | 限制最大token数 |
temperature | Float | Y | 想象力 |
model | String | Y | 模型名 |
repository | String | N | 指定要搜索的知识库/如果没有则属于对话模式 |
threshold | Float | Y | 指定相似度阈值 |
questionToken | String | Y | 问题唯一token |
notifyUrl | String | Y | 数据回调地址ws协议/uran/lm/notify |
响应字段 ( 格式json)
名称 | 类型 | 是否必须 | 说明 |
---|---|---|---|
status | Int | Y | 状态码200为成功,其余为出错 |
message | String | Y | 当status=200为”success”, 其余为错误信息 |
示例 :
请求
{
"text": "What’s the phone number of Qiu?",
"respUrl": "http://10.10.1.111:666/uran/llm/response"
}
响应
{
"staus": 200,
"message": "success"
}
Embedding: AI Question Service(AI问题服务)->LLM Service( 大语言模型服务 )
协议接口
传输协议 | HTTP(POST) |
---|---|
URI PATH | /uran/llm/embedding |
Headers | Content-Type:application/json;charset=UTF-8 |
Version | v1.0 |
请求字段
名称 | 类型 | 是否必须 | 说明 |
---|---|---|---|
text | String | Y | 待搜索的问题 |
响应字段 ( 格式json)
名称 | 类型 | 是否必须 | 说明 |
---|---|---|---|
status | Int | Y | 状态码200为成功,其余为出错 |
message | String | Y | 当status=200为”success”, 其余为错误信息 |
data | Object | N | 成功返回embedding |
+embedding | Vector <float> |
N | 问题embedding后的向量数组 |
示例 :
请求
{
"text": "What’s the phone number of Qiu?"
}
响应
{
"staus": 200,
"message": "success",
"data":{
"embedding" : [0.8934, 0.81, 0.1111....]
}
}
AI Question Service(AI问题服务)->Request Channel->AI Search Service(AI搜索服务)
RabbitMQ QueueName “Request”
消息体均为json
发布消息字段
名称 | 类型 | 是否必须 | 说明 |
---|---|---|---|
question_token | String | Y | 问题唯一标识token |
question | String | Y | 原问题字符串 |
resp_url | String | Y | 回复答案的url地址 |
embedding | Vector <float> |
Y | 问题embedding后的向量数组 |
示例 :
{
"question_token": "w3rdsjighh1388903",
"question": "What’s the phone number of Qiu?",
"resp_url": "http://10.10.1.111:666/uran/lm/response",
"embedding" : [0.8934, 0.81, 0.1111....]
}
AI Search Service(AI搜索服务)->Response Channel->AI Answer Service(AI应答服务)
RabbitMQ QueueName “Response”
消息体均为json
发布消息字段
名称 | 类型 | 是否必须 | 说明 |
---|---|---|---|
question_token | String | Y | 问题唯一标识token |
question | String | Y | 原问题字符串 |
resp_url | String | Y | 回复答案的url地址 |
texts | Vector <String> |
Y | 搜索到整理后合规的答案数组 |
示例 :
{
"question_token": "w3rdsjighh1388903",
"question": "What’s the phone number of Qiu?",
"resp_url": "http://10.10.1.111:666/uran/lm/response",
"texts" : ["He’s first phone number is 1xxxx", "He’s second phone number is 1xxxxxx", ...]
}
AI Answer Service(AI应答服务)->LLM Service(大语言模型服务)
协议接口
传输协议 | HTTP(POST) |
---|---|
URI PATH | /uran/lm/combine |
Headers | Content-Type:application/json;charset=UTF-8 |
Version | v1.0 |
请求字段
名称 | 类型 | 是否必须 | 说明 |
---|---|---|---|
question | String | Y | 问题 |
texts | Vector <String> |
Y | 搜索到整理后合规的答案数组 |
响应字段 ( 格式json)
名称 | 类型 | 是否必须 | 说明 |
---|---|---|---|
status | Int | Y | 状态码200为成功,其余为出错 |
message | String | Y | 当status=200为”success”, 其余为错误信息 |
data | Object | N | 成功返回整理后的回答 |
+answer | String | N | 回答 |
示例 :
请求
{
"question": "What’s the phone number of Qiu?",
"texts" : ["He’s first phone number is 1xxxx", "He’s second phone number is 1xxxxxx", ...]
}
响应
{
"staus": 200,
"message": "success",
"data":{
"answer" : "He’s phone numbers are 1xxxx, 13xxxxx...."
}
}
AI Answer Service(AI应答服务)->AI Search Service Gateway(AI 搜索网关 )
协议接口
传输协议 | HTTP(POST) |
---|---|
URI PATH | /ruran/lm/response |
Headers | Content-Type:application/json;charset=UTF-8 |
Version | v1.0 |
请求字段
名称 | 类型 | 是否必须 | 说明 |
---|---|---|---|
questionToken | String | Y | 问题唯一标识token |
answer | String | Y | 问题最终答案 |
响应字段 ( 格式json)
名称 | 类型 | 是否必须 | 说明 |
---|---|---|---|
status | Int | Y | 状态码200为成功,其余为出错 |
message | String | Y | 当status=200为”success”, 其余为错误信息 |
data | Object | N | 成功返回整理后的回答 |
示例 :
请求
{
"questionToken": "w3rdsjighh1388903",
"answer" : "He’s phone numbers are 1xxxx, 13xxxxx...."
}
}
响应
{
"staus": 200,
"message": "success"
}