Compare commits
4 Commits
a396ff86da
...
939baea34e
| Author | SHA1 | Date | |
|---|---|---|---|
| 939baea34e | |||
| 79068a28c1 | |||
| ddb9c9f603 | |||
| 9b9eec24c2 |
@@ -1504,8 +1504,7 @@ class References extends Base
|
||||
}
|
||||
|
||||
/**
|
||||
* 仅重跑某篇文章下 status=3(校对失败)的相关性记录(不清空,不抓摘要,不清洗文献内容)
|
||||
* 联合引用组会整组重跑。
|
||||
* 仅重跑某篇文章下 status=3(校对失败)的相关性记录:先将 status 重置为 0,其余与 referenceRelevanceCheckRecheckPendingAI 相同。
|
||||
* POST: p_article_id
|
||||
*/
|
||||
public function referenceRelevanceCheckRecheckFailedAI()
|
||||
|
||||
@@ -205,11 +205,10 @@ class ReferenceRelevanceCheckService
|
||||
}
|
||||
|
||||
/**
|
||||
* 仅重新校对某篇文章下 status=3(失败)的记录;不刷新 refer_text / 文献摘要,只重置结果字段后入队。
|
||||
* 联合引用组会整组重跑(与 enqueueRecheckFailedByPReferIdWithGroup 一致)。
|
||||
* 仅重新校对某篇文章下 status=3(失败)的记录:先将 status 重置为 0,其余与 recheckPendingOnlyByArticle 相同。
|
||||
*
|
||||
* @param int $pArticleId
|
||||
* @return array{p_article_id:int,reset:int,queued:int,check_ids:int[],transport:string,queue:string}
|
||||
* @return array{p_article_id:int,queued:int,check_ids:int[],transport:string,queue:string}
|
||||
*/
|
||||
public function recheckFailedOnlyByArticle($pArticleId)
|
||||
{
|
||||
@@ -222,12 +221,12 @@ class ReferenceRelevanceCheckService
|
||||
$rows = Db::name('article_reference_relevance_check_result')
|
||||
->where('p_article_id', $pArticleId)
|
||||
->where('status', self::RECORD_FAILED)
|
||||
->field('id,reference_no,am_id,text_start')
|
||||
->order('reference_no asc,am_id asc,text_start asc,id asc')
|
||||
->select();
|
||||
if (empty($rows)) {
|
||||
return [
|
||||
'p_article_id' => $pArticleId,
|
||||
'reset' => 0,
|
||||
'queued' => 0,
|
||||
'check_ids' => [],
|
||||
'transport' => self::TRANSPORT_RABBITMQ,
|
||||
@@ -235,26 +234,14 @@ class ReferenceRelevanceCheckService
|
||||
];
|
||||
}
|
||||
|
||||
$now = date('Y-m-d H:i:s');
|
||||
$resetFields = $this->relevanceCheckResultResetFields([
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
|
||||
$targetRows = [];
|
||||
foreach ($rows as $row) {
|
||||
$groupRows = $this->findCitationGroupRows($row);
|
||||
foreach ($groupRows as $gr) {
|
||||
$checkId = $this->resolveCheckRowId($gr);
|
||||
if ($checkId > 0) {
|
||||
$targetRows[$checkId] = $gr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$pendingJobs = [];
|
||||
foreach ($targetRows as $row) {
|
||||
$checkId = $this->resolveCheckRowId($row);
|
||||
Db::name('article_reference_relevance_check_result')->where('id', $checkId)->update($resetFields);
|
||||
$checkIds = [];
|
||||
foreach ($rows as $row) {
|
||||
$checkId = intval($row['id']);
|
||||
if ($checkId <= 0) {
|
||||
continue;
|
||||
}
|
||||
$checkIds[] = $checkId;
|
||||
$pendingJobs[] = [
|
||||
'check_id' => $checkId,
|
||||
'reference_no' => intval($row['reference_no']),
|
||||
@@ -262,14 +249,32 @@ class ReferenceRelevanceCheckService
|
||||
'text_start' => intval($row['text_start']),
|
||||
];
|
||||
}
|
||||
if (empty($checkIds)) {
|
||||
return [
|
||||
'p_article_id' => $pArticleId,
|
||||
'queued' => 0,
|
||||
'check_ids' => [],
|
||||
'transport' => self::TRANSPORT_RABBITMQ,
|
||||
'queue' => self::TRANSPORT_RABBITMQ,
|
||||
];
|
||||
}
|
||||
|
||||
$checkIds = $this->enqueueChecksSortedByReferenceNo($pendingJobs, $pArticleId, 'recheck_failed');
|
||||
Db::name('article_reference_relevance_check_result')
|
||||
->whereIn('id', $checkIds)
|
||||
->update([
|
||||
'status' => self::RECORD_PENDING,
|
||||
'queue_status' => self::QUEUE_PENDING,
|
||||
'retry_count' => 0,
|
||||
'error_msg' => '',
|
||||
'updated_at' => date('Y-m-d H:i:s'),
|
||||
]);
|
||||
|
||||
$queuedIds = $this->enqueueChecksSortedByReferenceNo($pendingJobs, $pArticleId, 'recheck_failed');
|
||||
|
||||
return [
|
||||
'p_article_id' => $pArticleId,
|
||||
'reset' => count($targetRows),
|
||||
'queued' => count($checkIds),
|
||||
'check_ids' => $checkIds,
|
||||
'queued' => count($queuedIds),
|
||||
'check_ids' => $queuedIds,
|
||||
'transport' => self::TRANSPORT_RABBITMQ,
|
||||
'queue' => self::TRANSPORT_RABBITMQ,
|
||||
];
|
||||
@@ -576,15 +581,18 @@ class ReferenceRelevanceCheckService
|
||||
}
|
||||
|
||||
$claims = $this->decodeClaimsJson(isset($row['claims_json']) ? $row['claims_json'] : '');
|
||||
$author_comment = $this->resolveAuthorCommentFromRow($row, $claims);
|
||||
$author_comment = $author_comment?"<b>[文献 ".intval($row['reference_no'])."]: </b>".$author_comment:$author_comment;
|
||||
$g['records'][] = [
|
||||
'check_id' => intval($row['id']),
|
||||
'reference_no' => intval($row['reference_no']),
|
||||
'am_id' => intval($row['am_id']),
|
||||
'status' => $st,
|
||||
'is_relevant' => intval($row['is_relevant']),
|
||||
'relevance_score' => $score,
|
||||
'is_pass' => $isPass,
|
||||
'reason' => (string)$row['reason'],
|
||||
'author_comment' => $this->resolveAuthorCommentFromRow($row, $claims),
|
||||
'author_comment' => $author_comment,
|
||||
'combined_relevance_score' => floatval($row['combined_relevance_score']),
|
||||
'combined_reason' => (string)$row['combined_reason'],
|
||||
'cite_group_refs' => (string)$row['cite_group_refs'],
|
||||
@@ -2474,11 +2482,11 @@ class ReferenceRelevanceCheckService
|
||||
->where('p_article_id', $pArticleId)
|
||||
->delete();
|
||||
|
||||
if ($articleId > 0 && $this->hasAmRefCheckStatusColumn()) {
|
||||
if ($articleId > 0) {
|
||||
Db::name('article_main')
|
||||
->where('article_id', $articleId)
|
||||
->whereIn('state', [0, 2])
|
||||
->update(['ref_check_status' => self::AM_STATUS_NONE]);
|
||||
->update(['ref_check_status' => self::ARTICLE_PROGRESS_NONE]);
|
||||
}
|
||||
|
||||
return intval($deleted);
|
||||
|
||||
@@ -464,7 +464,7 @@ Claim 具体内容见顶层 `claims`,combined_reason **只用字母指代**(
|
||||
"is_relevant": 0,
|
||||
"relevance_score": 0.45,
|
||||
"reason": "系统综述,主语一致。Claim覆盖:A✔ B✔ C部分 D✘。类型部分匹配。因缺 D 且 C 仅背景,未达 0.65,故 0.45。",
|
||||
"author_comment": "该文献与正文主张仅部分匹配,仍缺关键论点支撑。建议补充更直接覆盖核心结论的参考文献。"
|
||||
"author_comment": "该文献与正文主张仅部分对应,关键论点仍缺直接证据。请改引更能支撑核心结论的文献,或明确现有引用依据。"
|
||||
},
|
||||
{
|
||||
"reference_no": 2,
|
||||
@@ -478,8 +478,8 @@ Claim 具体内容见顶层 `claims`,combined_reason **只用字母指代**(
|
||||
|
||||
**顶层 claims**:本引用组共用,只写一次;键为 A/B/C…(按实际拆解数量),值为各 Claim 中文具体内容。
|
||||
**results 每条仅含**:reference_no、is_relevant、relevance_score、reason、author_comment。
|
||||
`author_comment` 规则:当 `relevance_score <= 0.65` 时必须生成(中文、礼貌、适合展示给作者、可执行,≤90字);当 `relevance_score > 0.65` 时必须返回空字符串 `""`。
|
||||
注意:`author_comment` 禁止出现 A/B/C/D、✔/✘、"Claim覆盖"、具体分值(如 0.65)等技术表达,需改写为作者易读总结。
|
||||
`author_comment` 规则:当 `relevance_score <= 0.65` 时必须生成(中文、**以期刊编辑审稿口吻**、礼貌可执行,**80–100字**,句尾需句号);当 `relevance_score > 0.65` 时必须返回空字符串 `""`。
|
||||
注意:`author_comment` 禁止出现 A/B/C/D、✔/✘、"Claim覆盖"、具体分值(如 0.65)等技术表达,需改写为作者易读的编辑批注。
|
||||
**禁止**在 results 各条中写 combined_relevance_score、combined_reason、cite_group_refs、claims。
|
||||
PROMPT;
|
||||
}
|
||||
@@ -502,7 +502,7 @@ PROMPT;
|
||||
if ($abstractText !== '') {
|
||||
$parts[] = "【文献摘要/清洗后内容(Europe PMC·PubMed·Crossref·PDF)】\n" . $abstractText;
|
||||
}
|
||||
$tail = '请严格按六步标准校对流程执行:①提取Claim→②提取文献证据→③Claim Mapping(✔/部分/✘)→④计算覆盖率→⑤判断支持类型→⑥输出分值与理由。先在 JSON 顶层 claims 写出各 Claim 具体内容(多事实背景句须拆出比较型/成因型/进展型/数据型独立 Claim),再对每篇文献给出单条 relevance_score(弱相关文献不得因联合抬高),最后写顶层 combined_relevance_score 与 combined_reason。results 每条只写 reference_no、is_relevant、relevance_score、reason、author_comment。author_comment 规则:score<=0.65 时输出给作者看的中文批注(礼貌、可执行,≤90字);score>0.65 时固定空字符串;author_comment 禁止出现 A/B/C/D、✔/✘、Claim覆盖、具体分值。禁止 reason_en、combined_reason_en、relevance_level、relevance_role、combined_is_relevant 等多余字段。';
|
||||
$tail = '请严格按六步标准校对流程执行:①提取Claim→②提取文献证据→③Claim Mapping(✔/部分/✘)→④计算覆盖率→⑤判断支持类型→⑥输出分值与理由。先在 JSON 顶层 claims 写出各 Claim 具体内容(多事实背景句须拆出比较型/成因型/进展型/数据型独立 Claim),再对每篇文献给出单条 relevance_score(弱相关文献不得因联合抬高),最后写顶层 combined_relevance_score 与 combined_reason。results 每条只写 reference_no、is_relevant、relevance_score、reason、author_comment。author_comment 规则:score<=0.65 时输出以期刊编辑审稿口吻的中文批注(礼貌、可执行,80–100字,句尾需句号);若出现“建议补充/补充文献/补充说明”等措辞,需改写为“建议替换/改引/明确现有依据”,避免引导新增文献编号;score>0.65 时固定空字符串;author_comment 禁止出现 A/B/C/D、✔/✘、Claim覆盖、具体分值。禁止 reason_en、combined_reason_en、relevance_level、relevance_role、combined_is_relevant 等多余字段。';
|
||||
if ($this->hasMixedReferTypes($referTypeMap)) {
|
||||
$tail .= ' 注意:本组为图书与期刊混排引用,务必按上方【各编号文献类型标注】分轨判断——图书/教材走「书目推断」轨(据书名、副标题、作者、ISBN、出版社判断主题,缺摘要不得默认 0.25);期刊/原始研究走「摘要核对」轨(据摘要/清洗内容逐项核对 claim)。同组内两类分别按各自标准独立打分,切勿用同一把尺子。';
|
||||
} elseif ($this->allReferType($referTypeMap, 'book')) {
|
||||
@@ -1612,27 +1612,28 @@ PROMPT;
|
||||
if ($authorComment !== '') {
|
||||
$authorComment = $this->sanitizeAuthorCommentText($authorComment);
|
||||
if ($authorComment !== '') {
|
||||
return mb_substr($authorComment, 0, 120);
|
||||
return $this->finalizeAuthorComment($authorComment);
|
||||
}
|
||||
}
|
||||
|
||||
$fallback = '该条参考文献与正文匹配度有限,关键论点仍缺直接证据。请改引更能支撑核心结论的文献,或明确现有引用依据。';
|
||||
$reason = trim((string)$reason);
|
||||
if ($reason === '') {
|
||||
return '该条参考文献与正文匹配度有限,建议补充更直接支持该论点的文献。';
|
||||
return $this->finalizeAuthorComment($fallback);
|
||||
}
|
||||
// 去掉显式分数结论,保留给作者可读的改进建议
|
||||
// 去掉显式分数结论,保留给作者可读的编辑批注
|
||||
$reason = preg_replace('/Claim覆盖[::].*/u', '', $reason);
|
||||
$reason = preg_replace('/故\s*(?:联合分?)?\s*[01](?:\.\d+)?[。.]?/u', '', $reason);
|
||||
$reason = trim((string)$reason);
|
||||
if ($reason === '') {
|
||||
return '该条参考文献与正文匹配度有限,建议补充更直接支持该论点的文献。';
|
||||
return $this->finalizeAuthorComment($fallback);
|
||||
}
|
||||
$reason = $this->sanitizeAuthorCommentText($reason);
|
||||
if ($reason === '') {
|
||||
return '该条参考文献与正文匹配度有限,建议补充更直接支持该论点的文献。';
|
||||
return $this->finalizeAuthorComment($fallback);
|
||||
}
|
||||
|
||||
return mb_substr('建议:' . $reason, 0, 120);
|
||||
return $this->finalizeAuthorComment($reason);
|
||||
}
|
||||
|
||||
private function sanitizeAuthorCommentText($text)
|
||||
@@ -1646,12 +1647,26 @@ PROMPT;
|
||||
$text = preg_replace('/[✔✘]/u', '', $text);
|
||||
$text = preg_replace('/\b0?\.\d{1,2}\b/u', '', $text);
|
||||
$text = preg_replace('/\b\d{1,3}%\b/u', '', $text);
|
||||
$text = preg_replace('/建议\s*补充/u', '建议替换', $text);
|
||||
$text = preg_replace('/补充文献/u', '替换文献', $text);
|
||||
$text = preg_replace('/补充说明/u', '明确依据', $text);
|
||||
$text = preg_replace('/\s{2,}/u', ' ', $text);
|
||||
$text = trim((string)$text, " \t\n\r\0\x0B;;,,");
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
private function finalizeAuthorComment($text)
|
||||
{
|
||||
$text = mb_substr(trim((string)$text), 0, 100);
|
||||
$text = trim($text, " \t\n\r\0\x0B;;,,。");
|
||||
if ($text === '') {
|
||||
return '';
|
||||
}
|
||||
|
||||
return $text . '。';
|
||||
}
|
||||
|
||||
private function boolVal($v)
|
||||
{
|
||||
if (is_bool($v)) {
|
||||
|
||||
Reference in New Issue
Block a user