Skip to content
Snippets Groups Projects
Commit 393bf4b9 authored by Simonas's avatar Simonas
Browse files

routeConfig + function call

parent f6298bee
No related branches found
No related tags found
No related merge requests found
%% Cell type:markdown id: tags:
### Set up functions and routes
%% Cell type:code id: tags:
``` python
def get_time(location: str) -> str:
"""Useful to get the time in a specific location"""
print(f"Calling `get_time` function with location: {location}")
print(f"Result from: `get_time` function with location: `{location}`")
return "get_time"
def get_news(category: str, country: str) -> str:
"""Useful to get the news in a specific country"""
print(
f"Calling `get_news` function with category: {category} and country: {country}"
f"Result from: `get_news` function with category: `{category}` "
f"and country: `{country}`"
)
return "get_news"
```
%% Cell type:markdown id: tags:
Now generate a dynamic routing config for each function
%% Cell type:code id: tags:
``` python
from semantic_router.route import Route, RouteConfig
functions = [get_time, get_news]
routes = []
for function in functions:
route = await Route.from_dynamic_route(entity=function)
routes.append(route)
route_config = RouteConfig(routes=routes)
```
%% Output
/Users/jakit/customers/aurelio/semantic-router/.venv/lib/python3.11/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html
from .autonotebook import tqdm as notebook_tqdm
None of PyTorch, TensorFlow >= 2.0, or Flax have been found. Models won't be available and only tokenizers, configuration and file/data utilities can be used.
2023-12-19 16:06:38 INFO semantic_router.utils.logger Generating dynamic route...
2023-12-19 16:06:44 INFO semantic_router.utils.logger Generated route config:
2023-12-19 17:46:30 INFO semantic_router.utils.logger Generating dynamic route...
2023-12-19 17:46:40 INFO semantic_router.utils.logger Generated route config:
{
"name": "get_time",
"utterances": [
"What's the time in [location]?",
"Can you tell me the time in [location]?",
"I need to know the time in [location].",
"What time is it in [location]?",
"Can you give me the time in [location]?"
"What's the time in New York?",
"Can you tell me the time in Tokyo?",
"What's the current time in London?",
"Can you give me the time in Sydney?",
"What's the time in Paris?"
]
}
2023-12-19 16:06:44 INFO semantic_router.utils.logger Generating dynamic route...
2023-12-19 16:06:50 INFO semantic_router.utils.logger Generated route config:
2023-12-19 17:46:40 INFO semantic_router.utils.logger Generating dynamic route...
2023-12-19 17:46:43 INFO semantic_router.utils.logger Generated route config:
{
"name": "get_news",
"utterances": [
"Tell me the latest news from the US",
"Tell me the latest news from the United States",
"What's happening in India today?",
"Get me the top stories from Japan",
"Can you give me the breaking news from Brazil?",
"Can you give me the top stories from Japan",
"Get me the breaking news from the UK",
"What's the latest in Germany?"
]
}
%% Cell type:code id: tags:
``` python
# You can manually add or remove routes
get_weather_route = Route(
name="get_weather",
utterances=[
"what is the weather in SF",
"what is the current temperature in London?",
"tomorrow's weather in Paris?",
],
)
route_config.add(get_weather_route)
route_config.remove("get_weather")
route_config.to_dict()
```
%% Output
2023-12-19 16:07:10 INFO semantic_router.utils.logger Added route `get_weather`
2023-12-19 16:07:10 INFO semantic_router.utils.logger Removed route `get_weather`
2023-12-19 17:46:43 INFO semantic_router.utils.logger Added route `get_weather`
2023-12-19 17:46:43 INFO semantic_router.utils.logger Removed route `get_weather`
[{'name': 'get_time',
'utterances': ["What's the time in [location]?",
'Can you tell me the time in [location]?',
'I need to know the time in [location].',
'What time is it in [location]?',
'Can you give me the time in [location]?'],
'utterances': ["What's the time in New York?",
'Can you tell me the time in Tokyo?',
"What's the current time in London?",
'Can you give me the time in Sydney?',
"What's the time in Paris?"],
'description': None},
{'name': 'get_news',
'utterances': ['Tell me the latest news from the US',
'utterances': ['Tell me the latest news from the United States',
"What's happening in India today?",
'Get me the top stories from Japan',
'Can you give me the breaking news from Brazil?',
'Can you give me the top stories from Japan',
'Get me the breaking news from the UK',
"What's the latest in Germany?"],
'description': None}]
%% Cell type:code id: tags:
``` python
# Get a route by name
route_config.get("get_time")
```
%% Output
Route(name='get_time', utterances=["What's the time in [location]?", 'Can you tell me the time in [location]?', 'I need to know the time in [location].', 'What time is it in [location]?', 'Can you give me the time in [location]?'], description=None)
Route(name='get_time', utterances=["What's the time in New York?", 'Can you tell me the time in Tokyo?', "What's the current time in London?", 'Can you give me the time in Sydney?', "What's the time in Paris?"], description=None)
%% Cell type:markdown id: tags:
Save config to a file (.json or .yaml)
%% Cell type:code id: tags:
``` python
route_config.to_file("route_config.json")
```
%% Output
2023-12-19 16:04:24 INFO semantic_router.utils.logger Saving route config to route_config.json
2023-12-19 17:46:43 INFO semantic_router.utils.logger Saving route config to route_config.json
%% Cell type:markdown id: tags:
### Define routing layer
%% Cell type:markdown id: tags:
Load from local file
%% Cell type:code id: tags:
``` python
from semantic_router.route import RouteConfig
route_config = RouteConfig.from_file("route_config.json")
```
%% Output
2023-12-19 16:07:16 INFO semantic_router.utils.logger Loading route config from route_config.json
%% Cell type:markdown id: tags:
### Define routing layer
2023-12-19 17:46:43 INFO semantic_router.utils.logger Loading route config from route_config.json
%% Cell type:code id: tags:
``` python
from semantic_router import RouteLayer
route_layer = RouteLayer(routes=route_config.routes)
```
%% Cell type:markdown id: tags:
Do a function call with functions as tool
%% Cell type:code id: tags:
``` python
from semantic_router.utils.function_call import route_and_execute
tools = [get_time, get_news]
await route_and_execute(
query="What is the time in Stockholm?", functions=tools, route_layer=route_layer
)
await route_and_execute(
query="What is the tech news in the Lithuania?",
functions=tools,
route_layer=route_layer,
)
await route_and_execute(query="Hi!", functions=tools, route_layer=route_layer)
```
%% Output
2023-12-19 16:07:25 INFO semantic_router.utils.logger Extracting function input...
2023-12-19 17:46:43 INFO semantic_router.utils.logger Extracting function input...
Calling function: get_time
Result from: `get_time` function with location: `Stockholm`
2023-12-19 16:07:27 ERROR semantic_router.utils.logger Input name missing from query
Inputs: {'location': 'Stockholm'}
Schema: {'name': 'get_time', 'description': 'Useful to get the time in a specific location', 'signature': '(location: str) -> str', 'output': "<class 'str'>"}
2023-12-19 17:46:49 INFO semantic_router.utils.logger Extracting function input...
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
/Users/jakit/customers/aurelio/semantic-router/docs/examples/function_calling.ipynb Cell 14 line 5
<a href='vscode-notebook-cell:/Users/jakit/customers/aurelio/semantic-router/docs/examples/function_calling.ipynb#Y115sZmlsZQ%3D%3D?line=0'>1</a> from semantic_router.utils.function_call import route_and_execute
<a href='vscode-notebook-cell:/Users/jakit/customers/aurelio/semantic-router/docs/examples/function_calling.ipynb#Y115sZmlsZQ%3D%3D?line=2'>3</a> tools = [get_time, get_news]
----> <a href='vscode-notebook-cell:/Users/jakit/customers/aurelio/semantic-router/docs/examples/function_calling.ipynb#Y115sZmlsZQ%3D%3D?line=4'>5</a> await route_and_execute(
<a href='vscode-notebook-cell:/Users/jakit/customers/aurelio/semantic-router/docs/examples/function_calling.ipynb#Y115sZmlsZQ%3D%3D?line=5'>6</a> query="What is the time in Stockholm?", functions=tools, route_layer=route_layer
<a href='vscode-notebook-cell:/Users/jakit/customers/aurelio/semantic-router/docs/examples/function_calling.ipynb#Y115sZmlsZQ%3D%3D?line=6'>7</a> )
<a href='vscode-notebook-cell:/Users/jakit/customers/aurelio/semantic-router/docs/examples/function_calling.ipynb#Y115sZmlsZQ%3D%3D?line=7'>8</a> await route_and_execute(
<a href='vscode-notebook-cell:/Users/jakit/customers/aurelio/semantic-router/docs/examples/function_calling.ipynb#Y115sZmlsZQ%3D%3D?line=8'>9</a> query="What is the tech news in the Lithuania?",
<a href='vscode-notebook-cell:/Users/jakit/customers/aurelio/semantic-router/docs/examples/function_calling.ipynb#Y115sZmlsZQ%3D%3D?line=9'>10</a> functions=tools,
<a href='vscode-notebook-cell:/Users/jakit/customers/aurelio/semantic-router/docs/examples/function_calling.ipynb#Y115sZmlsZQ%3D%3D?line=10'>11</a> route_layer=route_layer,
<a href='vscode-notebook-cell:/Users/jakit/customers/aurelio/semantic-router/docs/examples/function_calling.ipynb#Y115sZmlsZQ%3D%3D?line=11'>12</a> )
<a href='vscode-notebook-cell:/Users/jakit/customers/aurelio/semantic-router/docs/examples/function_calling.ipynb#Y115sZmlsZQ%3D%3D?line=12'>13</a> await route_and_execute(query="Hi!", functions=tools, route_layer=route_layer)
File ~/customers/aurelio/semantic-router/semantic_router/utils/function_call.py:125, in route_and_execute(query, functions, route_layer)
123 print(f"Calling function: {function.__name__}")
124 schema = get_schema(function)
--> 125 inputs = await extract_function_inputs(query, schema)
126 call_function(function, inputs)
File ~/customers/aurelio/semantic-router/semantic_router/utils/function_call.py:83, in extract_function_inputs(query, function_schema)
81 function_inputs = json.loads(output)
82 if not is_valid_inputs(function_inputs, function_schema):
---> 83 raise ValueError("Invalid inputs")
84 return function_inputs
ValueError: Invalid inputs
Calling function: get_news
Result from: `get_news` function with category: `tech` and country: `Lithuania`
%% Cell type:code id: tags:
2023-12-19 17:46:52 WARNING semantic_router.utils.logger No function found, calling LLM...
``` python
```
'Hello! How can I assist you today?'
......
[{"name": "get_time", "utterances": ["What's the time in [location]?", "Can you tell me the time in [location]?", "I need to know the time in [location].", "What time is it in [location]?", "Can you give me the time in [location]?"], "description": null}, {"name": "get_news", "utterances": ["Tell me the latest news from the US", "What's happening in India today?", "Get me the top stories from Japan", "Can you give me the breaking news from Brazil?", "What's the latest news from Germany?"], "description": null}]
[{"name": "get_time", "utterances": ["What's the time in New York?", "Can you tell me the time in Tokyo?", "What's the current time in London?", "Can you give me the time in Sydney?", "What's the time in Paris?"], "description": null}, {"name": "get_news", "utterances": ["Tell me the latest news from the United States", "What's happening in India today?", "Can you give me the top stories from Japan", "Get me the breaking news from the UK", "What's the latest in Germany?"], "description": null}]
......@@ -98,7 +98,7 @@ class Route(BaseModel):
Only include the "name" and "utterances" keys in your answer.
The "name" should match the function name and the "utterances"
should comprise a list of 5 example phrases that could be used to invoke
the function.
the function. Use real values instead of placeholders.
Input schema:
{function_schema}
......
......@@ -86,19 +86,19 @@ async def extract_function_inputs(query: str, function_schema: dict[str, Any]) -
def is_valid_inputs(inputs: dict[str, Any], function_schema: dict[str, Any]) -> bool:
"""Validate the extracted inputs against the function schema"""
print(f"Inputs: {inputs}")
print(f"Schema: {function_schema}")
try:
for name, param in function_schema.items():
# Extract parameter names and types from the signature string
signature = function_schema["signature"]
param_info = [param.strip() for param in signature[1:-1].split(",")]
param_names = [info.split(":")[0].strip() for info in param_info]
param_types = [
info.split(":")[1].strip().split("=")[0].strip() for info in param_info
]
for name, type_str in zip(param_names, param_types):
if name not in inputs:
logger.error(f"Input {name} missing from query")
return False
if not isinstance(inputs[name], param["type"]):
logger.error(f"Input {name} is not of type {param['type']}")
return False
return True
except Exception as e:
logger.error(f"Input validation error: {str(e)}")
......@@ -117,7 +117,7 @@ async def route_and_execute(query: str, functions: list[Callable], route_layer):
function_name = route_layer(query)
if not function_name:
logger.warning("No function found, calling LLM...")
return llm(query)
return await llm(query)
for function in functions:
if function.__name__ == function_name:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment