From 39849d22cb845ac13d06adfa4210921318237dd2 Mon Sep 17 00:00:00 2001 From: team 1 Date: Sun, 19 Apr 2026 14:49:51 +0200 Subject: [PATCH] new config PromptBuilderConfig.php --- src/Agent/PromptBuilder.php | 114 ++++------------------------- src/Commerce/ShopSearchService.php | 2 - src/Config/PromptBuilderConfig.php | 96 ++++++++++++++++++++++++ 3 files changed, 109 insertions(+), 103 deletions(-) create mode 100644 src/Config/PromptBuilderConfig.php diff --git a/src/Agent/PromptBuilder.php b/src/Agent/PromptBuilder.php index 975b955..d2de794 100644 --- a/src/Agent/PromptBuilder.php +++ b/src/Agent/PromptBuilder.php @@ -5,6 +5,7 @@ declare(strict_types=1); namespace App\Agent; use App\Commerce\Dto\ShopProductResult; +use App\Config\PromptBuilderConfig; use App\Context\ContextService; use App\Repository\SystemPromptRepository; use App\Service\ModelGenerationConfigProvider; @@ -13,95 +14,6 @@ use RuntimeException; final readonly class PromptBuilder { - /** - * Approximate character-to-token ratio for conservative prompt budgeting. - */ - private const CHARS_PER_TOKEN = 4; - - /** - * Keep a small gap so history does not consume the last available prompt space. - */ - private const HISTORY_PADDING_CHARS = 400; - - /** - * Reserve some space for the model output. - */ - private const OUTPUT_RESERVE_RATIO = 0.25; - private const OUTPUT_RESERVE_MIN_TOKENS = 768; - private const OUTPUT_RESERVE_MAX_TOKENS = 6000; - - /** - * Reserve a small safety buffer to avoid hitting the context limit too tightly. - */ - private const SAFETY_RESERVE_RATIO = 0.05; - private const SAFETY_RESERVE_MIN_TOKENS = 256; - private const SAFETY_RESERVE_MAX_TOKENS = 1024; - - /** - * Ensure the prompt budget never collapses completely on smaller models. - */ - private const MIN_PROMPT_BUDGET_TOKENS = 1024; - - /** - * Limit how many ranked shop results are passed into the final prompt. - * The shop search may return many candidates, but the LLM should only see - * the most relevant top subset after local reranking. - */ - private const MAX_SHOP_RESULTS_IN_PROMPT = 8; - - /** - * Technical product prompts should be answered like documentation, - * not like sales copy. - */ - private const TECHNICAL_PRODUCT_KEYWORDS = [ - 'technisch', - 'technical', - 'produkt', - 'product', - 'gerät', - 'device', - 'modell', - 'model', - 'messprinzip', - 'measurement principle', - 'schnittstelle', - 'interface', - 'relais', - 'relay', - 'indikator', - 'indicator', - 'spannung', - 'voltage', - 'strom', - 'current', - 'druck', - 'pressure', - 'temperatur', - 'temperature', - 'schutzart', - 'ip', - 'fehlercode', - 'error code', - 'wasserhärte', - 'hardness', - 'testomat', - ]; - - private const ACCESSORY_REQUEST_KEYWORDS = [ - 'passend', - 'passende', - 'passendes', - 'zubehör', - 'zubehor', - 'dazu', - 'indikator', - 'reagenz', - 'kit', - 'set', - 'zusatz', - 'ergänzung', - 'ergaenzung', - ]; public function __construct( private ContextService $contextService, @@ -257,7 +169,7 @@ final readonly class PromptBuilder } $totalCount = count($normalizedShopResults); - $limitedShopResults = array_slice($normalizedShopResults, 0, self::MAX_SHOP_RESULTS_IN_PROMPT); + $limitedShopResults = array_slice($normalizedShopResults, 0, PromptBuilderConfig::MAX_SHOP_RESULTS_IN_PROMPT); $isDetailed = count($limitedShopResults) <= 5; $lines = []; @@ -440,27 +352,27 @@ final readonly class PromptBuilder $numCtx = $this->modelGenerationConfigProvider->getActiveNumCtx(); $outputReserveTokens = $this->clamp( - (int) floor($numCtx * self::OUTPUT_RESERVE_RATIO), - self::OUTPUT_RESERVE_MIN_TOKENS, - self::OUTPUT_RESERVE_MAX_TOKENS + (int) floor($numCtx * PromptBuilderConfig::OUTPUT_RESERVE_RATIO), + PromptBuilderConfig::OUTPUT_RESERVE_MIN_TOKENS, + PromptBuilderConfig::OUTPUT_RESERVE_MAX_TOKENS ); $safetyReserveTokens = $this->clamp( - (int) floor($numCtx * self::SAFETY_RESERVE_RATIO), - self::SAFETY_RESERVE_MIN_TOKENS, - self::SAFETY_RESERVE_MAX_TOKENS + (int) floor($numCtx * PromptBuilderConfig::SAFETY_RESERVE_RATIO), + PromptBuilderConfig::SAFETY_RESERVE_MIN_TOKENS, + PromptBuilderConfig::SAFETY_RESERVE_MAX_TOKENS ); $promptBudgetTokens = max( - self::MIN_PROMPT_BUDGET_TOKENS, + PromptBuilderConfig::MIN_PROMPT_BUDGET_TOKENS, $numCtx - $outputReserveTokens - $safetyReserveTokens ); - $promptBudgetChars = $promptBudgetTokens * self::CHARS_PER_TOKEN; + $promptBudgetChars = $promptBudgetTokens * PromptBuilderConfig::CHARS_PER_TOKEN; $remaining = $promptBudgetChars - mb_strlen($fixedPrompt) - - self::HISTORY_PADDING_CHARS; + - PromptBuilderConfig::HISTORY_PADDING_CHARS; return max(0, $remaining); } @@ -577,7 +489,7 @@ final readonly class PromptBuilder $matches = 0; - foreach (self::TECHNICAL_PRODUCT_KEYWORDS as $keyword) { + foreach (PromptBuilderConfig::TECHNICAL_PRODUCT_KEYWORDS as $keyword) { if (str_contains($normalized, $keyword)) { $matches++; } @@ -594,7 +506,7 @@ final readonly class PromptBuilder { $normalized = mb_strtolower($prompt, 'UTF-8'); - foreach (self::ACCESSORY_REQUEST_KEYWORDS as $keyword) { + foreach (PromptBuilderConfig::ACCESSORY_REQUEST_KEYWORDS as $keyword) { if (str_contains($normalized, $keyword)) { return true; } diff --git a/src/Commerce/ShopSearchService.php b/src/Commerce/ShopSearchService.php index 79a5e1e..f015d63 100644 --- a/src/Commerce/ShopSearchService.php +++ b/src/Commerce/ShopSearchService.php @@ -115,8 +115,6 @@ final readonly class ShopSearchService ): array { $criteria = $this->criteriaBuilder->build($query, $this->maxResults); - $response = []; - try { $response = $this->storeApiClient->searchProducts($criteria); } catch ( diff --git a/src/Config/PromptBuilderConfig.php b/src/Config/PromptBuilderConfig.php new file mode 100644 index 0000000..03c85c6 --- /dev/null +++ b/src/Config/PromptBuilderConfig.php @@ -0,0 +1,96 @@ +