Skip to content

Commit

Permalink
prototype for agentic behavior
Browse files Browse the repository at this point in the history
  • Loading branch information
yachty66 committed Jun 30, 2024
1 parent 22ac2ce commit 8da318d
Show file tree
Hide file tree
Showing 4 changed files with 244 additions and 3 deletions.
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,19 @@
The future of Maps

- [x] find minimalistic chatinterface for the left side
- [ ] add a minimalistic field where a user can enter a text together with an button
- [x] add a minimalistic field where a user can enter a text together with an button
- [ ] find a one examples from existing chatgpt plugin what can be worth to implement in combination with the map
- [ ] user types in "go to X" and on the map it goes to X

should i do a custom implementation for now or should i use existing tepl

the thing holding me back using framework is that i later might want to use custom rendering in the app
how should i implement this part with the chatinterface. either i use vercel chatbot or i use


if we build this from scratch than i dont even need supabase
if we build this from scratch than i dont even need supabase


## backlog

- [ ] add cyberpunk mode to map - if the user clicks one of the major cities here futuristic gen ai images of the city are displayed
3 changes: 3 additions & 0 deletions api/index.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ async def get_events():
logger.error(f"Exception occurred: {e}")
raise HTTPException(status_code=500, detail=str(e))


#how to build a good agent system with tools - thinking of just using openai function calling

@app.post("/api/ask")
async def ask(req: dict):
logger.info("Received request for /api/ask with data: %s", req)
Expand Down
230 changes: 230 additions & 0 deletions function_calling.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,230 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"\"\"\" \n",
"the input will be a string and based on this string i need to call a function \n",
"\n",
"option i am considering:\n",
"\n",
"- use openai function calling\n",
"- create my own function calling framework\n",
"\n",
"really good blog https://docs.mistral.ai/capabilities/function_calling/\n",
"\"\"\""
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"#tools \n",
"def go_to_place_in_map(place):\n",
" print(f\"going to {place}\")\n",
" #thats it for now - later i will add more functionalit"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"tools = [\n",
" {\n",
" \"type\": \"function\",\n",
" \"function\": {\n",
" \"name\": \"go_to_place_in_map\",\n",
" \"description\": \"Go to a place in the map\",\n",
" \"parameters\": {\n",
" \"type\": \"object\",\n",
" \"properties\": {\n",
" \"place\": {\n",
" \"type\": \"string\",\n",
" \"description\": \"The name of the place to navigate to.\",\n",
" }\n",
" },\n",
" \"required\": [\"place\"],\n",
" },\n",
" },\n",
" }\n",
"]"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"import functools\n",
"\n",
"names_to_functions = {\n",
" 'go_to_place_in_map': functools.partial(go_to_place_in_map)\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"#this cell figures out what function to call\n",
"from openai import OpenAI\n",
"import os \n",
"\n",
"openai_api_key = os.environ.get(\"OPENAI_API_KEY\")\n",
"client = OpenAI(api_key=openai_api_key)\n",
"\n",
"\n",
"system=f\"\"\"\n",
"You are a chatbot on top of a map. Your job is to help the user navigate the map. You can use the available functions to help you with this task.\n",
"\"\"\"\n",
"user_query=\"Go to berlin.\"\n",
"user_content=f\"\"\"\n",
"You are giving a chat conversation and based on this conversation you need to decide if an function from the available functions needs to be called. the available functions are:\n",
"\n",
"---\n",
"{tools}\n",
"---\n",
"\n",
"in the case a function can be called return the function name and the arguments that need to be passed to the function in JSON. Its important that the name of the key for the function name is `function_name` and the name of the key for the arguments is `arguments`. In the case a function cannot be called return an empty JSON object. \n",
"\n",
"Following the chat conversation:\n",
"\n",
"---\n",
"{user_query}\n",
"---\n",
"\"\"\"\n",
"\n",
"\n",
"\n",
"completion = client.chat.completions.create(\n",
" model=\"gpt-3.5-turbo\",\n",
" response_format={ \"type\": \"json_object\" },\n",
" temperature=0.0,\n",
" messages=[\n",
" {\"role\": \"system\", \"content\": system},\n",
" {\"role\": \"user\", \"content\": user_content}\n",
" ]\n",
")\n",
"response_content = completion.choices[0].message.content"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{\n",
" \"function_name\": \"go_to_place_in_map\",\n",
" \"arguments\": {\n",
" \"place\": \"berlin\"\n",
" }\n",
"}\n"
]
}
],
"source": [
"print(response_content)"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"go_to_place_in_map {'place': 'berlin'}\n",
"going to berlin\n"
]
}
],
"source": [
"#this cell is executing a function if there is one to execute\n",
"import json\n",
"\n",
"response_json = json.loads(response_content)\n",
"\n",
"function_name = response_json[\"function_name\"]\n",
"function_params = response_json[\"arguments\"]\n",
"print(function_name, function_params)\n",
"\n",
"function_result = names_to_functions[function_name](**function_params)"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"If you need any more information or further assistance while you're in Berlin, feel free to ask. Enjoy your time in the city!\n"
]
}
],
"source": [
"#generate final answer\n",
"prompt_for_final_response=\"Provide a final response to the user\"\n",
"\n",
"completion = client.chat.completions.create(\n",
" model=\"gpt-4-turbo\",\n",
" temperature=0.0,\n",
" messages = [\n",
" {\"role\": \"system\", \"content\": system},\n",
" {\"role\": \"user\", \"content\": user_query},\n",
" {\"role\": \"assistant\", \"content\": response_content},\n",
" {\"role\": \"user\", \"content\": prompt_for_final_response}\n",
"]\n",
")\n",
"response_content = completion.choices[0].message.content\n",
"print(response_content)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "base",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.7"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
4 changes: 3 additions & 1 deletion public/chat.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ document.addEventListener("DOMContentLoaded", function() {
const chatMessages = document.getElementById("chatMessages");
let isStreaming = false; // Flag to track if a response is being streamed

//const baseURL = window.location.hostname === "localhost" ? "http://localhost:8000" : "https://www.pantheon.so";

function sendMessage() {
if (isStreaming) {
alert("Please wait for the current response to finish.");
Expand All @@ -24,7 +26,7 @@ document.addEventListener("DOMContentLoaded", function() {

isStreaming = true; // Set the flag to true when streaming starts

fetch("/api/ask", {
fetch("http://127.0.0.1:8000/api/ask", {
method: "POST",
headers: {
"Content-Type": "application/json"
Expand Down

0 comments on commit 8da318d

Please sign in to comment.