main #11

Merged
mstoeck3 merged 66 commits from main into forensic-ai 2025-08-11 12:02:56 +00:00
2 changed files with 115 additions and 28 deletions
Showing only changes of commit d043bba17f - Show all commits

View File

@ -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 {

View File

@ -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,