Legal pluralism

Deciding from retrieved precedent

The system keeps accumulated decisions as a collection of past cases, each with its recorded reasoning. At decision time, it retrieves the cases relevant to the current situation and reasons from them in context. Nothing is trained for each group and no rule is written. Serving a new group or a newly written policy therefore means adding cases to the collection rather than retraining, and this portability is the main purpose of the approach. The two papers divide the collection differently and retrieve differently. One indexes cases by demographic group and deliberately prefers scenarios that sharply separate groups over scenarios that merely look similar, so the retrieved examples carry the disagreement. The other indexes cases by user-written policy and retrieves earlier inputs similar to the current one, together with the critique-and-revise reasoning they produced.

The method (highlighting differences with Legal pluralism)

Scroll the diagram sideways to see all of it.

Use it in codefrom aiag.cases import GroupPrecedent
from aiag import LM
from aiag.cases import CaseBank, GroupPrecedent

lm = LM("Qwen/Qwen2.5-1.5B-Instruct")
bank = CaseBank(lm)
for answer, decision, group in [
    ("A one-line answer with no sources", "remove", "r/AskHistorians"), ("A one-line answer with no sources", "keep", "r/history"),
    ("A joke reply to a question", "remove", "r/AskHistorians"), ("A long answer citing two books", "keep", "r/AskHistorians"),
]:
    bank.add(answer, decision, group=group)

# Decide as the community would from its own precedents, favouring cases where communities split
mods = GroupPrecedent(lm, bank, "r/AskHistorians", k=2)
print(mods.chat("A short answer that links one Wikipedia page"))

pip install aiagEvery method in aiag Library on GitHub

Papers

arXiv:2411.10912MethodBuiltAuthority: Affected public (open)

Retrieves few-shot examples for a model from a bank of past scenarios, using metrics that weigh how groups differ rather than similarity alone. On an alignment task with inputs from four demographic groups (n = 544), the retrieved examples matched observed preferences more closely. In an end-to-end evaluation (n = 120), SPICA was rated above similarity-based retrieval. Groups gained up to 0.16 points on a five-point scale, and every group benefited rather than only some.

CodeSPICA
from aiag import LM
from aiag.cases import SPICA, CaseBank

lm = LM("Qwen/Qwen2.5-1.5B-Instruct")
bank = CaseBank(lm)  # each group's rating, 1-5, of how acceptable a scenario is
for scenario, group, rating in [("Eating meat", "vegans", 1), ("Eating meat", "farmers", 5), ("Wearing wool", "vegans", 2),
                                ("Wearing wool", "farmers", 5), ("Recycling", "vegans", 5), ("Recycling", "farmers", 5)]:
    bank.add(scenario, f"rated {rating}/5", group=group, rating=rating)

# Retrieve by similarity plus how far the group's rating departs from other groups', so examples carry what sets it apart
spica = SPICA(lm, bank, "vegans", k=2)
print(spica.examples("Wearing leather"))  # the group's scenarios to show the model
print(spica.chat("Wearing leather"))
  • SPICAWrapperaiag/cases/legal_pluralism.py:336 SPICA: a group's few-shot scenarios are retrieved by similarity plus a group-contrast score, how far the group's rating of a scenario departs from other groups' ratings of it, so the examples carry what sets the group apart rather than what merely looks alike (Chen et al., 2024).

pip install aiagEvery method in aiag Library on GitHub

arXiv:2507.20503MethodBuiltAuthority: Developer (open)

Judges whether an image breaches a user-defined content policy by conditioning on precedents rather than on the policy text. Precedents are the recorded reasoning from earlier similar inputs, collected by a critique-and-revise mechanism. The paper reports better results than previous methods in both few-shot and full-dataset settings, and better generalization to policies never seen in training.

CodePrecedentGuardrail
from aiag import LM
from aiag.cases import CaseBank, PrecedentGuardrail

lm = LM("Qwen/Qwen2.5-1.5B-Instruct")
guard = PrecedentGuardrail(lm, CaseBank(lm), "no-violence", "No depictions of graphic violence.")

# Collect precedents: reasoning is critiqued and revised until it reaches the known label, then joins the bank
guard.collect([("A photo of a street brawl with blood on the ground", True), ("A poster for a boxing match", False)])

# New inputs are judged from retrieved precedents of the policy, not from its text
print(guard.violates(["A cartoon of two knights dueling"]))  # P(violation) for each input
  • PrecedentGuardrailWrapperaiag/cases/legal_pluralism.py:352 Precedent-based guardrail: for each user-defined policy, precedents (an input, reasoning about it, the verdict) are collected by critiquing and revising the reasoning until it reaches the known label, and new inputs are judged from the retrieved precedents of that policy rather than from its text (Yang et al., 2025).

pip install aiagEvery method in aiag Library on GitHub