Each tool spec is a plist with the keys :name
, :function
, :description
, :args
and :async
.
The corresponding values:
:name
: The name of the tool, recommended to be in Javascript style snake_case.
:function
: The function itself (lambda or symbol) that runs the tool.
:description
: A verbose description of what the tool does, how to
call it and what it returns.
:args
: A list of plists specifying the arguments, or nil for a function that
takes no arguments. Each plist in ARGS requires the following keys:
:name
and :description
, as strings.type
, as a symbol. Allowed types are those understood by the JSONstring
, number
, integer
, boolean
, array
, object
or null
The following plist keys are conditional/optional:
:optional
, boolean indicating if argument is optional:enum
for enumerated types, whose value is a vector of strings representing:type
is still required for enums.:items
, if the :type
is array
. Its value must be a plist including at least:type
, as a symbol.:properties
, if the :type
is object. Its value must be a plist that can bejson-serialize
, with the exception that :type
specifications in this plist must be symbols.:required
, if the :type
is "object"
. Its value is a vector of strings listing the required object keys.:async
: boolean indicating if the elisp function is asynchronous. If :async
is t
, the function should take a callback as its first argument, along with the arguments specified in :args
, and run the callback with the tool call result when it's ready. (This callback is an implementation detail and must not be specified in :args
.)
object
type
Under these rules, the following tool call JSON spec:
{ "name": "record_summary", "description": "record summary of an image using well-structured json.", "input_schema": { "type": "object", "properties": { "key_colors": { "type": "array", "items": { "type": "object", "properties": { "r": { "type": "number", "description": "red value [0.0, 1.0]" }, "g": { "type": "number", "description": "green value [0.0, 1.0]" }, "b": { "type": "number", "description": "blue value [0.0, 1.0]" }, "name": { "type": "string", "description": "human-readable color name in snake_case, e.g. \"olive_green\" or \"turquoise\"" } }, "required": [ "r", "g", "b", "name" ] }, "description": "key colors in the image. limit to less then four." }, "description": { "type": "string", "description": "image description. one to two sentences max." }, "estimated_year": { "type": "integer", "description": "estimated year that the images was taken, if is it a photo. only set this if the image appears to be non-fictional. rough estimates are okay!" } }, "required": [ "key_colors", "description" ] } }
is constructed via llm-make-tool
or gptel-make-tool
as
(gptel-make-tool ;or `llm-make-tool' :name "record_summary" :description "Record summary of an image using well-structured JSON." :function #'identity ;or anything :args (list '(:name "key_colors" :description "Key colors in the image. Limit to less than four." :type array :items (:type object :properties (:r (:type number :description "red value [0.0, 1.0]") :g (:type number :description "green value [0.0, 1.0]") :b (:type number :description "blue value [0.0, 1.0]") :name (:type string :description: "Human-readable color name in snake_case, e.g. \"olive_green\" or \"turquoise\"")) :required ["r" "g" "b" "name"])) '(:name "description" :type string :description "Image description. One to two sentences max.") '(:name "estimated_year" :type integer :optional t :description "Estimated year that the images was taken, if is it a photo. Only set this if the image appears to be non-fictional. Rough estimates are okay!")))
Note the following:
:args
is a list of argument plists.:name
and :description
are always strings.:type
are always symbols."key_colors"
argument is an array, whose items are of type object.:properties
of this object are specified as a plist whose keys are :r
, :g
and :b
. This property plist is converted by json-serialize
into:{ "r": { "type": "number", "description": "red value [0.0, 1.0]" }, "g": { "type": "number", "description": "green value [0.0, 1.0]" }, "b": { "type": "number", "description": "blue value [0.0, 1.0]" }, "name": { "type": "string", "description:": "Human-readable color name in snake_case, e.g. \"olive_green\" or \"turquoise\"" } }
which has the form we want.
Example with:enum
and :optional
argument
(gptel-make-tool :function (lambda (location unit) (url-retrieve-synchronously (format "api.weather.com/..." location unit))) :name "get_weather" :description "Get the current weather in a given location" :args (list '(:name "location" :type string :description "The city and state, e.g. San Francisco, CA") '(:name "unit" :type string :enum ["celsius" "farenheit"] :description "The unit of temperature, either 'celsius' or 'fahrenheit'" :optional t)))
Note the following:
:enum
is an array of strings.:type
is still required when :enum
is provided.:optional t
.RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4