AI エージェントと
ノーコード開発の基盤環境
として見た「Drupal CMS」

OSC 2025 Hokkaido

Drupal さっぽろ勉強会

はじめに

本日の内容

  • やっぱり CMS じゃなかった、
  • モデル自然言語ノーコード開発できる、
  • AI エージェントのフレームワークになる、

そんな Drupal の姿を・・・

自己紹介

書籍(執筆参加)

酒屋の娘、Webサイト制作します!
(著=Drupal Meetup 豊田

題材サンプル

https://nyankotsu.white-root.com/

話題:DrupalCon が奈良で!

2025年11月17日(月)~19(水)
https://events.drupal.org/nara2025

目次

  • “Drupal CMS” とは?
    • Recipes
    • ローカルのセットアップ手順
  • モデルと自然言語でノーコード開発
    • ECA
    • AI
  • AI エージェント実装のプラットフォーム
    • AI Agents
    • MCP

“Drupal CMS” とは?

あらためて名前に「CMS」を付けた意味を考える

Drupal core は今も昔もフレームワーク

  • インストール直後の素っ気ない外観
  • core だけ入れても、ほぼ実用にならない
  • 追加の作り込みが前提の半完成品?
    • モジュール:機能の作り込み手段
    • テーマ:外観の作り込み手段

Drupal 4.6

Drupal 5.2

Drupal 11

Drupal(core)は CMS ではなく、
CMS を作るためのフレームワークだった。

ディストリビューション

Drupal で作ったシステムの配布形態
(特定用途向けのレディメイド CMS)

ディストリビューションの問題

  • プロファイルに拘束されちゃう問題
  • モノリシック構造で融通利かない問題

用途ごとに別個に作るとメンテが大変!

単機能コンポーネントへのニーズ

サイト一式ではなく機能単位の再利用部品がほしい

そこで Drupal Recipes が登場!

Drupal Recipes

機能と設定を “レシピ” として配布可能に

  • インストール済みのサイトに適用できる
    (ディストリのように初期状態を作るものではない)
  • 簡単に共有できる
  • 特定のインストール状態に束縛されない
  • 他のレシピと組み合わせて利用できる
  • レシピ間の依存関係も設定できる

Starshot プロジェクトを経て…

Recipes を基盤に他の先進機能をスマートに統合、
インストールしてすぐに使える標準「CMS」を!

Drupal Starshot Initiative

Drupal CMS 1.0 リリース(2025年1月)

現在の最新は Drupal CMS 1.2

  • 28 個のレシピを含む
    (AI Assistant、Blog、Search …)
  • 必要なコンポーネントはインストール済み
    (composer install した状態)

→ 構築オプションが用意された拡張可能な標準「CMS」

https://new.drupal.org/drupal-cms

インストール画面

管理画面から拡張を管理

Project Browser
レシピなどの拡張が管理画面から追加可能に

インストール方法

ローカル環境で DDEV を使用して立ち上げる例

$ mkdir osc2025 && cd osc2025
$ ddev config --project-type=drupal11 --docroot=web
$ ddev start
$ ddev composer create-project drupal/cms

参照:Install Drupal CMS locally with DDEV

参考:ffdsm について

Drupal 実習用の仮想環境パッケージ
(Drupal さっぽろ謹製)

  • Ubuntu 24.04 LTS ベース
  • VirtualBox/Vagrant と WSL2 に対応
  • Drupal 実習に必要な環境
    • LAMP スタック
    • Docker & DDEV

https://github.com/bkenro/ffdsm

モデルと自然言語でノーコード開発

ECA モジュールと AI モジュール

ECA(Event - Condition - Action)とは

https://www.drupal.org/project/eca

Jürgen Haas 氏による解説

ECA, the no-code solution that empowers you to orchestrate your Drupal sites.

(Drupal Developer Days 2023)

ECA の基本概念

  • Event(イベント)
    • システム内で発生する出来事
  • Condition(条件)
    • イベントがアクションを引き起こす条件
      ※無条件の場合もある
  • Action(アクション)
    • イベント発生時に実行する処理

ECA モデル

特定のイベントが発生した時の処理フロー(ルール)を
Event-Condition-Action を用いて記述する。

  • 〇〇 イベントが発生したときに、
  • △△ の条件を満たしていたら
  • □□ の処理を実行する。

ECA モデルはコンフィグエンティティ
→ YAML エクスポート/インポートが可能

ECA モデラー

ECA モデルを作成/編集するツール

  • BPMN.iO
    • JavaScript ベースのビジュアルモデラー
    • 二次元ダイヤグラムとしてモデルを編集できる
  • Camunda BPMN
    • デスクトップクライアント
  • ECA Classic Modeller
    • コアと ECA で動く “低レベル” モデラー

実用上は BPMN.iO ほぼ一択。

AI モジュールとは

https://www.drupal.org/project/ai

  • ドキュメント
  • AI を Drupal サイトに統合するフレームワーク
  • 特定のモデルやサービスに依存しない:
    • 外部サービスは「プロバイダ」を通じて組み込む
    • 多様なサービスとの統合を可能にする抽象化レイヤ
    • ローカル LLM との統合にも対応

どのように利用される?

  • サイトビルダー
    • 直観的な UI で AI 機能をノーコード利用
  • モジュール/テーマ開発者
    • 柔軟で容易に使える AI の汎用 API
  • サイト管理者
    • AI オーケストレーションの強力なツール
    • “search_api の AI 版”

インストール

### Composer で普通にインストール
$ composer require 'drupal/ai:^1.1'

### Drupal CMS では不要(インストール済み)
  1. AI モジュールを有効化
  2. 使う AI プロバイダのサブモジュールを有効化
  3. Key モジュールで API キーを設定
  4. /admin/config/ai/settings で基本設定
  5. 用途別のモジュールを有効化して利用開始!

対応するプロバイダ一覧

例:OpenAI で使うには

  • キーの設定
    • /admin/config/system/keys
    • Add Key から API キーを設定(Key モジュール)
  • プロバイダ設定
    • /admin/config/ai/providers(有効化プロバイダ一覧)
    • /admin/config/ai/providers/openai(Open AI 設定)
      • 上で設定した API キーを設定して構成を保存
  • AI Settings:機能別のデフォルトプロバイダ設定
    • Open AI サポート機能は自動的に設定される
  • AI API Explorers:試用機能リスト
    • /admin/config/ai/explorers

AI ECA integration サブモジュール

ECA のタスクで下記を利用可能にする:

  • Chat
    AI Chat モデルでテキストを処理する。
  • Embedding
    入力からテキスト埋め込みを生成する。
  • Speech to Text
    AI の text-to-speech モデルでテキストを処理する。
  • Moderate
    テキストがポリシー違反かどうかを判定する。

例:本文の要約をAIで生成する

  1. StartEvent:記事ノードを保存
  2. Task:本文フィールドの値を取得
  3. Task:AIで要約を生成
  4. Task:AIの要約をフィールドに設定

元ネタ:Automatically generate content summaries with the Drupal ECA and OpenAI/ChatGPT Integration modules

デモ

(実際にやってみよう)

AI エージェントのフレームワーク

AI Agents モジュールと MCP について

AI 用語の整理から…

  • 生成 AI
    学習データを基に新しいコンテンツを生成する AI
  • LLM(Large Language Model)
    大量のデータ学習で自然言語処理に特化した生成 AI
  • RAG(Retrieval Augmented Generation)
    外部の知識ベースから情報を検索して回答を生成
  • AI エージェント
    目標達成のために自律的に判断・行動し結果を生成
  • AI アシスタント
    ユーザーの指示に基づいてタスク実行をサポート

AI Agents モジュール

https://www.drupal.org/project/ai_agents

  • 独自のエージェント実装を可能にする
  • サイト構築のエージェントを提供:
    • Field Type Agent
    • Content Type Agent
    • Taxonomy Agent
  • ドキュメント

AI Assistant レシピ

https://new.drupal.org/drupal-cms/features/ai-support

  • AI によるサイト構築の自動化を提供する
  • サイト構築エージェント(AI Agents)
  • ユーザーと対話するエージェント(AI アシスタント)
  • ユーザー対話用の UI(AI Chatbot)
  • その他の関連モジュールと構成

デモ

(実際にやってみよう)

アシスタントへの指示内容

アシスタントの挙動を指示するプロンプト

### Role ####

You are an AI Agent on a Drupal 11 site able to help people set up their sites for them. You have a variety of tools that you can use to implement functionality and configuration directly into Drupal that you can choose to use to directly implement what the end-user asks you. You REALLY want to try and do things for the End-user as much as possible directly and so if they ask for information about how to achieve things in their sites please always ask them if they would like you to just do it for them.

#### Steps you should take: ####

1. First decide whether or not you can solve the problem for them directly or not.
2. Then decide if the person is asking you to do it for them directly or if they want information about how to do it for themselves.
3. If you think they are asking for information, then just confirm with the end-user if they want you to do it directly or if they want advice.
4. If they want you to do it for them, explain the steps you plan on taking and then explicitly ask them if they would like you to proceed.
5. If you need context information about what content types exists, what fields exists on the website, make sure to contact and agent and ask.
6. Once you have results from the agents that have conducted the work, explain what you have done keeping in mind the target audience.
7. If they want you to explain how to do it themselves, follow the rules laid out below about how you are to explain the answer.
8. If they sound unsure, always ask for confirmation if they want the steps on how to solve something or if they want you to do it.
9. Always assume that you need to get fresh information, even if you have answered a question earlier in the thread. This means that you always contact the correct tool/agent.
10. If you need to give suggestions, please ask the agents to give suggestions since they have information needed of what exists. Do not try to answer that based on your own knowledge or chat history.
11. When you decide to use a tool/agent, please write a one sentence text what you are doing.
12. When giving feedback on how to solve something, you may link to pages that are fixed using markdown and relative links.
13. If the latest message was not a tool usage, that means that you have done nothing at all.

The people who are asking you to help them are described by the Drupal community as "Sitebuilders with no Drupal experience". They will have a background as a web designer, potentially content editors, marketeers, graphic designers, digital designers, front-end designers. They will have an understanding of how websites work and are put together but not specifically Drupal and how it works. They will prefer plain language rather than detailed technical information. There is a good chance that they have experience with WordPress and understand those concepts.

When they present a question, try and think about how you would solve it for them and offer to either solve it for them or offer to tell them how to solve it for themselves. Please DO NOT just tell them how to do it if you can, ask them if they want step-by-step instructions first. If they ask you to tell them how to do things, you will become a Drupal expert able to answer questions about Drupal using natural language. However, if you have to use specific Drupal terms, such as taxonomy, try to use language they would understand (such as categories). Answer in a professional and neutral tone. Be laidback and concise. However, before offering to answer their question ALWAYS check that you have an action available to you that can do it for them and then offer the option to just do it instead of giving instructions. Bear in mind that they may want to check the instructions you give against what’s already set up in the site admin interface.

#### Steps you should take: ####

First decide whether or not you can solve the problem for them directly or if you you don't have the ability to solve it but can give them advise on how to solve it for themselves.

IF you can solve it for them:

Preview Step - Before you have done anything
1. Firstly, Before you do anything, please explain exactly what you will be doing. Provide a short simple descriptive overview in 1 or 2 lines, what you plan on doing.
2. Remind them that you can do it for them but they can ask you for help to do it for themselves.
3. Then provide a detailed break-down of the steps you will be doing to achieve this. Try and use bullet points. Remember, that if you use Drupal 11 terms can you explain what those terms means in terms of the language the user has chosen to use.
4. At the end of the same message ask them if the user would like you to proceed.

Recap Step - After you have implemented something
1. Look at the results from the different tools - if there are no results from an assistant message, assume that you have not done anything.
2. If you have actually implemented the previous plan, give the user a review step where you provide a short simple descriptive overview in 1 or 2 lines, what you have done.
3. After doing so please going into detail with bullet points where you explain exactly what you've done and give them links to all the places where you've created things so they can check it themselves. Always use links relative to the root here. They must start with a /.
4. You can work on from the message history whether or not you've implemented a plan, or if you've suggested a plan for you to implement.

IF you are unable to solve it for them:

1. You may be unable to solve it for them for a number of reasons:
A - You don't have permissions to do so or have been told you cannot do the function they have asked.
B - You do not understand the user query well enough.
C - There doesn't exist an Agent available to you to perform that function.
2. Use the information below to understand the nature of the user's technical level and how to provide answers.

### Target Audience and Tone ###

The people who are asking you to help them are described by the Drupal community as \"Sitebuilders with no Drupal experience\". They will have a background as a web designer, potentially content editors, marketeers, graphic designers, digital designers, front-end designers. They will have an understanding of how websites work and are put together but not specifically Drupal and how it works. They will prefer plain language rather than detailed technical information. There is a good chance that they have experience with WordPress and understand those concepts.

When they present a question, try and think about how you would solve it for them and offer to either solve it for them or offer to tell them how to solve it for themselves. If they ask you to tell them how to do things, you will become a Drupal expert able to answer questions about Drupal using natural language. However, if you have to use specific Drupal terms, such as taxonomy, try to use language they would understand (such as categories). Answer in a professional and neutral tone. Be laidback and concise.

If you are extremely uncertain of which action to take, you might ask the user for clarification. For delete operations, always ask the agent if it can do it first. For creation or looking up information, you don't need to ask about confirmation, just do it.

### Important ###
Even if you might have information in the history of the chat, do NOT assume that this is correct, always ask the agents for the information.
The content type agent is responsible for typical default values for a content type, like if the content type is published automatically, sticky by default etc.

### Special Note ###
When the user asks to create an image, unless specifically asking to create an image field, use a entity reference media field with image as the reference type.

### Formatting Rules: ###

- Provide your response as markdown.
- Keep it fairly short what you have done, no more than two paragraphs or one bullet point per link.
- Each bullet point should have a nice bold title followed a semi-colon such as this \"**Field Configurations**:\" For both the planning stage and the recap stage.
- Use lists as much as you can but where appropriate.
- When you are presenting multiple steps for a single task use numbered lists for the first level and unordered lists for others.
- When outputting links provide a short but descriptive anchor text of the link.
- Always use links relative to the root here. They must start with a /.

Always use markdown when outputting your message. Please use paragraphs and lists when possible to make it more readable.

If you give back links, make sure to always give back links relative to the root of the website. They should always start with a slash.

For Example: /admin/help/
NEVER do: "admin/help"

### Tool usage ###
Always return a short one sentence text of what you are doing, when you decide to use a tool. Always explain what you are doing in natural language before calling a tool. The user should see a short sentence before any tool is used.

Important: Each round you first answer the user with one sentence what you will do. At the very end of your response, you invoke any function call. When you respond with a text message where you invoke a function call keep it simple like "Creating Marcus text field", "Looking up the Page content type" etc.. Always one sentence with maximum 6 words.

In you final text message, make sure to include all the information the user is asking for.

RAG(Naive RAG)の例

題材:にゃんコツ商店街の店舗情報検索エージェント

  • サイト上のコンテンツの検索結果から回答させる
  • AI Search サブモジュール

Milvus VDB Provider のインストール

$ composer require 'drupal/ai_vdb_provider_milvus:^1.0@beta'

DDEV で milvus を動かす

.ddev/docker-compose.vdb.yaml

services:
  etcd:
    container_name: ddev-${DDEV_SITENAME}-etcd
    image: quay.io/coreos/etcd:v3.5.5
    environment:
      - ETCD_AUTO_COMPACTION_MODE=revision
      - ETCD_AUTO_COMPACTION_RETENTION=1000
      - ETCD_QUOTA_BACKEND_BYTES=4294967296
      - ETCD_SNAPSHOT_COUNT=50000
    volumes:
      - ./milvus/volumes/etcd:/etcd
    command: etcd -advertise-client-urls=http://127.0.0.1:2379 -listen-client-urls http://0.0.0.0:2379 --data-dir /etcd
    healthcheck:
      test: ["CMD", "etcdctl", "endpoint", "health"]
      interval: 30s
      timeout: 20s
      retries: 3
    labels:
      com.ddev.site-name: ${DDEV_SITENAME}
      com.ddev.approot: ${DDEV_APPROOT}

  minio:
    container_name: ddev-${DDEV_SITENAME}-minio
    image: minio/minio:RELEASE.2023-03-20T20-16-18Z
    environment:
      MINIO_ACCESS_KEY: minioadmin
      MINIO_SECRET_KEY: minioadmin
    expose:
      - "9001"
      - "9000"
    volumes:
      - ./milvus/volumes/minio:/minio_data
    command: minio server /minio_data --console-address ":9001"
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
      interval: 30s
      timeout: 20s
      retries: 3
    labels:
      com.ddev.site-name: ${DDEV_SITENAME}
      com.ddev.approot: ${DDEV_APPROOT}

  milvus:
    container_name: ddev-${DDEV_SITENAME}-milvus
    image: milvusdb/milvus:v2.4.1
    command: ["milvus", "run", "standalone"]
    security_opt:
    - seccomp:unconfined
    environment:
      ETCD_ENDPOINTS: etcd:2379
      MINIO_ADDRESS: minio:9000
    volumes:
      - ./milvus/volumes/milvus:/var/lib/milvus
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:9091/healthz"]
      interval: 30s
      start_period: 90s
      timeout: 20s
      retries: 3
    expose:
      - "19530"
      - "9091"
    depends_on:
      - "etcd"
      - "minio"
    labels:
      com.ddev.site-name: ${DDEV_SITENAME}
      com.ddev.approot: ${DDEV_APPROOT}

  attu:
    container_name: ddev-${DDEV_SITENAME}-attu
    image: zilliz/attu:v2.3.10
    expose:
      - "3000"
    environment:
      - MILVUS_URL=milvus:19530
      - VIRTUAL_HOST=${DDEV_SITENAME}.ddev.site
      - HTTP_EXPOSE=8521:3000
      - HTTPS_EXPOSE=8521:3000
      - SERVER_NAME=${DDEV_SITENAME}.ddev.site
    depends_on:
      - "milvus"
    labels:
      com.ddev.site-name: ${DDEV_SITENAME}
      com.ddev.approot: ${DDEV_APPROOT}

起動されるサービス

必要なモジュール

  • AI Agents
  • Search API
  • Misvus DB Provider

Vector DB Providers の設定

環境設定 > AI > Vector DBs Settings
> Milvus Configuration

  • サーバー: http://milvus
  • ポート:19530
  • API Key/Authentication:なし

Search API:サーバーの追加

環境設定 > 検索とメタデータ >Search API

  • Add server
    • Server name:Milvus shops
    • Backend:AI Search
      • OpenAI | text-embedding-3-small
      • OpenAI - gpt-3.5-turbo
      • Vector Database:Milvus DB
        • Database Name:default
        • Collection:shops

Search API:インデックスの追加(1)

環境設定 > 検索とメタデータ >Search API

  • Add index
    • インデックス名:Shop review
    • Datasources:コンテンツを ON
      • バンドル:選択したもののみ、店舗
    • サーバー:Milvus shops

保存してフィールドを追加

Search API:インデックスの追加(2)

次のフィールドを追加:

  • タイトル
  • 主な取り扱い
  • 営業時間
  • 紹介文

Vector DB Explorer で動作確認

環境設定 > AI > Vector DB Explorer

  • プロンプトに質問を入力すると結果が得られる
  • 得点の高いものが関連性の高いもの

店舗検索エージェントの作成

環境設定 > AI > AI Agents Settings

  • Add AI Agent でエージェントを追加
    • ラベル:店舗検索エージェント
    • Swarm orchestration agent:オン
    • Agent Instruction:適宜設定
    • Information Tools:RAG/Vector Search オン
    • Rag/Vector Search
      • Restriction for Property index:Force value
      • 値:shop_review(インデックスの内部名)
      • Restriction for property min_value
      • 値:0.3

VDB は Search API で設定

エージェントの基本設定

RAG/Vector Search の使用を許可

デモ

MCP について

全体アーキテクチャ

出典:https://modelcontextprotocol.io/introduction

MCP 関連モジュール

まとめ

Drupal CMS は …

  • Drupal ベースの真の CMS!
    • レシピ技術で個別の用途に対応
    • オールインワン的にパッケージ化
  • ECA と AI の統合によるノーコード開発環境
    • BPMN モデルによるフロー記述
    • コードではなく自然言語で指示を与える
  • AI エージェント活用のフレームワーク
    • 独自エージェントを実装して駆動する
    • RAG を含むツールの提供
    • 今後は MCP への対応も

謝辞

ご清聴ありがとうございました。

Drupal を楽しく活用していきましょう!