Skip to content
DenseChip
Learn
PracticeCode labInterview

DenseChip

Navigate

Menu

LearnPracticeCode labInterview

Tools

All toolsSV editorCode repoResume
DenseChip

Practice, courses, and chip-design tools in one focused workspace.

LearnPracticeCode labInterviewToolsLearning paths

© 2026 DenseChip

AboutContactPrivacyTerms
Skip to lesson

Course contents

  • Getting Started with AI for VLSI Engineers5
  • Just Enough AI: Models and Context15
  • Prompting13
  • Trust and Verification14
  • Using AI for Engineering Work17
  • Engineering Walkthroughs7
  • Practical Foundations for AI Workflows4
  • Engineering Data5
  • Retrieval-Augmented Generation6
  • Agents and Tool Use18
    • What an Agent Is
    • Tool Use and Structured Output
      • Describing Tools to a Model
      • Propose, Execute, Validate
      • Handling Malformed Calls
      • Idempotent and Side-Effecting Tools
      • Tool-Call Validator Lab
    • Planning, Memory and Stopping
    • Multi-Agent Patterns and When Not to Use Agents
  • Agent Design8
  • MCP and Skills6
  • Multi-Agent Design6
  • Practical Capstone6
  • Tokens, Cost and Latency12
  • Agentic Workflows for Chip Teams18
  • Interview and Judgment10
  • AI Skills: Full Course Index
  • Working with AI Glossary
  • Working with AI Cheatsheet
Loading lesson

‹Tool Use and Structured Output
  1. Topics
  2. AI Skills for VLSI Engineers
  3. Agents and Tool Use
  4. Tool Use and Structured Output
  5. Propose, Execute, Validate

Tools, Workflows and Agents · Beginner to Intermediate

Propose, Execute, Validate

The call loop: the model proposes a call, the program validates arguments and runs the tool.

On this page

    The model proposes, the program executes

    Each loop turn has the same shape. The model emits a call as data, the program validates it, and only a valid call reaches the tool.

    The tool result returns as another input, called an observation. The model then proposes the next call or stops.

    Validation before execution

    Validation runs in a fixed order: shape, name, fields, types, then ranges. The first failure decides the verdict, so each rejection names one cause.

    How strictly a model follows a schema varies by model: measure it. The program checks every call regardless, since no proposer is exact.

    Step

    Check

    Rejects with

    1

    Call is an object with tool and arguments.

    not-an-object, missing-tool, bad-arguments

    2

    tool names a registered tool.

    unknown-tool, wrong-tool

    3

    Every required argument is present.

    missing-<name>

    4

    Each argument has the schema type.

    type-<name>

    5

    Each argument sits inside its bounds.

    range-<name>

    A worked validation

    The trace below is schematic, not output from any real system. It walks one write call through the five steps.

    plaintext
    1
    2
    3
    4
    5
    6
    7
    8
    schematic validation trace (illustrative, not from any real system)
    call: {"tool": "write_register", "arguments": {"addr": 16, "data": 1}}
    step 1: object with tool and arguments -> pass
    step 2: write_register is registered -> pass
    step 3: addr and data present -> pass
    step 4: both are integers -> pass
    step 5: addr 16 outside 0 to 15 -> reject with range-addr
    result: rejected, nothing runs

    Validation probe

    The program below uses a fake scripted proposer in place of a model. Eight checks accept one call and sort five faults.

    example.py
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    def validate(call):
        if not isinstance(call, dict):
            return "not-an-object"
        if call.get("tool") != "write_register":
            return "wrong-tool"
        args = call.get("arguments")
        if not isinstance(args, dict):
            return "bad-arguments"
        if "addr" not in args:
            return "missing-addr"
        if "data" not in args:
            return "missing-data"
        if not isinstance(args["addr"], int):
            return "type-addr"
        if not isinstance(args["data"], int):
            return "type-data"
        if args["addr"] < 0 or args["addr"] > 15:
            return "range-addr"
        if args["data"] < 0 or args["data"] > 255:
            return "range-data"
        return "ok"
    
    def fake_program_execute(call):
        verdict = validate(call)
        if verdict != "ok":
            return ("rejected", verdict)
        return ("executed", "addr " + str(call["arguments"]["addr"]))
    
    TESTS = [
        ({"tool": "write_register", "arguments": {"addr": 3, "data": 255}}, "ok"),
        ({"tool": "write_register", "arguments": {"data": 1}}, "missing-addr"),
        ({"tool": "write_register", "arguments": {"addr": "3", "data": 1}}, "type-addr"),
        ({"tool": "write_register", "arguments": {"addr": 16, "data": 1}}, "range-addr"),
        ({"tool": "write_register", "arguments": {"addr": 3, "data": 300}}, "range-data"),
        ({"tool": "erase_chip", "arguments": {"addr": 3, "data": 1}}, "wrong-tool"),
    ]
    
    bad = 0
    for call, want in TESTS:
        if validate(call) != want:
            bad += 1
    if fake_program_execute(TESTS[0][0])[0] != "executed":
        bad += 1
    if fake_program_execute(TESTS[3][0])[0] != "rejected":
        bad += 1
    
    if bad == 0:
        print("PASS: 8 validation checks accept 1 call and sort 5 faults")
    else:
        print("FAIL: " + str(bad) + " of 8 validation checks went wrong")
        raise SystemExit(1)

    Common mistakes

    Common pitfall

    Validating after execution leaves nothing to protect. The checks must run first, and a rejection must run nothing at all.

    Interview

    Likely probes: where proposal ends and execution begins, and the check order.

    • Proposal and execution live apart: the model writes data, the program acts.

    • Validation order is shape, name, fields, types, ranges, first failure wins.

    • Observations are input for the next turn, not proof the action was wise.

    Check yourself A call passes steps 1 to 4 but data is 300 with a bound of 255. What happens?

    The program rejects it with range-data. No write runs, and the model receives the verdict as the next input.

    Check yourself Why does the program recheck a call the model claims is valid?

    The claim is more text from the proposer. Only the program verdict decides execution, since proposer exactness varies by model.

    Related topics

    • Handling malformed calls

    • Verifying AI output

    Previous

    93 / 173

    Next: Handling Malformed Calls

    Up next

    Up nextHandling Malformed Calls

    Sign in to save progress

    Practice this lessonReport an error

    See also

    • Idempotent and Side-Effecting Tools
    • Tool-Call Validator Lab