Skip to content

feat(agent): curb concept/entity sprawl (strict entity types, name-length gate, pending buffer) - #248

Open
sebastianbraun25 wants to merge 5 commits into
VectifyAI:mainfrom
sebastianbraun25:feat/issue-247-curb-entity-sprawl
Open

feat(agent): curb concept/entity sprawl (strict entity types, name-length gate, pending buffer)#248
sebastianbraun25 wants to merge 5 commits into
VectifyAI:mainfrom
sebastianbraun25:feat/issue-247-curb-entity-sprawl

Conversation

@sebastianbraun25

Copy link
Copy Markdown

Note

This PR was created in collaboration between a human and AI: implementation, tests, and PR
text were created by an AI assistant under the guidance and review of the human author.

Problem

The concept/entity plan step creates a dedicated wiki page for almost anything the LLM proposes
on its very first mention — including a document's own ticket/case identifier and overly specific
one-off names (e.g. "person name + their role in this one case"). For ingest workloads with many
short, similar documents (support tickets, case records), this produces a large number of low-value
entity/concept pages that are never referenced again. entity_types: (a configurable per-KB
vocabulary for the entity type field) is currently only used to label entities, not to gate
whether they get created at all — a mismatched type silently falls back to "other".

Solution / Changes

  • strict_entity_types (new opt-in config key, default false): when true, an entity whose
    LLM-returned type doesn't match the configured entity_types vocabulary is dropped instead of
    coerced to "other". Backward compatible (default preserves today's behavior exactly).
  • Name-length gate: a brand-new concept/entity name longer than 3 words (splitting on
    -/_/whitespace) is dropped — a lightweight, deterministic proxy for "too specific to be
    reusable knowledge" (unique keys, hashes, ticket numbers, and multi-part combinations all tend
    to produce long names). Applies only to create items, never to update (an already-existing,
    already-vetted name/type).
  • Soft prompt guidance (_CONCEPTS_PLAN_USER): a reuse-first framing, a concrete per-document
    "propose at most N brand-new concepts+entities" suggestion computed from the document's actual
    token count (reusing the existing summary/overview call's usage, no extra API call), and a
    name-generality rule. Purely textual — never enforced in code.
  • Pending-topics buffer (new openkb/pending.py, PendingTopicsStore): a brand-new
    concept/entity now collects up to 2 short notes across documents before a dedicated page is
    created on the 3rd mention, instead of getting a page on the very first mention. Works in both
    concept_update_mode values:

Dependencies

  • Depends on #246 (fix/issue-245-append-note-concept-update-mode, not yet merged) — the
    pending-buffer's "append" mode promotion reuses compiler_notes.append_concept_note/
    append_entity_note introduced there.

Testing

New tests: strict_entity_types resolver, the max-words filter (concepts + entities,
_parse_entities_plan threading), _doc_token_guidance, PendingTopicsStore unit tests (add/
promote/remove/persistence/brief formatting), and two end-to-end lifecycle tests (rewrite/append)
proving 3 mentions across separate documents are required before a page exists, with all
contributing sources merged. Existing create-path tests updated for the new buffer-then-promote
semantics.

Issues

Resolves #247

Sebastian Braun added 5 commits September 7, 2026 10:29
Adds concept_update_mode (default "rewrite", unchanged) with a new "append"
mode: instead of sending an existing concept/entity page's full body to the
LLM for a rewrite, generates a short 1-2 sentence note (the LLM never sees
the existing page) and appends it deterministically under a "## Notes"
heading, keyed by source document so re-ingesting an updated document
replaces its own line instead of duplicating it. Removal cleanup and config
docs updated accordingly.

Resolves VectifyAI#245
VectifyAI#245)

Adds a new `openkb consolidate [PAGE_NAME] [--all] [--min-notes N]
[--dry-run] [--yes]` command (mirrors `recompile`'s CLI shape) and a new
`openkb/agent/consolidator.py` module. For concept/entity pages accumulating
notes under `concept_update_mode: append`, this folds the pending "## Notes"
section into curated prose with a single LLM call per page — no new source
document, no concept/entity classification, since the page is already fixed.

- Contradictions between notes (or notes vs. existing prose) are described
  directly in the rewritten text rather than silently resolved.
- The full wikilink whitelist is sent here (once per page per run, not per
  ticket) so consolidated prose can properly cross-link to other pages.
- The "## Notes" section is replaced entirely; `sources:`/`type:` are
  preserved, only `description:` may be refreshed. A later `append_*_note`
  call re-creates a fresh "## Notes" section, so the next consolidation run
  only ever sees what changed since the last one — no extra tracking state
  needed.
- Manual, opt-in only (no automatic trigger during ingest).
… gate, and a pending-topics buffer

Problem: the plan step creates a dedicated wiki page for almost anything
proposed on its first mention, including a document's own ticket/case
identifier and overly specific one-off names. entity_types only labeled the
"type" field and never gated whether an entity got created at all.

Changes:
- config: opt-in `strict_entity_types` (default false) drops an entity whose
  type doesn't match entity_types instead of coercing it to "other".
- compiler: hard cap of 3 words on brand-new concept/entity names
  (_count_words), applied to "create" items only.
- compiler: __DOC_TOKEN_GUIDANCE__ prompt substitution — a concrete,
  per-document "propose at most N brand-new items" suggestion computed from
  the document's real token count (reused from the existing summary/overview
  call's usage, no extra API call). Purely textual guidance, never enforced
  in code.
- new openkb/pending.py (PendingTopicsStore): a brand-new concept/entity now
  collects up to 2 short notes across documents before a real page is
  created on the 3rd mention. Works in both concept_update_mode values —
  "append" mode promotion reuses the existing note-append writers with no
  extra LLM call; "rewrite" mode does one enriched create call using the
  buffered notes as context, then merges all contributing sources.
- pending topics are surfaced to the plan call as quasi-existing briefs (for
  dedup) but never added to the wikilink whitelist.

Tests: strict_entity_types resolver, max-words filter (concepts+entities),
_doc_token_guidance, PendingTopicsStore unit tests, and two end-to-end
lifecycle tests (rewrite/append) proving 3 mentions across documents are
needed before a page exists. Updated existing create-path tests for the new
buffer-then-promote semantics — 0 regressions against the pre-existing
Windows-environment baseline (18 known failures, unchanged).

Resolves VectifyAI#247
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(agent): curb concept/entity sprawl (strict entity types, name-length gate, pending buffer)

1 participant