#
Transform/Propagate
While the Unit abstraction may feel insufficient to express complex logic or limiting, we provide two mechanisms for arbitrary Python code execution that enable quick iteration without giving up the benefits of the Schema type enforcement.
#
Map/Transform
MapUnit allows you to apply an arbitrary function to the output of a Unit.
from verdict.common.judge import JudgeUnit
from verdict.transform import MapUnit
JudgeUnit() \
>> MapUnit(lambda judge: Schema.of(score=((judge.score / 5) * 7))) # normalize to 1-7 scale
It has native support for multiple dependencies, which are indexed first-come first-serve at definition-time.
Reduce
Index
from verdict import Layer
Layer(JudgeUnit(), 5) \
>> MapUnit(lambda judges: Schema.of(score=min(judge.score for judge in judges)))
Layer([
JudgeUnit(DiscreteScale((1, 5), end_is_worst=False)),
JudgeUnit(DiscreteScale((1, 5), end_is_worst=True))]) \
>> MapUnit(lambda judges: Schema.of(score=(judges[0].score + (6 - judges[1].score)) / 2))
Additionally, we provide the following built-in MapUnits for convenience.
#
Propagate
You can specify special logic to modify the OutputSchema of a Unit post-execution by using the .propagate() directive. This is particularly useful for propagating forward the OutputSchema of a dependency. Refer to the Previous section for more details.
Propagate Dependency
MapUnit Example
from verdict.schema import Schema
ConversationalUnit("Proponent").propagate(
lambda unit, previous, input, output: Schema.of(
thought=previous.thought,
conversation=output.conversation
))
from verdict.common.judge import JudgeUnit
JudgeUnit().propagate(
lambda unit, previous, input, output: Schema.of(
score=(previous.score / 5) * 7
)) \
>> ...