更新
This commit is contained in:
@@ -5,11 +5,12 @@ declare(strict_types=1);
|
||||
namespace app\common\service\prescriptionai;
|
||||
|
||||
use app\common\service\DifyChatService;
|
||||
use app\common\service\NihaixiaClinicalSkill;
|
||||
|
||||
/** One model branch. It receives a saved context and never queries patient data. */
|
||||
final class PrescriptionAiGenerator
|
||||
{
|
||||
public const PROMPT_VERSION = 'manual-prescription-required-candidate-v4';
|
||||
public const PROMPT_VERSION = 'manual-prescription-required-candidate-nihaixia-v5';
|
||||
private const REPORT_KEYS = ['summary', 'diagnosis', 'risk_assessment', 'treatment_advice', 'evidence_references', 'missing_information'];
|
||||
private const RETRYABLE = ['UPSTREAM_TIMEOUT', 'UPSTREAM_BUSY', 'UPSTREAM_UNAVAILABLE', 'INCOMPLETE_RESPONSE', 'EMPTY_RESPONSE',
|
||||
'CANDIDATE_WITHHELD_BY_MODEL', 'INVALID_EVIDENCE_OUTPUT', 'INVALID_REPORT_OUTPUT'];
|
||||
@@ -212,12 +213,12 @@ final class PrescriptionAiGenerator
|
||||
// model prescribes plain names such as 麦冬 while the clinic stocks 生麦冬, and every
|
||||
// row is then an unmappable identity rather than a comparable one.
|
||||
$catalogNames = self::catalogNames($context, $inputBudget);
|
||||
if (strlen(self::finalPrompt([], $coverage, $candidateBlocked, $requireCandidate, $dispensing, $catalogNames, $readIds)) + ($insistRounds > 0 ? self::INSIST_RESERVE : 0) > $inputBudget) {
|
||||
if (strlen(NihaixiaClinicalSkill::augmentQuery(self::finalPrompt([], $coverage, $candidateBlocked, $requireCandidate, $dispensing, $catalogNames, $readIds))) + ($insistRounds > 0 ? self::INSIST_RESERVE : 0) > $inputBudget) {
|
||||
throw new \RuntimeException('FINAL_CONTEXT_EXCEEDS_BUDGET');
|
||||
}
|
||||
// Include the complete coverage and prompt overhead when deciding to reduce evidence.
|
||||
$prompt = self::finalPrompt($summaries, $coverage, $candidateBlocked, $requireCandidate, $dispensing, $catalogNames, $readIds);
|
||||
for ($round = 0; strlen($prompt) + ($insistRounds > 0 ? self::INSIST_RESERVE : 0) > $inputBudget; $round++) {
|
||||
for ($round = 0; strlen(NihaixiaClinicalSkill::augmentQuery($prompt)) + ($insistRounds > 0 ? self::INSIST_RESERVE : 0) > $inputBudget; $round++) {
|
||||
if ($round >= 8) {
|
||||
throw new \RuntimeException('SYNTHESIS_BUDGET_EXCEEDED');
|
||||
}
|
||||
@@ -354,7 +355,7 @@ final class PrescriptionAiGenerator
|
||||
$progress['format_rejects'][count($progress['format_rejects'] ?? []) - 1]['content_length'] = $reject['content_length'];
|
||||
self::invalidateStep($key, $progress, $checkpoint);
|
||||
$repairPrompt = self::repairPrompt($prompt, $reject['rule']);
|
||||
if (strlen($repairPrompt) > $inputBudget) {
|
||||
if (strlen(NihaixiaClinicalSkill::augmentQuery($repairPrompt)) > $inputBudget) {
|
||||
return ['value' => $value, 'parsed' => null];
|
||||
}
|
||||
$repaired = self::step($key . ':repair', $repairPrompt, $files, $modelKey, $context, $progress, $transport, $checkpoint, $inputBudget, $maxCalls);
|
||||
@@ -382,6 +383,7 @@ final class PrescriptionAiGenerator
|
||||
|
||||
private static function step(string $key, string $prompt, array $files, string $model, array $context, array &$progress, callable $transport, ?callable $checkpoint, int $inputBudget, int $maxCalls): array
|
||||
{
|
||||
$prompt = NihaixiaClinicalSkill::augmentQuery($prompt);
|
||||
// UTF-8 byte length is a conservative upper bound for byte-fallback tokenizers. File
|
||||
// vision tokens depend on provider preprocessing and are tracked as unknown usage.
|
||||
if (strlen($prompt) > $inputBudget) {
|
||||
|
||||
Reference in New Issue
Block a user