fix: entity-orphan guard + log message correction for memory system - #199
Conversation
Memories are injected into user prompt prefix (executor.ts:481), not system prompt. The stale log message caused confusion during debugging. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When the extraction LLM produces a fact/relation/decision that references entities (person names, project names) not present in the source conversation, the memory is now rejected instead of stored. Two-layer defense: 1. Prompt rule: instructs extraction LLM to skip facts whose entities lack explicit textual evidence in the conversation 2. Code validation: filterUngroundedMemories() verifies every declared entity appears in the conversation text via substring match This prevents the propagation chain where hallucinated facts about one candidate get stored and later injected into analyses of different candidates. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
Claude finished @lishuceo's task in 1m 9s —— View job PR Review: Entity-Orphan Guard + Log Message Correction
✅ Approved — Clean, well-scoped fix with good test coverage. AssessmentThis PR adds a solid defense-in-depth mechanism against hallucinated entity extraction. The approach is sound: a hard substring check on declared entities, applied only to entity-bearing memory types ( What looks good:
Minor observations (not blocking):
Overall this is a well-designed fix that addresses a real cross-contamination bug in the memory pipeline. The "prefer false negatives over false positives" philosophy is exactly right for a memory system. |
9 new test cases: - parseExtractionResponse: entities field parsing and missing field handling - filterUngroundedMemories: grounded entities kept, orphaned entities rejected, partial missing rejected, preference/state bypass, backward compatibility, mixed batch filtering Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
a7fb33b to
420be4e
Compare
|
Claude finished @lishuceo's task in 1m 4s —— View job PR Review: Entity-Orphan Guard + Log Message Correction
✅ Approved — Clean, well-scoped fix with good test coverage. AssessmentThis PR adds a solid defense-in-depth mechanism against hallucinated entity extraction. The approach is sound: a hard substring check on declared entities, applied only to entity-bearing memory types ( What looks good:
Minor observations (not blocking):
Overall this is a well-designed fix that addresses a real cross-contamination bug in the memory pipeline. The "prefer false negatives over false positives" philosophy is exactly right for a memory system. |
|
Claude finished @lishuceo's task in 1m 1s —— View job PR Review: Entity-Orphan Guard + Log Message Correction
✅ Approved — Clean, well-scoped fix with good test coverage. AssessmentThis PR adds a solid defense-in-depth mechanism against hallucinated entity extraction. The approach is sound: a hard substring check on declared entities, applied only to entity-bearing memory types ( What looks good:
Minor observations (not blocking):
Overall this is a well-designed fix that addresses a real cross-contamination bug in the memory pipeline. The "prefer false negatives over false positives" philosophy is exactly right for a memory system. |
…199) * fix: correct misleading log message for memory injection location Memories are injected into user prompt prefix (executor.ts:481), not system prompt. The stale log message caused confusion during debugging. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: entity-orphan guard to prevent ungrounded memory extraction When the extraction LLM produces a fact/relation/decision that references entities (person names, project names) not present in the source conversation, the memory is now rejected instead of stored. Two-layer defense: 1. Prompt rule: instructs extraction LLM to skip facts whose entities lack explicit textual evidence in the conversation 2. Code validation: filterUngroundedMemories() verifies every declared entity appears in the conversation text via substring match This prevents the propagation chain where hallucinated facts about one candidate get stored and later injected into analyses of different candidates. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * test: add entity-orphan guard and entities field parsing tests 9 new test cases: - parseExtractionResponse: entities field parsing and missing field handling - filterUngroundedMemories: grounded entities kept, orphaned entities rejected, partial missing rejected, preference/state bypass, backward compatibility, mixed batch filtering Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Summary
"Memories injected into system prompt"→"into user prompt prefix",消除调试时的误导Root Cause
记忆提取 LLM 会将聊天上下文中的碎片信息(如父群讨论的其他候选人的面试结果)错误地归到当前分析对象身上,并作为
fact存入记忆库。后续分析新候选人时,这些虚假记忆被注入 system prompt,导致错误信息在候选人之间传播。传播链:
父群上下文混合 → LLM幻觉 → 存为fact → 注入新候选人分析 → 再存一条错误factChanges
src/memory/extractor.tsentities输出字段和实体溯源规则filterUngroundedMemories()硬校验:每个声明的 entity 必须在对话文本中有子串匹配src/memory/injector.tsTest plan
🤖 Generated with Claude Code