gaslit

package module
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 28, 2026 License: MIT Imports: 14 Imported by: 0

README

gaslit

A Go framework that stress-tests AI agents by staging a supervised courtroom debate. Gaslit runs a panel of debater agents against a multiple-choice question, cross-examines them with a moderator, and detects when agents drift or hallucinate.

Built on top of cloudwego/eino.

How it works

  1. Baseline — every agent answers the question with per-option confidences.
  2. Cross-examination — a supervisor moderator challenges panelists using their own claims and any challenges agents raised, via a cross_examine_agent tool.
  3. Re-evaluation — agents give final positions.
  4. Drift detection — flips, confidence erosion, and total variation distance are measured, and influence is attributed to the swaying agent (or the supervisor).
  5. Grill — the single most drifted/influential agent is grilled with an inversion probe and scored on a confidence/consistency quadrant.
Quadrant diagnostics
Quadrant Confidence Consistency Meaning
PEAK high high Grounded, resilient knowledge
HALLUCINATING / MALICIOUS high low Confident but fabricating contradictory facts
KB_DEFICIT low high Logically consistent but lacking evidence
WRONG / UNCERTAIN low low Guessing without internal consistency

Install

go get github.com/ItsArnavSh/gaslit

Requires Go 1.26+.

Usage

package main

import (
	"context"
	"fmt"
	"log"

	"github.com/ItsArnavSh/gaslit"
	"github.com/cloudwego/eino/adk"
)

func main() {
	ctx := context.Background()

	// 1. Build your debater agents (any eino adk.Agent).
	econ, _ := adk.NewChatModelAgent(ctx, &adk.ChatModelAgentConfig{
		Name:        "economic_historian",
		Description: "Analyzes events from a socio-economic lens.",
		Instruction: "You are an economic historian. Argue that economic forces drive history.",
		Model:       myModel,
	})
	pol, _ := adk.NewChatModelAgent(ctx, &adk.ChatModelAgentConfig{
		Name:        "political_historian",
		Description: "Analyzes events through leadership and military strategy.",
		Instruction: "You are a political and military historian.",
		Model:       myModel,
	})

	// 2. Initialize the engine with a supervisor model + the panel.
	engine, err := gaslit.Init(ctx, myModel, []adk.Agent{econ, pol})
	if err != nil {
		log.Fatal(err)
	}

	// 3. Run the debate.
	summary, err := engine.Debate(ctx, "What caused the Roman Empire's collapse?", []string{
		"Economic exhaustion",
		"Military breakdown",
	}, true)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("Outcome: %s\n", summary.OverallOutcome)
	fmt.Printf("Drift: %t (driver: %s)\n", summary.DriftVerdict.HasDrift, summary.DriftVerdict.PrimaryDriver)
	for name, diag := range summary.Diagnostics {
		fmt.Printf("%s → %s (conf %.2f, consistency %.2f)\n", name, diag.Quadrant, diag.ConfidenceScore, diag.ConsistencyScore)
	}
}

API

  • Init(ctx, supervisorModel, agents) (*Gaslit, error) — build an engine from a panel of adk.Agents and a supervisor model.
  • (*Gaslit).Debate(ctx, question, options, verbose) (*FullDebateSummary, error) — run the full baseline → cross-examine → evaluate → drift → grill pipeline.
  • FullDebateSummary, PromptResult, DriftVerdict, DiagnosticResult, QuadrantState — result types describing positions, drift, and per-agent diagnostics.

Example

See examples/basic for a full runnable program using Groq's API, including a 429-backoff transport and a "panel of historians" demo.

GROQ_API_KEY=... go run ./examples/basic

License

MIT

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type DiagnosticResult

type DiagnosticResult struct {
	AgentName        string        `json:"agent_name"`
	ConfidenceScore  float64       `json:"confidence_score"`  // X-axis (0.0 -> 1.0)
	ConsistencyScore float64       `json:"consistency_score"` // Y-axis (0.0 -> 1.0)
	Quadrant         QuadrantState `json:"quadrant"`
	InitialReasonR1  string        `json:"r1_initial_reasoning"`
	CounterReasonR2  string        `json:"r2_counter_reasoning"`
	Recommendation   string        `json:"recommendation"`
}

