作者的ai总结field

This commit is contained in:
wangjinlei
2026-05-21 13:47:43 +08:00
parent 4940db73fe
commit c1cfae17a7
3 changed files with 92 additions and 17 deletions

View File

@@ -166,7 +166,7 @@ class UserFieldAiService
while (true) {
$query = Db::name('user')->alias('u')
->leftJoin('t_user_reviewer_info uri', 'uri.reviewer_id = u.user_id')
->join('t_user_reviewer_info uri', 'uri.reviewer_id = u.user_id',"left")
->where('u.user_id', '>', $cursor);
if (!$force) {
$query->where(function ($q) {
@@ -270,13 +270,70 @@ class UserFieldAiService
return array_values(array_unique(array_filter(array_map('trim', $titles))));
}
/**
* 解析 OpenAI 兼容 chat/completions 完整 URL。
* base.model_url 常为站点根(如 http://chat.taimed.cn直接 POST 会 404。
*/
private function resolveLlmChatUrl()
{
$candidates = [
// Env::get('user_field_ai.chat_url', ''),
// Env::get('promotion.promotion_llm_url', ''),
// Env::get('expert_country_chat_url', ''),
// Env::get('citation_chat_url', ''),
Env::get('base.model_url1', ''),
];
foreach ($candidates as $u) {
$u = trim((string) $u);
if ($u === '') {
continue;
}
$normalized = $this->normalizeChatCompletionsUrl($u);
if ($normalized !== '') {
return $normalized;
}
}
return '';
}
private function normalizeChatCompletionsUrl($url)
{
$url = trim((string) $url);
if ($url === '') {
return '';
}
if (stripos($url, 'chat/completions') !== false) {
return $url;
}
return rtrim($url, '/') . '/v1/chat/completions';
}
private function resolveLlmModel()
{
$candidates = [
Env::get('user_field_ai.chat_model', ''),
Env::get('base.model', ''),
Env::get('promotion.promotion_llm_model', ''),
Env::get('expert_country_chat_model', ''),
Env::get('citation_chat_model', ''),
'gpt-4.1',
];
foreach ($candidates as $m) {
$m = trim((string) $m);
if ($m !== '' && strtolower($m) !== 'your-model-name') {
return $m;
}
}
return '';
}
private function summarizeWithLlm(array $context)
{
$url = trim((string) Env::get('user_field_ai.chat_url', Env::get('expert_country_chat_url', Env::get('citation_chat_url', ''))));
$model = trim((string) Env::get('user_field_ai.chat_model', Env::get('expert_country_chat_model', Env::get('citation_chat_model', 'gpt-4.1'))));
$url = $this->resolveLlmChatUrl();
$model = $this->resolveLlmModel();
$apiKey = trim((string) Env::get('user_field_ai.chat_api_key', Env::get('expert_country_chat_api_key', Env::get('citation_chat_api_key', ''))));
if ($url === '' || $model === '') {
throw new Exception('user_field_ai chat not configured (chat_url / chat_model)');
throw new Exception('user_field_ai chat not configured (set user_field_ai.chat_url or promotion PROMOTION_LLM_URL / base.model_url)');
}
$payloadJson = json_encode($context, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
@@ -321,7 +378,10 @@ class UserFieldAiService
throw new Exception('LLM curl error: ' . $err);
}
if ($code < 200 || $code >= 300) {
throw new Exception('LLM HTTP ' . $code . ': ' . mb_substr((string) $raw, 0, 400));
$hint = ($code === 404 && stripos($url, 'chat/completions') === false)
? ' (chat_url may be missing /v1/chat/completions)'
: '';
throw new Exception('LLM HTTP ' . $code . $hint . ': ' . mb_substr((string) $raw, 0, 400));
}
$data = json_decode($raw, true);
@@ -378,7 +438,6 @@ class UserFieldAiService
}
Db::name('user_reviewer_info')->insert([
'reviewer_id' => $userId,
'ctime' => time(),
'state' => 0,
]);
}