Multi Step JSON Tool Calling Agent#

Source: examples/agents/multi_step_json_tool_calling_agent.py

Introduction#

Toolformer motivates tool-use planning, JSON Schema defines stable machine-readable contracts, and OpenAI function-calling guidance captures operational patterns for structured tool dispatch. This example shows a JSON-mode agent that repeatedly selects tools through explicit schema-constrained payloads.

Note

This example’s checked-in local LlamaCppServerLLMClient config uses a Qwen3-4B GGUF model. On lower-RAM machines, swap in a smaller local model or start with Ollama Local Client.

Technical Implementation#

  1. Configure Tracer with JSONL + console output so each run emits machine-readable traces and lifecycle logs.

  2. Build the runtime surface (public APIs only) and execute MultiStepAgent.run(...) with a fixed request_id.

  3. Configure and invoke Toolbox integrations (core/script/MCP/callable) before assembling the final payload.

  4. Print a compact JSON payload including trace_info for deterministic tests and docs examples.

        flowchart LR
    A["Input prompt or scenario"] --> B["main(): runtime wiring"]
    B --> C["MultiStepAgent.run(...)"]
    C --> D["WorkflowRuntime loop enforces explicit final-answer and max-step policy"]
    C --> E["Tracer JSONL + console events"]
    D --> F["ExecutionResult/payload"]
    E --> F
    F --> G["Printed JSON output"]
    
 1from __future__ import annotations
 2
 3import json
 4from pathlib import Path
 5
 6import design_research_agents as drag
 7
 8# This checked-in local config uses a Qwen3-4B GGUF model to exercise a richer
 9# multi-step path. On lower-RAM machines, swap in a smaller local model or
10# start with the lighter Ollama local client example first.
11_EXAMPLE_LLAMA_CLIENT_KWARGS = {
12    "model": "Qwen_Qwen3-4B-Instruct-2507-Q4_K_M.gguf",
13    "hf_model_repo_id": "bartowski/Qwen_Qwen3-4B-Instruct-2507-GGUF",
14    "api_model": "qwen3-4b-instruct-2507-q4km",
15    "context_window": 8192,
16    "startup_timeout_seconds": 240.0,
17    "request_timeout_seconds": 240.0,
18}
19
20
21def main() -> None:
22    """Execute one traced multi-step JSON tool-calling run."""
23    # Stable ids make trace correlation and docs output easier to audit.
24    request_id = "example-multi-step-json-design-001"
25    tracer = drag.Tracer(
26        enabled=True,
27        trace_dir=Path("artifacts/examples/traces"),
28        enable_jsonl=True,
29        enable_console=True,
30    )
31    # Run the JSON tool-calling example using public runtime surfaces. Using this with statement will automatically
32    # shut down the managed client and tool runtime when the example is done.
33    with drag.Toolbox() as tool_runtime, drag.LlamaCppServerLLMClient(**_EXAMPLE_LLAMA_CLIENT_KWARGS) as llm_client:
34        json_tool_agent = drag.MultiStepAgent(
35            mode="json",
36            llm_client=llm_client,
37            tool_runtime=tool_runtime,
38            max_steps=3,
39            # Constrain selection so the example exercises an explicit tool surface.
40            allowed_tools=("text.word_count",),
41            tracer=tracer,
42        )
43        result = json_tool_agent.run(
44            prompt=(
45                "Use text.word_count once to count the words in the phrase "
46                "'design research agents', then finish by returning only the word_count."
47            ),
48            request_id=request_id,
49        )
50
51    # Print the results
52    summary = result.summary()
53    print(json.dumps(summary, ensure_ascii=True, indent=2, sort_keys=True))
54
55
56if __name__ == "__main__":
57    main()

Expected Results#

Run Command

PYTHONPATH=src python3 examples/agents/multi_step_json_tool_calling_agent.py

Example output shape (values vary by run):

{
  "success": true,
  "final_output": "<example-specific payload>",
  "terminated_reason": "<string-or-null>",
  "error": null,
  "trace": {
    "request_id": "<request-id>",
    "trace_dir": "artifacts/examples/traces",
    "trace_path": "artifacts/examples/traces/run_<timestamp>_<request_id>.jsonl"
  }
}

References#