更新
This commit is contained in:
@@ -41,8 +41,15 @@ skillExpect(NihaixiaClinicalSkill::augmentMessages($augmented) === $augmented, '
|
||||
|
||||
$source = NihaixiaClinicalSkill::knowledgeSource();
|
||||
skillExpect($source['commit'] === '270e94e637c4249dc411e54ac6715f21247de3cb', 'metadata pins the complete vendored commit');
|
||||
skillExpect($source['url'] === NihaixiaClinicalSkill::REPOSITORY_URL . '/blob/' . $source['commit'] . '/SKILL.md', 'metadata links directly to the fixed skill document');
|
||||
skillExpect($source['url'] === '' && $source['path'] === 'SKILL.md', 'metadata points to the locally installed skill without an external link');
|
||||
skillExpect($source['sections'] === ['六经速查表', '六经辨证诊断公式', '七步走辨证思维模式'], 'metadata names only the extracted sections');
|
||||
$savedSource = $source;
|
||||
$savedSource['url'] = 'https://github.com/coinweth/nihaixia-skill/blob/' . $source['commit'] . '/SKILL.md';
|
||||
unset($savedSource['path']);
|
||||
$localizedSource = NihaixiaClinicalSkill::localizeKnowledgeSource($savedSource);
|
||||
skillExpect($localizedSource['url'] === '' && $localizedSource['path'] === 'SKILL.md'
|
||||
&& $localizedSource['commit'] === $source['commit'] && $localizedSource['sections'] === $source['sections'],
|
||||
'saved skill source loses the external URL and retains its local file');
|
||||
skillExpect(NihaixiaClinicalSkill::knowledgeSourceForPromptVersion('patient-longitudinal-report-v2') === null, 'legacy prompt versions do not acquire fabricated sources');
|
||||
skillExpect(NihaixiaClinicalSkill::knowledgeSourceForPromptVersion('patient-longitudinal-report-nihaixia-ancient-v4') === $source, 'new ancient-book reports retain the existing skill attribution');
|
||||
|
||||
|
||||
@@ -40,7 +40,9 @@ $query = '患者糖尿病、高血糖,请分析病症。';
|
||||
$sources = TcmAncientBooksReference::sourcesForText($query);
|
||||
ancientExpect(count($sources) === 1, 'matching patient symptoms select one excerpt');
|
||||
ancientExpect($sources[0]['title'] === '测试古籍' && $sources[0]['chapter'] === '消渴篇', 'book and chapter retained');
|
||||
ancientExpect(str_ends_with($sources[0]['url'], '/123-%E6%B5%8B%E8%AF%95%E5%8F%A4%E7%B1%8D.txt#L42'), 'permalink pins file and line');
|
||||
ancientExpect($sources[0]['url'] === '' && $sources[0]['path'] === '123-测试古籍.txt' && $sources[0]['line'] === 42,
|
||||
'local citation retains file and line without an external URL');
|
||||
ancientExpect($sources[0]['excerpt'] === '原文中谈到消渴的历史记载。', 'local citation retains verifiable original text');
|
||||
ancientExpect(TcmAncientBooksReference::sourcesForText('请分析耳鸣。') === [], 'unmatched symptoms have no invented citation');
|
||||
ancientExpect(TcmAncientBooksReference::sourcesForText('患者出现痛风症状。')[0]['line'] === 88, 'unlisted diseases can match indexed chapter headings');
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@ require dirname(__DIR__) . '/vendor/autoload.php';
|
||||
|
||||
use app\adminapi\logic\tcm\DiagnosisAiLogic;
|
||||
use app\adminapi\logic\tcm\PatientAiReportLogic;
|
||||
use app\adminapi\logic\tcm\PrescriptionAiLogic;
|
||||
use app\common\service\NihaixiaClinicalSkill;
|
||||
use app\common\service\TcmAncientBooksReference;
|
||||
|
||||
function provenanceExpect(bool $condition, string $message): void
|
||||
@@ -18,10 +20,15 @@ function provenanceExpect(bool $condition, string $message): void
|
||||
|
||||
$source = [
|
||||
'title' => '测试古籍', 'chapter' => '消渴篇', 'path' => '123-测试古籍.txt',
|
||||
'excerpt' => '原文中谈到消渴的历史记载。',
|
||||
'line' => 42, 'commit' => TcmAncientBooksReference::COMMIT,
|
||||
'url' => TcmAncientBooksReference::REPOSITORY_URL . '/blob/'
|
||||
'url' => 'https://github.com/xiaopangxia/TCM-Ancient-Books/blob/'
|
||||
. TcmAncientBooksReference::COMMIT . '/123-%E6%B5%8B%E8%AF%95%E5%8F%A4%E7%B1%8D.txt#L42',
|
||||
];
|
||||
$localizedSource = $source;
|
||||
$localizedSource['url'] = '';
|
||||
$localized = TcmAncientBooksReference::localizeSources([$source]);
|
||||
provenanceExpect($localized === [$localizedSource], 'saved citation drops external URL without losing original text or location');
|
||||
$json = json_encode([$source], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
||||
|
||||
$diagnosisFormat = new ReflectionMethod(DiagnosisAiLogic::class, 'formatReportRow');
|
||||
@@ -30,7 +37,7 @@ $diagnosis = $diagnosisFormat->invoke(null, [
|
||||
'prompt_version' => 'patient-context-case-explain-nihaixia-ancient-v4',
|
||||
'ancient_book_sources_json' => $json,
|
||||
], '');
|
||||
provenanceExpect($diagnosis['ancient_book_sources'] === [$source], 'diagnosis report retains saved book and line');
|
||||
provenanceExpect($diagnosis['ancient_book_sources'] === [$localizedSource], 'diagnosis report localizes saved book and line');
|
||||
$oldDiagnosis = $diagnosisFormat->invoke(null, ['report_content' => '{}', 'prompt_version' => 'legacy-v2'], '');
|
||||
provenanceExpect($oldDiagnosis['ancient_book_sources'] === [], 'old diagnosis report gets no ancient citation');
|
||||
|
||||
@@ -40,8 +47,32 @@ $patient = $patientFormat->invoke(null, [
|
||||
'prompt_version' => 'patient-longitudinal-report-nihaixia-ancient-v4',
|
||||
'ancient_book_sources_json' => $json,
|
||||
]);
|
||||
provenanceExpect($patient['ancient_book_sources'] === [$source], 'patient report retains saved book and line');
|
||||
provenanceExpect($patient['ancient_book_sources'] === [$localizedSource], 'patient report localizes saved book and line');
|
||||
$oldPatient = $patientFormat->invoke(null, ['report_json' => '{}', 'prompt_version' => 'legacy-v2']);
|
||||
provenanceExpect($oldPatient['ancient_book_sources'] === [], 'old patient report gets no ancient citation');
|
||||
$anotherSource = $source;
|
||||
$anotherSource['path'] = '124-测试古籍二.txt';
|
||||
$anotherSource['line'] = 88;
|
||||
$anotherSource['url'] = 'https://github.com/xiaopangxia/TCM-Ancient-Books/blob/'
|
||||
. TcmAncientBooksReference::COMMIT . '/124-%E6%B5%8B%E8%AF%95%E5%8F%A4%E7%B1%8D%E4%BA%8C.txt#L88';
|
||||
$mergeSources = new ReflectionMethod(PatientAiReportLogic::class, 'mergeAncientBookSources');
|
||||
$merged = $mergeSources->invoke(null, [$localizedSource], ['ancient_book_sources' => [$source, $anotherSource]]);
|
||||
$localizedAnother = $anotherSource;
|
||||
$localizedAnother['url'] = '';
|
||||
provenanceExpect($merged === [$localizedSource, $localizedAnother], 'different local file lines remain distinct while duplicates collapse');
|
||||
|
||||
$prescriptionBody = [
|
||||
'report' => ['diagnosis' => '保留原有报告'],
|
||||
'knowledge_source' => NihaixiaClinicalSkill::knowledgeSource(),
|
||||
'ancient_book_sources' => [$source],
|
||||
];
|
||||
$prescriptionBody['knowledge_source']['url'] = 'https://github.com/coinweth/nihaixia-skill/blob/'
|
||||
. NihaixiaClinicalSkill::COMMIT . '/SKILL.md';
|
||||
$localizePrescription = new ReflectionMethod(PrescriptionAiLogic::class, 'localizeSourceMetadata');
|
||||
$prescription = $localizePrescription->invoke(null, $prescriptionBody);
|
||||
provenanceExpect($prescription['report'] === $prescriptionBody['report'], 'prescription report content is preserved');
|
||||
provenanceExpect($prescription['knowledge_source']['url'] === ''
|
||||
&& $prescription['knowledge_source']['path'] === 'SKILL.md', 'saved prescription skill source is local');
|
||||
provenanceExpect($prescription['ancient_book_sources'] === [$localizedSource], 'saved prescription book citation is local');
|
||||
|
||||
echo "TCM ancient-books report provenance contract passed.\n";
|
||||
|
||||
Reference in New Issue
Block a user