Skip to content

fact_type misclassified — user preferences/rules/corrections stored as "experience" instead of "world" #2437

Description

@jasstionzyf

Bug Description

Title:

Bug Description

When users state preferences, rules, or corrections during assistant interactions (e.g., "优先用 browser_navigate 而非 web_search"), the retain pipeline classifies them as experience ("assistant") type facts instead of world type.

Root Cause

The LLM extraction prompt in fact_extraction.py uses a rule that is too broad:

> fact_type: use "world" unless the content is clearly an interaction with the assistant.

This causes any fact stated within an interaction to be classified as "assistant" (→ experience), regardless of its nature. User preferences and permanent rules are objective facts about the world — they would exist without this conversation — but are being stored as transient experiences.

Location

hindsight-api-slim/hindsight_api/engine/retain/fact_extraction.py:

- Line 769: "fact_type: use \"world\" unless the content is clearly an interaction with the assistant."
- Lines 1393-1402: raw "assistant" → "experience", "world" → "world" mapping
- Lines 195-196, 298-299, 348-349: Field descriptions that don't distinguish between "doing something" and "saying something"

See also retain/prompts.py line 870:
> world: User's life, other people, events (would exist without this conversation)

This definition is actually correct — the problem is the line 769 rule overrides it.

Consequence

- User preferences stored as experience degrade recall ranking (experience is for one-time events, not persistent rules)
- Consolidation treats them as episodic rather than durable knowledge
- A planned world-fact conflict detection feature would miss them entirely

Proposed Fix

Update the fact_type boundary guidance to distinguish "action" from "statement":

diff
- fact_type: use "world" unless the content is clearly an interaction with the assistant.
+ fact_type 判定:
+ - "world": user preferences, rules, corrections, constraints, and objective facts —
+   even when stated during conversation.
+   Examples: "user wants browser_navigate prioritized", "user forbids unapproved code changes"
+ - "assistant" (→ experience): actions the assistant/agent actually performed,
+   not things discussed.
+   Examples: "I deployed X", "I debugged Y"


Also update the Field descriptions in the Pydantic models to emphasize that factual content remains "world" even when communicated through interaction.

Environment

- Hindsight v0.8.3 (ee81c65)
- LLM: deepseek-v4-flash
- Bank: hermes

Steps to Reproduce

above

Expected Behavior

above

Actual Behavior

above

Version

v0.8.3

LLM Provider

OpenAI

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions