InterviewPrepKit

Home / Coding / Agent Coding / The Agent Loop / Deduplicating Parallel Tool Calls

Deduplicating Parallel Tool Calls

medium 00:00
Solving tips
  • A tool call's identity is (name, args) together — never the name alone, since one tool gets called with many different args.
  • args is a dict, so it isn't hashable; build a canonical string key with json.dumps(args, sort_keys=True) so key order doesn't matter.
  • Cache on first execution and reuse: duplicates should hit the cache, not the tool.

When a model requests several tool calls at once (a “parallel” turn), the list often contains identical calls — the same tool with the same arguments. Running each one separately wastes time and money and, for a non-idempotent tool, can be outright wrong. Your job is the dispatch layer that runs each unique call exactly once and lets duplicates reuse the cached result.

The problem

A call is a dict {"name": str, "args": dict}. Two calls are the same when they have the same name and the same args — where {"a": 1, "b": 2} and {"b": 2, "a": 1} count as the same args, since key order is not meaningful. You cannot use the args dict directly as a cache key because dicts are unhashable, so you build a canonical key from it.

Task

Complete run_parallel_calls(tools, calls):

  1. For each call, build a canonical key from its name and args, for example f"{name}({json.dumps(args, sort_keys=True)})". sort_keys=True makes the key independent of args ordering.
  2. Keep a cache dict from key -> result. The first time you see a key, look the tool up in tools, call it with args, and store the result under that key. On a repeated key, do not call the tool again.
  3. Return the cache dict: one entry per unique call, mapping the canonical key to its result.
  4. If a call names a tool that isn’t in tools, store an error string (e.g. f"error: unknown tool '{name}'") as that call’s result instead of crashing.

Example

calls_log = []
def search(args):
    calls_log.append(args["q"])
    return f"results for {args['q']}"

tools = {"search": search}
calls = [
    {"name": "search", "args": {"q": "cats"}},
    {"name": "search", "args": {"q": "dogs"}},
    {"name": "search", "args": {"q": "cats"}},   # duplicate of the first call
]

run_parallel_calls(tools, calls)
# -> {
#     'search({"q": "cats"})': 'results for cats',
#     'search({"q": "dogs"})': 'results for dogs',
# }
# calls_log == ["cats", "dogs"]   # "cats" ran once, not twice

Constraints

  • Each unique (name, args) call must invoke its tool at most once.
  • Treat args dicts that differ only in key order as identical.
  • Assume args values are JSON-serializable.
  • Do not call any real LLM or network — tools are plain callables provided to you.

Write your solution, then hit Run tests to check it — or get a mock grade from the AI coach.

The coach remembers this session — revise your code and ask again, and it grades your progress. It gives hints, not the answer.
Report a bug