This function adds the ability for the a LLM to call R functions.
Users can specify a list of functions that the LLM can call, and the
prompt will be modified to include information, as well as an
accompanying extraction function to call the functions (handled by
send_prompt()
). Documentation for the functions is extracted from
the help file (if available), or from documentation added by
tools_add_docs()
Arguments
- prompt
A single string or a
tidyprompt()
object- tools
An R function or a list of R functions that the LLM can call. If the function has been documented in a help file (e.g., because it is part of a package), the documentation will be parsed from the help file. If it is a custom function, documentation should be added with
tools_add_docs()
- type
(optional) The way that tool calling should be enabled. 'auto' will automatically determine the type based on 'llm_provider$api_type' (note that this does not consider model compatibility, and could lead to errors; set 'type' manually if errors occur). 'openai' and 'ollama' will set the relevant API parameters. 'text-based' will provide function definitions in the prompt, extract function calls from the LLM response, and call the functions, providing the results back via
llm_feedback()
. 'text-based' always works, but may be inefficient for APIs that support tool calling natively. However, 'text-based' may be more reliable and flexible, especially when combining with other prompt wraps. 'openai' and 'ollama' may not allow for retries if the function call did not provide the expected result. Note that when using 'openai' or 'ollama', tool calls are not counted as interactions and may continue indefinitely (use with caution)
Value
A tidyprompt()
with an added prompt_wrap()
which
will allow the LLM to call R functions
Details
Note that this method of function calling is purely text-based. This makes it suitable for any LLM and any LLM provider. However, 'native' function calling (where the LLM model provider restricts the model to special tokens that can be used to call functions) may perform better in terms of accuracy and efficiency. 'tidyprompt' may support 'native' function calling in the future
See also
answer_using_r()
tools_get_docs()
Other pre_built_prompt_wraps:
add_text()
,
answer_as_boolean()
,
answer_as_integer()
,
answer_as_json()
,
answer_as_list()
,
answer_as_named_list()
,
answer_as_regex_match()
,
answer_as_text()
,
answer_by_chain_of_thought()
,
answer_by_react()
,
answer_using_r()
,
answer_using_sql()
,
prompt_wrap()
,
quit_if()
,
set_system_prompt()
Other answer_using_prompt_wraps:
answer_using_r()
,
answer_using_sql()
Other tools:
tools_add_docs()
,
tools_get_docs()
Examples
if (FALSE) { # \dontrun{
# When using functions from base R or R packages,
# documentation is automatically extracted from help files:
"What are the files in my current directory?" |>
answer_using_tools(dir) |> # 'dir' function is from base R
send_prompt()
} # }
# Custom functions may also be provided;
# in this case, some documentation is extracted from the function's formals;
# descriptions may be added manually. See below
# Example fake weather function to add to the prompt:
temperature_in_location <- function(
location = c("Amsterdam", "Utrecht", "Enschede"),
unit = c("Celcius", "Fahrenheit")
) {
location <- match.arg(location)
unit <- match.arg(unit)
temperature_celcius <- switch(
location,
"Amsterdam" = 32.5,
"Utrecht" = 19.8,
"Enschede" = 22.7
)
if (unit == "Celcius") {
return(temperature_celcius)
} else {
return(temperature_celcius * 9/5 + 32)
}
}
# Generate documentation for a function
# (based on formals, & help file if available)
docs <- tools_get_docs(temperature_in_location)
# The types get inferred from the function's formals
# However, descriptions are still missing as the function is not from a package
# We can modify the documentation object to add descriptions:
docs$description <- "Get the temperature in a location"
docs$arguments$unit$description <- "Unit in which to return the temperature"
docs$arguments$location$description <- "Location for which to return the temperature"
docs$return$description <- "The temperature in the specified location and unit"
# (See `?tools_add_docs` for more details on the structure of the documentation)
# When we are satisfied with the documentation, we can add it to the function:
temperature_in_location <- tools_add_docs(temperature_in_location, docs)
if (FALSE) { # \dontrun{
# Now the LLM can use the function:
"Hi, what is the weather in Enschede? Give me Celcius degrees" |>
answer_using_tools(temperature_in_location) |>
send_prompt()
} # }