Files
sbnews/server/app/common/service/ai/AiAssistantRanker.php
T

48 lines
1.6 KiB
PHP

<?php
namespace app\common\service\ai;
use app\common\model\ai\AiConfig;
class AiAssistantRanker
{
public static function rank(AiAssistantTrace $trace): AiAssistantTrace
{
$knowledgeHits = $trace->retrievals['knowledge_hits'] ?? [];
$preferredDomain = (string) ($trace->plan['preferred_domain'] ?? '');
usort($knowledgeHits, static function (array $left, array $right) use ($preferredDomain) {
$leftScore = (float) ($left['score'] ?? 0);
$rightScore = (float) ($right['score'] ?? 0);
if ($preferredDomain !== '') {
if (($left['domain'] ?? '') === $preferredDomain) {
$leftScore += 0.05;
}
if (($right['domain'] ?? '') === $preferredDomain) {
$rightScore += 0.05;
}
}
return $rightScore <=> $leftScore;
});
$limit = max(1, min(12, (int) AiConfig::getVal('assistant_kb_topk', '6')));
$trace->rankedHits = array_slice($knowledgeHits, 0, $limit);
$payload = AiAssistantContextService::composePayload(
$trace->rankedHits,
$trace->retrievals['match_items'] ?? [],
$trace->retrievals['crypto_items'] ?? [],
$trace->retrievals['web_news_items'] ?? [],
$trace->plan
);
$trace->finalSources = $payload['sources'] ?? [];
$trace->contextText = (string) ($payload['context_text'] ?? '{}');
$trace->hasContext = !empty($payload['has_context']);
return $trace;
}
}