SuperSeller3000/src/Infrastructure/AI/Agent/OllamaVisionAgent.php
Simon Kuehn 974bd239a5 fix: prevent serial bleed into MODEL_NUMBER in vision output
Parser now strips any embedded field labels (e.g. "SERIAL: x") that the
LLM mistakenly appends to a field value. Prompt updated with a concrete
example showing MODEL_NUMBER as blank to reinforce leaving it empty when
no separate part code is visible.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 10:19:17 +00:00

47 lines
1.5 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Infrastructure\AI\Agent;
use App\Infrastructure\AI\OllamaClientInterface;
use App\Infrastructure\AI\PromptTemplateService;
final class OllamaVisionAgent
{
public function __construct(
private readonly OllamaClientInterface $ollama,
private readonly PromptTemplateService $prompts,
private readonly string $model,
) {
}
/** @return array{manufacturer: string, modelName: string, modelNumber: string, serial: string} */
public function analyze(string $imagePath): array
{
$prompt = $this->prompts->render('vision_analyze');
$response = $this->ollama->generateWithImage($this->model, $prompt, $imagePath);
return [
'manufacturer' => $this->extractField($response, 'MANUFACTURER'),
'modelName' => $this->extractField($response, 'MODEL_NAME'),
'modelNumber' => $this->extractField($response, 'MODEL_NUMBER'),
'serial' => $this->extractField($response, 'SERIAL'),
];
}
private function extractField(string $response, string $field): string
{
if (!preg_match('/^'.$field.':\s*(.*)$/m', $response, $matches)) {
return '';
}
$value = trim($matches[1]);
// Strip any embedded field label the model mistakenly included (e.g. "SERIAL: PNV09SJZ")
$value = preg_replace('/\s+[A-Z_]+:.*$/i', '', $value) ?? $value;
return trim($value);
}
}