Batch Processing¶
Langroid can run many tasks or agent methods concurrently over a list of items.
The helpers in langroid/agent/batch.py are run_batch_tasks,
run_batch_task_gen, run_batch_agent_method, llm_response_batch,
agent_response_batch, and run_batch_function.
Basic usage¶
Given a configured agent, create a task and map each item to its input and each task result to the value needed by the caller:
from langroid.agent.batch import run_batch_tasks
from langroid.agent.task import Task
task = Task(agent, interactive=False)
items = ["first question", "second question"]
answers = run_batch_tasks(
task,
items,
input_map=lambda item: item,
output_map=lambda result: None if result is None else result.content,
sequential=False,
)
The returned list has the same length and ordering as items.
Stopping at the first valid result¶
Set stop_on_first_result=True for a search-style batch that should return as
soon as any task produces a valid result. A result is valid when it is non-None
after output_map runs. The usual idiom is therefore to map unusable output
to None; the batch will keep waiting for another task.
Results retain their original input positions. Entries are None for tasks
that were cancelled or whose output mapped to None. If every task finishes
with a None-mapped result, the function returns an all-None list after all
tasks have completed.
For helpers that accept handle_exceptions, its value also affects stopping:
ExceptionHandling.RETURN_NONEconverts an exception toNone, so the batch keeps waiting.ExceptionHandling.RETURN_EXCEPTIONreturns the exception object. Because that object is non-None, it counts as a stopping result and occupies the failed task's original position.ExceptionHandling.RAISE, the default, propagates the exception.
For example, suppose the first search finishes quickly without a usable result, the second finds an answer later, and the third is still running:
items = ["fast miss", "slower match", "long-running search"]
results = run_batch_tasks(
search_task,
items,
input_map=lambda query: query,
output_map=lambda result: (
result.content if result is not None and is_usable(result) else None
),
stop_on_first_result=True,
sequential=False,
)
# The fast miss does not stop the batch. The long search is cancelled.
assert results == [None, "the valid answer", None]
Behavior change¶
In earlier versions, a fast result that mapped to None could cancel the
remaining tasks and return an all-None list. This was fixed in
GitHub issue #1068. Users do
not need to make any API changes.
Batching¶
Set batch_size to process fixed-size batches in input order. With
stop_on_first_result=True, once a valid result is found, later batches are
skipped and their positions are filled with None.
Set sequential=True to process items one at a time when normal batch
processing is used. The stop_on_first_result path schedules the tasks in the
current batch concurrently so that it can return whichever valid result
finishes first.
See tests/main/test_batch.py for executable examples and edge-case coverage.