model = $this->modelService->getModelById($id); $this->modelToken = AuthController::getUserToken($id); return $this; } private function query(string $word): array { $search = app(OpenSearchService::class); // 组装搜索参数 $params = [ 'query' => $word, 'resourceType' => 'tipitaka', 'granularity' => 'paragraph', 'pageSize' => $this->pageSize, ]; $result = $search->search($params); $dto = SearchDataDTO::fromArray($result); $res = array(); foreach ($dto->hits->items as $key => $item) { $res[] = [ 'title' => $item->title, 'content' => $item->content, 'path' => $item->path, 'pid' => $item->getParaId(), 'link' => $item->getParaLink() ]; } Log::debug('query ' . count($res)); return $res; } public function update(string $id) { // 获取术语 $term = $this->termService->getRaw($id); // 全文搜索 $query = $this->query($term->word); $res = json_encode($query, JSON_UNESCAPED_UNICODE); $resText = "# 搜索结果\n```json\n{$res}\n```\n"; $termText = "# 巴利术语\n\n{$term->word}\n\n"; //LLM 生成 $response = $this->openAIService->setApiUrl($this->model['url']) ->setModel($this->model['model']) ->setApiKey($this->model['key']) ->setSystemPrompt($this->sysPrompt) ->setTemperature(0.5) ->setStream(false) ->send($resText . $termText); $content = $response['choices'][0]['message']['content'] ?? ''; //输出自检报告 Log::debug('llm response', ['strlen' => $content]); $paraIds = $this->extractAllParaIds($content); Log::debug('has paragraph ref ', ['total' => count($paraIds), 'id' => $paraIds]); $searchPid = array_map(fn($item) => $item['pid'], $query); $diff = array_values(array_diff($paraIds, $searchPid)); Log::debug('diff', ['total' => count($diff), 'data' => $diff]); $this->termService->update($id, ['note' => $content]); return $content; } public function create(string $word) {} /** * Extract all unique ID values from MediaWiki template parameter strings * * Parses a string that may contain multiple "{{para|...}}" templates * and returns an array of unique 'id' parameter values found. * * @param string $str The input string containing zero or more {{para|...}} templates * @return array Array of unique extracted ID values (e.g., ['16-1376', 'ABC-123']) * Returns empty array if no IDs are found * * @example * // Single template * extractAllParaIds('{{para|id=16-1376|title=test}}') * // returns ['16-1376'] * * // Multiple templates with duplicates * extractAllParaIds('{{para|id=16-1376}} and {{para|id=16-1376|style=ref}}') * // returns ['16-1376'] (duplicate removed) * * // Multiple unique IDs * extractAllParaIds('{{para|id=16-1376}} {{para|id=ABC-123}} {{para|id=16-1376}}') * // returns ['16-1376', 'ABC-123'] */ public function extractAllParaIds(string $str): array { $ids = []; // Find all {{para|...}} patterns if (preg_match_all('/{{para\|(.*?)}}/', $str, $matches)) { foreach ($matches[1] as $content) { // Extract id= value from each template content if (preg_match('/id=([^|&}]+)/', $content, $idMatch)) { $ids[] = $idMatch[1]; } } } // Remove duplicates and preserve order of first occurrence return array_values(array_unique($ids)); } }