feat(kg): expand entity types and improve extraction prompt

Add 3 new entity types: technology, product, document — reducing
concept catch-all bucket. Add 4 new relation types: authored,
references, provides, requires. Improve prompt with disambiguation
guide between similar types, stricter related_to usage, and varied
confidence examples. Update graph view colors and mass for new types.
This commit is contained in:
viettranx committed 2026-03-31 19:03:43 +07:00
1 parent 09a7823498
commit c49952a1e5
3 files changed
+41 -20

No files matched your search

+35 -17
View File
@@ -1,6 +1,6 @@
package knowledgegraph
const extractionSystemPrompt = `You are a knowledge graph extractor for an AI assistant's memory system. Given text (usually personal notes, work logs, or conversation summaries), extract the most important entities and their relationships.
const extractionSystemPrompt = `You are a knowledge graph extractor for an AI assistant's memory system. Given text (personal notes, work logs, conversation summaries, or any domain content), extract the most important entities and their relationships.
Output valid JSON with this schema:
{
@@ -8,7 +8,7 @@ Output valid JSON with this schema:
{
"external_id": "unique-lowercase-id",
"name": "Display Name",
"entity_type": "person|project|task|event|concept|location|organization",
"entity_type": "person|organization|project|product|technology|task|event|document|concept|location",
"description": "Brief description of the entity",
"confidence": 0.0-1.0
}
@@ -30,14 +30,24 @@ Output valid JSON with this schema:
- Same real-world entity MUST always get the same external_id across extractions
- When a pronoun or partial reference clearly refers to a named entity, use that entity's ID — do NOT create a new entity
## Entity Types
- person: named individuals
- organization: companies, teams, departments
- project: software projects, initiatives, products
- task: specific work items, tickets, TODOs
- event: meetings, releases, incidents, deadlines
- concept: technologies, methodologies, domains
- location: cities, offices, regions
## Entity Types (use ONLY these 10)
- person: named individuals (developer, manager, doctor, teacher)
- organization: companies, teams, departments, groups (Google, marketing team, hospital)
- project: initiatives, campaigns, programs being built or executed (GoClaw, thesis, ad campaign)
- product: finished goods, services, SaaS, platforms being used or sold (LadiSales, iPhone, insurance plan)
- technology: software, tools, frameworks, languages, databases, hardware (PostgreSQL, Docker, React, MRI machine)
- task: specific work items, tickets, TODOs (fix bug #123, deploy v2, quarterly review)
- event: meetings, releases, incidents, deadlines, milestones (launch day, sprint review, server outage)
- document: articles, reports, specs, contracts, guides, files (Q1 report, API spec, user manual)
- concept: abstract ideas, methodologies, domains, standards, patterns (RBAC, Agile, machine learning, GDPR)
- location: cities, offices, regions, venues (HCM, AWS us-east-1, room 3, building A)
Choosing between similar types:
- project vs product: project = being built/executed, product = being used/sold/consumed
- technology vs concept: technology = concrete tool/software you install/run, concept = abstract idea/methodology
- technology vs product: technology = technical tool (PostgreSQL, Docker), product = commercial offering (Salesforce, iPhone)
- document vs concept: document = a specific artifact (Q1 report), concept = an abstract idea (quarterly reporting)
- task vs event: task = actionable work item with an owner, event = a point in time that happened/will happen
## Relation Types (use ONLY these)
- works_on, manages, reports_to, collaborates_with (people↔work)
@@ -45,31 +55,39 @@ Output valid JSON with this schema:
- created, completed, assigned_to, scheduled_for (actions)
- located_in, based_at (location)
- uses, implements, integrates_with (technology)
- related_to (fallback — use sparingly)
- authored, references (documents: who wrote it, what it refers to)
- provides, requires (capabilities: what an entity offers or needs)
- related_to (LAST RESORT — if no specific relation fits, prefer omitting the relation entirely)
## Rules
- Extract 3-15 entities depending on text density. Short text = fewer entities
- Confidence: 1.0 = explicitly stated, 0.7 = strongly implied, 0.4 = weakly inferred
- Confidence: 1.0 = explicitly stated fact, 0.8 = strongly implied, 0.5 = inferred from context
- Use varied confidence — NOT everything is 1.0. Reserve 1.0 for direct, unambiguous statements
- Keep names in original language
- Descriptions: 1 sentence max, capture the entity's role or significance
- Skip generic/vague entities ("the system", "the team" without specific name)
- Do NOT use related_to as a default — if you cannot determine a specific relation, omit it
- Output ONLY the JSON object, no markdown, no code blocks
## Example
Input: "Talked to Minh about the GoClaw migration. He'll handle the database schema changes by Friday. The team uses PostgreSQL with pgvector."
Input: "Talked to Minh about the GoClaw migration. He'll handle the database schema changes by Friday. The team uses PostgreSQL with pgvector. I wrote the migration guide yesterday."
Output:
{
"entities": [
{"external_id": "minh", "name": "Minh", "entity_type": "person", "description": "Handling database schema changes for GoClaw", "confidence": 1.0},
{"external_id": "goclaw", "name": "GoClaw", "entity_type": "project", "description": "Project undergoing migration", "confidence": 1.0},
{"external_id": "goclaw-migration", "name": "GoClaw Migration", "entity_type": "task", "description": "Database migration task for GoClaw", "confidence": 1.0},
{"external_id": "postgresql", "name": "PostgreSQL", "entity_type": "concept", "description": "Database technology used with pgvector", "confidence": 1.0}
{"external_id": "goclaw-migration", "name": "GoClaw Migration", "entity_type": "task", "description": "Database migration task, deadline Friday", "confidence": 1.0},
{"external_id": "postgresql", "name": "PostgreSQL", "entity_type": "technology", "description": "Database used with pgvector extension", "confidence": 1.0},
{"external_id": "pgvector", "name": "pgvector", "entity_type": "technology", "description": "PostgreSQL extension for vector embeddings", "confidence": 0.8},
{"external_id": "migration-guide", "name": "Migration Guide", "entity_type": "document", "description": "Guide for the GoClaw database migration", "confidence": 1.0}
],
"relations": [
{"source_entity_id": "minh", "relation_type": "works_on", "target_entity_id": "goclaw-migration", "confidence": 1.0},
{"source_entity_id": "minh", "relation_type": "assigned_to", "target_entity_id": "goclaw-migration", "confidence": 1.0},
{"source_entity_id": "goclaw-migration", "relation_type": "part_of", "target_entity_id": "goclaw", "confidence": 1.0},
{"source_entity_id": "goclaw", "relation_type": "uses", "target_entity_id": "postgresql", "confidence": 1.0}
{"source_entity_id": "goclaw", "relation_type": "uses", "target_entity_id": "postgresql", "confidence": 1.0},
{"source_entity_id": "postgresql", "relation_type": "integrates_with", "target_entity_id": "pgvector", "confidence": 0.8},
{"source_entity_id": "migration-guide", "relation_type": "references", "target_entity_id": "goclaw-migration", "confidence": 1.0}
]
}`
+1 -1
View File
@@ -42,7 +42,7 @@ func (t *KnowledgeGraphSearchTool) Parameters() map[string]any {
},
"entity_type": map[string]any{
"type": "string",
"description": "Filter by entity type (person, project, task, event, concept, location, organization)",
"description": "Filter by entity type (person, organization, project, product, technology, task, event, document, concept, location)",
},
"entity_id": map[string]any{
"type": "string",
+5 -2
View File
@@ -29,17 +29,20 @@ interface TypeColor {
}
const TYPE_COLORS: Record<string, TypeColor> = {
person: { border: "#E85D24", dark: { bg: "rgba(232,93,36,0.15)", text: "#f4a574" }, light: { bg: "#fde8d8", text: "#7a2610" } },
organization: { border: "#ef4444", dark: { bg: "rgba(239,68,68,0.15)", text: "#fca5a5" }, light: { bg: "#fee2e2", text: "#991b1b" } },
project: { border: "#22c55e", dark: { bg: "rgba(34,197,94,0.15)", text: "#86efac" }, light: { bg: "#dcfce7", text: "#166534" } },
product: { border: "#f97316", dark: { bg: "rgba(249,115,22,0.15)", text: "#fdba74" }, light: { bg: "#ffedd5", text: "#9a3412" } },
technology: { border: "#3b82f6", dark: { bg: "rgba(59,130,246,0.15)", text: "#93c5fd" }, light: { bg: "#dbeafe", text: "#1e40af" } },
task: { border: "#f59e0b", dark: { bg: "rgba(245,158,11,0.15)", text: "#fcd34d" }, light: { bg: "#fef3c7", text: "#92400e" } },
event: { border: "#ec4899", dark: { bg: "rgba(236,72,153,0.15)", text: "#f9a8d4" }, light: { bg: "#fce7f3", text: "#9d174d" } },
document: { border: "#8b5cf6", dark: { bg: "rgba(139,92,246,0.15)", text: "#c4b5fd" }, light: { bg: "#ede9fe", text: "#6d28d9" } },
concept: { border: "#a78bfa", dark: { bg: "rgba(167,139,250,0.12)", text: "#c4b5fd" }, light: { bg: "#ede9fe", text: "#5b21b6" } },
location: { border: "#14b8a6", dark: { bg: "rgba(20,184,166,0.15)", text: "#5eead4" }, light: { bg: "#ccfbf1", text: "#115e59" } },
organization: { border: "#ef4444", dark: { bg: "rgba(239,68,68,0.15)", text: "#fca5a5" }, light: { bg: "#fee2e2", text: "#991b1b" } },
};
const DEFAULT_TC: TypeColor = { border: "#9ca3af", dark: { bg: "rgba(156,163,175,0.12)", text: "#d1d5db" }, light: { bg: "#f3f4f6", text: "#374151" } };
const TYPE_MASS: Record<string, number> = {
organization: 8, project: 6, person: 4, concept: 3, location: 3, event: 2, task: 1.5,
organization: 8, project: 6, product: 5, person: 4, technology: 3.5, concept: 3, location: 3, document: 2.5, event: 2, task: 1.5,
};
const DEFAULT_MASS = 2;