Tool Chaining: Multiple Tools in Sequence, Passing Outputs Between Tools

~15 min read

Real tasks often need more than one tool call in sequence, with one tool's output feeding the next tool's input — a natural extension of the book's single-tool CurrencyConverterTool example to multi-step, multi-tool workflows.

This course's CurrencyConverterTool example demonstrates a single tool handling one complete request. Many real tasks need more than that: a genuine multi-step workflow where one tool's output becomes another tool's input, chained together to accomplish something no single tool call could handle alone.

Consider extending the currency example: 'What would a $500 hotel booking in Tokyo cost in USD, including a 10% weekend surcharge?' This genuinely needs multiple steps — looking up the current USD/JPY exchange rate (one tool), computing the surcharge-adjusted total in JPY (a calculation, potentially another tool), and converting that final JPY amount back to USD (the same currency tool again, but with different inputs than the first call). None of these steps can be skipped, and each one's output feeds the next step's input.

There are two broad ways this chaining actually happens in practice. The first is agent-driven chaining: the LLM itself decides, turn by turn, to call one tool, receives its result, and then decides to call the next tool based on that result — this is exactly the ReAct-style Thought/Action/Observation loop covered elsewhere in this curriculum, just now involving multiple DIFFERENT tools across iterations rather than one tool called repeatedly. The second is explicit orchestration: application code (not the LLM) defines the fixed sequence of tool calls and explicitly passes each tool's output as the next tool's input — closer to the Sequential multi-agent pattern covered elsewhere in this curriculum, just applied to tools rather than full agents.

The trade-off between the two: agent-driven chaining is more flexible (the model can adapt the sequence based on intermediate results, skip unnecessary steps, or recover from a tool returning an unexpected result) but less predictable and harder to debug. Explicit orchestration is predictable and easy to trace but can't adapt if the actual task doesn't match the hardcoded sequence. Real production systems often use a hybrid: explicit orchestration for well-understood, repeated workflows, and agent-driven chaining for genuinely open-ended tasks where the right sequence of tools can't be known in advance.

💻 Code example

# Explicit orchestration — application code defines the fixed sequence
# and passes outputs between tool calls directly.

def get_exchange_rate(source: str, target: str) -> float:
    return 0.0067  # stand-in for a real API call, e.g. JPY -> USD

def apply_surcharge(amount: float, surcharge_pct: float) -> float:
    return amount * (1 + surcharge_pct / 100)

def orchestrated_chain(base_amount_jpy: float, surcharge_pct: float) -> float:
    # Each tool's output explicitly feeds the next tool's input
    surcharged_jpy = apply_surcharge(base_amount_jpy, surcharge_pct)
    jpy_to_usd_rate = get_exchange_rate("JPY", "USD")
    return surcharged_jpy * jpy_to_usd_rate

print(f"${orchestrated_chain(500, 10):.2f}")

# Agent-driven chaining — the LLM itself decides the sequence and
# which tool to call next, based on each tool's result (ReAct-style)
from openai import OpenAI
client = OpenAI()

TOOLS = {"apply_surcharge": apply_surcharge, "get_exchange_rate": get_exchange_rate}
# ... the agent loop (covered in react-agent-from-scratch) decides which
# of TOOLS to call next based on the running conversation, rather than
# application code hardcoding the order upfront

💬 Deep Dive with AI

Key points

  • Real tasks often need multiple tool calls in sequence, with one tool's output feeding the next tool's input
  • Agent-driven chaining: the LLM itself decides, turn by turn, which tool to call next — the ReAct-style loop, extended across different tools
  • Explicit orchestration: application code defines the fixed sequence and passes outputs between tools directly
  • Agent-driven chaining is more flexible and adaptive; explicit orchestration is more predictable and easier to debug
  • Production systems often use a hybrid — explicit orchestration for known workflows, agent-driven chaining for genuinely open-ended tasks