phase completion justification
This commit is contained in:
parent
9e42b2a98d
commit
d043bba17f
@ -1,4 +1,4 @@
|
|||||||
// src/config/prompts.ts - Centralized German prompts for AI pipeline
|
// src/config/prompts.ts - Enhanced with phase completion reasoning
|
||||||
|
|
||||||
export const AI_PROMPTS = {
|
export const AI_PROMPTS = {
|
||||||
|
|
||||||
@ -111,7 +111,7 @@ Antwort: Fließtext ohne Listen, max 100 Wörter.`;
|
|||||||
const tools = phaseTools.filter(t => t.type === 'software');
|
const tools = phaseTools.filter(t => t.type === 'software');
|
||||||
|
|
||||||
if (phaseTools.length === 0) {
|
if (phaseTools.length === 0) {
|
||||||
return `Keine Tools für Phase "${phase.name}" verfügbar. Antworte mit leerem Array: []`;
|
return `Keine Methoden/Tools für Phase "${phase.name}" verfügbar. Antworte mit leerem Array: []`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return `Du bist ein DFIR-Experte. Wähle die 2-3 BESTEN Items für Phase "${phase.name}".
|
return `Du bist ein DFIR-Experte. Wähle die 2-3 BESTEN Items für Phase "${phase.name}".
|
||||||
@ -125,7 +125,7 @@ METHODEN (${methods.length}):
|
|||||||
${methods.map((method: any) =>
|
${methods.map((method: any) =>
|
||||||
`- ${method.name}
|
`- ${method.name}
|
||||||
Typ: ${method.type}
|
Typ: ${method.type}
|
||||||
Beschreibung: ${method.description.slice(0, 150)}...
|
Beschreibung: ${method.description}
|
||||||
Domains: ${method.domains?.join(', ') || 'N/A'}
|
Domains: ${method.domains?.join(', ') || 'N/A'}
|
||||||
Skill Level: ${method.skillLevel}`
|
Skill Level: ${method.skillLevel}`
|
||||||
).join('\n\n')}
|
).join('\n\n')}
|
||||||
@ -136,7 +136,7 @@ SOFTWARE TOOLS (${tools.length}):
|
|||||||
${tools.map((tool: any) =>
|
${tools.map((tool: any) =>
|
||||||
`- ${tool.name}
|
`- ${tool.name}
|
||||||
Typ: ${tool.type}
|
Typ: ${tool.type}
|
||||||
Beschreibung: ${tool.description.slice(0, 150)}...
|
Beschreibung: ${tool.description}
|
||||||
Plattformen: ${tool.platforms?.join(', ') || 'N/A'}
|
Plattformen: ${tool.platforms?.join(', ') || 'N/A'}
|
||||||
Skill Level: ${tool.skillLevel}`
|
Skill Level: ${tool.skillLevel}`
|
||||||
).join('\n\n')}
|
).join('\n\n')}
|
||||||
@ -155,7 +155,7 @@ ANTWORT AUSSCHLIESSLICH IM JSON-FORMAT OHNE JEGLICHEN TEXT AUSSERHALB:
|
|||||||
{
|
{
|
||||||
"toolName": "Exakter Name aus der Liste oben",
|
"toolName": "Exakter Name aus der Liste oben",
|
||||||
"taskRelevance": 85,
|
"taskRelevance": 85,
|
||||||
"justification": "Spezifische Begründung warum optimal für ${phase.name}",
|
"justification": "Detaillierte Begründung (60-80 Wörter) warum optimal für ${phase.name} - erkläre Anwendung, Vorteile und spezifische Relevanz",
|
||||||
"limitations": ["Mögliche Einschränkung für diese Phase"]
|
"limitations": ["Mögliche Einschränkung für diese Phase"]
|
||||||
}
|
}
|
||||||
]`;
|
]`;
|
||||||
@ -202,23 +202,55 @@ ANTWORT AUSSCHLIESSLICH IM JSON-FORMAT OHNE JEGLICHEN TEXT AUSSERHALB DER JSON-S
|
|||||||
]`;
|
]`;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
phaseCompletionReasoning: (
|
||||||
|
originalQuery: string,
|
||||||
|
phase: any,
|
||||||
|
selectedToolName: string,
|
||||||
|
tool: any,
|
||||||
|
completionContext: string
|
||||||
|
) => {
|
||||||
|
return `Du bist ein DFIR-Experte. Erkläre warum dieses Tool nachträglich zur Vervollständigung hinzugefügt wurde.
|
||||||
|
|
||||||
|
KONTEXT DER NACHTRÄGLICHEN ERGÄNZUNG:
|
||||||
|
- Ursprüngliche KI-Auswahl war zu spezifisch/eng gefasst
|
||||||
|
- Phase "${phase.name}" war unterrepräsentiert in der initialen Auswahl
|
||||||
|
- Semantische Suche fand zusätzlich relevante Tools für diese Phase
|
||||||
|
- Tool wird nachträglich hinzugefügt um Vollständigkeit zu gewährleisten
|
||||||
|
|
||||||
|
URSPRÜNGLICHE ANFRAGE: "${originalQuery}"
|
||||||
|
PHASE ZU VERVOLLSTÄNDIGEN: ${phase.name} - ${phase.description || ''}
|
||||||
|
HINZUGEFÜGTES TOOL: ${selectedToolName} (${tool.type})
|
||||||
|
TOOL-BESCHREIBUNG: ${tool.description}
|
||||||
|
|
||||||
|
BEGRÜNDUNGSKONTEXT: ${completionContext}
|
||||||
|
|
||||||
|
Erstelle eine präzise Begründung (max. 40 Wörter), die erklärt:
|
||||||
|
1. WARUM dieses Tool nachträglich hinzugefügt wurde
|
||||||
|
2. WIE es die ${phase.name}-Phase ergänzt
|
||||||
|
3. DASS es die ursprünglich zu spezifische Auswahl erweitert
|
||||||
|
|
||||||
|
Antwort: Prägnanter Fließtext, knappe Begründung für Nachergänzung. Vermeide Begriffe wie "Das Tool" und gib keinen einleitenden Text wie "Begründung (40 Wörter):" an.`;
|
||||||
|
},
|
||||||
|
|
||||||
generatePhaseCompletionPrompt(
|
generatePhaseCompletionPrompt(
|
||||||
originalQuery: string,
|
originalQuery: string,
|
||||||
phase: any,
|
phase: any,
|
||||||
candidateTools: any[],
|
candidateTools: any[],
|
||||||
candidateConcepts: any[]
|
candidateConcepts: any[]
|
||||||
): string {
|
): string {
|
||||||
return `Du bist ein DFIR-Experte. Die Phase "${phase.name}" ist in der aktuellen Analyse unterrepräsentiert.
|
return `Du bist ein DFIR-Experte. Die initiale KI-Auswahl war zu spezifisch - die Phase "${phase.name}" ist unterrepräsentiert.
|
||||||
|
|
||||||
|
KONTEXT: Die Hauptauswahl hat zu wenige Tools für "${phase.name}" identifiziert. Wähle jetzt ergänzende Tools aus semantischer Nachsuche.
|
||||||
|
|
||||||
ORIGINAL ANFRAGE: "${originalQuery}"
|
ORIGINAL ANFRAGE: "${originalQuery}"
|
||||||
PHASE ZU VERVOLLSTÄNDIGEN: ${phase.name} - ${phase.description || ''}
|
UNTERREPRÄSENTIERTE PHASE: ${phase.name} - ${phase.description || ''}
|
||||||
|
|
||||||
Wähle 1-2 BESTE Tools aus den gefundenen Kandidaten, die diese Phase optimal ergänzen:
|
SEMANTISCH GEFUNDENE KANDIDATEN für Nachergänzung:
|
||||||
|
|
||||||
VERFÜGBARE TOOLS (${candidateTools.length}):
|
VERFÜGBARE TOOLS (${candidateTools.length}):
|
||||||
${candidateTools.map((tool: any) => `
|
${candidateTools.map((tool: any) => `
|
||||||
- ${tool.name} (${tool.type})
|
- ${tool.name} (${tool.type})
|
||||||
Beschreibung: ${tool.description.slice(0, 120)}...
|
Beschreibung: ${tool.description}
|
||||||
Skill Level: ${tool.skillLevel}
|
Skill Level: ${tool.skillLevel}
|
||||||
`).join('')}
|
`).join('')}
|
||||||
|
|
||||||
@ -226,20 +258,20 @@ ${candidateConcepts.length > 0 ? `
|
|||||||
VERFÜGBARE KONZEPTE (${candidateConcepts.length}):
|
VERFÜGBARE KONZEPTE (${candidateConcepts.length}):
|
||||||
${candidateConcepts.map((concept: any) => `
|
${candidateConcepts.map((concept: any) => `
|
||||||
- ${concept.name}
|
- ${concept.name}
|
||||||
Beschreibung: ${concept.description.slice(0, 120)}...
|
Beschreibung: ${concept.description}
|
||||||
`).join('')}
|
`).join('')}
|
||||||
` : ''}
|
` : ''}
|
||||||
|
|
||||||
AUSWAHLREGELN:
|
AUSWAHLREGELN FÜR NACHERGÄNZUNG:
|
||||||
1. Wähle Tools, die die ${phase.name}-Phase der ursprünglichen Anfrage optimal ergänzen
|
1. Wähle 1-2 BESTE Methoden/Tools die die ${phase.name}-Phase optimal ergänzen
|
||||||
2. Priorisiere Tools, die zur Gesamtlösung beitragen
|
2. Methoden/Tools müssen für die ursprüngliche Anfrage relevant sein
|
||||||
3. Maximal 2 Tools für diese Phase
|
3. Ergänzen, nicht ersetzen - erweitere die zu spezifische Erstauswahl
|
||||||
|
|
||||||
ANTWORT AUSSCHLIESSLICH IM JSON-FORMAT:
|
ANTWORT AUSSCHLIESSLICH IM JSON-FORMAT:
|
||||||
{
|
{
|
||||||
"selectedTools": ["ToolName1", "ToolName2"],
|
"selectedTools": ["ToolName1", "ToolName2"],
|
||||||
"selectedConcepts": ["ConceptName1"],
|
"selectedConcepts": ["ConceptName1"],
|
||||||
"reasoning": "Kurze Begründung der Auswahl für ${phase.name}"
|
"completionReasoning": "Kurze Erklärung warum diese Nachergänzung für ${phase.name} notwendig war"
|
||||||
}`;
|
}`;
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -267,6 +299,7 @@ export function getPrompt(key: 'criticalConsiderations', isWorkflow: boolean, us
|
|||||||
export function getPrompt(key: 'phaseToolSelection', userQuery: string, phase: any, phaseTools: any[]): string;
|
export function getPrompt(key: 'phaseToolSelection', userQuery: string, phase: any, phaseTools: any[]): string;
|
||||||
export function getPrompt(key: 'toolEvaluation', userQuery: string, tool: any, rank: number, taskRelevance: number): string;
|
export function getPrompt(key: 'toolEvaluation', userQuery: string, tool: any, rank: number, taskRelevance: number): string;
|
||||||
export function getPrompt(key: 'backgroundKnowledgeSelection', userQuery: string, mode: string, selectedToolNames: string[], availableConcepts: any[]): string;
|
export function getPrompt(key: 'backgroundKnowledgeSelection', userQuery: string, mode: string, selectedToolNames: string[], availableConcepts: any[]): string;
|
||||||
|
export function getPrompt(key: 'phaseCompletionReasoning', originalQuery: string, phase: any, selectedToolName: string, tool: any, completionContext: string): string;
|
||||||
export function getPrompt(key: 'finalRecommendations', isWorkflow: boolean, userQuery: string, selectedToolNames: string[]): string;
|
export function getPrompt(key: 'finalRecommendations', isWorkflow: boolean, userQuery: string, selectedToolNames: string[]): string;
|
||||||
export function getPrompt(key: 'generatePhaseCompletionPrompt', originalQuery: string, phase: any, candidateTools: any[], candidateConcepts: any[]): string;
|
export function getPrompt(key: 'generatePhaseCompletionPrompt', originalQuery: string, phase: any, candidateTools: any[], candidateConcepts: any[]): string;
|
||||||
export function getPrompt(promptKey: keyof typeof AI_PROMPTS, ...args: any[]): string {
|
export function getPrompt(promptKey: keyof typeof AI_PROMPTS, ...args: any[]): string {
|
||||||
|
@ -1046,7 +1046,7 @@ class ImprovedMicroTaskAIPipeline {
|
|||||||
const phaseStart = Date.now();
|
const phaseStart = Date.now();
|
||||||
const phaseQuery = phaseQueryTemplates[phase.id] || `forensic ${phase.name.toLowerCase()} tools methods`;
|
const phaseQuery = phaseQueryTemplates[phase.id] || `forensic ${phase.name.toLowerCase()} tools methods`;
|
||||||
|
|
||||||
console.log('[AI-PIPELINE] Starting phase completion micro-task for:', phase.id);
|
console.log('[AI-PIPELINE] Starting enhanced phase completion micro-task for:', phase.id);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const phaseResults = await embeddingsService.findSimilar(phaseQuery, 20, 0.2);
|
const phaseResults = await embeddingsService.findSimilar(phaseQuery, 20, 0.2);
|
||||||
@ -1083,42 +1083,96 @@ class ImprovedMicroTaskAIPipeline {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const prompt = AI_PROMPTS.generatePhaseCompletionPrompt(originalQuery, phase, phaseTools, phaseConcepts);
|
// Step 1: AI selection of tools for completion
|
||||||
const response = await this.callAI(prompt, 800);
|
const selectionPrompt = AI_PROMPTS.generatePhaseCompletionPrompt(originalQuery, phase, phaseTools, phaseConcepts);
|
||||||
const selection = this.safeParseJSON(response, { selectedTools: [], selectedConcepts: [] });
|
const selectionResult = await this.callMicroTaskAI(selectionPrompt, context, 800);
|
||||||
|
|
||||||
|
if (!selectionResult.success) {
|
||||||
|
console.error('[AI-PIPELINE] Phase completion selection failed for:', phase.id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const selection = this.safeParseJSON(selectionResult.content, {
|
||||||
|
selectedTools: [],
|
||||||
|
selectedConcepts: [],
|
||||||
|
completionReasoning: ''
|
||||||
|
});
|
||||||
|
|
||||||
const validTools = selection.selectedTools
|
const validTools = selection.selectedTools
|
||||||
.map((name: string) => phaseTools.find((t: any) => t && t.name === name))
|
.map((name: string) => phaseTools.find((t: any) => t && t.name === name))
|
||||||
.filter((tool: any): tool is NonNullable<any> => tool !== undefined && tool !== null)
|
.filter((tool: any): tool is NonNullable<any> => tool !== undefined && tool !== null)
|
||||||
.slice(0, 2);
|
.slice(0, 2);
|
||||||
|
|
||||||
validTools.forEach((tool: any) => {
|
if (validTools.length === 0) {
|
||||||
console.log('[AI-PIPELINE] Adding phase completion tool:', tool.name, 'for', phase.id);
|
console.log('[AI-PIPELINE] No valid tools selected for phase completion:', phase.id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 2: Generate detailed reasoning for each selected tool
|
||||||
|
for (const tool of validTools) {
|
||||||
|
console.log('[AI-PIPELINE] Generating reasoning for phase completion tool:', tool.name);
|
||||||
|
|
||||||
|
const reasoningPrompt = getPrompt(
|
||||||
|
'phaseCompletionReasoning',
|
||||||
|
originalQuery,
|
||||||
|
phase,
|
||||||
|
tool.name,
|
||||||
|
tool,
|
||||||
|
selection.completionReasoning || 'Nachergänzung zur Vervollständigung der Phasenabdeckung'
|
||||||
|
);
|
||||||
|
|
||||||
|
const reasoningResult = await this.callMicroTaskAI(reasoningPrompt, context, 400);
|
||||||
|
|
||||||
|
let detailedJustification: string;
|
||||||
|
if (reasoningResult.success) {
|
||||||
|
detailedJustification = reasoningResult.content.trim();
|
||||||
|
} else {
|
||||||
|
detailedJustification = `Nachträglich hinzugefügt zur Vervollständigung der ${phase.name}-Phase. Die ursprüngliche KI-Auswahl war zu spezifisch und hat wichtige Tools für diese Phase übersehen.`;
|
||||||
|
}
|
||||||
|
|
||||||
this.addToolToSelection(
|
this.addToolToSelection(
|
||||||
context,
|
context,
|
||||||
tool,
|
tool,
|
||||||
phase.id,
|
phase.id,
|
||||||
'medium',
|
'medium',
|
||||||
`Hinzugefügt zur Vervollständigung der ${phase.name}-Phase`,
|
detailedJustification,
|
||||||
75,
|
75,
|
||||||
['Via phasenspezifische semantische Suche hinzugefügt']
|
['Nachträgliche Ergänzung via semantische Phasensuche']
|
||||||
);
|
);
|
||||||
});
|
|
||||||
|
console.log('[AI-PIPELINE] Added phase completion tool with reasoning:', tool.name);
|
||||||
|
}
|
||||||
|
|
||||||
this.addAuditEntry(
|
this.addAuditEntry(
|
||||||
context,
|
context,
|
||||||
'validation',
|
'validation',
|
||||||
'phase-completion',
|
'phase-completion',
|
||||||
{ phase: phase.id, phaseQuery, candidatesFound: phaseTools.length },
|
{
|
||||||
{ toolsAdded: validTools.length, addedTools: validTools.map((t: any) => t.name) },
|
phase: phase.id,
|
||||||
|
phaseQuery,
|
||||||
|
candidatesFound: phaseTools.length,
|
||||||
|
selectionReasoning: selection.completionReasoning
|
||||||
|
},
|
||||||
|
{
|
||||||
|
toolsAdded: validTools.length,
|
||||||
|
addedTools: validTools.map((t: any) => ({
|
||||||
|
name: t.name,
|
||||||
|
type: t.type,
|
||||||
|
reasoning: 'Generated via micro-task'
|
||||||
|
}))
|
||||||
|
},
|
||||||
validTools.length > 0 ? 80 : 40,
|
validTools.length > 0 ? 80 : 40,
|
||||||
phaseStart,
|
phaseStart,
|
||||||
{ phaseCompletion: true, semanticSearch: true }
|
{
|
||||||
|
phaseCompletion: true,
|
||||||
|
semanticSearch: true,
|
||||||
|
microTaskReasoning: true,
|
||||||
|
contextualExplanation: true
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[AI-PIPELINE] Phase completion failed for:', phase.id, error);
|
console.error('[AI-PIPELINE] Enhanced phase completion failed for:', phase.id, error);
|
||||||
|
|
||||||
this.addAuditEntry(
|
this.addAuditEntry(
|
||||||
context,
|
context,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user