Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add autogpt example #3

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
43 changes: 43 additions & 0 deletions docs/advanced.rst
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,49 @@ like Wikipedia.

You may also use ``@ai_function(auto_truncate=...)`` if truncating the response is acceptable.

AutoGPT
---------
AutoGPT is an experiment that aims to make GPT autonomous. In this example, we implement a basic version that can
retrieve information from the web, download and query that information, and use it to answer questions and accomplish goals.

.. code-block:: python

class AutoGPTKani(Kani):
def __init__(self, *args, **kwargs):
...

@ai_function()
async def search(...):

@ai_function()
async def download(...):

@ai_function()
async def query(...):

@ai_function()
async def write(...):

@ai_function()
async def leave_message(...):


.. code-block:: pycon

>>> chat_in_terminal(AutoGPTKani(engine))
USER: Search for the most popular train lines in US, find me a train line that serves crab cakes and book me a ticket by leaving a message by phone and write the train line and the cost of the crab cakes in a file named 'train.txt'
AI: Thinking (search)...
AI: Thinking (search)...
AI: Thinking (leave_message)...
AI: Thinking (write)...
AI: I have completed the tasks you requested. Here is the information you were looking for:

Based on my search, one of the most popular train lines in the US is the Amtrak train line. It offers a variety of services and routes across the country. Additionally, I found that Amtrak offers lobster crab cakes as part of their onboard dining options. The cost of the crab cakes is $15.99.

I have also left a message on the provided phone number to book a train ticket on a popular train line in the US.

Lastly, I have written the train line and the cost of the crab cakes in a file named 'train.txt'.

Hosting kani Online
-------------------
What if you want to host a web service that allows its users to chat with kani? In this example, we show how you can
Expand Down
93 changes: 93 additions & 0 deletions examples/5_advanced_autogpt.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
"""Example from Advanced Usage docs.

This example shows how kani can be used to easily implement auto-gpt functionality (https://github.com/Significant-Gravitas/Auto-GPT),
which aims to autonomously run GPT.
"""
import json
import os
from typing import Annotated, List

from kani import Kani, chat_in_terminal, ai_function, AIParam
from kani.engines.httpclient import BaseClient
from kani.engines.openai import OpenAIEngine

import aiohttp
import sys

api_key = os.getenv("OPENAI_API_KEY")

engine = OpenAIEngine(api_key, model="gpt-3.5-turbo")


class AutoGPTKani(Kani):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.max_search_results = 5
self.cached_webpages = {}

@ai_function()
async def search(
self,
search_terms: Annotated[
str,
AIParam(desc='Using the search terms "Train station" will return a list related to "Train station".'),
],
):
"""Search a list of terms with duckduckgo."""
try:
from duckduckgo_search import DDGS
except ImportError as e:
raise ImportError("Please install duckduckgo-search to use this function.") from e

with DDGS() as ddgs:
results = []
for result in ddgs.text(search_terms):
if len(results) >= self.max_search_results:
break
results.append(result)
return json.dumps(results)

@ai_function()
async def download(self, url: Annotated[str, AIParam(desc="URL to download contents to disk.")]):
"""Downloads and syncs a webpage to the cache."""

async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
text = await response.text()
self.cached_webpages[url] = text

@ai_function()
async def query(self, query: str):
"""Queries cache for information."""

# Query can be more complex, but for now we'll just do a simple search for matching text
for url, text in self.cached_webpages.items():
if query in text:
return text

return f"No results found. Try downloading a webpage containing {query} first."

@ai_function()
async def write(self, filename: str, text: str):
"""Writes text to disk."""

with open(filename, "w+") as f:
f.write(text)

return "Success!"

@ai_function()
async def leave_message(
self,
number: Annotated[str, AIParam(desc="Phone number to contact.")],
message: Annotated[str, AIParam(desc="Message left for the phone number recipient.")],
):
"""Calls a phone number and plays a message."""

# This is a placeholder for a real function that would call a phone number and play a message.
return f"Message left for {number} saying {message}."


ai = AutoGPTKani(engine)
if __name__ == "__main__":
chat_in_terminal(ai)