mirror of
https://github.com/EvolutionAPI/adk-python.git
synced 2025-12-18 19:32:21 -06:00
Create a developer folder and add samples.
PiperOrigin-RevId: 755885332
This commit is contained in:
committed by
Copybara-Service
parent
180c2a934b
commit
a4adb739c0
115
contributing/samples/hello_world_ollama/README.md
Normal file
115
contributing/samples/hello_world_ollama/README.md
Normal file
@@ -0,0 +1,115 @@
|
||||
# Using ollama models with ADK
|
||||
|
||||
## Model choice
|
||||
|
||||
If your agent is relying on tools, please make sure that you select a model with tool support from [ollama website](https://ollama.com/search?c=tools).
|
||||
|
||||
For reliable results, we recommend using a decent size model with tool support.
|
||||
|
||||
The tool support for the model can be checked with the following command:
|
||||
|
||||
```bash
|
||||
ollama show mistral-small3.1
|
||||
Model
|
||||
architecture mistral3
|
||||
parameters 24.0B
|
||||
context length 131072
|
||||
embedding length 5120
|
||||
quantization Q4_K_M
|
||||
|
||||
Capabilities
|
||||
completion
|
||||
vision
|
||||
tools
|
||||
```
|
||||
|
||||
You are supposed to see `tools` listed under capabilities.
|
||||
|
||||
You can also look at the template the model is using and tweak it based on your needs.
|
||||
|
||||
```bash
|
||||
ollama show --modelfile llama3.1 > model_file_to_modify
|
||||
```
|
||||
|
||||
Then you can create a model with the following command:
|
||||
|
||||
```bash
|
||||
ollama create llama3.1-modified -f model_file_to_modify
|
||||
```
|
||||
|
||||
## Using ollama_chat provider
|
||||
|
||||
Our LiteLlm wrapper can be used to create agents with ollama models.
|
||||
|
||||
```py
|
||||
root_agent = Agent(
|
||||
model=LiteLlm(model="ollama_chat/mistral-small3.1"),
|
||||
name="dice_agent",
|
||||
description=(
|
||||
"hello world agent that can roll a dice of 8 sides and check prime"
|
||||
" numbers."
|
||||
),
|
||||
instruction="""
|
||||
You roll dice and answer questions about the outcome of the dice rolls.
|
||||
""",
|
||||
tools=[
|
||||
roll_die,
|
||||
check_prime,
|
||||
],
|
||||
)
|
||||
```
|
||||
|
||||
**It is important to set the provider `ollama_chat` instead of `ollama`. Using `ollama` will result in unexpected behaviors such as infinite tool call loops and ignoring previous context.**
|
||||
|
||||
While `api_base` can be provided inside litellm for generation, litellm library is calling other APIs relying on the env variable instead as of v1.65.5 after completion. So at this time, we recommend setting the env variable `OLLAMA_API_BASE` to point to the ollama server.
|
||||
|
||||
```bash
|
||||
export OLLAMA_API_BASE="http://localhost:11434"
|
||||
adk web
|
||||
```
|
||||
|
||||
## Using openai provider
|
||||
|
||||
Alternatively, `openai` can be used as the provider name. But this will also require setting the `OPENAI_API_BASE=http://localhost:11434/v1` and `OPENAI_API_KEY=anything` env variables instead of `OLLAMA_API_BASE`. **Please notice that api base now has `/v1` at the end.**
|
||||
|
||||
```py
|
||||
root_agent = Agent(
|
||||
model=LiteLlm(model="openai/mistral-small3.1"),
|
||||
name="dice_agent",
|
||||
description=(
|
||||
"hello world agent that can roll a dice of 8 sides and check prime"
|
||||
" numbers."
|
||||
),
|
||||
instruction="""
|
||||
You roll dice and answer questions about the outcome of the dice rolls.
|
||||
""",
|
||||
tools=[
|
||||
roll_die,
|
||||
check_prime,
|
||||
],
|
||||
)
|
||||
```
|
||||
|
||||
```bash
|
||||
export OPENAI_API_BASE=http://localhost:11434/v1
|
||||
export OPENAI_API_KEY=anything
|
||||
adk web
|
||||
```
|
||||
|
||||
## Debugging
|
||||
|
||||
You can see the request sent to the ollama server by adding the following in your agent code just after imports.
|
||||
|
||||
```py
|
||||
import litellm
|
||||
litellm._turn_on_debug()
|
||||
```
|
||||
|
||||
Look for a line like the following:
|
||||
|
||||
```bash
|
||||
quest Sent from LiteLLM:
|
||||
curl -X POST \
|
||||
http://localhost:11434/api/chat \
|
||||
-d '{'model': 'mistral-small3.1', 'messages': [{'role': 'system', 'content': ...
|
||||
```
|
||||
15
contributing/samples/hello_world_ollama/__init__.py
Executable file
15
contributing/samples/hello_world_ollama/__init__.py
Executable file
@@ -0,0 +1,15 @@
|
||||
# Copyright 2025 Google LLC
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from . import agent
|
||||
89
contributing/samples/hello_world_ollama/agent.py
Executable file
89
contributing/samples/hello_world_ollama/agent.py
Executable file
@@ -0,0 +1,89 @@
|
||||
# Copyright 2025 Google LLC
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import random
|
||||
|
||||
from google.adk.agents import Agent
|
||||
from google.adk.models.lite_llm import LiteLlm
|
||||
|
||||
|
||||
def roll_die(sides: int) -> int:
|
||||
"""Roll a die and return the rolled result.
|
||||
|
||||
Args:
|
||||
sides: The integer number of sides the die has.
|
||||
|
||||
Returns:
|
||||
An integer of the result of rolling the die.
|
||||
"""
|
||||
return random.randint(1, sides)
|
||||
|
||||
|
||||
def check_prime(numbers: list[int]) -> str:
|
||||
"""Check if a given list of numbers are prime.
|
||||
|
||||
Args:
|
||||
numbers: The list of numbers to check.
|
||||
|
||||
Returns:
|
||||
A str indicating which number is prime.
|
||||
"""
|
||||
primes = set()
|
||||
for number in numbers:
|
||||
number = int(number)
|
||||
if number <= 1:
|
||||
continue
|
||||
is_prime = True
|
||||
for i in range(2, int(number**0.5) + 1):
|
||||
if number % i == 0:
|
||||
is_prime = False
|
||||
break
|
||||
if is_prime:
|
||||
primes.add(number)
|
||||
return (
|
||||
"No prime numbers found."
|
||||
if not primes
|
||||
else f"{', '.join(str(num) for num in primes)} are prime numbers."
|
||||
)
|
||||
|
||||
|
||||
root_agent = Agent(
|
||||
model=LiteLlm(model="ollama_chat/mistral-small3.1"),
|
||||
name="dice_roll_agent",
|
||||
description=(
|
||||
"hello world agent that can roll a dice of any number of sides and"
|
||||
" check prime numbers."
|
||||
),
|
||||
instruction="""
|
||||
You roll dice and answer questions about the outcome of the dice rolls.
|
||||
You can roll dice of different sizes.
|
||||
You can use multiple tools in parallel by calling functions in parallel(in one request and in one round).
|
||||
It is ok to discuss previous dice roles, and comment on the dice rolls.
|
||||
When you are asked to roll a die, you must call the roll_die tool with the number of sides. Be sure to pass in an integer. Do not pass in a string.
|
||||
You should never roll a die on your own.
|
||||
When checking prime numbers, call the check_prime tool with a list of integers. Be sure to pass in a list of integers. You should never pass in a string.
|
||||
You should not check prime numbers before calling the tool.
|
||||
When you are asked to roll a die and check prime numbers, you should always make the following two function calls:
|
||||
1. You should first call the roll_die tool to get a roll. Wait for the function response before calling the check_prime tool.
|
||||
2. After you get the function response from roll_die tool, you should call the check_prime tool with the roll_die result.
|
||||
2.1 If user asks you to check primes based on previous rolls, make sure you include the previous rolls in the list.
|
||||
3. When you respond, you must include the roll_die result from step 1.
|
||||
You should always perform the previous 3 steps when asking for a roll and checking prime numbers.
|
||||
You should not rely on the previous history on prime results.
|
||||
""",
|
||||
tools=[
|
||||
roll_die,
|
||||
check_prime,
|
||||
],
|
||||
)
|
||||
77
contributing/samples/hello_world_ollama/asyncio_run.py
Executable file
77
contributing/samples/hello_world_ollama/asyncio_run.py
Executable file
@@ -0,0 +1,77 @@
|
||||
# Copyright 2025 Google LLC
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import asyncio
|
||||
import time
|
||||
import warnings
|
||||
|
||||
import agent
|
||||
from dotenv import load_dotenv
|
||||
from google.adk import Runner
|
||||
from google.adk.artifacts import InMemoryArtifactService
|
||||
from google.adk.cli.utils import logs
|
||||
from google.adk.sessions import InMemorySessionService
|
||||
from google.adk.sessions import Session
|
||||
from google.genai import types
|
||||
|
||||
load_dotenv(override=True)
|
||||
warnings.filterwarnings('ignore', category=UserWarning)
|
||||
logs.log_to_tmp_folder()
|
||||
|
||||
|
||||
async def main():
|
||||
app_name = 'my_app'
|
||||
user_id_1 = 'user1'
|
||||
session_service = InMemorySessionService()
|
||||
artifact_service = InMemoryArtifactService()
|
||||
runner = Runner(
|
||||
app_name=app_name,
|
||||
agent=agent.root_agent,
|
||||
artifact_service=artifact_service,
|
||||
session_service=session_service,
|
||||
)
|
||||
session_11 = session_service.create_session(
|
||||
app_name=app_name, user_id=user_id_1
|
||||
)
|
||||
|
||||
async def run_prompt(session: Session, new_message: str):
|
||||
content = types.Content(
|
||||
role='user', parts=[types.Part.from_text(text=new_message)]
|
||||
)
|
||||
print('** User says:', content.model_dump(exclude_none=True))
|
||||
async for event in runner.run_async(
|
||||
user_id=user_id_1,
|
||||
session_id=session.id,
|
||||
new_message=content,
|
||||
):
|
||||
if event.content.parts and event.content.parts[0].text:
|
||||
print(f'** {event.author}: {event.content.parts[0].text}')
|
||||
|
||||
start_time = time.time()
|
||||
print('Start time:', start_time)
|
||||
print('------------------------------------')
|
||||
await run_prompt(session_11, 'Hi, introduce yourself.')
|
||||
await run_prompt(
|
||||
session_11, 'Roll a die with 100 sides and check if it is prime'
|
||||
)
|
||||
await run_prompt(session_11, 'Roll it again.')
|
||||
await run_prompt(session_11, 'What numbers did I got?')
|
||||
end_time = time.time()
|
||||
print('------------------------------------')
|
||||
print('End time:', end_time)
|
||||
print('Total time:', end_time - start_time)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
asyncio.run(main())
|
||||
Reference in New Issue
Block a user