Drupal's OpenAI / ChatGPT / AI Search Integration contrib module - initial impressions
Ever since it was announced, I've been itching to play with the new OpenAI / ChatGPT / AI Search Integration contrib module. From what I had read about it from Kevin Quillen, it was being written in a way that was going to make it flexible and with an eye toward customization.
On a self-serving note, one of our clients is interested in an AI-based solution for a task we're working on for them, so I had an agenda; test-driving this module for content-related tasks.
My initial impressions came from using version 1.0.0-alpha10 and within the first 20 minutes:
- The module only supports text fields (so far…)
- The module is only compatible with Drupal 10.
- There's not too much documentation yet - which isn't super-surprising considering it's being actively developed (and is still in alpha state).
While the module includes nine(!) sub-modules, I decided to focus on only three of them - all related to content generation and manipulation.
While there is a free OpenAI API tier, it is important to note that the experiments below were all made with a paid OpenAI API account - the total cost was less than $0.25 USD.
A note about OpenAI API keys
My OpenAI account has two organizations - my Personal organization and an organization created by our DrupalEasy client. My Personal organization is not yet on a paid plan, but our client's organization is. When creating an API key be sure to select the Default organization first, and then click to create a new API key. It appears that API keys are somehow associated with the organization.
Before I figured this out, none of my initial testing worked, I would always get a OpenAI\Exceptions\ErrorException or a You exceeded your quota… error because my personal account's initial credit has expired ☹️
OpenAI ChatGPT Devel Generate
Being able to generate realistic sample content is the dream (or not) of many Drupal developers - this submodule promises to provide this functionality. Via the Configuration | Generate | Generate content from ChatGPT admin menu item, this allows developers to select the content type, Profile (which is provided as part of the prompt provided to the OpenAI API), and text fields to populate with the OpenAI response. With the following Profile, I was able to populate the Title and Body fields with content.
Profile: Your task is to generate content. I would like you to generate content about Batman.
Sample node content:
Title: The Gadgets and Tech of Batman: Examining the Caped Crusader's Arsenal
Body: Batman is known for his impressive arsenal of gadgets and technology, which he uses to fight crime and protect the citizens of Gotham City. From his iconic Batarangs to his high-tech Batmobile, Batman's gadgets are an essential part of his crime-fighting persona. One of Batman's most famous gadgets is the utility belt, which contains a variety of tools and weapons that he can use in a pinch. These include smoke pellets, grappling hooks, and even a miniature explosive charge…
The content generation process is much slower than standard Devel Generate (for obvious reasons), but it does result in much more engaging sample content.
OpenAI Content Tools
This submodule provides some interesting tools for updating content. Once enabled, the module provides some options in the sidebar of the Drupal add/edit content page.
Each of the three tools demonstrated below provide their results directly in the sidebar - it is up to the author to copy/paste the results into the appropriate fields in the node's add/edit form. It seems that there are contribution opportunities for further integration. For example, it would be useful to automatically add the summary text to the Summary sub-field, should it exist (with consideration for what, if any summary text already exists…)
Adjust content tone
This allows the author to change the tone of the body text by selecting one of the default options: Friendly, Professional, Helpful, High school level reader, College level reader, and Explain it like I'm 5.
For example, with the original text of:
But we’ve met before. That was a long time ago, I was a kid at St. Swithin’s, it used to be funded by the Wayne Foundation.
The Friendly option returned:
Oh wow! We've actually met before, haven't we? That was such a long time ago when I was a youngster at St. Swithins. I remember it was funded by the Wayne Foundation back then!
The College level reader option returned:
We've met before. That was quite a while ago - when I was a student at St. Swithins. It was funded by the Wayne Foundation back then.
Extending the module to include additional options looks to be currently possible via a hook_form_alter().
Summarize text
This option summarizes the original text as:
The speaker and the listener have met before, when the speaker was a child attending the St. Swithins school. The school was funded by the Wayne Foundation.
When testing with much longer body text (~45,000 words) a summary was provided, but due to limitations of the API, only the first 3,900 characters of the body text were provided to the API.
Suggest taxonomy
Using the same original text, OpenAI provides the following taxonomy term suggestions:
Funded, Kid, St. Swithins, Wayne, Long
Taking a quick peek at the code, the prompt used is Suggest five words to classify the following text. The words must be nouns or adjectives in a comma delimited list.
Again, poking around the source code for a few minutes showed that there are potential options to extend the current functionality. This includes the ability to add additional content tone and taxonomy term generations options.
OpenAI CKEditor integration
This submodule provides a new OpenAI button that can be placed on any CKEditor toolbar. For this example, I added it to the default Basic HTML text format toolbar (be sure to also enable the OpenAI tools option in the CKEditor 5 plugin settings area for each text format!)
Text completion
When selected, a text field is displayed for the author to provide the prompt to generate text based on (much like ChatGPT). I tested it with the prompt:
Who is Batman's best friend?
The response:
Batman's best friend is his loyal butler, Alfred Pennyworth.
The response is added directly in the text field at the current cursor position.
Adjust tone/voice
Allows the author to provide an adjective to adjust the tone/voice of the entire (or selected portion of) body field. This is very similar to the OpenAI Content Tools module's Adjust content tone option, but allows for a freeform prompt.
Original text:
Bruce Wayne, eccentric billionaire. I'll be standing where l belong. Between you and the peopIe of Gotham. Does it come in black? No guns, no killing. It's ends here. Hero can be anyone. Even a man knowing something as simple and reassuring as putting a coat around a young boy shoulders to let him know the world hadn't ended.
Using formal resulted in the original text being replaced with:
Bruce Wayne, eccentric billionaire. I'll be standing where I belong - between you and the people of Gotham. Does it come in black? No guns, no violence. Let's put an end to this. Heroes come in all shapes and sizes - even a man who can show a young boy that the world is still a safe and comforting place, simply by draping a coat around his shoulders.
Summarize
Same as the option provided by the OpenAI Content Tools submodule.
Reformat/correct HTML
Not tested.
Translate
Allows the author to provide language to translate the contents of the body field. Using Flemish on the same original text as above resulted in the original text being replaced with:
Bruce Wayne, excentrieke miljardair. Ik zal staan waar ik hoort. Tussen jou en de mensen van Gotham. Komt het in het zwart? Geen wapens, geen doden. Het eindigt hier. Een held kan iedereen zijn. Zelfs een man die iets zo simpels en geruststellends doet als een jongen een jas omhangen om hem te laten weten dat de wereld niet was geëindigd.
I'm not a native Flemish speaker, but both Google translate and a close-to-fluent Flemish speaker agree that the translation is sound.
Summary
Overall, once I got past the API and (minor) configuration hurdles, the submodules I tested performed as I expected. I did poke around the code a bit with an eye toward expandability/customization to support our client's requests and was not surprised by the high quality of the code.
I continue to think about how scary it is to generate quality content based on a short(ish) prompt - I really worry about the implications of relying on potentially low-quality content generated purely by AI.
I look forward to seeing how this module develops in the next few months.