Skip to content

Simplify base Tool implementation #48

@felixarntz

Description

@felixarntz

I think the current tool implementation is unnecessarily complicated:

  • To pass function declarations, you'll need to instantiate a Tool with multiple function declarations in it.
  • In JSON, this becomes a very verbose and deeply nested:
{
    "tools": [
        {
            "type": "functionDeclarations",
            "functionDeclarations": [
                { "...": "..." },
                { "...": "..." },
                { "...": "..." }
            ]
        },
        {
            "type": "webSearch",
            "webSearch": {
                "allowedDomains": ["my-site.com"]
            }
        }
    ]
}

Instead, I would suggest we either replace the type functionDeclarations with a new type functionDeclaration, so that every individual function declaration itself is considered a tool. This is also more commonly aligned with the "tool" language, where the word "tool" and "function declaration" are often used interchangeably - albeit this is also not necessarily true since there are other tools than function declarations (like web search).

To clarify with an example, this would change the JSON shape above to:

{
    "tools": [
        {
            "type": "functionDeclaration",
            "functionDeclaration": { "...": "..." }
        },
        {
            "type": "functionDeclaration",
            "functionDeclaration": { "...": "..." }
        },
        {
            "type": "functionDeclaration",
            "functionDeclaration": { "...": "..." }
        },
        {
            "type": "webSearch",
            "webSearch": {
                "allowedDomains": ["my-site.com"]
            }
        }
    ]
}

IMO more intuitive.

Yet another alternative would be to do away with the "tool" abstraction entirely and simply pass around the different types of tools directly. This would be especially reasonable since there are only 2 types of tools, and we could easily replace ModelConfig:$tools with ModelConfig:$functionDeclarations and ModelConfig:$webSearch. A potential counterargument could be that there might be more types of tools to add in the future, but I'd argue even then we could just add more properties to ModelConfig - that'll inevitably grow with time anyway, as new model config parameters become relevant.

To clarify with an example, this would change the JSON shape above to:

{
    "functionDeclarations": [
        { "...": "..." },
        { "...": "..." },
        { "...": "..." }
    ],
    "webSearch": {
        "allowedDomains": ["my-site.com"]
    }
}

Another benefit of the last approach would be that it makes it very easy to use these same model config keys to express whether a model or provider supports the respective type of tool. With the current KEY_TOOLS, we can't do that, since that single key encompasses all the kinds of tools. But if we have KEY_FUNCTION_DECLARATIONS and KEY_WEB_SEARCH, we could use those same keys to say "Model A supports KEY_FUNCTION_DECLARATIONS, while model B supports KEY_FUNCTION_DECLARATIONS and KEY_WEB_SEARCH".

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions