
# 第三方通用知识库接入规范
#### 前言
该规范面向的对象是第三方知识库的开发者（下文简称开发者），其目的是为开发者对AgentArts平台适配提供指导，最终能够将第三方知识库的内容接入到AgentArts平台使用。
#### API接口规范
对于API接口适配，开发者需要新增两个接口，一个是**获取知识库列表** ，一个是**检索知识库** 。开发者按照[接口：获取知识库列表]、[接口：检索知识库]规范提供对外接口，并在接口内实现密钥鉴权、数据查询、知识检索等业务逻辑，最后按照规范返回对应数据。
 #### 接口：获取知识库列表
- URI：GET /knowledge-bases
- 查询Query参数
  表1查询Query参数 
  | 参数     | 是否必选 | 参数类型    | 描述                                                                                                                                                                                                                                                                         |
  |:---|:---|:---|:---|
  | name   | 否    | String  | **参数解释**： 知识库名称，用于列出知识库列表时筛选知识库名称。 **取值范围：** 长度不超过64个字符。 **默认取值：** 不涉及。                 |
  | offset | 否    | Integer | **参数解释：** 当前请求的分页偏移量，表示从第几条开始获取数据。默认值为0，表示从第0条开始获取数据。 **取值范围：** 0～65535。 **默认取值：** 0。    |
  | limit  | 否    | Integer | **参数解释：** 当前请求返回的分页最大数据数量，表示一次请求返回的数据条数。默认值为10，表示一页最多展示10条数据。 **取值范围：** 1-100。 **默认取值：** 10。 |
     
  
- 请求Header参数
  表2请求Header参数 
  | 参数            | 是否必选 | 参数类型   | 描述                                                                                                                                                                                                                                                                                                                                        |
  |:---|:---|:---|:---|
  | Authorization | 是    | String | **参数解释**： 认证鉴权使用的api-key密钥，拼接"Bearer "后的字符串。 示例：Bearer d59\*\*\*\*\*\*9C3，用于第三方知识库的鉴权。 **取值范围：** 不涉及。 **默认取值：** 不涉及。 |
     
  
- 响应参数
  表3响应参数200 
  | 参数                  | 参数类型                                                 | 描述                                                                                                                                                                                            |
  |:---|:---|:---|
  | total               | Integer                                              | **参数解释**： 知识库数据总数。 **取值范围：** 不涉及。                                                |
  | knowledge_base_list | Array of [表4] | **参数解释：** 知识库数据信息列表，注：第三方知识库应当只返回可用的知识库，即在当前时刻可被外部引用并支持检索的知识库数据。 **取值范围：** 不涉及。 |
     
   表4KnowledgeBaseInfo 
  | 参数                | 参数类型   | 描述                                                                                                                                          |
  |:---|:---|:---|
  | knowledge_base_id | String | **参数解释**： 知识库ID。 **取值范围：** 不涉及。   |
  | name              | String | **参数解释：** 知识库名称。 **取值范围：** 不涉及。 |
  | description       | String | **参数解释**： 知识库描述。 **取值范围：** 不涉及。    |
     
  表5响应参数400、500等 
  | 参数         | 参数类型   | 描述                                                                                                                                          |
  |:---|:---|:---|
  | error_code | String | **参数解释**： 错误码。 **取值范围：** 不涉及   |
  | error_msg  | String | **参数解释：** 错误描述。 **取值范围：** 不涉及 |
     
  
 
 #### 接口：检索知识库
- URI：POST /knowledge-bases/retrieve
- 请求Header参数
  表6请求Header参数 
  | 参数            | 是否必选 | 参数类型   | 描述                                                                                                                                                                                                                                                                                                                             |
  |:---|:---|:---|:---|
  | Authorization | 是    | String | **参数解释**： 认证鉴权使用的api-key密钥，拼接"Bearer "后的字符串。 示例：Bearer d59\*\*\*\*\*\*9C3，用于第三方知识库的鉴权。 **取值范围：** 不涉及。 **默认取值：** 不涉及。 |
     
  