DiagnosticResult is the outcome of grilling a single agent: where it lands on the confidence/consistency grid and what action is recommended.

type DriftVerdict

type DriftVerdict struct {
	// HasDrift reports whether any agent flipped or significantly eroded.
	HasDrift bool `json:"has_drift"`
	// DriftedAgents lists the names of agents that drifted.
	DriftedAgents []string `json:"drifted_agents"`
	// PrimaryDriver is the agent (or the supervisor) responsible for the shift.
	PrimaryDriver string `json:"primary_driver"`
	// DriverImpact is a human-readable description of who swayed whom.
	DriverImpact string `json:"driver_impact"`
	// AgentShifts maps each agent name to its total variation distance.
	AgentShifts map[string]float64 `json:"agent_shifts"`
}

DriftVerdict describes whether agents changed their positions over the course of a debate, which agents moved, and who drove the shift.

type FullDebateSummary

type FullDebateSummary struct {
	Question       string                       `json:"question"`
	Options        []string                     `json:"options"`
	OptionLabels   []string                     `json:"option_labels"`
	PromptResult   *PromptResult                `json:"prompt_result"`
	DriftVerdict   DriftVerdict                 `json:"drift_verdict"`
	Diagnostics    map[string]*DiagnosticResult `json:"diagnostics,omitempty"` // Targeted grilling results
	OverallOutcome string                       `json:"overall_outcome"`
}

FullDebateSummary is the complete result of a Debate run: the question and options, pre/post positions, drift verdict, and targeted grilling diagnostics.

type Gaslit

type Gaslit struct {
	// contains filtered or unexported fields
}

Gaslit orchestrates a panel of debater agents under a supervising moderator.

func Init

func Init(ctx context.Context, supervisorModel model.BaseModel[*schema.Message], agents []adk.Agent) (*Gaslit, error)

Init builds a Gaslit engine around the supplied supervisor model and debater agents. At least one agent is required. The returned engine serializes the baseline/evaluation phases, supervised cross-examination, and drift analysis.

The agents are keyed by their Name, which must be unique. Concurrent calls to Debate on the same engine are safe.

func (*Gaslit) Debate

func (g *Gaslit) Debate(ctx context.Context, question string, options []string, verbose bool) (*FullDebateSummary, error)

Debate runs a full panel evaluation on the given multiple-choice question:

  1. Collects each agent's baseline position and confidence.
  2. Has the supervisor moderator cross-examine panelists (honoring any challenges agents raised in their baseline answers).
  3. Re-collects each agent's final position.
  4. Detects drift and attributes influence between agents.
  5. Grills the single most influential/drifted agent to produce a diagnostic.

Options are labeled A, B, C, ... in order. When verbose is true, phase progress is logged via the standard library logger.

type PromptResult

type PromptResult struct {
	Before map[string]*mcqAnswer
	After  map[string]*mcqAnswer
}

PromptResult captures each agent's position before and after the debate.

type QuadrantState

type QuadrantState string

QuadrantState is the 2D classification of an agent based on its confidence (x-axis) and semantic consistency (y-axis) under cross-examination.

const (
	// QuadrantPeak indicates high confidence and high consistency.
	QuadrantPeak QuadrantState = "PEAK (Grounded Knowledge)"
	// QuadrantHallucinating indicates high confidence with fabricated contradictions.
	QuadrantHallucinating QuadrantState = "HALLUCINATING / MALICIOUS"
	// QuadrantKBDeficit indicates consistent but low-confidence answers.
	QuadrantKBDeficit QuadrantState = "KB_DEFICIT (Incomplete Info)"
	// QuadrantWrong indicates low confidence and inconsistent internal logic.
	QuadrantWrong QuadrantState = "WRONG / UNCERTAIN"
)

Directories

Path Synopsis
examples
basic command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL