optimize ux think mode
This commit is contained in:
@@ -13,10 +13,11 @@ use App\Knowledge\Retrieval\RetrieverInterface;
|
||||
use Generator;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Throwable;
|
||||
use App\Agent\StreamChunker;
|
||||
|
||||
final readonly class AgentRunner
|
||||
{
|
||||
private bool $systemMsgOn;
|
||||
|
||||
public function __construct(
|
||||
private PromptBuilder $promptBuilder,
|
||||
private ThinkSuppressor $thinkSuppressor,
|
||||
@@ -32,12 +33,14 @@ final readonly class AgentRunner
|
||||
private bool $logContext,
|
||||
)
|
||||
{
|
||||
$this->systemMsgOn = true;
|
||||
}
|
||||
|
||||
public function run(string $prompt, string $userId, ?bool $includeFullContext = false): Generator
|
||||
public function run(string $prompt, string $userId, ?bool $includeFullContext = true): Generator
|
||||
{
|
||||
$prompt = trim($prompt);
|
||||
$shopResults = [];
|
||||
$swagFullOutPut = '';
|
||||
|
||||
if ($prompt === '') {
|
||||
yield '❌ Empty prompt.';
|
||||
@@ -53,6 +56,49 @@ final readonly class AgentRunner
|
||||
// 1) Context strategy
|
||||
// ---------------------------------------------------------
|
||||
//$includeFullContext = false;
|
||||
if ($includeFullContext) {
|
||||
|
||||
yield $this->systemMsg("Ich analyse deine Anfrage...", "think");
|
||||
|
||||
$promptSwagSearch = '
|
||||
Erzeuge aus dem folgenden Nutzereingabetext einen kurzen Suchtext für die Shopware-6-Suche.
|
||||
|
||||
Regeln:
|
||||
- Gib nur den finalen Suchtext aus.
|
||||
- Keine Einleitung, keine Erklärung, keine Anführungszeichen.
|
||||
- Verwende nur die wichtigsten Suchbegriffe aus dem Text.
|
||||
- Maximal 6 Keywords, besser weniger.
|
||||
- Entferne Füllwörter, Höflichkeitsformen und irrelevante Wörter.
|
||||
- Erhalte Produktnamen, Marken, Modellnummern und zusammengesetzte Begriffe exakt, wenn sie relevant sind.
|
||||
- Zahlen, die zu einem Produktnamen oder Modell gehören, müssen erhalten bleiben.
|
||||
- Trenne die Begriffe nur durch Leerzeichen.
|
||||
|
||||
Ausgabeformat:
|
||||
Keyword1 Keyword2 Keyword3
|
||||
|
||||
Text: ' . $prompt . '
|
||||
';
|
||||
|
||||
$this->thinkSuppressor->reset();
|
||||
foreach ($this->ollamaClient->stream($promptSwagSearch) as $swagToken) {
|
||||
|
||||
if (!is_string($swagToken)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$swagCleanToken = $this->thinkSuppressor->filter($swagToken);
|
||||
|
||||
if ($swagCleanToken === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$swagFullOutPut .= $swagCleanToken;
|
||||
}
|
||||
|
||||
yield $this->systemMsg("Ich habe folgende Keywords an die Shopsuche geschickt: " . $swagFullOutPut, "think");
|
||||
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// 2) Extract URL content (if present)
|
||||
@@ -62,7 +108,7 @@ final readonly class AgentRunner
|
||||
// ---------------------------------------------------------
|
||||
// 3) Retrieve RAG knowledge
|
||||
// ---------------------------------------------------------
|
||||
yield "Hole Daten aus dem RAG Wissen... \n";
|
||||
yield $this->systemMsg("Ich hole relevante Daten aus meinem RAG Wissen...", "think");
|
||||
|
||||
$knowledgeChunks = $this->retriever->retrieve($prompt);
|
||||
|
||||
@@ -71,11 +117,11 @@ final readonly class AgentRunner
|
||||
// ---------------------------------------------------------
|
||||
|
||||
$commerceMeta = $this->commerceIntentLite->detect($prompt);
|
||||
$commerceIntent = (string) ($commerceMeta['intent'] ?? CommerceIntentLite::NONE);
|
||||
$commerceIntent = (string)($commerceMeta['intent'] ?? CommerceIntentLite::NONE);
|
||||
|
||||
if($commerceIntent === CommerceIntentLite::ADVISORY_PRODUCT_SEARCH || $commerceIntent === CommerceIntentLite::PRODUCT_SEARCH){
|
||||
yield "Rufe Shop auf (type: ".$commerceIntent.")... \n";
|
||||
$shopResults = $this->shopSearchService->search($prompt,$commerceIntent);
|
||||
if ($commerceIntent === CommerceIntentLite::ADVISORY_PRODUCT_SEARCH || $commerceIntent === CommerceIntentLite::PRODUCT_SEARCH) {
|
||||
yield $this->systemMsg("Rufe Shop auf (type: " . $commerceIntent . ")", "think");
|
||||
$shopResults = $swagFullOutPut ? $this->shopSearchService->search($swagFullOutPut, $commerceIntent) : '';
|
||||
}
|
||||
|
||||
if ($commerceIntent === CommerceIntentLite::PRODUCT_SEARCH) {
|
||||
@@ -84,13 +130,13 @@ final readonly class AgentRunner
|
||||
$knowledgeChunks = array_slice($knowledgeChunks, 0, 3);
|
||||
}
|
||||
|
||||
if($shopResults){
|
||||
yield "Verarbeite Shopdaten... \n<hr>\n";
|
||||
}else{
|
||||
yield "Keine releveanten Shopdaten gefunden... \n<hr>\n";
|
||||
if ($shopResults) {
|
||||
yield $this->systemMsg("Verarbeite Shopdaten...", "think");
|
||||
} else {
|
||||
yield $this->systemMsg("Keine releveanten Shopdaten gefunden...", "think");
|
||||
}
|
||||
|
||||
yield "Denke nach...\n<hr>\n";
|
||||
yield $this->systemMsg("Denke nach...", "think");
|
||||
|
||||
|
||||
// ---------------------------------------------------------
|
||||
@@ -123,6 +169,8 @@ final readonly class AgentRunner
|
||||
// ---------------------------------------------------------
|
||||
$fullOutput = '';
|
||||
$chunker = new StreamChunker();
|
||||
$chunker->flush();
|
||||
$this->thinkSuppressor->reset();
|
||||
|
||||
foreach ($this->ollamaClient->stream($finalPrompt) as $token) {
|
||||
|
||||
@@ -142,16 +190,16 @@ final readonly class AgentRunner
|
||||
// ⬇️ Token in Chunker geben
|
||||
$chunk = $chunker->push($cleanToken);
|
||||
if ($chunk !== null) {
|
||||
yield $chunk;
|
||||
yield $this->systemMsg($chunk, 'answer');
|
||||
}
|
||||
}
|
||||
|
||||
// ⬇️ Rest flushen
|
||||
$finalChunk = $chunker->flush();
|
||||
if ($finalChunk !== null) {
|
||||
yield $finalChunk;
|
||||
yield $this->systemMsg($finalChunk, 'answer');
|
||||
} else {
|
||||
yield '... no data received from llm';
|
||||
yield $this->systemMsg('... no data received from llm', 'err');
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------
|
||||
@@ -176,7 +224,20 @@ final readonly class AgentRunner
|
||||
'exception' => $e,
|
||||
]);
|
||||
|
||||
yield "\n❌ An internal error occurred while processing the request. \nError: " . $e->getMessage();
|
||||
$this->systemMsg("\n❌ An internal error occurred while processing the request. \nError: " . $e->getMessage(), 'err');
|
||||
}
|
||||
}
|
||||
|
||||
private function systemMsg(string $msg, string $type = ''): string
|
||||
{
|
||||
if (!$this->systemMsgOn) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return match ($type) {
|
||||
'answer' => '' . $msg,
|
||||
'err' => '<span class="text-danger">' . $msg . "</span>\n<hr>\n",
|
||||
'think' => '<span class="text-info think">' . $msg . "</span>\n"
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user