feat: implement automated knowledge graph extraction pipeline and visualization component

This commit is contained in:
RaymondVerhoef
2026-05-20 08:55:27 +02:00
parent 08aaed591f
commit d5655d2232
3 changed files with 35 additions and 7 deletions

View File

@@ -311,11 +311,12 @@ Rules:
1. Identify topics that mean exactly the same thing. Choose one to keep, and one to delete.
2. Identify topics that are too vague, irrelevant, or malformed to delete.
3. Identify missing logical relations (depends_on, part_of, related_to) if two topics are conceptually linked but missing a relation.
4. Return ONLY a valid JSON object describing the ACTIONS to take. Do not return the entire graph. Do not wrap in markdown blocks.`;
4. Evaluate the learning_relevance of each topic. If a topic is purely operational/mundane (like a printer guide), mark it as "exclude". If it's low priority, mark "peripheral".
5. Return ONLY a valid JSON object describing the ACTIONS to take. Do not return the entire graph. Do not wrap in markdown blocks.`;
// Send a compact representation to minimize token usage and avoid rate limits.
// The AI only needs id, label, and type to identify duplicates/merges.
const compactTopics = currentTopics.map(({ id, label, type }) => ({ id, label, type }));
// The AI only needs id, label, type, and relevance to identify duplicates/merges and adjust relevance.
const compactTopics = currentTopics.map(({ id, label, type, learning_relevance }) => ({ id, label, type, learning_relevance }));
const compactRelations = currentRelations.map(r => ({
source: r.source?.id || r.source,
target: r.target?.id || r.target,
@@ -329,7 +330,8 @@ Analyze this graph and return ONLY the optimized JSON object with this EXACT str
{
"merges": [ { "keepId": "id_to_keep", "deleteId": "id_to_delete" } ],
"deletions": [ "id_to_delete_completely" ],
"newRelations": [ { "source": "id1", "target": "id2", "type": "depends_on" } ]
"newRelations": [ { "source": "id1", "target": "id2", "type": "depends_on" } ],
"relevanceUpdates": [ { "id": "topic_id", "learning_relevance": "exclude" } ]
}`;
const responseText = await anthropicApi.generateContent(systemPrompt, userPrompt);
@@ -364,6 +366,15 @@ Analyze this graph and return ONLY the optimized JSON object with this EXACT str
}
}
if (actions.relevanceUpdates && Array.isArray(actions.relevanceUpdates)) {
for (const update of actions.relevanceUpdates) {
const topicIndex = updatedTopics.findIndex(t => t.id === update.id);
if (topicIndex !== -1) {
updatedTopics[topicIndex] = { ...updatedTopics[topicIndex], learning_relevance: update.learning_relevance };
}
}
}
// Ensure all relations only reference existing nodes and are normalized to string IDs
const finalTopicIds = new Set(updatedTopics.map(t => t.id));
updatedRelations = updatedRelations