Skip to content
Snippets Groups Projects
Unverified Commit 0f6c948d authored by Siraj R Aizlewood's avatar Siraj R Aizlewood
Browse files

Got Ollama working with Dynamic Routes.

This involved updating the prompt in llms > base.py to be more reliable.

Also created Notebook 07 to showcase Ollama with dynamic routes.
parent 24c27cfb
No related branches found
No related tags found
No related merge requests found
%% Cell type:markdown id: tags:
[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/aurelio-labs/semantic-router/blob/main/docs/07-ollama-local-execution.ipynb) [![Open nbviewer](https://raw.githubusercontent.com/pinecone-io/examples/master/assets/nbviewer-shield.svg)](https://nbviewer.org/github/aurelio-labs/semantic-router/blob/main/docs/07-ollama-local-execution.ipynb)
%% Cell type:markdown id: tags:
# Local Dynamic Routes - With Ollama
%% Cell type:markdown id: tags:
## Fully local Semantic Router with Ollama and HuggingFace Encoder
There are many reasons users might choose to roll their own LLMs rather than use a third-party service. Whether it's due to cost, privacy or compliance, Semantic Router supports the use of "local" LLMs through `llama.cpp`.
Below is an example of using semantic router which leverages Ollama in order to utilize the **OpenHermes** LLM.
%% Cell type:markdown id: tags:
We need `pillow`, `torch` and `transformers` for the HuggingFace encoders.
%% Cell type:markdown id: tags:
## Installing the Library and Dependencies
%% Cell type:code id: tags:
``` python
!pip install semantic_router[local]==0.0.23 \
pillow torch transformers
```
%% Output
Requirement already satisfied: semantic_router[local]==0.0.23 in c:\users\siraj\documents\personal\work\aurelio\20240123 semantic router\venvs\semantic_router\lib\site-packages (0.0.23)
Requirement already satisfied: pillow in c:\users\siraj\documents\personal\work\aurelio\20240123 semantic router\venvs\semantic_router\lib\site-packages (10.2.0)
Requirement already satisfied: torch in c:\users\siraj\documents\personal\work\aurelio\20240123 semantic router\venvs\semantic_router\lib\site-packages (2.2.0)
Requirement already satisfied: transformers in c:\users\siraj\documents\personal\work\aurelio\20240123 semantic router\venvs\semantic_router\lib\site-packages (4.38.0)
Requirement already satisfied: black<24.0.0,>=23.12.1 in c:\users\siraj\documents\personal\work\aurelio\20240123 semantic router\venvs\semantic_router\lib\site-packages (from semantic_router[local]==0.0.23) (23.12.1)
Requirement already satisfied: cohere<5.0,>=4.32 in c:\users\siraj\documents\personal\work\aurelio\20240123 semantic router\venvs\semantic_router\lib\site-packages (from semantic_router[local]==0.0.23) (4.47)
Requirement already satisfied: colorama<0.5.0,>=0.4.6 in c:\users\siraj\documents\personal\work\aurelio\20240123 semantic router\venvs\semantic_router\lib\site-packages (from semantic_router[local]==0.0.23) (0.4.6)
Requirement already satisfied: colorlog<7.0.0,>=6.8.0 in c:\users\siraj\documents\personal\work\aurelio\20240123 semantic router\venvs\semantic_router\lib\site-packages (from semantic_router[local]==0.0.23) (6.8.2)
Requirement already satisfied: llama-cpp-python<0.3.0,>=0.2.28 in c:\users\siraj\documents\personal\work\aurelio\20240123 semantic router\venvs\semantic_router\lib\site-packages (from semantic_router[local]==0.0.23) (0.2.45)
Requirement already satisfied: mistralai<0.0.13,>=0.0.12 in c:\users\siraj\documents\personal\work\aurelio\20240123 semantic router\venvs\semantic_router\lib\site-packages (from semantic_router[local]==0.0.23) (0.0.12)
Requirement already satisfied: numpy<2.0.0,>=1.25.2 in c:\users\siraj\documents\personal\work\aurelio\20240123 semantic router\venvs\semantic_router\lib\site-packages (from semantic_router[local]==0.0.23) (1.26.4)
Requirement already satisfied: openai<2.0.0,>=1.10.0 in c:\users\siraj\documents\personal\work\aurelio\20240123 semantic router\venvs\semantic_router\lib\site-packages (from semantic_router[local]==0.0.23) (1.12.0)
Requirement already satisfied: pydantic<3.0.0,>=2.5.3 in c:\users\siraj\documents\personal\work\aurelio\20240123 semantic router\venvs\semantic_router\lib\site-packages (from semantic_router[local]==0.0.23) (2.6.1)
Requirement already satisfied: pyyaml<7.0.0,>=6.0.1 in c:\users\siraj\documents\personal\work\aurelio\20240123 semantic router\venvs\semantic_router\lib\site-packages (from semantic_router[local]==0.0.23) (6.0.1)
Requirement already satisfied: filelock in c:\users\siraj\documents\personal\work\aurelio\20240123 semantic router\venvs\semantic_router\lib\site-packages (from torch) (3.13.1)
Requirement already satisfied: typing-extensions>=4.8.0 in c:\users\siraj\documents\personal\work\aurelio\20240123 semantic router\venvs\semantic_router\lib\site-packages (from torch) (4.9.0)
Requirement already satisfied: sympy in c:\users\siraj\documents\personal\work\aurelio\20240123 semantic router\venvs\semantic_router\lib\site-packages (from torch) (1.12)
Requirement already satisfied: networkx in c:\users\siraj\documents\personal\work\aurelio\20240123 semantic router\venvs\semantic_router\lib\site-packages (from torch) (3.2.1)
Requirement already satisfied: jinja2 in c:\users\siraj\documents\personal\work\aurelio\20240123 semantic router\venvs\semantic_router\lib\site-packages (from torch) (3.1.3)
Requirement already satisfied: fsspec in c:\users\siraj\documents\personal\work\aurelio\20240123 semantic router\venvs\semantic_router\lib\site-packages (from torch) (2024.2.0)
Requirement already satisfied: huggingface-hub<1.0,>=0.19.3 in c:\users\siraj\documents\personal\work\aurelio\20240123 semantic router\venvs\semantic_router\lib\site-packages (from transformers) (0.20.3)
Requirement already satisfied: packaging>=20.0 in c:\users\siraj\documents\personal\work\aurelio\20240123 semantic router\venvs\semantic_router\lib\site-packages (from transformers) (23.2)
Requirement already satisfied: regex!=2019.12.17 in c:\users\siraj\documents\personal\work\aurelio\20240123 semantic router\venvs\semantic_router\lib\site-packages (from transformers) (2023.12.25)
Requirement already satisfied: requests in c:\users\siraj\documents\personal\work\aurelio\20240123 semantic router\venvs\semantic_router\lib\site-packages (from transformers) (2.31.0)
Requirement already satisfied: tokenizers<0.19,>=0.14 in c:\users\siraj\documents\personal\work\aurelio\20240123 semantic router\venvs\semantic_router\lib\site-packages (from transformers) (0.15.2)
Requirement already satisfied: safetensors>=0.4.1 in c:\users\siraj\documents\personal\work\aurelio\20240123 semantic router\venvs\semantic_router\lib\site-packages (from transformers) (0.4.2)
Requirement already satisfied: tqdm>=4.27 in c:\users\siraj\documents\personal\work\aurelio\20240123 semantic router\venvs\semantic_router\lib\site-packages (from transformers) (4.66.2)
Requirement already satisfied: click>=8.0.0 in c:\users\siraj\documents\personal\work\aurelio\20240123 semantic router\venvs\semantic_router\lib\site-packages (from black<24.0.0,>=23.12.1->semantic_router[local]==0.0.23) (8.1.7)
Requirement already satisfied: mypy-extensions>=0.4.3 in c:\users\siraj\documents\personal\work\aurelio\20240123 semantic router\venvs\semantic_router\lib\site-packages (from black<24.0.0,>=23.12.1->semantic_router[local]==0.0.23) (1.0.0)
Requirement already satisfied: pathspec>=0.9.0 in c:\users\siraj\documents\personal\work\aurelio\20240123 semantic router\venvs\semantic_router\lib\site-packages (from black<24.0.0,>=23.12.1->semantic_router[local]==0.0.23) (0.12.1)
Requirement already satisfied: platformdirs>=2 in c:\users\siraj\documents\personal\work\aurelio\20240123 semantic router\venvs\semantic_router\lib\site-packages (from black<24.0.0,>=23.12.1->semantic_router[local]==0.0.23) (4.2.0)
Requirement already satisfied: aiohttp<4.0,>=3.0 in c:\users\siraj\documents\personal\work\aurelio\20240123 semantic router\venvs\semantic_router\lib\site-packages (from cohere<5.0,>=4.32->semantic_router[local]==0.0.23) (3.9.3)
Requirement already satisfied: backoff<3.0,>=2.0 in c:\users\siraj\documents\personal\work\aurelio\20240123 semantic router\venvs\semantic_router\lib\site-packages (from cohere<5.0,>=4.32->semantic_router[local]==0.0.23) (2.2.1)
Requirement already satisfied: fastavro<2.0,>=1.8 in c:\users\siraj\documents\personal\work\aurelio\20240123 semantic router\venvs\semantic_router\lib\site-packages (from cohere<5.0,>=4.32->semantic_router[local]==0.0.23) (1.9.4)
Requirement already satisfied: importlib_metadata<7.0,>=6.0 in c:\users\siraj\documents\personal\work\aurelio\20240123 semantic router\venvs\semantic_router\lib\site-packages (from cohere<5.0,>=4.32->semantic_router[local]==0.0.23) (6.11.0)
Requirement already satisfied: urllib3<3,>=1.26 in c:\users\siraj\documents\personal\work\aurelio\20240123 semantic router\venvs\semantic_router\lib\site-packages (from cohere<5.0,>=4.32->semantic_router[local]==0.0.23) (2.2.1)
Requirement already satisfied: diskcache>=5.6.1 in c:\users\siraj\documents\personal\work\aurelio\20240123 semantic router\venvs\semantic_router\lib\site-packages (from llama-cpp-python<0.3.0,>=0.2.28->semantic_router[local]==0.0.23) (5.6.3)
Requirement already satisfied: MarkupSafe>=2.0 in c:\users\siraj\documents\personal\work\aurelio\20240123 semantic router\venvs\semantic_router\lib\site-packages (from jinja2->torch) (2.1.5)
Requirement already satisfied: httpx<0.26.0,>=0.25.2 in c:\users\siraj\documents\personal\work\aurelio\20240123 semantic router\venvs\semantic_router\lib\site-packages (from mistralai<0.0.13,>=0.0.12->semantic_router[local]==0.0.23) (0.25.2)
Requirement already satisfied: orjson<4.0.0,>=3.9.10 in c:\users\siraj\documents\personal\work\aurelio\20240123 semantic router\venvs\semantic_router\lib\site-packages (from mistralai<0.0.13,>=0.0.12->semantic_router[local]==0.0.23) (3.9.14)
Requirement already satisfied: anyio<5,>=3.5.0 in c:\users\siraj\documents\personal\work\aurelio\20240123 semantic router\venvs\semantic_router\lib\site-packages (from openai<2.0.0,>=1.10.0->semantic_router[local]==0.0.23) (4.2.0)
Requirement already satisfied: distro<2,>=1.7.0 in c:\users\siraj\documents\personal\work\aurelio\20240123 semantic router\venvs\semantic_router\lib\site-packages (from openai<2.0.0,>=1.10.0->semantic_router[local]==0.0.23) (1.9.0)
Requirement already satisfied: sniffio in c:\users\siraj\documents\personal\work\aurelio\20240123 semantic router\venvs\semantic_router\lib\site-packages (from openai<2.0.0,>=1.10.0->semantic_router[local]==0.0.23) (1.3.0)
Requirement already satisfied: annotated-types>=0.4.0 in c:\users\siraj\documents\personal\work\aurelio\20240123 semantic router\venvs\semantic_router\lib\site-packages (from pydantic<3.0.0,>=2.5.3->semantic_router[local]==0.0.23) (0.6.0)
Requirement already satisfied: pydantic-core==2.16.2 in c:\users\siraj\documents\personal\work\aurelio\20240123 semantic router\venvs\semantic_router\lib\site-packages (from pydantic<3.0.0,>=2.5.3->semantic_router[local]==0.0.23) (2.16.2)
Requirement already satisfied: charset-normalizer<4,>=2 in c:\users\siraj\documents\personal\work\aurelio\20240123 semantic router\venvs\semantic_router\lib\site-packages (from requests->transformers) (3.3.2)
Requirement already satisfied: idna<4,>=2.5 in c:\users\siraj\documents\personal\work\aurelio\20240123 semantic router\venvs\semantic_router\lib\site-packages (from requests->transformers) (3.6)
Requirement already satisfied: certifi>=2017.4.17 in c:\users\siraj\documents\personal\work\aurelio\20240123 semantic router\venvs\semantic_router\lib\site-packages (from requests->transformers) (2024.2.2)
Requirement already satisfied: mpmath>=0.19 in c:\users\siraj\documents\personal\work\aurelio\20240123 semantic router\venvs\semantic_router\lib\site-packages (from sympy->torch) (1.3.0)
Requirement already satisfied: aiosignal>=1.1.2 in c:\users\siraj\documents\personal\work\aurelio\20240123 semantic router\venvs\semantic_router\lib\site-packages (from aiohttp<4.0,>=3.0->cohere<5.0,>=4.32->semantic_router[local]==0.0.23) (1.3.1)
Requirement already satisfied: attrs>=17.3.0 in c:\users\siraj\documents\personal\work\aurelio\20240123 semantic router\venvs\semantic_router\lib\site-packages (from aiohttp<4.0,>=3.0->cohere<5.0,>=4.32->semantic_router[local]==0.0.23) (23.2.0)
Requirement already satisfied: frozenlist>=1.1.1 in c:\users\siraj\documents\personal\work\aurelio\20240123 semantic router\venvs\semantic_router\lib\site-packages (from aiohttp<4.0,>=3.0->cohere<5.0,>=4.32->semantic_router[local]==0.0.23) (1.4.1)
Requirement already satisfied: multidict<7.0,>=4.5 in c:\users\siraj\documents\personal\work\aurelio\20240123 semantic router\venvs\semantic_router\lib\site-packages (from aiohttp<4.0,>=3.0->cohere<5.0,>=4.32->semantic_router[local]==0.0.23) (6.0.5)
Requirement already satisfied: yarl<2.0,>=1.0 in c:\users\siraj\documents\personal\work\aurelio\20240123 semantic router\venvs\semantic_router\lib\site-packages (from aiohttp<4.0,>=3.0->cohere<5.0,>=4.32->semantic_router[local]==0.0.23) (1.9.4)
Requirement already satisfied: httpcore==1.* in c:\users\siraj\documents\personal\work\aurelio\20240123 semantic router\venvs\semantic_router\lib\site-packages (from httpx<0.26.0,>=0.25.2->mistralai<0.0.13,>=0.0.12->semantic_router[local]==0.0.23) (1.0.3)
Requirement already satisfied: h11<0.15,>=0.13 in c:\users\siraj\documents\personal\work\aurelio\20240123 semantic router\venvs\semantic_router\lib\site-packages (from httpcore==1.*->httpx<0.26.0,>=0.25.2->mistralai<0.0.13,>=0.0.12->semantic_router[local]==0.0.23) (0.14.0)
Requirement already satisfied: zipp>=0.5 in c:\users\siraj\documents\personal\work\aurelio\20240123 semantic router\venvs\semantic_router\lib\site-packages (from importlib_metadata<7.0,>=6.0->cohere<5.0,>=4.32->semantic_router[local]==0.0.23) (3.17.0)
[notice] A new release of pip is available: 23.1.2 -> 24.0
[notice] To update, run: python.exe -m pip install --upgrade pip
%% Cell type:code id: tags:
``` python
from semantic_router.encoders import HuggingFaceEncoder
encoder = HuggingFaceEncoder()
```
%% Output
c:\Users\Siraj\Documents\Personal\Work\Aurelio\20240123 Semantic Router\venvs\semantic_router\Lib\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
%% Cell type:markdown id: tags:
## Define Static Routes
%% Cell type:code id: tags:
``` python
from semantic_router import Route
# we could use this as a guide for our chatbot to avoid political conversations
politics = Route(
name="politics",
utterances=[
"isn't politics the best thing ever",
"why don't you tell me about your political opinions",
"don't you just love the president" "don't you just hate the president",
"they're going to destroy this country!",
"they will save the country!",
],
)
# this could be used as an indicator to our chatbot to switch to a more
# conversational prompt
chitchat = Route(
name="chitchat",
utterances=[
"how's the weather today?",
"how are things going?",
"lovely weather today",
"the weather is horrendous",
"let's go to the chippy",
],
)
# we place both of our decisions together into single list
routes = [politics, chitchat]
```
%% Cell type:markdown id: tags:
## Define Route Layer with Ollama
%% Cell type:code id: tags:
``` python
from semantic_router.layer import RouteLayer
from semantic_router.llms.ollama import OllamaLLM
llm = OllamaLLM(llm_name="openhermes") # Change llm_name if you want to use a different LLM with dynamic routes.
rl = RouteLayer(encoder = encoder, routes=routes, llm=llm)
```
%% Output
2024-02-22 10:59:54 INFO semantic_router.utils.logger local
%% Cell type:markdown id: tags:
## Test Static Routes
%% Cell type:code id: tags:
``` python
rl("don't you love politics?").name
```
%% Output
'politics'
%% Cell type:code id: tags:
``` python
rl("how's the weather today?").name
```
%% Output
'chitchat'
%% Cell type:code id: tags:
``` python
rl("I'm interested in learning about llama 2").name
```
%% Cell type:markdown id: tags:
## Test Dynamic Routes
Dynamic routes work by associating a function with a route. If the input utterance is similar enough to the utterances of the route, such that route is chosen by the semantic router, then this triggers a secondary process:
The LLM we specified in the `RouteLayer` (we specified Ollama, which isn't strictly an LLM, but which defaults to using the `OpenHermes` LLM), is then usde to take a `function_schema`, and the input utterance, and extract values from the input utterance which can be used as arguments for `function` described by the the `funcion_schema`. The returned values can then be used in the `function` to obtain an output.
So, in short, it's a way of generating `function` inputs from an utterance, if that utterance matches the route utterances closely enough.
In the below example the utterance **"what is the time in new york city?"** is used to trigger the "get_time" route, which has the `function_schema` of a likewise named `get_time()` function associated with it. Then Ollama is used to run `OpenHermes` locally, which extracts the correctly formatted IANA timezone (`"America/New York"`), based on this utterance and information we provide it about the `function` in the `function_schema`. The returned stirng "America/New York" can then be used directly in the `get_time()` function to return the actual time in New York city.
%% Cell type:markdown id: tags:
%% Cell type:code id: tags:
``` python
from datetime import datetime
from zoneinfo import ZoneInfo
def get_time(timezone: str) -> str:
"""
Finds the current time in a specific timezone.
:param timezone: The timezone to find the current time in, should
be a valid timezone from the IANA Time Zone Database like
"America/New_York" or "Europe/London". Do NOT put the place
name itself like "rome", or "new york", you must provide
the IANA format.
:type timezone: str
:return: The current time in the specified timezone.
"""
now = datetime.now(ZoneInfo(timezone))
return now.strftime("%H:%M")
```
%% Cell type:code id: tags:
``` python
get_time("America/New_York")
```
%% Output
'01:59'
%% Cell type:code id: tags:
``` python
from semantic_router.utils.function_call import get_schema
schema = get_schema(get_time)
schema
```
%% Output
{'name': 'get_time',
'description': 'Finds the current time in a specific timezone.\n\n:param timezone: The timezone to find the current time in, should\n be a valid timezone from the IANA Time Zone Database like\n "America/New_York" or "Europe/London". Do NOT put the place\n name itself like "rome", or "new york", you must provide\n the IANA format.\n:type timezone: str\n:return: The current time in the specified timezone.\n ',
'signature': '(timezone: str) -> str',
'output': "<class 'str'>"}
%% Cell type:code id: tags:
``` python
time_route = Route(
name="get_time",
utterances=[
"what is the time in new york city?",
"what is the time in london?",
"I live in Rome, what time is it?",
],
function_schema=schema,
)
```
%% Cell type:code id: tags:
``` python
rl.add(time_route)
```
%% Output
2024-02-22 10:59:55 INFO semantic_router.utils.logger Adding `get_time` route
%% Cell type:code id: tags:
``` python
out = rl("what is the time in new york city?")
print(out)
```
%% Output
2024-02-22 11:01:29 INFO semantic_router.utils.logger Extracting function input...
2024-02-22 11:01:32 INFO semantic_router.utils.logger LLM output: {
"timezone": "America/New_York"
}
2024-02-22 11:01:32 INFO semantic_router.utils.logger Function inputs: {'timezone': 'America/New_York'}
name='get_time' function_call={'timezone': 'America/New_York'} similarity_score=None trigger=None
%% Cell type:code id: tags:
``` python
get_time(**out.function_call)
```
%% Output
'02:01'
%% Cell type:code id: tags:
``` python
```
......@@ -46,33 +46,55 @@ class BaseLLM(BaseModel):
logger.info("Extracting function input...")
prompt = f"""
You are a helpful assistant designed to output JSON.
Given the following function schema
<< {function_schema} >>
and query
<< {query} >>
extract the parameters values from the query, in a valid JSON format.
Example:
Input:
query: "How is the weather in Hawaii right now in International units?"
schema:
{{
"name": "get_weather",
"description": "Useful to get the weather in a specific location",
"signature": "(location: str, degree: str) -> str",
"output": "<class 'str'>",
}}
Result: {{
"location": "London",
"degree": "Celsius",
}}
Input:
query: {query}
schema: {function_schema}
Result:
"""
You are an accurate and reliable computer program that only outputs valid JSON.
Your task is to output JSON representing the input arguments of a Python function.
This is the Python function's schema:
### FUNCTION_SCHEMA Start ###
{function_schema}
### FUNCTION_SCHEMA End ###
This is the input query.
### QUERY Start ###
{query}
### QUERY End ###
The arguments that you need to provide values for, together with their datatypes, are stated in "signature" in the FUNCTION_SCHEMA.
The values these arguments must take are made clear by the QUERY.
Use the FUNCTION_SCHEMA "description" too, as this might provide helpful clues about the arguments and their values.
Return only JSON, stating the argument names and their corresponding values.
### FORMATTING_INSTRUCTIONS Start ###
Return a respones in valid JSON format. Do not return any other explanation or text, just the JSON.
The JSON-Keys are the names of the arguments, and JSON-values are the values those arguments should take.
### FORMATTING_INSTRUCTIONS End ###
### EXAMPLE Start ###
=== EXAMPLE_INPUT_QUERY Start ===
"How is the weather in Hawaii right now in International units?"
=== EXAMPLE_INPUT_QUERY End ===
=== EXAMPLE_INPUT_SCHEMA Start ===
{{
"name": "get_weather",
"description": "Useful to get the weather in a specific location",
"signature": "(location: str, degree: str) -> str",
"output": "<class 'str'>",
}}
=== EXAMPLE_INPUT_QUERY End ===
=== EXAMPLE_OUTPUT Start ===
{{
"location": "Hawaii",
"degree": "Celsius",
}}
=== EXAMPLE_OUTPUT End ===
### EXAMPLE End ###
Note: I will tip $500 for and accurate JSON output. You will be penalized for an inaccurate JSON output.
Provide JSON output now:
"""
llm_input = [Message(role="user", content=prompt)]
output = self(llm_input)
......
......@@ -48,9 +48,7 @@ class OllamaLLM(BaseLLM):
"format": "json",
"stream": stream,
}
response = requests.post("http://localhost:11434/api/chat", json=payload)
output = response.json()["message"]["content"]
return output
......
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