Overview
Tools are how an agent safely touches the outside world (search, databases, calculators, internal APIs).
In Coevolved, a “tool” is:
- A
Step
- Annotated with
kind="tool"
- Optionally paired with a Pydantic schema that describes its arguments (for LLM function calling)
Wrap a function as a tool with tool_step(...):
from coevolved.core.llm import tool_step
def search(state: dict) -> str:
query = state["tool_args"]["query"]
return f"results for {query}"
search_tool = tool_step(search, name="search", result_key="tool_result")
LLM providers typically require a JSON schema for tool arguments. Coevolved generates this from your Pydantic schema:
from pydantic import BaseModel
from coevolved.core.llm import tool_step
from coevolved.core.tools import tool_spec_from_step
class SearchArgs(BaseModel):
query: str
tool = tool_step(lambda s: "...", name="search", tool_schema=SearchArgs)
spec = tool_spec_from_step(tool)
You then attach specs to LLMConfig.tools so the LLM can request them.
The prebuilt ReAct agent:
- Reads tool calls from
LLMResponse.tool_calls
- Resolves a matching tool by name
- Executes it and stores the result (by default under
tool_result)
- Appends tool messages back into
messages
Tool calls are easiest when you standardize state keys (tool_args, tool_result, etc.). ReAct defaults are a good baseline.
Next steps