- Body参数
  表7Body参数 
  | 参数                 | 是否必选 | 参数类型                                                  | 描述                                                                                                                                                                                                                                                                               |
  |:---|:---|:---|:---|
  | knowledge_base_ids | 是    | Array of String                                       | **参数解释**： 知识库ID的列表，用于指定搜索时需要检索的知识库。 **取值范围：** 列表长度大于等于1，即至少指定检索一个知识库。 **默认取值：** 不涉及。       |
  | query              | 是    | String                                                | **参数解释：** 搜索内容。 **取值范围：** 长度不超过4096个字符。 **默认取值：** 不涉及。                                         |
  | method             | 是    | String                                                | **参数解释：** 搜索方式。语义检索："doc"。 **取值范围：** 不涉及。 **默认取值：** 不涉及。                                    |
  | offset             | 否    | Integer                                               | **参数解释：** 当前请求的分页偏移量，表示从第几条开始获取数据。默认值为0，表示从第0条开始获取数据。 **取值范围：** 0～65535。 **默认取值：** 0。       |
  | limit              | 否    | Integer                                               | **参数解释：** 当前请求返回的分页最大数据数量，表示一次请求返回的数据条数。默认值为10，表示一页最多展示10条数据。 **取值范围：** 1-100。 **默认取值：** 10。 |
  | top_k              | 否    | Integer                                               | **参数解释：** 检索返回结果的最大召回数量。 **取值范围：** 1-1024。 **默认取值：** 50。                                      |
  | search_threshold   | 否    | Number                                                | **参数解释：** 检索时的相关度得分阈值，取默认值0.0时表示不设置相关度得分阈值。 **取值范围：** 0.0 - 1.0。 **默认取值：** 0.0。             |
  | extra_params       | 否    | Array of [表8] | **参数解释**： 额外的参数，用于传递第三方知识库所需的其他参数。 **取值范围：** 不涉及。 **默认取值：** 不涉及。                            |
     
   表8KnowledgeBaseExtraParam 
  | 参数    | 是否必选 | 参数类型   | 描述                                                                                                                                            |
  |:---|:---|:---|:---|
  | key   | 是    | String | **参数解释**： 额外参数主键名。 **取值范围：** 不涉及。 |
  | value | 是    | String | **参数解释：** 额外参数的值。 **取值范围：** 不涉及。   |
     
  
- 响应参数
  表9响应参数200 
  | 参数                 | 参数类型                                                    | 描述                                                                                                                                              |
  |:---|:---|:---|
  | total              | Integer                                                 | **参数解释**： 检索结果总数。 **取值范围：** 不涉及。  |
  | search_result_list | Array of [表10] | **参数解释：** 检索结果的信息列表。 **取值范围：** 不涉及。 |
     
   表10SearchChunkInfo 
  | 参数                | 参数类型   | 描述                                                                                                                                                    |
  |:---|:---|:---|
  | knowledge_base_id | String | **参数解释**： 知识库ID。 **取值范围：** 不涉及。       |
  | file_id           | String | **参数解释：** 文件ID。 **取值范围：** 不涉及。             |
  | chunk_id          | String | **参数解释**： 切片ID。 **取值范围：** 不涉及。             |
  | content           | String | **参数解释**： 检索返回的文本内容。 **取值范围：** 不涉及。        |
  | score             | Number | **参数解释**： 检索结果的打分。 **取值范围：** 0.0 - 1.0。    |
  | title             | String | **参数解释**： 文本标题，推荐返回文件名称。 **取值范围：** 不涉及。 |
     
  表11响应参数400、500等 
  | 参数         | 参数类型   | 描述                                                                                                                                      |
  |:---|:---|:---|
  | error_code | String | **参数解释**： 错误码。 **取值范围：** 不涉及。   |
  | error_msg  | String | **参数解释：** 错误描述。 **取值范围：** 不涉及。 |
     
  
 
#### API接口实现案例（Java）
```
@Slf4j
@RestController
public class commonThirdpartyKnowledgeBaseController {
    /**
     * list knowledgeBase function
     *
     * @param name
     * @param offset
     * @param limit
     * @param authorization
     * @return ListKnowledgeBaseResponse
     */
    @GetMapping("/knowledge-bases")
    public ListKnowledgeBaseResponse listKnowledgeBase(
            @RequestHeader("Authorization") String authorization,
            @RequestParam(required = false) String name,
            @RequestParam(required = false) Integer offset,
            @RequestParam(required = false) Integer limit) {
        /**
         * 对密钥认证鉴权
         * Verify and authenticate the key
         */
        if (!authorization.startsWith("Bearer ")) {
            log.error("invalid authorization");
            throw new RuntimeException("invalid authorization");
        }
        String apikey = authorization.substring("Bearer ".length());
        /**
         * then do something for authorization
         *
         */
        /**
         * 根据业务实现代码逻辑，构造返回结果
         * Construct and return results based on your business implementation and code logic
         */
        ListKnowledgeBaseResponse response = new ListKnowledgeBaseResponse();
        response.total = 1;
        KnowledgeBaseInfo knowledgeBaseInfo = new KnowledgeBaseInfo();
        knowledgeBaseInfo.knowledge_base_id = "001";
        knowledgeBaseInfo.name = "一个通用第三方知识库的名称 / this is a knowledgeBase name";
        knowledgeBaseInfo.description = "一个描述 / a description";
        response.knowledge_base_list = List.of(knowledgeBaseInfo);
        return response;
    }
    /**
     * @param authorization
     * @param request
     * @return RetrieveKnowledgeBaseResponse
     */
    @PostMapping("/knowledge-bases/retrieve")
    public RetrieveKnowledgeBaseResponse retrieveKnowledgeBase(
            @RequestHeader("Authorization") String authorization,
            @RequestBody RetrieveKnowledgeBaseRequest request) {
        /**
         * 对密钥认证鉴权
         * Verify and authenticate the key
         */
        if (!authorization.startsWith("Bearer ")) {
            log.error("invalid authorization");
            throw new RuntimeException("invalid authorization");
        }
        String apikey = authorization.substring("Bearer ".length());
        /**
         * then do something for authorization
         *
         */
        /**
         * 根据业务实现代码逻辑，构造返回结果
         * Construct and return results based on your business implementation and code logic
         */
        RetrieveKnowledgeBaseResponse response = new RetrieveKnowledgeBaseResponse();
        response.total = 1;
        SearchChunkInfo searchChunkInfo = new SearchChunkInfo();
        searchChunkInfo.knowledge_base_id = "001";
        searchChunkInfo.file_id = "101";
        searchChunkInfo.chunk_id = "201";
        searchChunkInfo.content = "一个通用第三方知识库的检索切片内容 / this is a retrieve chunk content";
        searchChunkInfo.title = "检索切片的标题 / retrieve chunk title";
        searchChunkInfo.score = 0.8f;
        response.search_result_list = List.of(searchChunkInfo);
        return response;
    }
    /*
     * the response structure of the listKnowledgeBase function
     */
    @Data
    public class ListKnowledgeBaseResponse {
        Integer total;
        List<KnowledgeBaseInfo> knowledge_base_list;
    }
    @Data
    public class KnowledgeBaseInfo {
        String knowledge_base_id;
        String name;
        String description;
    }
    /*
     * the request structure of the retrieveKnowledgeBase function
     */
    @Data
    public static class RetrieveKnowledgeBaseRequest {
        List<String> knowledge_base_ids;
        String query;
        String method;
        Integer offset;
        Integer limit;
        Integer top_k;
        Float search_threshold;
        List<KnowledgeBaseExtraParam> extra_params;
    }
    @Data
    public static class KnowledgeBaseExtraParam {
        String key;
        String value;
    }
    /*
     * the response structure of the retrieveKnowledgeBase function
     */
    @Data
    public class RetrieveKnowledgeBaseResponse {
        Integer total;
        List<SearchChunkInfo> search_result_list;
    }
    @Data
    public class SearchChunkInfo {
        String knowledge_base_id;
        String file_id;
        String chunk_id;
        String content;
        Float score;
        String title;
    }
}
```
