# Layer

A Layer is simply a list of Units grouped together in a stage of execution for the purposes of organization and shared configuration (e.g., sharing a model + inference parameters with .via will apply to all Units in the Layer). This container allows you to quickly re-organize and scale up Units in an ensemble, round-robin, or other arbitrary configurations.

By default, a Layer propagates information through a judge system in a feedforward fashion with the Units of a subsequent Layer receive the output of a previous Layer's Units in a fully-connected fashion; furthermore, Units within a Layer are fully independent of one another.

Ensemble with 3 Judges
Plot
from verdict import Layer
from verdict.common.judge import JudgeUnit
from verdict.transform import MeanPoolUnit

ensemble = Layer(JudgeUnit(), 3).via('gpt-4o', temperature=0.8) \
    >> MeanPoolUnit("score")

However, it is possible to customize Unit behavior both within a Layer (using keyword inner=) and between current and subsequent Layers (using keyword outer=). Below are common instances of how Units can be stitched together from Layer to Layer. Using the inner='chain' keyword, we can stitch together subsequent JudgeUnit's within the Layer.

Round-Robin with 3 Judges
Plot
from verdict.schema import Schema, Field
from verdict.scale import DiscreteScale

class JudgeRoundRobinUnit(JudgeUnit):
    class InputSchema(Schema):
        explanation: str = Field(default="")

round_robin = Layer(
    JudgeRoundRobinUnit(DiscreteScale((1, 5)), explanation=True).prompt("""
        Rate how funny this joke is.
        {source.joke}

        Consider the previous Judge's explanation to produce your own judgement
        {input.explanation}
""")
, 3, inner='chain').via('gpt-4o', temperature=0.8) \
    >> MeanPoolUnit("score")

Perhaps we only want to output the final Judge's score. Of course, you can simply reference the final previous.judge[2].score using the Previous keyword in a subsequent Prompt. We also can also use the last keyword.

Round-Robin with 3 Judges
Plot
from verdict import Unit

round_robin = Layer(
    JudgeRoundRobinUnit()
, 3, inner='chain', outer='last') \
    >> Unit() # dummy Unit for demonstration

We can also customize the root/leaf node indices that are used to connect Layers.

Conversation; Only Take Opponent Arguments
Plot
from verdict.common.conversational import ConversationalUnit
from verdict.common.judge import JudgeUnit

conversation = Layer([
    ConversationalUnit(role_name='Proponent'),
    ConversationalUnit(role_name='Opponent')
], 3, inner='chain', outer='broadcast').with_leaf([1, 3, 5]) \
    >> Layer(JudgeUnit(), 3)

# Usage

Parameters
Glossary
inner= Description
none Independent (i.e., ensemble)
chain U -> U -> U (i.e., round-robin)
outer= Description
dense fully-connected to nodes of next Layer
broadcast broadcast 1-1
next Layer must have same length
cumulative each Unit receives one more previous Unit
next Layer must have same length
last Units between Layers are connected in a last fashion.

# Unraveling

By default, a Layer takes a single primitive (i.e., Unit/Layer/Block); however, you can also pass a list of primitives to a Layer and it will be unraveled appropriately.