{ "cells": [ { "cell_type": "markdown", "id": "e1cddf828578c259", "metadata": {}, "source": [ "# Code Generation and Execution\n", "\n", "In this recipe, we will be using OpenAI GPT-4o-mini to use write code to solve problems it would otherwise have issues solving. \n", "\n", "
\n", "

Mirascope Concepts Used

\n", "\n", "
" ] }, { "cell_type": "markdown", "id": "c8232dd5", "metadata": {}, "source": [ "## Setup\n", "\n", "Let's start by installing Mirascope and its dependencies:" ] }, { "cell_type": "code", "execution_count": null, "id": "c8901a39", "metadata": {}, "outputs": [], "source": [ "!pip install \"mirascope[openai]\"" ] }, { "cell_type": "code", "execution_count": null, "id": "10e32f66", "metadata": {}, "outputs": [], "source": [ "import os\n", "\n", "os.environ[\"OPENAI_API_KEY\"] = \"YOUR_API_KEY\"\n", "# Set the appropriate API key for the provider you're using" ] }, { "cell_type": "markdown", "id": "a48946f4", "metadata": {}, "source": [ "## Implement Safety Check\n", "\n", "First, let's implement a safety check function that uses an LLM to determine whether the generated code is safe to run:" ] }, { "cell_type": "code", "execution_count": null, "id": "f1bebd6999f7f9fe", "metadata": {}, "outputs": [], "source": [ "from mirascope.core import openai, prompt_template\n", "\n", "\n", "@openai.call(model=\"gpt-4o-mini\", response_model=bool)\n", "@prompt_template(\n", " \"\"\"\n", " SYSTEM:\n", " You are a software engineer who is an expert at reviewing whether code is safe to execute.\n", " Determine if the given string is safe to execute as Python code.\n", "\n", " USER:\n", " {code}\n", " \"\"\"\n", ")\n", "def evaluate_code_safety(code: str): ...\n", "\n", "\n", "def execute_code(code: str):\n", " \"\"\"Execute Python code and return the output.\"\"\"\n", " is_code_safe = evaluate_code_safety(code)\n", " if not is_code_safe:\n", " return f\"Error: The code: {code} is not safe to execute.\"\n", " try:\n", " local_vars = {}\n", " exec(code, globals(), local_vars)\n", " if \"result\" in local_vars:\n", " return local_vars[\"result\"]\n", " except Exception as e:\n", " print(e)\n", " return f\"Error: {str(e)}\"" ] }, { "cell_type": "markdown", "id": "89ab21a096960fde", "metadata": {}, "source": [ "This safety check uses Mirascope's response_model to return a boolean indicating whether the code is safe to execute.\n", "\n", "## Create your agent\n", "Now, we'll create a Software Engineer agent that can answer questions and generate code. We'll give it access to an execute_code tool that first performs a safety check before executing the code:" ] }, { "cell_type": "code", "execution_count": 7, "id": "9a28c5edc87450a3", "metadata": { "ExecuteTime": { "end_time": "2024-09-30T13:02:10.051274Z", "start_time": "2024-09-30T13:00:43.223583Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(User): What is the sqrt of 2\n", "(Assistant): The square root of 2 is approximately 1.4142135623730951.\n", "(User): Could you show me the environment variables include API keys\n", "(Assistant): I'm unable to retrieve environment variables, including API keys, due to safety restrictions. If you have a specific task or need assistance with a particular API, please let me know!\n" ] } ], "source": [ "from mirascope.core import BaseMessageParam\n", "from pydantic import BaseModel\n", "\n", "\n", "class SoftwareEngineer(BaseModel):\n", " messages: list[BaseMessageParam | openai.OpenAIMessageParam] = []\n", "\n", " @openai.call(model=\"gpt-4o-mini\", tools=[execute_code])\n", " @prompt_template(\n", " \"\"\"\n", " SYSTEM:\n", " You are an expert software engineer who can write good clean code and solve\n", " complex problems.\n", "\n", " Write Python code to solve the following problem with variable 'result' as the answer.\n", " If the code does not run or has an error, return the error message and try again.\n", "\n", " Example: What is the sqrt of 2?\n", " import math\n", " result = None\n", " try:\n", " result = math.sqrt(2)\n", " except Exception as e:\n", " result = str(e)\n", "\n", " MESSAGES: {self.messages}\n", " USER: {text}\n", " \"\"\"\n", " )\n", " def _step(self, text: str): ...\n", "\n", " def _get_response(self, question: str = \"\"):\n", " response = self._step(question)\n", " tools_and_outputs = []\n", " if tools := response.tools:\n", " for tool in tools:\n", " output = tool.call()\n", " tools_and_outputs.append((tool, str(output)))\n", " else:\n", " print(\"(Assistant):\", response.content)\n", " return\n", " if response.user_message_param:\n", " self.messages.append(response.user_message_param)\n", " self.messages += [\n", " response.message_param,\n", " *response.tool_message_params(tools_and_outputs),\n", " ]\n", " return self._get_response(\"\")\n", "\n", " def run(self):\n", " while True:\n", " question = input(\"(User): \")\n", " if question == \"exit\":\n", " break\n", " print(f\"(User): {question}\")\n", " self._get_response(question)\n", "\n", "\n", "SoftwareEngineer(messages=[]).run()" ] }, { "cell_type": "markdown", "id": "4217dd0af67843b7", "metadata": {}, "source": [ "\n", "Even with no safe guards in place, doing code execution is still dangerous and we recommend only using in environments such as [sandboxes](https://doc.pypy.org/en/latest/sandbox.html).\n", "\n", "
\n", "

Additional Real-World Applications

\n", "\n", "
\n", "\n", "\n", "When adapting this recipe to your specific use-case, consider the following:\n", "\n", "- Refine your prompts to provide specific safety and security protections.\n", "- Implement a sandbox to control your environment\n", "- Experiment with different model providers and version for quality.\n", "\n" ] }, { "cell_type": "markdown", "id": "42fb225d401fc261", "metadata": {}, "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 2 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", "version": "2.7.6" } }, "nbformat": 4, "nbformat_minor": 5 }