first commit
This commit is contained in:
136
src/Agent/PromptBuilder.php
Normal file
136
src/Agent/PromptBuilder.php
Normal file
@@ -0,0 +1,136 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Agent;
|
||||
|
||||
use App\Context\ContextService;
|
||||
use App\Context\UrlAnalyzer;
|
||||
use DateTimeImmutable;
|
||||
|
||||
final class PromptBuilder
|
||||
{
|
||||
public function __construct(
|
||||
private readonly ContextService $contextService,
|
||||
private readonly UrlAnalyzer $urlAnalyzer,
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the final prompt string for the LLM.
|
||||
*
|
||||
* @param string $prompt
|
||||
* @param string $userId
|
||||
* @param string $urlContent
|
||||
* @param string[] $knowledgeChunks
|
||||
* @param bool $fullContext
|
||||
*/
|
||||
public function build(
|
||||
string $prompt,
|
||||
string $userId,
|
||||
string $urlContent,
|
||||
array $knowledgeChunks,
|
||||
bool $fullContext = false,
|
||||
): string
|
||||
{
|
||||
$now = (new DateTimeImmutable())->format('Y-m-d H:i:s');
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// 1) SYSTEM INSTRUCTIONS
|
||||
// ------------------------------------------------------------
|
||||
$systemLines = [
|
||||
'You are a conversational AI assistant.',
|
||||
'Respond clearly, precisely, and in context of the ongoing conversation.',
|
||||
'The conversation context is authoritative and must be respected.',
|
||||
'External knowledge is supporting information only.',
|
||||
'If the user asks for contact details such as phone number, email address, postal address or contact person, and the provided context contains such information, answer explicitly with the concrete data.',
|
||||
'Do not omit contact details.',
|
||||
'It is allowed and desired to quote contact data verbatim if it appears in the context.',
|
||||
"Current date and time: {$now}",
|
||||
'',
|
||||
'IMPORTANT FORMATTING RULES:',
|
||||
'- Always answer in valid Markdown.',
|
||||
'- Use headings, lists, and paragraphs where appropriate.',
|
||||
'- Insert line breaks early and often.',
|
||||
'- Never write long paragraphs without newlines.',
|
||||
'- Each list item must start on a new line.',
|
||||
'- Prefer short paragraphs over dense text blocks.',
|
||||
'',
|
||||
'IMPORTANT LANGUAGE RULES:',
|
||||
'- If the user input contains misspellings, silently use the correct canonical terms in your answer.',
|
||||
'- Never mention, explain, or point out spelling mistakes.',
|
||||
'- Do not ask clarifying questions about possible misspellings.',
|
||||
'- Do not repeat or quote misspelled terms from the user input.',
|
||||
'- Always use the correct technical spelling found in the provided context.',
|
||||
'- Answer directly and confidently using always correct canonical terminology.'
|
||||
];
|
||||
|
||||
$systemBlock = "SYSTEM:\n" . implode("\n", $systemLines);
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// 2) CONVERSATION CONTEXT (AUTHORITATIVE)
|
||||
// ------------------------------------------------------------
|
||||
$history = $this->contextService->buildUserContext(
|
||||
userId: $userId,
|
||||
full: $fullContext
|
||||
);
|
||||
|
||||
$contextBlock = '';
|
||||
if ($history !== '') {
|
||||
$contextBlock =
|
||||
"CONVERSATION CONTEXT (authoritative):\n" .
|
||||
"The following messages are the previous turns of this conversation.\n" .
|
||||
"They must be considered when answering the next question.\n\n" .
|
||||
$history;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// 3) EXTERNAL KNOWLEDGE (SUPPORTING)
|
||||
// ------------------------------------------------------------
|
||||
$knowledgeParts = [];
|
||||
|
||||
if ($knowledgeChunks !== []) {
|
||||
$lines = [];
|
||||
|
||||
foreach ($knowledgeChunks as $i => $chunk) {
|
||||
$n = $i + 1;
|
||||
$lines[] = "[{$n}] {$chunk}";
|
||||
}
|
||||
|
||||
$knowledgeParts[] =
|
||||
"RETRIEVED KNOWLEDGE (supporting):\n" .
|
||||
implode("\n\n", $lines);
|
||||
}
|
||||
|
||||
if ($urlContent !== '') {
|
||||
$knowledgeParts[] =
|
||||
"CONTENT FROM URL (supporting):\n" .
|
||||
$urlContent;
|
||||
}
|
||||
|
||||
$knowledgeBlock = '';
|
||||
if ($knowledgeParts !== []) {
|
||||
$knowledgeBlock = implode("\n\n", $knowledgeParts);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// 4) USER QUESTION
|
||||
// ------------------------------------------------------------
|
||||
$userBlock =
|
||||
"USER QUESTION:\n" .
|
||||
$prompt;
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// 5) FINAL PROMPT ASSEMBLY
|
||||
// ------------------------------------------------------------
|
||||
$blocks = array_filter([
|
||||
$systemBlock,
|
||||
$contextBlock,
|
||||
$knowledgeBlock,
|
||||
$userBlock,
|
||||
]);
|
||||
|
||||
return implode("\n\n", $blocks);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user