DEV Community

Khaled Hammrouni
Khaled Hammrouni

Posted on

What if your JSON schema was just a tool ?

Every integration I've inherited has the same line somewhere in it: "return valid JSON."

What if your JSON schema was just a tool ?

Then the parser throws commentary before the object, markdown fences around it, a field dropped because the source text was messy. The schema was never enforced - it was requested, in a language the model has no reason to obey.

There's a trick I keep coming back to stop describing the schema. Make it the tool.

    $extracted = null;

    $saveProfile = new FunctionTool(
        name: 'save_profile',
        description: 'Saves the extracted profile data into the system.',
        parameters: [
            'type' => 'object',
            'properties' => [
                'full_name'        => ['type' => 'string'],
                'skills'           => ['type' => 'array', 'items' => ['type' => 'string']],
                'experience_years' => ['type' => 'integer'],
            ],
            'required' => ['full_name', 'skills'],
        ],
        callable: function (array $args) use (&$extracted) {
            $extracted = $args;
            return "Captured profile for {$args['full_name']}.";
        },
    );

    $agent = new Agent(
        llm: $llmConfig,
        systemPrompt: 'You extract profile details. Your ONLY task is to call save_profile once. Answer only via tool call.',
        tools: [$saveProfile],
    );

    $agent->chat($unstructuredText);
    // $extracted is now a typed array — full_name, skills, experience_years

Enter fullscreen mode Exit fullscreen mode

You don't validate the output afterwards, you don't strip fences, the model has to produce arguments that satisfy your schema, because that is the shape of a tool call - the same mechanism that makes every tool call reliable is what makes your "JSON" reliable.

It works with any provider that does tool calling, hosted or running on the machine next to you, and the validation happens on your side, in your language, where you can react to it.

The full pattern with more examples is article #04 of my PHP-AI series

What's your structured-output approach, schema-as-tool, a provider's native mode, or regex salvage ? Genuinely asking, because I've argued myself out of two of the three.

Top comments (0)