Build a Transparent LLM Agent in R with Tool Registration and Agent Loops
Writing a small LLM agent in R makes its mechanics visible: the model proposes an action, a function carries it out, and the result goes back into the conversation. A new section in the author’s live book walks through that process, while the turbochook package offers a hands-on version for experimentation. The appeal is partly educational: instead of treating an agent as a mysterious product, the walkthrough lays out the exchange between a model and the code it can call. That distinction matters because an agent’s apparent autonomy comes from a sequence of bounded steps, each shaped by the tools and instructions it receives.
From model response to action
The tutorial uses the ellmer package to connect R to an LLM. It then defines functions the model can call, such as writing and running R code, and gives the model instructions for using them. A parser checks each response for a tool call, runs the requested function, and feeds its output back to the model in a while loop. In practical terms, the model doesn’t directly reach into the R session: the surrounding program interprets its request and decides how to carry it out.
Formally registering tools with ellmer helps reduce syntax errors when the model calls them. That structure also makes the boundary between language and execution easier to see. The model can request an action, but the function definitions determine what actions are available and what inputs they accept. The pattern is compact, but it exposes the core cycle behind an agent: interpret a request, act through tools, inspect the result and continue.
That cycle is useful to understand because a tool call isn’t automatically a correct answer. The function might return an error, an unexpected result, or information that changes what the model should do next. The loop gives the model another chance to respond to that result, but the quality of the outcome still depends on the instructions, the available functions, and how clearly the program handles failures. A small example can make those dependencies easier to inspect than a larger system with layers of hidden behavior.
The full walkthrough is available in the book section on building an agent with R.
Three ways to run turbochook
To demonstrate registered tools, the author built turbochook, an R package developed with Claude Code and available on GitHub. The author describes it as a simple agent for learning and experimentation, alongside other R-based agents. Its three modes offer different levels of user involvement, which makes the package a way to compare how an agent’s workflow changes when approval is required, omitted, or organized around a list of tasks.
The modes also make a practical point: “agent” doesn’t describe one fixed level of autonomy. A user can choose a slower, more supervised interaction or let the program proceed through its own loop. Those choices affect how much opportunity there is to review each action, and how much of the workflow the user must monitor directly. Here’s the thing: the mode that feels most convenient may also be the one that asks the user to trust the program most.
handfish()is aimed at beginners and cautious users; it asks for manual approval at each step.turbochook()runs autonomously without pausing for permission.ralph()follows a “ralph loop,” working through a self-completing todo list.

turbochook in action in my R console
Visibility comes with limits
The package prints its progress, including tool calls and token usage, so users can follow what the agent is doing. That visibility can help a learner connect a prompt to the actions that follow, and notice when the system is repeating itself or taking an unexpected path. It doesn’t, by itself, establish that an action is safe or that the model’s interpretation is sound. A readable log is a useful window into behavior, not a guarantee about the result.
Because the implementation is in R, R users can inspect its behavior in a familiar language rather than interpreting the Unix or Python commands often produced by commercial agents such as Claude Code. That familiarity lowers the barrier to examining the code and changing the tools. It may also make the package a better teaching aid for people whose work already happens in R. If you’re working in this space, the interesting question is not only what the agent can do, but which parts of its behavior you can inspect and control.
This is more significant than it looks for learning: the package puts tool registration, execution, and feedback into a small enough example to study. The numbers here are underwhelming by design; the value is in making the moving parts legible. And yet, legibility has limits. An autonomous mode can carry out a chain of actions without stopping for approval, while the user still needs to understand what those actions can affect.
turbochook is still alpha software, and its author offers no cybersecurity guarantees. Running an agent in a sandbox or isolated container is the recommended precaution. Similar systems can execute code or interact with tools according to their setup, so the environment around an experiment matters as much as the model’s prompt. Isolation gives users a way to limit the consequences of mistakes while they learn how the loop behaves. A contained experiment, then.
For R practitioners, the practical value is a small, inspectable system for learning how tool use and agent loops work—and a concrete starting point for experimenting with their own. That said, the package’s status and stated security limits should shape how it’s used: as an educational project, with care around the code it can run. The broader lesson is straightforward. An agent is a program wrapped around a model, and understanding that wrapper is part of understanding the system.