Skip to content

Commit

Permalink
Docs: improve custom tool guide (#176)
Browse files Browse the repository at this point in the history
* DocsL improve custom tool guide

* Update tool_guide.md
  • Loading branch information
lusmoura authored Jun 6, 2024
1 parent 55190fa commit 1d143e5
Showing 1 changed file with 79 additions and 1 deletion.
80 changes: 79 additions & 1 deletion docs/custom_tool_guides/tool_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ If you need to install a new library to run your tool, execute the following com
```bash
poetry add <MODULE> --group community
```
### Implementing a Tool
### Implementing a Langchain Tool

Add the implementation inside a tool class that inherits from `BaseTool`. This class will need to implement the `call()` method, which should return a list of dictionary results.

Expand Down Expand Up @@ -67,6 +67,84 @@ class ArxivRetriever(BaseTool):
return [{"text": result}] # <- Return list of results, in this case there is only one
```

### Implementing a custom Tool

If you are implementing a custom tool, you can follow the same structure as the Langchain tools. This class will also need to implement the `call()` method, which should return a list of dictionary results with a "text" or "result" field.

#### Calculator Tool
For example, let's look at the calculator tool:

```python
from typing import Any, Dict, List

from py_expression_eval import Parser

from backend.tools.base import BaseTool


class Calculator(BaseTool):
"""
Function Tool that evaluates mathematical expressions.
"""

@classmethod
def is_available(cls) -> bool:
return True

def call(self, parameters: dict, **kwargs: Any) -> List[Dict[str, Any]]:
math_parser = Parser()
to_evaluate = parameters.get("code", "").replace("pi", "PI").replace("e", "E")

result = []
try:
result = {"result": math_parser.parse(to_evaluate).evaluate({})}
except Exception:
result = {"result": "Parsing error - syntax not allowed."}
return result
```

The `call()` method receives a dictionary of parameters, which is defined in the `Parameter_definitions` field in the tool configuration (described in the section below). The parameters are generated by the model and passed to the tool, so the tool should assume that the parameters are in the correct format and handle them.
In this case, the calculator tool expects a `code` parameter that contains the mathematical expression to evaluate. We then parse the expression and evaluate it, returning the result.

#### Python Interpreter Tool
Another example is the Python Interpreter tool:

```python
import json
import os
from typing import Any, Dict, Mapping

import requests
from langchain_core.tools import Tool as LangchainTool
from pydantic.v1 import BaseModel, Field

from backend.tools.base import BaseTool

class PythonInterpreter(BaseTool):
"""
This class calls arbitrary code against a Python interpreter.
It requires a URL at which the interpreter lives
"""

@classmethod
def is_available(cls) -> bool:
return cls.interpreter_url is not None

def call(self, parameters: dict, **kwargs: Any):
if not self.interpreter_url:
raise Exception("Python Interpreter tool called while URL not set")

code = parameters.get("code", "")
res = requests.post(self.interpreter_url, json={"code": code})
clean_res = self._clean_response(res.json())

return clean_res
```

The python interpreter tool expects a `code` parameter that contains the python code to execute. It then sends a POST request to the interpreter URL with the code and returns the result.
Note that this tool requires a secret `interpreter_url` to be set in the environment variables, and the same can be done for other tools that require secrets.


## Step 4: Making Your Tool Available

To make your tool available, add its definition to the community tools [config.py](https://github.com/cohere-ai/cohere-toolkit/blob/main/src/community/config/tools.py).
Expand Down

0 comments on commit 1d143e5

Please sign in to comment.