Skip to content
Blog

The "Ethics-by-Design" Framework: Embedding Values into Gemini 3 Agents

Don't bolt ethics on after the fact. Apply an Ethics-by-Design framework that embeds values, safety constraints, and audit trails directly into the Gemini 3 agent lifecycle.

Published on August 5, 2026

AI Assistant

An agent pressured to approve a borderline loan makes the “profitable” call. It wasn’t a bug — the value of profit was weighted higher than the value of fairness, and the system was built that way.

“Ethics” in AI is too often a review checkbox at the end. The Ethics-by-Design framework inverts this: you define the values, constraints, and audit mechanisms before Gemini 3 writes a line of reasoning, and you make those values structurally un-skirtable rather than advisory.

In this tutorial, you will learn how to embed values into an agent at four layers — principles, constraints, reasoning, and auditing — so that doing the right thing is the path of least resistance, not the exception.

The Four-Layer Ethics Stack

Values that live only in a prompt are opinions; values that live in architecture are policies. The framework maps values onto four concrete layers:

LayerWhat it holdsWhy it matters
PrinciplesThe org’s values, as directivesDefines what is right
ConstraintsHard, deterministic guardrailsCode cannot be argued with
ReasoningValues injected into the promptGuides how Gemini 3 decides
AuditHash-chained decision recordsMakes bias detectable
flowchart TD
    A["Organizational Values"] --> B["Principles (prompt directives)"]
    A --> C["Constraints (deterministic guardrails)"]
    B --> D["Gemini 3 Reasoning"]
    C --> D
    D --> E["Decision"]
    E --> F["Audit Hash Chain"]
    F --> G["Human Review Loop"]

Step 1: Define Principles as Directives

Start by turning values into operational directives that can be loaded into a prompt. Vague is worthless at runtime.

PRINCIPLES = {
    "fairness": "Never deny or approve based on protected attributes (race, gender, etc.).",
    "transparency": "You must state your reasoning and any uncertainty for every decision.",
    "privacy": "Do not request, assume, or retain PII you were not given.",
    "accountability": "When uncertain or when a decision has material impact, escalate to a human.",
}

These read as rules, but they anchor the model’s reasoning. The next three layers keep the model honest when a shortcut looks tempting.

Step 2: Build Deterministic Constraints

Principles tell the model what’s right. Constraints make sure a class of wrongness cannot happen. A fairness principle is advisory; a constraint that drops protected attributes from the decision inputs is structural.

PROTECTED_ATTRS = {"race", "gender", "religion", "age", "nationality"}


def sanitize_inputs(features: dict) -> tuple[dict, list[str]]:
    removed = [k for k in features if k in PROTECTED_ATTRS or k.startswith("proxy_for_")]
    clean = {k: v for k, v in features.items() if k not in removed}
    return clean, removed

By removing protected attributes before the model even sees them, you make certain ethical violations impossible by construction — the model can’t weigh a feature it never receives.

Step 3: Inject Values Into Reasoning

Even with clean inputs, the model chooses among value-laden trade-offs. Give it an explicit decision framework so its “reasoning” encodes the same values you wrote down.

def build_ethical_prompt(user_request: str, clean_features: dict) -> str:
    return f"""
Decide based on these PRINCIPLES, which override convenience:
{json.dumps(PRINCIPLES, indent=2)}

When principles conflict, weigh as: privacy > fairness > accountability > transparency.
If resolving requires unavailable data or crosses a principle, output
{{"action":"escalate"}}. Otherwise output {{"action","reason","principle_used"}}.

Request: {user_request}
Inputs (protected attributes already removed): {clean_features}
"""

The explicit priority chain (privacy > fairness > ...) removes ambiguity at conflict time. The model isn’t guessing what the organization values — it’s applying a stated ordering.

Step 4: Enforce With a Value Checker

The model’s verdict passes through a deterministic checker that tests the outcome against principle-level rules, independent of the model’s reasoning.

def check_value(analysis: dict, request: str) -> str:
    if analysis.get("action") == "escalate":
        return "escalate"

    # A "deny" touching protected attributes (shouldn't exist — inputs sanitized)
    if analysis.get("action") == "deny" and any(
        attr in request.lower() for attr in PROTECTED_ATTRS
    ):
        return "block: cannot deny on protected grounds"

    # Privacy: block if the model invented PII not in inputs
    for field in ("name", "email", "phone"):
        if field in analysis.get("reason", "").lower() and field not in request:
            return "block: cannot assume PII"
    return "allow"

This is the same philosophy as the audit proxy: the model proposes, the rule engine disposes. A hear-no-value bug in the model is walled off by a checker that never reasons — it just applies arithmetic.

Step 5: Audit Value Adherence

You can’t manage what you don’t record. Every decision gets hash-chained with the principle used, the inputs, and the outcome, so bias and value-drift are findable in the aggregate.

def record_decision(chain, decision, features, principle_used):
    return chain.record({
        "decision": decision,
        "features": list(features.keys()),  # never values, just keys
        "principle_used": principle_used,
        "escalated": decision == "escalate",
    })

Later, aggregate by principle_used and outcome to detect drift: “deny rate gap widening across a demographic” becomes a query, not an anecdote.

Hardening in Production

  1. Sanitize before reason — remove protected attributes at the input boundary, structurally.
  2. State the priority chain so conflicting values resolve deterministically, not by model whim.
  3. Gate outcomes with a deterministic checker that needs no intelligence.
  4. Hash-chain every decision and review escalation rates and decision distributions over time.

Conclusion

Ethics-by-Design is the difference between hoping an agent behaves and making it unable to misbehave in the ways you care about. Values embedded as additive prompts are optional; values embedded as architecture — sanitized inputs, priority chains, deterministic checkers, and audit chains — are enforced.

Do the hard work up front: define principles, strip the inputs, weight the conflicts, gate the verdict, and audit the pattern. An agent that must be fair, transparent, private, and accountable is not just ethical — it is trustworthy enough to be trusted. And in the agentic era, that trust is the whole product.