9.9.5 Open AI: Assistants - caligrafy/caligrafy-quill GitHub Wiki

Artificial Intelligence has made significant strides in the last couple of years especially - unexpectedly - in the creative world. OpenAI has been a major player in bringing generative artificial intelligence to the mass. For those of you who have not heard about generative AI before, it is the ability of the machine to create and produce new ideas from what it already knows. ChatGPT and DALL.E and Midjourney, to name a few, are examples of generative AI that create art (text or images) out of simple sentences provided by a user.

Caligrafy integrates seamlessly with OpenAI to allow developers to create and manage AI Assistants.


Initializing OpenAI

Step 1: Get an OpenAI Account

The first thing that needs to be done is to sign up for a free OpenAI account. When you sign up, OpenAPI gives you $18 for free to use its models.

Step 2: Get an OpenAI API Key

  • Create a new OpenAI secret key that will allow you to use the OpenAI APIs
  • Copy the API key and paste it into the Caligrafy .env file next to the OPEN_AI_KEY=<paste your key here>

Step 3: Prepare the Caligrafy controller

In order to create an OpenAI Assistant in Caligrafy, you need to first create an Assistant object. The Assistant class first needs to be imported into the Caligrafy controller where the assistant is created.

use Caligrafy\Controller;
use Caligrafy\Assistant; // <-- Make sure to important the Assistant class

class AssistantController extends Controller {

    // your code goes here

}

Creating & Managing Assistants

With Caligrafy, AI Assistants can be created, modified and deleted.

Create an Assistant

In order to create an OpenAI Assistant in Caligrafy, you need to first create an Assistant object. The Assistant object can be created without any parameters. By default, the Assistant will be a "Retrieval" Assistant running on the latest GPT model (refer to the OpenAI documentation to know more about the "retrieval" assistants).

use Caligrafy\Controller;
use Caligrafy\Assistant; // <-- Make sure to important the Assistant class

class TestController extends Controller {

    public function index() 
    {
        // Without any parameters
        $assistant = new Assistant(); 
        dump($assistant) // <-- to visualize the object created
  
    }

}

Upon running the above controller, an assistant with the default parameters is created in OpenAI. All the assistants create through Caligrafy can be viewed and managed from the OpenAI Assistants section.

An assistant_id is created upon the successful creation of an Assistant. Make sure to validate that the assistant_id exists before applying any of the methods on the Assistant.

In order to create more custom assistants, you need to provide more parameters to the Assistant object.

use Caligrafy\Controller;
use Caligrafy\Assistant; // <--- Make sure to important the Assistant class

class TestController extends Controller {

    public function index() 
    {
        // With parameters
        $assistant = new Assistant(array(
              // parameters are passed as key value pairs
              "name" => "My Assistant"

        ));       
    }

}

Here is a list of all the parameters that can be passed to the Assistant object

- name (string): the name of the assistant

- description (string): metadata that describes what the assistant does

- instructions (string): Instructing the assistant what it needs to do. For example, "You are a helpful assistant and you will use your knowledge to answer the user's questions"

- metadata (array): Array of additional meta information that your application would need about the assistant you are creating

- model (OpenAI models): Specify the GPT model if it is not the latest stable one from OpenAI

