InfoClassifier / openenv.yaml
I766446
final4
5ff0156
Raw History Blame Contribute Delete
9.41 kB
# ============================================================================
# openenv.yaml v1.1.0
# OpenEnv environment specification β€” passes `openenv validate`
# ============================================================================
name: information-integrity-env
version: "1.1.0"
author: openenv-content-moderation
description: >
A deterministic, benchmarkable content moderation environment where agents
verify claims, reason over pre-built evidence sources, and make explainable
moderation decisions (allow / flag / remove).
Evaluation runs fully offline β€” no external API calls during episodes.
Three difficulty tiers (easy / medium / hard) with static scenario datasets
ensure reproducible, comparable benchmarks across agent runs.
license: Apache-2.0
# ---------------------------------------------------------------------------
# Server
# ---------------------------------------------------------------------------
server:
type: http
reset_endpoint: POST /reset
step_endpoint: POST /step
health_endpoint: GET /health
tasks_endpoint: GET /tasks
grade_endpoint: POST /grade
collect_endpoint: POST /collect # dataset creation only; not used during eval
state_endpoint: GET /state/{session_id}
# ---------------------------------------------------------------------------
# Observation space
# ---------------------------------------------------------------------------
observation:
type: object
description: >
The agent observes the content under review, extracted claims (with live
verification status), a pre-built evidence pool, and a running interaction
history. Ground truth is never exposed.
properties:
content:
type: string
description: The piece of content under moderation review.
claims:
type: array
description: Verifiable claims extracted from the content.
items:
type: object
properties:
id: { type: string }
text: { type: string }
verification_status: { type: string, enum: [unverified, true, false, partially_true, unknown] }
confidence: { type: number, minimum: 0.0, maximum: 1.0 }
verified_by_sources: { type: array, items: { type: string } }
available_sources:
type: array
description: Pre-built evidence pool β€” fully deterministic, no live fetching.
items:
type: object
properties:
id: { type: string }
title: { type: string }
text: { type: string }
url: { type: string }
stance: { type: string, enum: [supporting, contradicting, neutral] }
reliability: { type: number, minimum: 0.0, maximum: 1.0 }
source_type: { type: string }
interaction_history:
type: array
description: Log of all previous actions and their results this episode.
status_flags:
type: object
properties:
decision_made: { type: boolean }
sufficient_evidence: { type: boolean }
premature_decision: { type: boolean }
redundant_actions: { type: integer }
max_steps_reached: { type: boolean }
step_count: { type: integer }
episode_id: { type: string }
task_difficulty: { type: string, enum: [easy, medium, hard] }
# ---------------------------------------------------------------------------
# Action space
# ---------------------------------------------------------------------------
actions:
verify_claim:
description: Investigate a specific claim and receive its verification status.
required_fields: [claim_id]
optional_fields: [reasoning]
example:
type: verify_claim
claim_id: claim_001
reasoning: "This is the central assertion β€” verify first."
check_source:
description: Read a source and receive its full text, stance, and reliability.
required_fields: [source_id]
optional_fields: [reasoning]
example:
type: check_source
source_id: src_003
reasoning: "WHO source β€” likely authoritative."
decide:
description: >
Make the final moderation decision, ending the episode.
Must verify >= 1 claim and check >= 2 sources first (or incur premature penalty).
required_fields: [decision]
optional_fields: [reasoning]
example:
type: decide
decision: remove
reasoning: "All claims false per three high-reliability sources."
# ---------------------------------------------------------------------------
# Reward
# ---------------------------------------------------------------------------
reward:
type: float
range: [-2.0, 2.0]
description: >
Dense step-level reward. Non-sparse by design β€” agents receive positive
signals for every unique claim verified and source checked.
See reward_config.yaml for configurable magnitudes.
components:
verify_claim_reward: "+0.20 per unique claim verified"
check_source_reward: "+0.20 per unique source checked"
multi_source_bonus: "+0.20 when >= 3 unique sources checked"
decision_correct: "+1.00 exact match with ground truth"
decision_partial: "+0.50 one step away (flag<->remove, flag<->allow)"
decision_wrong: "0.00"
premature_decision: "-0.50 deciding before sufficient evidence"
redundant_action: "-0.10 re-verifying / re-checking same id"
step_inefficiency: "-0.05 per step beyond efficient threshold"
over_aggression: "-0.30 choosing remove when ground truth is allow/flag"
# ---------------------------------------------------------------------------
# Tasks (deterministic datasets β€” no live API calls)
# ---------------------------------------------------------------------------
tasks:
- name: easy
grader: tasks.easy.grader.grade_episode
- name: medium
grader: tasks.medium.grader.grade_episode
- name: hard
grader: tasks.hard.grader.grade_episode
# ---------------------------------------------------------------------------
# Grader
# ---------------------------------------------------------------------------
grader:
output_range: [0.0, 1.0]
dimensions:
decision_score:
description: Correctness of the final moderation call (partial credit for adjacent decisions)
evidence_score:
description: Fraction of available sources consulted
reasoning_score:
description: Fraction of claims fully verified before deciding
efficiency_score:
description: Steps used relative to difficulty-specific ideal maximum
# ---------------------------------------------------------------------------
# Evaluation protocol
# ---------------------------------------------------------------------------
evaluation:
description: >
Run inference.py in benchmark mode to evaluate an agent across all 15 scenarios.
No external API calls are made during evaluation episodes.
command: python inference.py --benchmark --out results.json
expected_output_format: |
difficulty=easy avg_score=X.XXXX avg_reward=X.XXXX n=5
difficulty=medium avg_score=X.XXXX avg_reward=X.XXXX n=5
difficulty=hard avg_score=X.XXXX avg_reward=X.XXXX n=5
tier_validation: easy_avg > medium_avg > hard_avg
runtime_budget: "< 20 minutes on 2 vCPU / 8 GB RAM"
logging_protocol: "[START] / [STEP] / [END]"
# ---------------------------------------------------------------------------
# Data pipeline (dataset creation only β€” not used during eval)
# ---------------------------------------------------------------------------
data_pipeline:
description: >
DataCollector is used ONLY to build the static scenario datasets in
tasks/{difficulty}/scenarios.json. It is NOT called during evaluation episodes.
backends:
- { name: serpapi, env_key: SERPAPI_KEY }
- { name: newsapi, env_key: NEWSAPI_KEY }
- { name: brave_search, env_key: BRAVE_SEARCH_KEY }
- { name: google_factcheck, env_key: GOOGLE_FACTCHECK_KEY }
- { name: duckduckgo, env_key: null, note: "No key required; rate-limited fallback" }
cache:
backend: redis
env_key: REDIS_URL
default: redis://localhost:6379
ttl_seconds: 86400
# ---------------------------------------------------------------------------
# Constraints
# ---------------------------------------------------------------------------
constraints:
- Ground truth is never exposed in the Observation
- No external API calls occur during env.step() or env.reset()
- All reward computations are deterministic
- Agents must gather evidence before deciding (premature decision penalty applies)
- Redundant actions (re-checking same id) are penalised
- Scenario datasets are static JSON β€” reproducible across runs
# ---------------------------------------------------------------------------
# Baseline
# ---------------------------------------------------------------------------
baseline:
script: inference.py
mode: --benchmark
agent_type: ReAct (LLM-driven)
logging_protocol: "[START] / [STEP] / [END]"
model_env_var: MODEL_NAME
api_base_env_var: API_BASE_URL
token_env_var: HF_TOKEN
expected_scores:
easy: { avg_score: "~0.78", avg_reward: "~1.20" }
medium: { avg_score: "~0.63", avg_reward: "~0.90" }
hard: { avg_score: "~0.52", avg_reward: "~0.65" }