* [story #78659] add method to search knowledge chunks.

This commit is contained in:
sunhao
2025-12-02 16:32:02 +08:00
parent 0d1ea56c7c
commit a6aa7c47b5
4 changed files with 152 additions and 2 deletions
+4 -2
View File
@@ -195,10 +195,12 @@ class zai extends control
* Ajax: 搜索知识库。
* Ajax: Search knowledge base.
*
* @param string $type 'chunk'(块) | 'content'(内容)
* @param int $limit
* @access public
* @return void
*/
public function ajaxSearchKnowledges(int $limit = 10)
public function ajaxSearchKnowledges(string $type = 'content', int $limit = 10)
{
if($_SERVER['REQUEST_METHOD'] !== 'POST')
{
@@ -215,7 +217,7 @@ class zai extends control
{
$key = $this->zai->getCollectionKey($collection);
if(empty($key)) continue;
$searchContents = $this->zai->searchKnowledges($userPrompt, $key, $setting, $limit + 10);
$searchContents = $type === 'chunk' ? $this->zai->searchKnowledgeChunks($userPrompt, $key, $setting, $limit + 10) : $this->zai->searchKnowledges($userPrompt, $key, $setting, $limit + 10);
if($searchContents) $contents = array_merge($contents, $searchContents);
}
+26
View File
@@ -427,6 +427,32 @@ class zaiModel extends model
return empty($result['data']) ? array() : $result['data'];
}
/**
* 搜索知识块。
* Search knowledge chunks.
*
* @access public
* @param string $query
* @param string $collection
* @param array $filter
* @param int $limit
* @param float $minSimilarity
* @return array
*/
public function searchKnowledgeChunks(string $query, string $collection, array $filter, int $limit = 20, float $minSimilarity = 0.8): array
{
$postData = array();
$postData['query'] = $query;
$postData['limit'] = $limit;
$postData['min_similarity'] = $minSimilarity;
$postData['content_filter'] = $filter;
$result = $this->callAdminAPI('/v8/memories/' . $collection . '/embeddings-search-chunks', 'POST', null, $postData);
if($result['result'] != 'success') return array();
return empty($result['data']) ? array() : $result['data'];
}
/**
* 判断用户是否可以查看对象。
* Check if user can view object.
@@ -394,6 +394,23 @@ class zaiTest
return $result;
}
/**
* Test searchKnowledgeChunks method.
*
* @param string $query
* @param string $collection
* @param array $filter
* @param int $limit
* @param float $minSimilarity
* @access public
* @return array
*/
public function searchKnowledgeChunksTest($query, $collection, $filter, $limit = 20, $minSimilarity = 0.8)
{
$result = $this->objectModel->searchKnowledgeChunks($query, $collection, $filter, $limit, $minSimilarity);
return $result;
}
/**
* Test getCollectionKey method.
*
+105
View File
@@ -0,0 +1,105 @@
#!/usr/bin/env php
<?php
/**
title=测试 zaiModel->searchKnowledgeChunks();
timeout=0
cid=0
- 测试没有ZAI设置时搜索知识库块 @0
- 测试设置ZAI配置后搜索知识库块(基本查询) @array
- 测试搜索知识库块并指定limit参数 @array
- 测试搜索知识库块并指定minSimilarity参数 @array
- 测试搜索知识库块并使用filter过滤条件 @array
- 测试搜索知识库块返回空数组(API失败) @0
- 测试搜索知识库块使用不同的collection @array
- 测试搜索知识库块使用复杂的filter条件 @array
- 测试搜索知识库块使用空查询字符串 @array
- 测试搜索知识库块使用最小相似度0.5 @array
- 测试搜索知识库块使用最大limit值 @array
- 测试搜索知识库块使用多个filter条件 @array
*/
include dirname(__FILE__, 5) . '/test/lib/init.php';
include dirname(__FILE__, 2) . '/lib/zai.unittest.class.php';
zenData('config')->gen(0);
zenData('user')->gen(1);
su('admin');
global $tester;
$zai = new zaiTest();
/* 测试没有ZAI设置时搜索知识库块 */
$result1 = $zai->searchKnowledgeChunksTest('测试查询', 'test-collection', array());
r(empty($result1) ? 0 : count($result1)) && p() && e('0'); // 测试没有ZAI设置时搜索知识库块
/* 设置ZAI配置 */
$setting = new stdClass();
$setting->host = 'testhost.com';
$setting->port = 8080;
$setting->appID = 'testappid123';
$setting->token = 'testtoken123';
$setting->adminToken = 'testadmintoken123';
$tester->loadModel('setting')->setItem('system.zai.global.setting', json_encode($setting));
/* 测试设置ZAI配置后搜索知识库块(基本查询) */
// 注意:由于没有真实的ZAI API服务器,这些测试会因为网络调用失败
// 但我们可以验证方法的逻辑执行和参数处理
$result2 = $zai->searchKnowledgeChunksTest('如何使用禅道', 'zentao_kb', array());
r(is_array($result2) ? 'array' : 'not_array') && p() && e('array'); // 测试设置ZAI配置后搜索知识库块(基本查询)
/* 测试搜索知识库块并指定limit参数 */
$result3 = $zai->searchKnowledgeChunksTest('需求管理', 'zentao_kb', array(), 10);
r(is_array($result3) ? 'array' : 'not_array') && p() && e('array'); // 测试搜索知识库块并指定limit参数
/* 测试搜索知识库块并指定minSimilarity参数 */
$result4 = $zai->searchKnowledgeChunksTest('缺陷跟踪', 'zentao_kb', array(), 20, 0.9);
r(is_array($result4) ? 'array' : 'not_array') && p() && e('array'); // 测试搜索知识库块并指定minSimilarity参数
/* 测试搜索知识库块并使用filter过滤条件 */
$filter = array('objectType' => 'story');
$result5 = $zai->searchKnowledgeChunksTest('用户故事', 'zentao_kb', $filter);
r(is_array($result5) ? 'array' : 'not_array') && p() && e('array'); // 测试搜索知识库块并使用filter过滤条件
/* 测试搜索知识库块返回空数组(API失败) */
// 由于没有真实服务器,API调用会失败,应该返回空数组
$result6 = $zai->searchKnowledgeChunksTest('测试', 'invalid_collection', array());
r(empty($result6) ? 0 : count($result6)) && p() && e('0'); // 测试搜索知识库块返回空数组(API失败)
/* 测试搜索知识库块使用不同的collection */
$result7 = $zai->searchKnowledgeChunksTest('项目管理', 'project_kb', array());
r(is_array($result7) ? 'array' : 'not_array') && p() && e('array'); // 测试搜索知识库块使用不同的collection
/* 测试搜索知识库块使用复杂的filter条件 */
$complexFilter = array(
'objectType' => 'bug',
'status' => 'active',
'product' => 1
);
$result8 = $zai->searchKnowledgeChunksTest('如何修复bug', 'zentao_kb', $complexFilter);
r(is_array($result8) ? 'array' : 'not_array') && p() && e('array'); // 测试搜索知识库块使用复杂的filter条件
/* 测试搜索知识库块使用空查询字符串 */
$result9 = $zai->searchKnowledgeChunksTest('', 'zentao_kb', array());
r(is_array($result9) ? 'array' : 'not_array') && p() && e('array'); // 测试搜索知识库块使用空查询字符串
/* 测试搜索知识库块使用最小相似度0.5 */
$result10 = $zai->searchKnowledgeChunksTest('测试用例', 'zentao_kb', array(), 20, 0.5);
r(is_array($result10) ? 'array' : 'not_array') && p() && e('array'); // 测试搜索知识库块使用最小相似度0.5
/* 测试搜索知识库块使用最大limit值 */
$result11 = $zai->searchKnowledgeChunksTest('文档管理', 'zentao_kb', array(), 100);
r(is_array($result11) ? 'array' : 'not_array') && p() && e('array'); // 测试搜索知识库块使用最大limit值
/* 测试搜索知识库块使用多个filter条件 */
$multiFilter = array(
'objectType' => 'doc',
'product' => 1,
'lib' => 2,
'type' => 'text'
);
$result12 = $zai->searchKnowledgeChunksTest('API文档', 'zentao_kb', $multiFilter, 15, 0.85);
r(is_array($result12) ? 'array' : 'not_array') && p() && e('array'); // 测试搜索知识库块使用多个filter条件