Skip to content

Commit 3fc76f4

Browse files
author
Arena AI Agent
committed
feat(core): šŸ›”ļø enforce absolute truthfulness (no claim without an epistemic warrant and falsifier) and integrate real LLM Claim Expert
1 parent 486841a commit 3fc76f4

3 files changed

Lines changed: 52 additions & 63 deletions

File tree

Lines changed: 37 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,39 @@
1-
"""Claim lattice expert."""
1+
"""Claim Lattice Expert Implementation."""
2+
from typing import Dict, Any
3+
from epistemic_forge.experts.base import EpistemicExpert
4+
from epistemic_forge.models import ProjectSpec, ClaimLatticeOutput
5+
from epistemic_forge.llm import generate_structured
6+
from loguru import logger
27

3-
from __future__ import annotations
8+
class ClaimLatticeExpert(EpistemicExpert):
9+
"""Deconstructs the question into a structured, epistemically grounded claim lattice."""
10+
11+
@property
12+
def expert_name(self) -> str:
13+
return "Epistemic_Claim_Lattice_Generator"
414

5-
from typing import Any, Dict, List
6-
7-
from epistemic_forge.models import Claim, Confidence, ProjectSpec
8-
9-
10-
def extract_claims(spec: ProjectSpec, instruction: str) -> Dict[str, Any]:
11-
q = spec.question.strip()
12-
title = spec.title.strip()
13-
# Deterministic structured extraction (no external LLM required)
14-
core = Claim(
15-
id="C1",
16-
text=f"Core thesis addressing: {q}",
17-
support=[
18-
f"Aligned with instruction: {instruction[:120]}...",
19-
f"Keywords in play: {', '.join(spec.keywords) or 'general domain cues'}",
20-
],
21-
objections=[
22-
"The framing may smuggle unstated assumptions about the audience.",
23-
"Evidence quality is not yet measured; confidence should stay provisional.",
24-
],
25-
confidence=Confidence.LIKELY,
26-
sources=["user-question", "instruction"],
27-
tags=["thesis"],
28-
)
29-
support_c = Claim(
30-
id="C2",
31-
text=f"Working support: a structured approach to Ā«{title}Ā» improves decision quality under uncertainty.",
32-
support=[
33-
"Decomposition reduces hidden tradeoffs.",
34-
"Explicit objections prevent one-sided writing.",
35-
],
36-
objections=["Structure without domain data can become cargo-cult rigor."],
37-
confidence=Confidence.POSSIBLE,
38-
tags=["support"],
39-
)
40-
residual = Claim(
41-
id="C3",
42-
text="Residual uncertainty: which single metric or stakeholder criterion should dominate tradeoffs?",
43-
support=["Multi-objective problems need a declared primary criterion."],
44-
objections=["Premature metric fixation can distort the inquiry."],
45-
confidence=Confidence.WEAK,
46-
tags=["uncertainty"],
47-
)
48-
claims: List[Claim] = [core, support_c, residual]
49-
return {
50-
"claims": [c.to_dict() for c in claims],
51-
"lattice_summary": (
52-
"Three-node lattice: thesis, support, residual uncertainty. "
53-
"Ready for dialectic stress-test and packaging."
54-
),
55-
}
15+
def analyze(self, spec: ProjectSpec, context: Dict[str, Any]) -> ClaimLatticeOutput:
16+
"""Forces the LLM to generate claims ONLY if it can provide a warrant/explanation."""
17+
18+
messages = [
19+
{
20+
"role": "system",
21+
"content": (
22+
"You are a rigorous analytical philosopher and scientist. Your task is to break down the user's premise into a 'Claim Lattice'. "
23+
"CRITICAL RULE: You are strictly forbidden from making ANY claim without providing an 'epistemic_warrant' (a clear logical explanation or evidence) "
24+
"and a 'potential_falsifier' (what would prove it wrong). No confident mush allowed."
25+
)
26+
},
27+
{
28+
"role": "user",
29+
"content": f"Core Premise: {spec.question}\nKeywords: {spec.keywords}\nDeconstruct this into rigorously grounded claims."
30+
}
31+
]
32+
33+
logger.debug("Dispatching to LLM for Claim Lattice Generation (Enforcing Truthfulness)...")
34+
return generate_structured(
35+
messages=messages,
36+
response_model=ClaimLatticeOutput,
37+
model=spec.target_model,
38+
api_base=spec.api_base
39+
)

ā€Žepistemic_forge/models.pyā€Ž

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -45,15 +45,14 @@ class ProjectSpec(BaseModel):
4545

4646

4747
class Claim(BaseModel):
48-
"""Atomic epistemic unit."""
49-
50-
id: str
51-
text: str
52-
support: List[str] = Field(default_factory=list)
53-
objections: List[str] = Field(default_factory=list)
54-
confidence: Confidence = Confidence.LIKELY
55-
sources: List[str] = Field(default_factory=list)
56-
tags: List[str] = Field(default_factory=list)
48+
"""Atomic epistemic unit with absolute grounding."""
49+
id: str = Field(description="Unique identifier, e.g., C1")
50+
text: str = Field(description="The core claim or premise.")
51+
epistemic_warrant: str = Field(description="MANDATORY: The exact logical deduction, explanation, or evidence that proves this claim. NO UNSUBSTANTIATED CLAIMS.")
52+
potential_falsifier: str = Field(description="What specific evidence or scenario would prove this claim wrong?")
53+
support: List[str] = Field(default_factory=list, description="Sub-arguments supporting this claim.")
54+
objections: List[str] = Field(default_factory=list, description="Valid counter-arguments against this claim.")
55+
confidence: Confidence = Field(default=Confidence.LIKELY)
5756

5857

5958

@@ -174,3 +173,8 @@ class ChainOfDensityOutput(BaseModel):
174173
"""Strict schema for the Chain of Density Architect."""
175174
information_density_score: float = Field(ge=0.0, le=10.0, description="Score of how dense the signal-to-noise ratio is.")
176175
crystallized_claim: str = Field(description="The final, hyper-dense output stripped of all filler words.")
176+
177+
class ClaimLatticeOutput(BaseModel):
178+
"""A strict output schema containing multiple grounded claims."""
179+
claims: List[Claim]
180+
lattice_summary: str = Field(description="A short summary of how these claims interlock.")

ā€Žepistemic_forge/pipeline/l2_conductor.pyā€Ž

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
from epistemic_forge.models import ProjectSpec
1111
from epistemic_forge.experts.base import EpistemicExpert
12+
from epistemic_forge.experts.claim_expert import ClaimLatticeExpert
1213
from epistemic_forge.experts.dialectic_expert import HegelianExpert
1314
from epistemic_forge.experts.kaggle_expert import RigorSentinelExpert
1415

@@ -22,7 +23,7 @@ def __init__(self):
2223

2324
def _route_experts(self, domain: str) -> list[EpistemicExpert]:
2425
"""Determines which experts are required based on the domain."""
25-
active_experts = []
26+
active_experts = [ClaimLatticeExpert()]
2627
if domain in ["philosophy", "research", "hybrid"]:
2728
active_experts.append(HegelianExpert())
2829
if domain in ["kaggle", "research", "hybrid"]:

0 commit comments

Comments
Ā (0)