- tools (array of array: ["type" => "file_search"], ["type" => "code_interpreter"], ["type" => [function]): OpenAI allows the creation of 3 types of assistants. Refer to the OpenAI documentation to know the difference.

- file_paths (array of paths): Provide the paths of all the files that you would like the assistant to learn about. Caligrafy makes sure to upload the files and associate them with the assistant.

- file_ids (array of string): If you have previously uploaded the files to the OpenAI platform, you can just provide the file ids in an array to the object.

- assistant_id: If you already have an OpenAI Assistant, you can provide the assistant_id into the object to manage it from Caligrafy.

Modify an Assistant

In order to modify an existing assistant (previously created through Caligrafy or in the OpenAI Assistant manager), an Assistant object can be instantiated with an assistant_id provided as a parameter along with any other parameters that you wish to modify.

   
    $assistant = new Assistant(array(
        "assistant_id"  =>  "<existing id>",
        
        //... any additional parameters to change

     ));

Delete an Assistant

In order to delete an Assistant, the Assistant object needs to be retrieved first then deleted.

     
    // An existing assistant needs to be retrieved first
    $assistant = new Assistant(array(
        "assistant_id"  =>  "<existing id>",
     ));

    // then deleted
    $assistant->delete();

Engaging with Assistants

In order to engage with an OpenAI Assistant, we need to understand how OpenAI defines the workflow.

Step 1 - Start a conversation

A thread needs to be started. Think of a thread as the conversation. It contains all the exchanged messages, thus forming the context of the dialogue. Similarly, when the conversation is finished, the thread needs to end.

In Caligrafy, starting and ending threads can be done as follows

   $assistant = new Assistant(array(
       "name" => "My Assistant"
   ));

   // Start a conversation
   $assistant->start();

   // End a conversation
   $assistant->end();

Step 2 - Create Messages

No conversation happens with the user initiating a dialogue. This means that messages need to be added to the thread.

   $assistant = new Assistant(array(
       "name" => "My Assistant"
   ));

   // Start a conversation
   $assistant->start();

   // Add a message
   $assistant->createMessage("Hi");

   // End a conversation
   $assistant->end();

Several Messages could be added. This can easily be done by chaining the method createMessage

    
   // pipelining messages
   $assistant->createMessage("Hi")
             ->createMessage("How are you?")
             ->createMessage("What's your name?")

Refer to the Assistant Methods at the end of this section to see all the parameters that could be given to the createMessage method.

Step 3 - Run the Assistant

While messages are added to the conversation, the assistant has not engaged yet. In order for the assistant to engage in a conversation, it needs to interpret what's in the conversation at a certain point in time. For that to happen, an explicit run method needs to be called to indicate to the assistant that it can now engage.

   $assistant = new Assistant(array(
       "name" => "My Assistant"
   ));

   // Start a conversation
   $assistant->start();

   // Add a message
   $assistant->createMessage("Hi");

   // Run the assistant
   $assistant->run();

   // End a conversation
   $assistant->end();

Step 4 - Retrieving the response

When the Assistant runs, it goes through a lifecycle. Refer to the OpenAI documentation to understand the lifecycle of the response. Caligrafy gives you a method that continues to poll the response until its status is no longer in queued nor in_progress. Therefore, from the moment there is response (completed or failed), it will be returned by this method.

   $assistant = new Assistant(array(
       "name" => "My Assistant"
   ));

   // Start a conversation
   $assistant->start();

   // Add a message
   $assistant->createMessage("Hi");

   // Run the assistant
   $assistant->run();

   // Retrieve Response
   $assistant->retrieveResponse()->messages;

   // End a conversation
   $assistant->end();

Assistant Properties & Methods

Caligrafy provides several capabilities in the Assistant class to help create AI assistants more efficiently and to help simplify the syntax.

Assistant Properties

private $_model;               // String of the GPT Model used
public $assistant_id;          // String of the assistant ID
public $name;                  // String of the assistant Name
public $description;           // String of the assistant Description
public $instructions;          // String of the Instructions given to the assistant
public $tools;                 // Array of array of types of assistant i.e array(["type" => "retrieval"], [...])
public $file_ids;              // Array of string of the file ids in the OpenAI File manager
public $file_paths;            // Array of string of the local file paths to upload
public $metadata;              // Array of key/value pairs of additional meta information
public $thread_id;             // String of the active conversation thread_id
public $run_id;                // String of the active run last executed on a thread
public $status;                // String of the status of the last run executed
public $messages;              // Array of all the message objects in the thread

Assistant Methods

// Chain-able methods

public function retrieve();          // If an assistant_id is given to the constructor then it retrieves the assistant information
public function start();             // starts a conversation thread
public function end();               // ends a conversation thread

public function createMessage(string $content, array $file_ids, array $metadata, string $role = "user");  
// Adds a message to the thread and additional files and metadata could be appended to the message as attachments

public function run();               // Runs the assistant on a thread
public function retrieveResponse()   // Retrieves the assistant responses


// Non chain-able methods

public function delete();           // Deletes the assistant object 
public function listMessages();     // Returns the list object of messages
public function uploadAssistantFiles($specified_paths = []);    // Uploads and attaches all the files specified in the array to the assistant
public function deleteAssistantFiles($file_id);                 // Deletes a file and detaches it from the assistant

Chaining

Most of the methods and properties of the Assistant object can be chained to simplify the syntax and to make the code more readable.

The complete code of our example can be rewritten using chaining.

   
   $assistant = new Assistant(array(
       "name" => "My Assistant"
   ));


   // Chaining
   $assistant->start()
             ->createMessage("Hi")
             ->run()
             ->retrieveResponse()->messages;

   // End a conversation
   $assistant->end();

A chain can no longer be continued when a property or a "non chain-able" method is at the end of the chain, as illustrated in the examples below.

   $assistant = new Assistant(array(
       "name" => "My Assistant"
   ));

   $assistant->start()->thread_id; // the last item in the chain is a property

   $assistant->start()
             ->createMessage("Hi")
             ->createMessage("How are you?")
             ->messages;  // last item in the chain is a property

   $assistant->run()
             ->retrieveResponse()
             ->listMessages();  // last item in the chain is a non-chainable method

That's it, you can now start the Caligrafy Assistants to create your next big idea!

⚠️ **GitHub.com Fallback** ⚠️