
Drupal AI: my first steps with AI module
Artificial Intelligence has arrived in the Drupal ecosystem and it is already making huge waves. This is the first in a series of articles about my experiences as I dip a toe into these exciting waters.
The task
I was working on a large website with plenty of content dating back years, including numerous product reviews that required improved categorisation. The goal was to tag all of these review nodes with the relevant Make and Model.
The approach
I chose to write a custom Drush script to loop through all of the review nodes, using Artificial Intelligence to parse the Title and Body fields and return the make and model discussed therein.
public function reviewsMakeModel(): void {
$fields = ['title', 'body'];
foreach ($review_nodes as $review_node) {
$data = [];
foreach ($fields as $field) {
$data[] = $review_node->get($field)->value;
}
$text = implode("\n", $data);
$makeAndModel = $this->getMakeAndModel($text);
// More to follow...
}
}
The provider
I wish I could say I carried out a thorough study of all of the available providers, ranking their pros and cons, but, as is often the commercial reality, I opted for the one where the company I was working for already had an account - Google Gemini.
The prompt
The joy of AI's natural language processing is that the core of the prompt is simply "What is the make and model discussed in this text?" followed by the content of the Title and Body fields of a review node.
The specifics
Of course AI prompts are never quite that simple; they need refinement to return the specific data in the required format. I did not want any extraneous information so I prefaced the prompt with
Only respond with the make and model
I can't speak for other AI providers, but Google Gemini is wont to deliver a response formatted in markdown, to get plain text I added:
Do not use markdown in responses
Rather than trying to parse the response to separate the make from the model I added:
Respond with json
protected function getManufacturerAndModel(string $text): string {
$message_texts = [
'Do not use markdown in responses',
'Only respond with the make and model',
'Respond with json',
'What is the make and model being talked about in this text',
$text,
];
$json = $this->aiChat->makeAiRequest($message_texts);
return Json::decode($json);
}
N.B. $this->aiChat
refers to a custom AI helper module I am developing that I will expand upon in next week's article.
In conjunction with the rest of the prompt, this causes Google Gemini to respond in the form:
{
make: BMW,
model: M5
}
The processing
Once the data has been obtained it is just a matter of setting the values of the Make and Model and saving the node. For simplicity we'll treat both as text fields (to avoid the complication of setting taxonomy term fields, which is not relevant for the purposes of this article).
public function reviewsMakeModel(): void {
$fields = ['title', 'body'];
foreach ($review_nodes as $review_node) {
$data = [];
foreach ($fields as $field) {
$data[] = $review_node->get($field)->value;
}
$text = implode("\n", $data);
$makeAndModel = $this->getMakeAndModel($text);
if (!empty($makeAndModel['make'])) {
$review_node->set('field_make', $makeAndModel['make']);
}
if (!empty($makeAndModel['model'])) {
$review_node->set('field_model', $makeAndModel['model']);
}
$review_node->save();
}
}
The disclaimer
As with all data obtained through Artificial Intelligence, the standard disclaimer applies: AI can make mistakes, so double check your results!