CogniCheck: Memory Contradiction Control for LLM NPCs

Research Prototype โ€” "CogniCheck: A Lightweight Memory Consistency Layer for LLM-Based Game NPCs"


Overview

CogniCheck is a modular, production-style system that detects and resolves memory contradictions in LLM-driven game NPCs. It dramatically reduces LLM API costs (target: 60โ€“80% reduction) while maintaining high memory consistency across multiple NPCs.


Key Features

Feature Description
๐Ÿง  Hybrid Detection Semantic embeddings + deterministic rules
โšก Cost Control LLM called only at high confidence (โ‰ฅ 0.75)
๐Ÿ“Š Full Metrics CRR, MCS, F1, FRR, latency, LLM reduction
๐Ÿ” Multi-Seed Runs 5 seeds with mean ยฑ std reporting
๐Ÿ”Œ REST API FastAPI endpoint for real-time integration
๐Ÿงช Unit Tests โ‰ฅ80% coverage on core modules
๐Ÿ”ฌ Ablation Study 3 variants to prove component contributions

Project Structure

cognicheck/
โ”œโ”€โ”€ core/
โ”‚   โ”œโ”€โ”€ memory.py          # SQLite-backed MemoryStore
โ”‚   โ”œโ”€โ”€ detector.py        # Contradiction Detector (semantic + rules)
โ”‚   โ”œโ”€โ”€ resolver.py        # Resolution Engine (4 strategies)
โ”‚   โ””โ”€โ”€ llm_gateway.py     # LLM cost gate + retry + logging
โ”œโ”€โ”€ simulation/
โ”‚   โ”œโ”€โ”€ event_generator.py # Scripted + probabilistic events
โ”‚   โ””โ”€โ”€ npc_sim.py         # Multi-NPC simulation runner
โ”œโ”€โ”€ evaluation/
โ”‚   โ”œโ”€โ”€ metrics.py         # CRR, MCS, P/R/F1, FRR, latency
โ”‚   โ”œโ”€โ”€ benchmark.py       # Per-seed benchmark runner
โ”‚   โ””โ”€โ”€ ablation.py        # Ablation study runner
โ”œโ”€โ”€ api/
โ”‚   โ”œโ”€โ”€ main.py            # FastAPI app
โ”‚   โ””โ”€โ”€ routes.py          # /process_event endpoint
โ”œโ”€โ”€ config/
โ”‚   โ”œโ”€โ”€ config.yaml        # All tunable parameters
โ”‚   โ””โ”€โ”€ settings.py        # Pydantic config loader
โ”œโ”€โ”€ tests/
โ”‚   โ”œโ”€โ”€ test_memory.py
โ”‚   โ”œโ”€โ”€ test_detector.py
โ”‚   โ””โ”€โ”€ test_resolver.py
โ”œโ”€โ”€ data/
โ”‚   โ”œโ”€โ”€ simulation_events.json
โ”‚   โ””โ”€โ”€ ground_truth_contradictions.json
โ”œโ”€โ”€ results/               # Auto-generated outputs
โ”œโ”€โ”€ main_cli.py            # CLI entry point
โ”œโ”€โ”€ run_all_seeds.py       # Run all 5 seeds + ablation
โ””โ”€โ”€ requirements.txt

Quick Start

1. Install Dependencies

cd cognicheck
pip install -r requirements.txt

2. Run Full Simulation (All Seeds)

python run_all_seeds.py

Or with the CLI directly:

python main_cli.py --seeds 42 123 456 --ablation

Offline mode (no LLM API needed โ€” uses local heuristic):

python main_cli.py --no-llm --ablation

3. Run Unit Tests

pytest tests/ -v --cov=cognicheck/core --cov-report=term-missing

4. Start the REST API

uvicorn cognicheck.api.main:app --host 0.0.0.0 --port 8000

Send an event:

curl -X POST http://localhost:8000/process_event \
  -H "Content-Type: application/json" \
  -d '{
    "npc_id": "npc_1",
    "event_text": "The player betrayed me.",
    "sentiment": -0.9,
    "entities": ["player"],
    "relation_change": "trust_decreased"
  }'

Configuration (config/config.yaml)

detection:
  similarity_threshold: 0.7        # Semantic threshold for contradiction
  retrieval_min_similarity: 0.5    # Min similarity for candidate retrieval
  confidence_low: 0.4              # Below โ†’ keep both + uncertain flag
  confidence_high: 0.75            # Above โ†’ call LLM
  rule_boost: 0.3                  # Added to score when a rule fires

resolution:
  enable_llm: true
  llm_model: "local"               # "local" | "openai" | "ollama"

Evaluation Outputs

After running, results/ contains:

File Description
evaluation_report_{seed}.json Full metrics per seed
final_memory_state_{seed}.json All NPC memories after simulation
results_summary.csv Aggregate table (all seeds)
llm_calls_log.json Every LLM call with latency
cognicheck.log Full simulation log

Resolution Strategies

Strategy Description
Naive Always store, never resolve
Recency New memory replaces old (audit trail kept)
Full LLM Every event triggers an LLM call (expensive baseline)
Hybrid โœ… Low conf โ†’ keep both; mid โ†’ recency; high โ†’ LLM

LLM Backend Options

llm_model Description
local Deterministic heuristic (offline, no API key)
openai OpenAI GPT-4o-mini (OPENAI_API_KEY env var needed)
ollama Local Ollama with llama3.2

Reproducibility

All simulations use fixed random seeds (random, numpy). Scripted events in data/simulation_events.json ensure deterministic base scenarios. Probabilistic extensions use seeded RNGs.

Built With

Share this project:

Updates