t27.aiРусский

The mind: an answer with a shape

You will learn

Why a program asks an agent for an answer with a fixed shape, and how it refuses a reply whose shape is wrong.

When you chat with an agent you read free text. When a program reads the answer, free text is a problem: it cannot tell a sentence from a request to run something. So the agent is asked for a reply with a shape: a kind, and the arguments that kind needs. This spec has 3 kinds: 0 say, 1 ask and 2 call a tool. A sentence needs no argument; a question and a tool call need at least 1. The program checks the shape first and acts only if it fits. A tool call that names no file is refused before anything runs. The negative control plants the bug in one place: set NEEDS_CALL to 0 and the test the_bad_reply_is_refused turns red, because a reply with no arguments is no longer too short.

Try it

Open the widget and find which kind needs no argument; then run the spec, set NEEDS_CALL to 0, and read which test fails and why. Put the line back and run it again.

Open the interactive lesson →

Vibecoding 19: an answer with a shape ↗

Three kinds of agent reply, how many arguments each needs, and the check a program runs before it acts on one. Lesson 19 of the Vibecoding from zero course.

specs/vibecoding/agent_mind.t27

// SPDX-License-Identifier: Apache-2.0
; specs/vibecoding/agent_mind.t27 -- vibecoding lesson 19: the mind of an agent, an answer with a shape.
; When a program has to read an agent's answer, free text is not enough: the agent hands back a
; reply with a fixed shape, a kind plus the arguments that kind needs. A program refuses a reply
; whose shape is wrong before it acts on it. Kinds: 0 say, 1 ask, 2 call a tool.
; A sentence needs no argument; a question needs one; a tool call needs at least one.
; Run the tests, then plant the bug named at the bottom and watch one test turn red.

module vibecoding_agent_mind;

pub const KIND_SAY : u8 = 0;
pub const KIND_ASK : u8 = 1;
pub const KIND_CALL : u8 = 2;
pub const KIND_COUNT : u8 = 3;

; Arguments each kind needs at least.
pub const NEEDS_SAY : u8 = 0;
pub const NEEDS_ASK : u8 = 1;
pub const NEEDS_CALL : u8 = 1;

; A good reply: a tool call that carries one argument (the file to read).
pub const GOOD_KIND : u8 = 2;
pub const GOOD_ARGS : u8 = 1;
; A bad reply: a tool call that names no file.
pub const BAD_KIND : u8 = 2;
pub const BAD_ARGS : u8 = 0;
; A reply of a kind that does not exist.
pub const ODD_KIND : u8 = 3;

test the_three_kinds_are_numbered_in_a_row {
    assert KIND_SAY == 0;
    assert KIND_ASK == 1;
    assert KIND_CALL == 2;
    assert KIND_COUNT == KIND_CALL + 1;
}

test a_sentence_needs_no_argument {
    assert NEEDS_SAY == 0;
}

test the_good_reply_has_enough_arguments {
    assert GOOD_KIND == KIND_CALL;
    assert GOOD_ARGS >= NEEDS_CALL;
}

; The negative control. The bad reply carries no argument and must be refused: it has fewer
; arguments than a call needs. Plant the bug by setting NEEDS_CALL to 0: this test turns red.
test the_bad_reply_is_refused {
    assert BAD_KIND == KIND_CALL;
    assert BAD_ARGS < NEEDS_CALL;
}

test an_unknown_kind_is_refused {
    assert ODD_KIND >= KIND_COUNT;
}

Open the lesson's spec in the player ↗

All lessons