feat(graphiti): Define entity and edge types in new graphiti_schema for structured data extraction feat(graphiti): Enhance ingest_episode_event_step with schema integration for improved episode processing
1096 lines
38 KiB
Python
1096 lines
38 KiB
Python
"""Graphiti Knowledge Graph – Zivilrechtliches Kanzlei-Schema (Graphiti-first).
|
||
|
||
Definiert Pydantic-Modelle für Entity- und Edge-Typen, die Graphiti beim
|
||
Extrahieren aus zivilrechtlichen Kanzleidokumenten verwenden soll.
|
||
|
||
Ziel des Schemas:
|
||
- praxisnah für deutsche Zivilrechtskanzleien
|
||
- Graphiti-first: wenige, klare, textnah extrahierbare Typen
|
||
- saubere Trennung zwischen:
|
||
* Tatsachenbehauptungen
|
||
* Rechtsbehauptungen / Rechtspositionen
|
||
* Auslegungen / Interpretationen
|
||
* Beweismitteln
|
||
* rechtlichen Autoritäten
|
||
* Interessen / Emotionen / internen Bewertungen
|
||
|
||
Verwendung in add_episode():
|
||
from services.graphiti_schema import (
|
||
ENTITY_TYPES,
|
||
EDGE_TYPES,
|
||
EDGE_TYPE_MAP,
|
||
EXTRACTION_INSTRUCTIONS,
|
||
)
|
||
|
||
await graphiti.add_episode(
|
||
...,
|
||
entity_types=ENTITY_TYPES,
|
||
edge_types=EDGE_TYPES,
|
||
edge_type_map=EDGE_TYPE_MAP,
|
||
custom_extraction_instructions=EXTRACTION_INSTRUCTIONS,
|
||
)
|
||
"""
|
||
|
||
from datetime import datetime
|
||
from typing import Optional
|
||
|
||
from pydantic import BaseModel, Field
|
||
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# Entity-Typen
|
||
# ---------------------------------------------------------------------------
|
||
|
||
|
||
class Actor(BaseModel):
|
||
"""A person or organization relevant to a legal matter, such as a party,
|
||
lawyer, witness, court, insurer, authority, expert, or company."""
|
||
|
||
actor_kind: Optional[str] = Field(
|
||
default=None,
|
||
description=(
|
||
"Kind of actor: person, organization, court, authority, insurer, "
|
||
"expert, lawyer, judge, notary, unknown"
|
||
),
|
||
)
|
||
legal_form: Optional[str] = Field(
|
||
default=None,
|
||
description="Legal form if applicable, e.g. GmbH, AG, e.V., GbR",
|
||
)
|
||
function_title: Optional[str] = Field(
|
||
default=None,
|
||
description=(
|
||
"Official or practical function, e.g. Geschäftsführer, Richterin, "
|
||
"Sachverständiger, Rechtsanwalt"
|
||
),
|
||
)
|
||
domicile: Optional[str] = Field(
|
||
default=None,
|
||
description="Residence, seat, registered office, or principal place of business",
|
||
)
|
||
|
||
|
||
class Matter(BaseModel):
|
||
"""A legal matter, mandate, dispute, proceeding, or case container."""
|
||
|
||
matter_type: Optional[str] = Field(
|
||
default=None,
|
||
description=(
|
||
"Type of matter: civil_litigation, advisory, pre_litigation, "
|
||
"appeal, enforcement, settlement, contract_review, other"
|
||
),
|
||
)
|
||
file_reference: Optional[str] = Field(
|
||
default=None,
|
||
description="Internal law-firm matter reference or internal file number",
|
||
)
|
||
court_reference: Optional[str] = Field(
|
||
default=None,
|
||
description="Court case number or external file number if available",
|
||
)
|
||
instance_level: Optional[str] = Field(
|
||
default=None,
|
||
description=(
|
||
"Procedural level: pre_litigation, first_instance, appeal, revision, "
|
||
"enforcement, post_judgment, non_contentious"
|
||
),
|
||
)
|
||
status: Optional[str] = Field(
|
||
default=None,
|
||
description="Current status of the matter",
|
||
)
|
||
subject_area: Optional[str] = Field(
|
||
default=None,
|
||
description=(
|
||
"Area of law, e.g. contract, tort, lease, employment, corporate, "
|
||
"commercial, inheritance"
|
||
),
|
||
)
|
||
|
||
|
||
class Document(BaseModel):
|
||
"""A document or communication artifact in or around the legal matter."""
|
||
|
||
document_type: Optional[str] = Field(
|
||
default=None,
|
||
description=(
|
||
"Type of document: pleading, brief, statement_of_claim, defense_brief, "
|
||
"judgment, order, protocol, contract, addendum, email, letter, invoice, "
|
||
"expert_report, note, attachment, chat, settlement_draft, other"
|
||
),
|
||
)
|
||
document_date: Optional[datetime] = Field(
|
||
default=None,
|
||
description="Date the document was created, signed, or issued",
|
||
)
|
||
source_kind: Optional[str] = Field(
|
||
default=None,
|
||
description=(
|
||
"Source category: client, opponent, court, internal, third_party, "
|
||
"authority, insurer, expert, unknown"
|
||
),
|
||
)
|
||
version_label: Optional[str] = Field(
|
||
default=None,
|
||
description="Version label such as draft, final, executed, amended, signed",
|
||
)
|
||
authenticity_status: Optional[str] = Field(
|
||
default=None,
|
||
description="Authenticity status: original, copy, disputed, verified, unknown",
|
||
)
|
||
|
||
|
||
class Event(BaseModel):
|
||
"""A real-world or procedural event relevant to the matter."""
|
||
|
||
event_type: Optional[str] = Field(
|
||
default=None,
|
||
description=(
|
||
"Type of event: contract_signing, delivery, payment, damage, defect_notice, "
|
||
"termination, negotiation, hearing, filing, service, judgment, settlement_talk, other"
|
||
),
|
||
)
|
||
event_layer: Optional[str] = Field(
|
||
default=None,
|
||
description="Layer of event: real_world or procedural",
|
||
)
|
||
event_date: Optional[datetime] = Field(
|
||
default=None,
|
||
description="Date or start date of the event",
|
||
)
|
||
end_date: Optional[datetime] = Field(
|
||
default=None,
|
||
description="End date if the event spans a period",
|
||
)
|
||
location: Optional[str] = Field(
|
||
default=None,
|
||
description="Relevant location of the event if stated",
|
||
)
|
||
certainty_level: Optional[str] = Field(
|
||
default=None,
|
||
description="Occurrence certainty: certain, likely, disputed, unclear",
|
||
)
|
||
|
||
|
||
class Issue(BaseModel):
|
||
"""A factual, legal, interpretive, procedural, damages-related, or strategic issue."""
|
||
|
||
issue_type: Optional[str] = Field(
|
||
default=None,
|
||
description=(
|
||
"Type of issue: factual, legal, interpretive, procedural, evidentiary, "
|
||
"damages, limitation, settlement, strategic"
|
||
),
|
||
)
|
||
issue_status: Optional[str] = Field(
|
||
default=None,
|
||
description="Status of the issue: open, disputed, clarified, partially_resolved, decided",
|
||
)
|
||
importance: Optional[str] = Field(
|
||
default=None,
|
||
description="Importance level: low, medium, high, critical",
|
||
)
|
||
description: Optional[str] = Field(
|
||
default=None,
|
||
description="Short issue description",
|
||
)
|
||
|
||
|
||
class FactAssertion(BaseModel):
|
||
"""A factual assertion about what happened, existed, was paid, signed, delivered,
|
||
said, known, caused, or otherwise factually occurred."""
|
||
|
||
assertion_text: Optional[str] = Field(
|
||
default=None,
|
||
description="Atomic factual assertion in natural language",
|
||
)
|
||
fact_type: Optional[str] = Field(
|
||
default=None,
|
||
description=(
|
||
"Type of factual assertion: event, state, causation, payment, communication, "
|
||
"authorship, authenticity, chronology, amount, identity, knowledge, possession, other"
|
||
),
|
||
)
|
||
status: Optional[str] = Field(
|
||
default=None,
|
||
description=(
|
||
"Status in the matter: asserted, disputed, undisputed, admitted, contradicted, "
|
||
"established, unclear"
|
||
),
|
||
)
|
||
assertion_date: Optional[datetime] = Field(
|
||
default=None,
|
||
description="Date on which the assertion was made or first recorded",
|
||
)
|
||
certainty_level: Optional[str] = Field(
|
||
default=None,
|
||
description="Confidence in the factual content: certain, likely, uncertain, disputed",
|
||
)
|
||
|
||
|
||
class LegalAssertion(BaseModel):
|
||
"""A legal assertion, legal position, or legal conclusion about rights,
|
||
obligations, validity, liability, admissibility, limitation, or legal effect."""
|
||
|
||
assertion_text: Optional[str] = Field(
|
||
default=None,
|
||
description="Atomic legal assertion in natural language",
|
||
)
|
||
legal_type: Optional[str] = Field(
|
||
default=None,
|
||
description=(
|
||
"Type of legal assertion: validity, invalidity, liability, no_liability, "
|
||
"admissibility, inadmissibility, limitation, enforceability, jurisdiction, "
|
||
"burden, interpretation_result, other"
|
||
),
|
||
)
|
||
status: Optional[str] = Field(
|
||
default=None,
|
||
description="Status of the legal position: asserted, contested, accepted, court_indicated, decided, unclear",
|
||
)
|
||
certainty_level: Optional[str] = Field(
|
||
default=None,
|
||
description="Strength or confidence: strong, moderate, weak, uncertain",
|
||
)
|
||
|
||
|
||
class Interpretation(BaseModel):
|
||
"""An interpretation of a contract, clause, statute, statement, conduct,
|
||
communication, or procedural act."""
|
||
|
||
interpretation_text: Optional[str] = Field(
|
||
default=None,
|
||
description="Natural language statement of the interpretation",
|
||
)
|
||
interpretation_type: Optional[str] = Field(
|
||
default=None,
|
||
description=(
|
||
"Type of interpretation: contract, clause, statute, statement, conduct, "
|
||
"procedural_act, communication"
|
||
),
|
||
)
|
||
method: Optional[str] = Field(
|
||
default=None,
|
||
description=(
|
||
"Interpretive method: wording, systematics, purpose, context, "
|
||
"party_intent, case_law_based, mixed"
|
||
),
|
||
)
|
||
status: Optional[str] = Field(
|
||
default=None,
|
||
description="Status: proposed, contested, plausible, preferred, court_adopted, rejected",
|
||
)
|
||
certainty_level: Optional[str] = Field(
|
||
default=None,
|
||
description="Confidence of the interpretation: strong, moderate, weak, uncertain",
|
||
)
|
||
|
||
|
||
class Evidence(BaseModel):
|
||
"""Evidence offered, available, produced, or evaluated in support of factual content."""
|
||
|
||
evidence_type: Optional[str] = Field(
|
||
default=None,
|
||
description=(
|
||
"Type of evidence: document, witness, expert_report, photo, video, audio, "
|
||
"log, invoice, chat, email, inspection, party_hearing, other"
|
||
),
|
||
)
|
||
evidence_date: Optional[datetime] = Field(
|
||
default=None,
|
||
description="Date of the evidence item or date it was generated",
|
||
)
|
||
origin: Optional[str] = Field(
|
||
default=None,
|
||
description="Origin of evidence: client, opponent, court, third_party, expert, authority, unknown",
|
||
)
|
||
authenticity_status: Optional[str] = Field(
|
||
default=None,
|
||
description="Authenticity or integrity status: verified, disputed, unknown, partial",
|
||
)
|
||
evidentiary_weight: Optional[str] = Field(
|
||
default=None,
|
||
description="Indicative evidentiary weight: weak, medium, strong, unclear",
|
||
)
|
||
evaluation_status: Optional[str] = Field(
|
||
default=None,
|
||
description="Evaluation state: offered, produced, admitted, examined, evaluated, rejected, not_used",
|
||
)
|
||
|
||
|
||
class Authority(BaseModel):
|
||
"""A legal authority such as a statute, court decision, contract clause,
|
||
contract text, or other normative/legal source used in reasoning."""
|
||
|
||
authority_type: Optional[str] = Field(
|
||
default=None,
|
||
description="Type of authority: statute, case_law, contract_clause, contract, regulation, procedural_rule, other",
|
||
)
|
||
citation: Optional[str] = Field(
|
||
default=None,
|
||
description=(
|
||
"Citation or identifier, e.g. § 280 Abs. 1 BGB, § 307 BGB, "
|
||
"BGH NJW 2021, 1234, clause 5.2"
|
||
),
|
||
)
|
||
authority_date: Optional[datetime] = Field(
|
||
default=None,
|
||
description="Date of the decision, version, or relevant authority text if available",
|
||
)
|
||
court_or_source: Optional[str] = Field(
|
||
default=None,
|
||
description="Issuing court or source if applicable",
|
||
)
|
||
version_label: Optional[str] = Field(
|
||
default=None,
|
||
description="Version or temporal qualifier if relevant",
|
||
)
|
||
|
||
|
||
class Claim(BaseModel):
|
||
"""A claim, defense, objection, set-off, counterclaim, or procedural application."""
|
||
|
||
claim_type: Optional[str] = Field(
|
||
default=None,
|
||
description=(
|
||
"Type: payment, damages, injunction, declaratory_relief, rescission, "
|
||
"setoff, limitation_defense, objection, counterclaim, procedural_application, other"
|
||
),
|
||
)
|
||
legal_basis: Optional[str] = Field(
|
||
default=None,
|
||
description="Stated legal basis, e.g. § 280 BGB, § 823 BGB, contract clause",
|
||
)
|
||
amount: Optional[float] = Field(
|
||
default=None,
|
||
description="Monetary amount if applicable",
|
||
)
|
||
currency: Optional[str] = Field(
|
||
default=None,
|
||
description="Currency code, e.g. EUR",
|
||
)
|
||
status: Optional[str] = Field(
|
||
default=None,
|
||
description="Status: asserted, disputed, pending, partially_granted, granted, rejected, settled, unclear",
|
||
)
|
||
limitation_status: Optional[str] = Field(
|
||
default=None,
|
||
description="Limitation status if relevant: not_raised, raised, disputed, expired, not_expired, unclear",
|
||
)
|
||
|
||
|
||
class FinancialItem(BaseModel):
|
||
"""A financial item such as payment, invoice, receivable, damage item,
|
||
fee, interest, or cost item."""
|
||
|
||
item_type: Optional[str] = Field(
|
||
default=None,
|
||
description="Type: payment, invoice, receivable, damage_item, fee, cost, interest, settlement_amount, other",
|
||
)
|
||
amount: Optional[float] = Field(
|
||
default=None,
|
||
description="Amount of the financial item",
|
||
)
|
||
currency: Optional[str] = Field(
|
||
default=None,
|
||
description="Currency code, e.g. EUR",
|
||
)
|
||
booking_date: Optional[datetime] = Field(
|
||
default=None,
|
||
description="Booking, invoice, payment, or valuation date",
|
||
)
|
||
due_date: Optional[datetime] = Field(
|
||
default=None,
|
||
description="Due date if applicable",
|
||
)
|
||
status: Optional[str] = Field(
|
||
default=None,
|
||
description="Status: claimed, paid, overdue, disputed, offset, partially_paid, written_off, unclear",
|
||
)
|
||
|
||
|
||
class Interest(BaseModel):
|
||
"""A substantive, economic, personal, reputational, relational, or strategic interest."""
|
||
|
||
interest_type: Optional[str] = Field(
|
||
default=None,
|
||
description="Type of interest: economic, personal, reputational, strategic, relational, procedural",
|
||
)
|
||
description: Optional[str] = Field(
|
||
default=None,
|
||
description="Description of the interest pursued or protected",
|
||
)
|
||
priority: Optional[str] = Field(
|
||
default=None,
|
||
description="Priority level: low, medium, high, critical",
|
||
)
|
||
explicitness: Optional[str] = Field(
|
||
default=None,
|
||
description="How explicit the interest is: explicit, inferred, assumed",
|
||
)
|
||
time_relevance: Optional[str] = Field(
|
||
default=None,
|
||
description="Temporal relevance: immediate, ongoing, long_term",
|
||
)
|
||
|
||
|
||
class Emotion(BaseModel):
|
||
"""An emotional state or emotional stance relevant to conflict dynamics,
|
||
credibility, escalation, negotiation, or settlement."""
|
||
|
||
emotion_type: Optional[str] = Field(
|
||
default=None,
|
||
description="Type: anger, fear, distrust, urgency, willingness, hostility, frustration, relief, uncertainty, other",
|
||
)
|
||
intensity: Optional[str] = Field(
|
||
default=None,
|
||
description="Intensity: low, medium, high",
|
||
)
|
||
polarity: Optional[str] = Field(
|
||
default=None,
|
||
description="Polarity: positive, negative, mixed, neutral",
|
||
)
|
||
inferred_from: Optional[str] = Field(
|
||
default=None,
|
||
description="Short explanation of what the emotional inference is based on",
|
||
)
|
||
temporal_scope: Optional[str] = Field(
|
||
default=None,
|
||
description="Temporal scope: momentary, ongoing, recurring, unclear",
|
||
)
|
||
|
||
|
||
class Assessment(BaseModel):
|
||
"""An internal assessment of risk, opportunity, strategy, weakness, strength,
|
||
evidentiary posture, legal strength, or settlement option."""
|
||
|
||
assessment_type: Optional[str] = Field(
|
||
default=None,
|
||
description=(
|
||
"Type: risk, opportunity, strategy, weakness, strength, settlement_option, "
|
||
"evidentiary_assessment, legal_assessment, procedural_assessment"
|
||
),
|
||
)
|
||
assessment_text: Optional[str] = Field(
|
||
default=None,
|
||
description="Text of the internal assessment",
|
||
)
|
||
severity: Optional[str] = Field(
|
||
default=None,
|
||
description="Severity or importance: low, medium, high, critical",
|
||
)
|
||
likelihood: Optional[str] = Field(
|
||
default=None,
|
||
description="Likelihood if relevant: low, medium, high, unclear",
|
||
)
|
||
assessment_date: Optional[datetime] = Field(
|
||
default=None,
|
||
description="Date of the assessment",
|
||
)
|
||
|
||
|
||
class Deadline(BaseModel):
|
||
"""A legal, procedural, contractual, or internal deadline or due date."""
|
||
|
||
deadline_type: Optional[str] = Field(
|
||
default=None,
|
||
description=(
|
||
"Type: court_deadline, limitation, reply_deadline, hearing_date, "
|
||
"payment_due_date, internal_deadline, appeal_deadline, enforcement_deadline"
|
||
),
|
||
)
|
||
due_date: Optional[datetime] = Field(
|
||
default=None,
|
||
description="Due date or scheduled time",
|
||
)
|
||
status: Optional[str] = Field(
|
||
default=None,
|
||
description="Status: upcoming, met, missed, extended, unclear",
|
||
)
|
||
consequence: Optional[str] = Field(
|
||
default=None,
|
||
description="Potential or actual consequence of meeting or missing the deadline",
|
||
)
|
||
|
||
|
||
class InformationGap(BaseModel):
|
||
"""A missing document, fact, evidence item, clarification, timeline element,
|
||
authority, or calculation needed for the matter."""
|
||
|
||
gap_type: Optional[str] = Field(
|
||
default=None,
|
||
description=(
|
||
"Type: missing_document, missing_fact, missing_evidence, missing_calculation, "
|
||
"missing_authority, missing_instruction, missing_timeline, other"
|
||
),
|
||
)
|
||
description: Optional[str] = Field(
|
||
default=None,
|
||
description="Description of what is missing",
|
||
)
|
||
relevance_level: Optional[str] = Field(
|
||
default=None,
|
||
description="Relevance: low, medium, high, critical",
|
||
)
|
||
requested_from: Optional[str] = Field(
|
||
default=None,
|
||
description="Who is expected to provide or clarify the missing information",
|
||
)
|
||
resolution_status: Optional[str] = Field(
|
||
default=None,
|
||
description="Status: open, requested, partially_resolved, resolved, unobtainable",
|
||
)
|
||
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# Edge-Typen
|
||
# ---------------------------------------------------------------------------
|
||
|
||
|
||
class HasRole(BaseModel):
|
||
"""Role of an actor in a matter."""
|
||
|
||
role_type: Optional[str] = Field(
|
||
default=None,
|
||
description=(
|
||
"Role in the matter: client, plaintiff, defendant, witness, expert, judge, "
|
||
"lawyer, opposing_lawyer, insurer, third_party, debtor, creditor, other"
|
||
),
|
||
)
|
||
side: Optional[str] = Field(
|
||
default=None,
|
||
description="Side in the matter: own_side, opposing_side, neutral, court_side, unclear",
|
||
)
|
||
start_date: Optional[datetime] = Field(
|
||
default=None,
|
||
description="Date the role began",
|
||
)
|
||
end_date: Optional[datetime] = Field(
|
||
default=None,
|
||
description="Date the role ended",
|
||
)
|
||
|
||
|
||
class OccursInMatter(BaseModel):
|
||
"""Connects an entity to the legal matter it belongs to."""
|
||
|
||
relevance: Optional[str] = Field(
|
||
default=None,
|
||
description="Relevance to the matter: peripheral, relevant, central",
|
||
)
|
||
|
||
|
||
class InvolvesActor(BaseModel):
|
||
"""Indicates involvement of an actor in another entity."""
|
||
|
||
involvement_type: Optional[str] = Field(
|
||
default=None,
|
||
description=(
|
||
"Type of involvement: author, sender, recipient, signatory, participant, "
|
||
"subject, holder, affected_party, beneficiary, target, issuer, addressee, other"
|
||
),
|
||
)
|
||
|
||
|
||
class ContainsFactAssertion(BaseModel):
|
||
"""A document contains a factual assertion."""
|
||
|
||
section_reference: Optional[str] = Field(
|
||
default=None,
|
||
description="Section, page, paragraph, sentence, or exhibit reference if available",
|
||
)
|
||
|
||
|
||
class ContainsLegalAssertion(BaseModel):
|
||
"""A document contains a legal assertion."""
|
||
|
||
section_reference: Optional[str] = Field(
|
||
default=None,
|
||
description="Section, page, paragraph, sentence, or exhibit reference if available",
|
||
)
|
||
|
||
|
||
class ContainsInterpretation(BaseModel):
|
||
"""A document contains an interpretation."""
|
||
|
||
section_reference: Optional[str] = Field(
|
||
default=None,
|
||
description="Section, page, paragraph, sentence, or exhibit reference if available",
|
||
)
|
||
|
||
|
||
class AssertsFact(BaseModel):
|
||
"""An actor asserts, denies, admits, reports, or disputes a factual assertion."""
|
||
|
||
modality: Optional[str] = Field(
|
||
default=None,
|
||
description="Modality: asserts, denies, admits, reports, suspects, recalls, disputes",
|
||
)
|
||
assertion_date: Optional[datetime] = Field(
|
||
default=None,
|
||
description="Date of the assertion if known",
|
||
)
|
||
|
||
|
||
class AssertsLegalPosition(BaseModel):
|
||
"""An actor advances, contests, accepts, or rejects a legal assertion."""
|
||
|
||
modality: Optional[str] = Field(
|
||
default=None,
|
||
description="Modality: asserts, contests, accepts, proposes, adopts, rejects",
|
||
)
|
||
assertion_date: Optional[datetime] = Field(
|
||
default=None,
|
||
description="Date the legal position was asserted",
|
||
)
|
||
|
||
|
||
class ProposesInterpretation(BaseModel):
|
||
"""An actor proposes, contests, adopts, prefers, or rejects an interpretation."""
|
||
|
||
modality: Optional[str] = Field(
|
||
default=None,
|
||
description="Modality: proposes, contests, adopts, rejects, prefers",
|
||
)
|
||
assertion_date: Optional[datetime] = Field(
|
||
default=None,
|
||
description="Date the interpretation was proposed or discussed",
|
||
)
|
||
|
||
|
||
class SupportsFact(BaseModel):
|
||
"""Evidence supports or tends to support a factual assertion."""
|
||
|
||
strength: Optional[str] = Field(
|
||
default=None,
|
||
description="Support strength: weak, medium, strong",
|
||
)
|
||
directness: Optional[str] = Field(
|
||
default=None,
|
||
description="Directness: direct, indirect, circumstantial",
|
||
)
|
||
|
||
|
||
class SupportsLegalPosition(BaseModel):
|
||
"""A legal authority supports or limits a legal assertion."""
|
||
|
||
support_type: Optional[str] = Field(
|
||
default=None,
|
||
description="Support type: direct, analogous, persuasive, conflicting, limiting",
|
||
)
|
||
strength: Optional[str] = Field(
|
||
default=None,
|
||
description="Support strength: weak, medium, strong",
|
||
)
|
||
|
||
|
||
class SupportsInterpretation(BaseModel):
|
||
"""An authority or factual context supports an interpretation."""
|
||
|
||
support_type: Optional[str] = Field(
|
||
default=None,
|
||
description="Support type: wording, context, purpose, case_law, factual_context, mixed",
|
||
)
|
||
strength: Optional[str] = Field(
|
||
default=None,
|
||
description="Support strength: weak, medium, strong",
|
||
)
|
||
|
||
|
||
class ConcernsIssue(BaseModel):
|
||
"""Connects an entity to an issue it concerns."""
|
||
|
||
relevance: Optional[str] = Field(
|
||
default=None,
|
||
description="Relevance to the issue: low, medium, high, critical",
|
||
)
|
||
|
||
|
||
class RelatesToClaim(BaseModel):
|
||
"""Connects an entity to a claim, defense, objection, or application."""
|
||
|
||
relation_type: Optional[str] = Field(
|
||
default=None,
|
||
description=(
|
||
"Relation type: supports, weakens, required_for, contests, quantifies, "
|
||
"limits, defeats, substantiates"
|
||
),
|
||
)
|
||
|
||
|
||
class Contradicts(BaseModel):
|
||
"""A contradiction or inconsistency between two elements."""
|
||
|
||
conflict_kind: Optional[str] = Field(
|
||
default=None,
|
||
description=(
|
||
"Kind of conflict: factual, legal, interpretive, evidentiary, chronology, "
|
||
"amount, authenticity"
|
||
),
|
||
)
|
||
severity: Optional[str] = Field(
|
||
default=None,
|
||
description="Severity: low, medium, high, critical",
|
||
)
|
||
explanation: Optional[str] = Field(
|
||
default=None,
|
||
description="Short explanation of the contradiction",
|
||
)
|
||
|
||
|
||
class Interprets(BaseModel):
|
||
"""An interpretation interprets a legal authority, document, clause, or legal proposition."""
|
||
|
||
target_aspect: Optional[str] = Field(
|
||
default=None,
|
||
description="Aspect interpreted: wording, clause_scope, intent, legal_effect, procedural_meaning, other",
|
||
)
|
||
|
||
|
||
class TriggersDeadline(BaseModel):
|
||
"""A document or event triggers a deadline."""
|
||
|
||
trigger_type: Optional[str] = Field(
|
||
default=None,
|
||
description="Type of trigger: service, filing, judgment, notice, contract_event, invoice, limitation_start, other",
|
||
)
|
||
|
||
|
||
class ConcernsFinancialItem(BaseModel):
|
||
"""Connects a document, event, or claim to a financial item."""
|
||
|
||
relation_type: Optional[str] = Field(
|
||
default=None,
|
||
description="Relation type: creates, evidences, claims, pays, reduces, offsets, calculates, disputes",
|
||
)
|
||
|
||
|
||
class HoldsInterest(BaseModel):
|
||
"""An actor holds or pursues an interest."""
|
||
|
||
basis: Optional[str] = Field(
|
||
default=None,
|
||
description="Basis: explicit_statement, negotiation_behavior, correspondence, internal_note, inferred, assumed",
|
||
)
|
||
|
||
|
||
class ExperiencesEmotion(BaseModel):
|
||
"""An actor experiences or displays an emotion or emotional stance."""
|
||
|
||
basis: Optional[str] = Field(
|
||
default=None,
|
||
description="Basis: explicit_statement, observed_behavior, tone, negotiation, internal_note, inferred",
|
||
)
|
||
|
||
|
||
class Influences(BaseModel):
|
||
"""A strategic, emotional, or analytical factor influences another element."""
|
||
|
||
influence_type: Optional[str] = Field(
|
||
default=None,
|
||
description=(
|
||
"Influence type: strengthens, weakens, delays, escalates, enables_settlement, "
|
||
"blocks_settlement, changes_priority, increases_risk"
|
||
),
|
||
)
|
||
strength: Optional[str] = Field(
|
||
default=None,
|
||
description="Influence strength: low, medium, high",
|
||
)
|
||
|
||
|
||
class IdentifiesGap(BaseModel):
|
||
"""An issue, claim, or assessment identifies a missing piece of information."""
|
||
|
||
urgency: Optional[str] = Field(
|
||
default=None,
|
||
description="Urgency: low, medium, high, critical",
|
||
)
|
||
|
||
|
||
class AddressesGap(BaseModel):
|
||
"""An entity helps resolve an information gap."""
|
||
|
||
resolution_quality: Optional[str] = Field(
|
||
default=None,
|
||
description="Quality of resolution: partial, substantial, complete",
|
||
)
|
||
|
||
|
||
class Assesses(BaseModel):
|
||
"""An internal assessment evaluates another entity."""
|
||
|
||
assessment_aspect: Optional[str] = Field(
|
||
default=None,
|
||
description=(
|
||
"Aspect evaluated: credibility, legal_strength, evidentiary_strength, "
|
||
"settlement_value, procedural_risk, economic_impact, strategic_value"
|
||
),
|
||
)
|
||
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# Zusammengefasste Exports
|
||
# ---------------------------------------------------------------------------
|
||
|
||
ENTITY_TYPES: dict[str, type[BaseModel]] = {
|
||
"Actor": Actor,
|
||
"Matter": Matter,
|
||
"Document": Document,
|
||
"Event": Event,
|
||
"Issue": Issue,
|
||
"FactAssertion": FactAssertion,
|
||
"LegalAssertion": LegalAssertion,
|
||
"Interpretation": Interpretation,
|
||
"Evidence": Evidence,
|
||
"Authority": Authority,
|
||
"Claim": Claim,
|
||
"FinancialItem": FinancialItem,
|
||
"Interest": Interest,
|
||
"Emotion": Emotion,
|
||
"Assessment": Assessment,
|
||
"Deadline": Deadline,
|
||
"InformationGap": InformationGap,
|
||
}
|
||
|
||
EDGE_TYPES: dict[str, type[BaseModel]] = {
|
||
"HasRole": HasRole,
|
||
"OccursInMatter": OccursInMatter,
|
||
"InvolvesActor": InvolvesActor,
|
||
"ContainsFactAssertion": ContainsFactAssertion,
|
||
"ContainsLegalAssertion": ContainsLegalAssertion,
|
||
"ContainsInterpretation": ContainsInterpretation,
|
||
"AssertsFact": AssertsFact,
|
||
"AssertsLegalPosition": AssertsLegalPosition,
|
||
"ProposesInterpretation": ProposesInterpretation,
|
||
"SupportsFact": SupportsFact,
|
||
"SupportsLegalPosition": SupportsLegalPosition,
|
||
"SupportsInterpretation": SupportsInterpretation,
|
||
"ConcernsIssue": ConcernsIssue,
|
||
"RelatesToClaim": RelatesToClaim,
|
||
"Contradicts": Contradicts,
|
||
"Interprets": Interprets,
|
||
"TriggersDeadline": TriggersDeadline,
|
||
"ConcernsFinancialItem": ConcernsFinancialItem,
|
||
"HoldsInterest": HoldsInterest,
|
||
"ExperiencesEmotion": ExperiencesEmotion,
|
||
"Influences": Influences,
|
||
"IdentifiesGap": IdentifiesGap,
|
||
"AddressesGap": AddressesGap,
|
||
"Assesses": Assesses,
|
||
}
|
||
|
||
# Erlaubte Kanten pro Entity-Paar: (Quell-Typ, Ziel-Typ) -> [erlaubte Edge-Typen]
|
||
EDGE_TYPE_MAP: dict[tuple[str, str], list[str]] = {
|
||
("Actor", "Matter"): ["HasRole"],
|
||
("Document", "Matter"): ["OccursInMatter"],
|
||
("Event", "Matter"): ["OccursInMatter"],
|
||
("Issue", "Matter"): ["OccursInMatter"],
|
||
("Claim", "Matter"): ["OccursInMatter"],
|
||
("Deadline", "Matter"): ["OccursInMatter"],
|
||
("Assessment", "Matter"): ["OccursInMatter"],
|
||
("Interest", "Matter"): ["OccursInMatter"],
|
||
("Emotion", "Matter"): ["OccursInMatter"],
|
||
("InformationGap", "Matter"): ["OccursInMatter"],
|
||
("FinancialItem", "Matter"): ["OccursInMatter"],
|
||
("Authority", "Matter"): ["OccursInMatter"],
|
||
("Evidence", "Matter"): ["OccursInMatter"],
|
||
("FactAssertion", "Matter"): ["OccursInMatter"],
|
||
("LegalAssertion", "Matter"): ["OccursInMatter"],
|
||
("Interpretation", "Matter"): ["OccursInMatter"],
|
||
|
||
("Document", "Actor"): ["InvolvesActor"],
|
||
("Event", "Actor"): ["InvolvesActor"],
|
||
("Claim", "Actor"): ["InvolvesActor"],
|
||
("Interest", "Actor"): ["InvolvesActor"],
|
||
("Emotion", "Actor"): ["InvolvesActor"],
|
||
("FinancialItem", "Actor"): ["InvolvesActor"],
|
||
|
||
("Document", "FactAssertion"): ["ContainsFactAssertion"],
|
||
("Document", "LegalAssertion"): ["ContainsLegalAssertion"],
|
||
("Document", "Interpretation"): ["ContainsInterpretation"],
|
||
|
||
("Actor", "FactAssertion"): ["AssertsFact"],
|
||
("Actor", "LegalAssertion"): ["AssertsLegalPosition"],
|
||
("Actor", "Interpretation"): ["ProposesInterpretation"],
|
||
|
||
("Evidence", "FactAssertion"): ["SupportsFact"],
|
||
("Authority", "LegalAssertion"): ["SupportsLegalPosition"],
|
||
("Authority", "Interpretation"): ["SupportsInterpretation"],
|
||
("FactAssertion", "Interpretation"): ["SupportsInterpretation"],
|
||
|
||
("FactAssertion", "Issue"): ["ConcernsIssue"],
|
||
("LegalAssertion", "Issue"): ["ConcernsIssue"],
|
||
("Interpretation", "Issue"): ["ConcernsIssue"],
|
||
("Evidence", "Issue"): ["ConcernsIssue"],
|
||
("Authority", "Issue"): ["ConcernsIssue"],
|
||
("Claim", "Issue"): ["ConcernsIssue"],
|
||
("FinancialItem", "Issue"): ["ConcernsIssue"],
|
||
("Assessment", "Issue"): ["ConcernsIssue"],
|
||
("Interest", "Issue"): ["ConcernsIssue"],
|
||
("Emotion", "Issue"): ["ConcernsIssue"],
|
||
("Deadline", "Issue"): ["ConcernsIssue"],
|
||
("InformationGap", "Issue"): ["ConcernsIssue"],
|
||
|
||
("FactAssertion", "Claim"): ["RelatesToClaim"],
|
||
("LegalAssertion", "Claim"): ["RelatesToClaim"],
|
||
("Interpretation", "Claim"): ["RelatesToClaim"],
|
||
("Evidence", "Claim"): ["RelatesToClaim"],
|
||
("Authority", "Claim"): ["RelatesToClaim"],
|
||
("FinancialItem", "Claim"): ["RelatesToClaim"],
|
||
("Assessment", "Claim"): ["RelatesToClaim"],
|
||
("Interest", "Claim"): ["RelatesToClaim"],
|
||
|
||
("FactAssertion", "FactAssertion"): ["Contradicts"],
|
||
("LegalAssertion", "LegalAssertion"): ["Contradicts"],
|
||
("Interpretation", "Interpretation"): ["Contradicts"],
|
||
("Evidence", "FactAssertion"): ["Contradicts"],
|
||
("FactAssertion", "Interpretation"): ["Contradicts"],
|
||
("LegalAssertion", "Interpretation"): ["Contradicts"],
|
||
|
||
("Interpretation", "Authority"): ["Interprets"],
|
||
("Interpretation", "Document"): ["Interprets"],
|
||
("Interpretation", "LegalAssertion"): ["Interprets"],
|
||
|
||
("Document", "Deadline"): ["TriggersDeadline"],
|
||
("Event", "Deadline"): ["TriggersDeadline"],
|
||
|
||
("Document", "FinancialItem"): ["ConcernsFinancialItem"],
|
||
("Event", "FinancialItem"): ["ConcernsFinancialItem"],
|
||
("Claim", "FinancialItem"): ["ConcernsFinancialItem"],
|
||
|
||
("Actor", "Interest"): ["HoldsInterest"],
|
||
("Actor", "Emotion"): ["ExperiencesEmotion"],
|
||
|
||
("Interest", "Claim"): ["Influences"],
|
||
("Interest", "Issue"): ["Influences"],
|
||
("Interest", "Assessment"): ["Influences"],
|
||
("Emotion", "Issue"): ["Influences"],
|
||
("Emotion", "Assessment"): ["Influences"],
|
||
("Assessment", "Claim"): ["Influences"],
|
||
("Assessment", "Issue"): ["Influences"],
|
||
("Assessment", "Matter"): ["Influences"],
|
||
|
||
("Assessment", "InformationGap"): ["IdentifiesGap"],
|
||
("Issue", "InformationGap"): ["IdentifiesGap"],
|
||
("Claim", "InformationGap"): ["IdentifiesGap"],
|
||
|
||
("Document", "InformationGap"): ["AddressesGap"],
|
||
("Evidence", "InformationGap"): ["AddressesGap"],
|
||
("FactAssertion", "InformationGap"): ["AddressesGap"],
|
||
("Authority", "InformationGap"): ["AddressesGap"],
|
||
|
||
("Assessment", "FactAssertion"): ["Assesses"],
|
||
("Assessment", "LegalAssertion"): ["Assesses"],
|
||
("Assessment", "Interpretation"): ["Assesses"],
|
||
("Assessment", "Evidence"): ["Assesses"],
|
||
("Assessment", "Claim"): ["Assesses"],
|
||
("Assessment", "FinancialItem"): ["Assesses"],
|
||
|
||
("Entity", "Entity"): ["RELATES_TO"],
|
||
}
|
||
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# Freitextanweisung für das LLM beim Extrahieren
|
||
# ---------------------------------------------------------------------------
|
||
|
||
EXTRACTION_INSTRUCTIONS = """
|
||
Du analysierst Dokumente einer deutschen Rechtsanwaltskanzlei im Zivilrecht.
|
||
|
||
Extrahiere nur Informationen, die für anwaltliche Arbeit sinnvoll sind, insbesondere
|
||
für Sachverhaltsaufklärung, Schriftsatzarbeit, Beweisführung, Anspruchsprüfung,
|
||
Vergleichsstrategie, Fristenkontrolle und Fallbewertung.
|
||
|
||
Wichtige Grundregeln:
|
||
|
||
1. Trenne strikt zwischen Tatsachen, Rechtspositionen und Auslegungen.
|
||
- FactAssertion:
|
||
Tatsachenbehauptungen über reale oder prozessuale Tatsachen.
|
||
Beispiele:
|
||
* "X unterzeichnete am 15.11.2020 den Dienstvertrag."
|
||
* "Die Rechnung über 12.500 EUR wurde am 04.02.2023 bezahlt."
|
||
* "Die Gegenseite erhielt das Schreiben am 18.01.2024."
|
||
- LegalAssertion:
|
||
Rechtsbehauptungen oder rechtliche Schlussfolgerungen.
|
||
Beispiele:
|
||
* "Der Vertrag ist wirksam."
|
||
* "Die Forderung ist verjährt."
|
||
* "Die Kündigung war unwirksam."
|
||
- Interpretation:
|
||
Auslegung von Vertrag, Klausel, Norm, Erklärung, Verhalten oder Kommunikation.
|
||
Beispiele:
|
||
* "§ 5 des Vertrags ist als Haftungsbegrenzung auszulegen."
|
||
* "Die E-Mail vom 12.03. ist als Kündigungserklärung zu verstehen."
|
||
|
||
2. Trenne strikt zwischen Evidence und Authority.
|
||
- Evidence:
|
||
Beweismittel für Tatsachen, z.B. Urkunden, E-Mails, Zeugen, Gutachten, Rechnungen, Fotos, Logs.
|
||
- Authority:
|
||
Rechtliche Autoritäten, z.B. Gesetze, Gerichtsentscheidungen, Vertragsklauseln, Vertragsbestimmungen.
|
||
|
||
3. Extrahiere Interests und Emotions nur, wenn sie im Text ausdrücklich erkennbar
|
||
oder aus dem Kontext mit hoher Plausibilität ableitbar sind.
|
||
- Interest:
|
||
wirtschaftliche, persönliche, strategische oder reputationsbezogene Interessen.
|
||
Beispiele:
|
||
* "Mandant will schnelle außergerichtliche Einigung."
|
||
* "Gegenseite will Präzedenzfall vermeiden."
|
||
- Emotion:
|
||
emotional relevante Lage oder Haltung.
|
||
Beispiele:
|
||
* "Mandant ist verärgert."
|
||
* "Gegenseite wirkt nicht vergleichsbereit."
|
||
Wenn unklar, lieber nicht extrahieren.
|
||
|
||
4. Extrahiere Issue-Knoten für zentrale Streitfragen oder Problemfelder.
|
||
Beispiele:
|
||
- "Zugang der Kündigung"
|
||
- "Wirksamkeit der AGB-Klausel"
|
||
- "Schadenshöhe"
|
||
- "Verjährung"
|
||
- "Aktivlegitimation"
|
||
|
||
5. Extrahiere Claim-Knoten für Ansprüche, Einreden, Einwendungen, Gegenansprüche
|
||
oder prozessuale Anträge.
|
||
Beispiele:
|
||
- Kaufpreisforderung
|
||
- Schadensersatzanspruch
|
||
- Einrede der Verjährung
|
||
- Aufrechnung
|
||
- Feststellungsantrag
|
||
|
||
6. Extrahiere FinancialItem-Knoten für Zahlungen, Rechnungen, Schadenspositionen,
|
||
Zinsen, Kosten oder sonstige Geldpositionen, soweit konkret erkennbar.
|
||
|
||
7. Extrahiere Deadlines nur, wenn eine Frist oder ein konkreter Termin deutlich genannt ist.
|
||
Beispiele:
|
||
- Berufungsfrist
|
||
- gerichtliche Erwiderungsfrist
|
||
- Zahlung fällig zum 31.03.2024
|
||
- Termin zur mündlichen Verhandlung
|
||
|
||
8. Extrahiere InformationGap nur, wenn im Text ausdrücklich oder sinngemäß erkennbar ist,
|
||
dass etwas fehlt oder noch beschafft/geklärt werden muss.
|
||
Beispiele:
|
||
- fehlende Originalvollmacht
|
||
- fehlender Zahlungsnachweis
|
||
- unklare Zustellung
|
||
- fehlende Schadensberechnung
|
||
|
||
Beachte bei der Extraktion:
|
||
- Nutze klare, atomare Informationen statt zusammengesetzter Sätze.
|
||
- Verwende für assertion_text und ähnliche Textfelder möglichst knappe, präzise Formulierungen.
|
||
- Datumsangaben nach Möglichkeit als ISO-Datum oder ISO-Zeitpunkt extrahieren.
|
||
- Extrahiere keine strafrechtsspezifischen Rollen oder Konzepte, wenn sie im zivilrechtlichen Kontext nicht relevant sind.
|
||
- Vermeide Dubletten; identische oder offensichtlich gleiche Entitäten möglichst zusammenführen.
|
||
- Wenn eine Information nur behauptet, aber bestritten ist, extrahiere sie trotzdem, aber mit passendem Status.
|
||
- Widersprüche zwischen Tatsachenbehauptungen, Rechtspositionen oder Auslegungen sollen möglichst als Contradicts-Beziehungen erfasst werden.
|
||
- Wenn eine Tatsachenbehauptung durch ein Beweismittel gestützt wird, nutze SupportsFact.
|
||
- Wenn eine Rechtsbehauptung durch Normen, Rechtsprechung oder Vertragsklauseln gestützt wird, nutze SupportsLegalPosition.
|
||
- Wenn eine Auslegung durch Wortlaut, Kontext, Parteiwillen oder Rechtsprechung gestützt wird, nutze SupportsInterpretation.
|
||
- Verknüpfe relevante Elemente mit Issues und Claims, wenn der Zusammenhang aus dem Text erkennbar ist.
|
||
- Verknüpfe Actors mit Matters über HasRole, wenn die Rolle im Mandat oder Verfahren erkennbar ist.
|
||
|
||
Nutze dieses Schema streng und bevorzuge juristisch brauchbare Präzision vor Vollständigkeit.
|
||
""".strip() |