feat: 增强 Manticore 向量更新逻辑,记录更新失败的 ID

This commit is contained in:
kuaifan 2026-01-03 21:59:44 +00:00
parent e020a80020
commit 9a8304d595
6 changed files with 70 additions and 6 deletions

View File

@ -330,8 +330,15 @@ class ManticoreBase
*/
public static function escapeMatch(string $keyword): string
{
// Manticore 特殊字符转义
$special = ['\\', '(', ')', '|', '-', '!', '@', '~', '"', '&', '/', '^', '$', '=', '<', '>', '*'];
// Manticore 特殊字符转义(完整列表)
// 参考: https://manual.manticoresearch.com/Searching/Full_text_matching/Escaping
$special = [
'\\', // 反斜杠(必须最先处理)
'(', ')', '[', ']', // 括号
'|', '-', '!', '@', '~', '^', '$', '*', '?', // 操作符
'"', '\'', // 引号
'&', '/', '=', '<', '>', ':', // 其他特殊字符
];
foreach ($special as $char) {
$keyword = str_replace($char, '\\' . $char, $keyword);
}

View File

@ -260,6 +260,8 @@ class ManticoreFile
$maxSize = self::getMaxFileSizeByExt($file->ext);
if ($file->size > $maxSize) {
Log::info("Manticore: Skip large file {$file->id} ({$file->size} bytes, max: {$maxSize})");
// 删除可能存在的旧索引(文件更新后可能超限)
self::delete($file->id);
return true;
}
@ -545,6 +547,7 @@ class ManticoreFile
}
$embeddings = $result['data'];
$failedIds = [];
// 5. 逐个更新向量到 Manticore
foreach ($ids as $index => $fileId) {
@ -555,8 +558,15 @@ class ManticoreFile
$vectorStr = '[' . implode(',', $embeddings[$index]) . ']';
if (ManticoreBase::updateFileVector($fileId, $vectorStr)) {
$successCount++;
} else {
$failedIds[] = $fileId;
}
}
// 记录更新失败的 ID
if (!empty($failedIds)) {
Log::warning('ManticoreFile: Vector update failed', ['file_ids' => $failedIds]);
}
}
return $successCount;

View File

@ -484,11 +484,15 @@ class ManticoreMsg
$result = AI::getBatchEmbeddings($texts);
if (Base::isError($result)) {
Log::warning('ManticoreMsg batch embedding failed: ' . ($result['msg'] ?? 'Unknown error'));
Log::warning('ManticoreMsg: Batch embedding failed', [
'msg_ids' => $idsArray,
'error' => $result['msg'] ?? 'Unknown error',
]);
continue;
}
$embeddings = $result['data'] ?? [];
$failedIds = [];
// 更新向量
foreach ($embeddings as $index => $embedding) {
@ -504,8 +508,15 @@ class ManticoreMsg
$vectorStr = '[' . implode(',', $embedding) . ']';
if (ManticoreBase::updateMsgVector($msgId, $vectorStr)) {
$count++;
} else {
$failedIds[] = $msgId;
}
}
// 记录更新失败的 ID
if (!empty($failedIds)) {
Log::warning('ManticoreMsg: Vector update failed', ['msg_ids' => $failedIds]);
}
}
return $count;

View File

@ -367,6 +367,7 @@ class ManticoreProject
}
$embeddings = $result['data'];
$failedIds = [];
// 5. 逐个更新向量到 Manticore
foreach ($ids as $index => $projectId) {
@ -377,8 +378,15 @@ class ManticoreProject
$vectorStr = '[' . implode(',', $embeddings[$index]) . ']';
if (ManticoreBase::updateProjectVector($projectId, $vectorStr)) {
$successCount++;
} else {
$failedIds[] = $projectId;
}
}
// 记录更新失败的 ID
if (!empty($failedIds)) {
Log::warning('ManticoreProject: Vector update failed', ['project_ids' => $failedIds]);
}
}
return $successCount;

View File

@ -151,7 +151,7 @@ class ManticoreTask
/**
* 获取任务的 allowed_users 列表
*
*
* 根据 visibility 计算有权限查看此任务的用户列表:
* - visibility=1: 项目成员
* - visibility=2: 任务成员(负责人/协作人)
@ -159,10 +159,22 @@ class ManticoreTask
* - 子任务: 还需要继承父任务的成员
*
* @param ProjectTask $task 任务模型
* @param int $depth 递归深度(防止无限递归)
* @param array $visited 已访问的任务ID防止循环引用
* @return array 有权限的用户ID数组
*/
public static function getAllowedUsers(ProjectTask $task): array
public static function getAllowedUsers(ProjectTask $task, int $depth = 0, array $visited = []): array
{
// 防止无限递归深度超过10层或循环引用
if ($depth > 10 || in_array($task->id, $visited)) {
Log::warning('ManticoreTask: getAllowedUsers recursion limit reached', [
'task_id' => $task->id,
'depth' => $depth,
]);
return [];
}
$visited[] = $task->id;
$userids = [];
// 1. 根据 visibility 获取基础成员
@ -191,7 +203,7 @@ class ManticoreTask
if ($task->parent_id > 0) {
$parentTask = ProjectTask::find($task->parent_id);
if ($parentTask) {
$parentUsers = self::getAllowedUsers($parentTask);
$parentUsers = self::getAllowedUsers($parentTask, $depth + 1, $visited);
$userids = array_merge($userids, $parentUsers);
}
}
@ -584,6 +596,7 @@ class ManticoreTask
}
$embeddings = $result['data'];
$failedIds = [];
// 5. 逐个更新向量到 Manticore
foreach ($ids as $index => $taskId) {
@ -594,8 +607,15 @@ class ManticoreTask
$vectorStr = '[' . implode(',', $embeddings[$index]) . ']';
if (ManticoreBase::updateTaskVector($taskId, $vectorStr)) {
$successCount++;
} else {
$failedIds[] = $taskId;
}
}
// 记录更新失败的 ID
if (!empty($failedIds)) {
Log::warning('ManticoreTask: Vector update failed', ['task_ids' => $failedIds]);
}
}
return $successCount;

View File

@ -332,6 +332,7 @@ class ManticoreUser
}
$embeddings = $result['data'];
$failedIds = [];
// 5. 逐个更新向量到 Manticore
foreach ($ids as $index => $userid) {
@ -342,8 +343,15 @@ class ManticoreUser
$vectorStr = '[' . implode(',', $embeddings[$index]) . ']';
if (ManticoreBase::updateUserVector($userid, $vectorStr)) {
$successCount++;
} else {
$failedIds[] = $userid;
}
}
// 记录更新失败的 ID
if (!empty($failedIds)) {
Log::warning('ManticoreUser: Vector update failed', ['user_ids' => $failedIds]);
}
}
return $successCount;