🙄

DDD文脈におけるメンタルモデルをDifyが担えるか?

2024/12/20に公開

どうも、やまぐちです。
Difyが好きでよく使っていますが、このようなLLMノーコードツールはかなり便利な反面、自由度はコードを書くよりは限られてきます。
そんなLLMのノーコードツールを使っていると

ドメイン駆動設計でいうメンタルモデルを担うようなものになるのでは...?

と思い始めてきました。
今回は、「LLMアプリ開発における課題 → Difyがその課題を解決する → その解決手段がDDD的なメンタルモデルとなり得る」という流れでお話ししたいと思います。

DDD的なメンタルモデルについて

ここで言う「DDD的なメンタルモデル」とは、ビジネスドメインにおける概念やルールをチーム全体で共有・理解し、それをプロダクト開発に反映させるための共通言語・抽象度の高いモデルを指します。


P8参照 『関数型ドメインモデリング ドメイン駆動設計とF#でソフトウェアの複雑さに立ち向かおう』

LLMアプリの開発には、ドメイン知識とエンジニアリング知識が必要

ここでは、広い意味でエンジニアリング知識もドメイン知識の一部と考えられなくはありませんが、本記事ではエンジニアリング知識と、それ以外の業務固有の専門知識を区別して記述していきます。
LLMアプリを開発する上で最も困難なのは、ドメインに即した専門知識とエンジニアリング知識の両方が求められる点です。ここでは、その難しさを整理するために、以下の二つの課題を挙げておきたいと思います。

  1. ドメイン知識を豊富に含むプロンプトチューニングはかなり高度な知識が必要である
  2. LLMワークフローを作成するにはエンジニアリング知識とドメイン知識の両方が必要である

課題1: ドメイン知識を豊富に含むプロンプトチューニングはかなり高度な知識が必要である

ここでは、実際の事例として、「DFT計算(量子化学計算の一種)で使用する汎関数をLLMに選ばせようと試みた際に作成したプロンプト」についてドメインエキスパートに相談したケースを紹介してみたいと思います。

まずは以下のようなプロンプトを作成してみました。

以下私が最初に作った汎函数選択のプロンプト

あなたは、特に量子化学の分野で非常に強力なアシスタントです。
量子力学と計算化学の原理を深く理解しているため、各研究プロジェクトの具体的な要件に基づいて、DFT計算に最適な汎関数を専門的に選択することができます。
出力は以下からお選びください。
  [slaterx, pw86x, vwn3c, vwn5c, pbec, pbex, beckex, beckecorrx, beckesrx, beckecamx, brx, brc ....(以下略)

当初、このプロンプトに対して特に細かい評価は行わず、試しにドメインエキスパートに見てもらったところ、以下のようなフィードバックが返ってきました。

量子化学計算を本当にちょっと齧ってる勢からすると、「こんな奥深いんや...」と衝撃を受けました。
これはGPT-4の時代に試したものなので、今であればより精度の高いLLMだとそこまでプロンプトを考えなくとももう少し的確な汎関数選びができるかもしれません。
しかし、すこし極端だったかもしれませんが、的確にプロンプトチューニングしようとするとここまで高度な知識が要求されます。

課題2: LLMワークフローを作成するにはエンジニアリング知識とドメイン知識の両方が必要である

LLMのAPIを単純に叩くだけであれば、それほど高度なエンジニアリング知識は必要ないかもしれません。しかし、実際には以下のような要求が生じることが多く、単なる呼び出し以上の工夫が求められます。

複数のLLMを連携させたい
LLMがわからない内容は、自動的に検索を挟んで情報補完したい
質問を分解し、その要素ごとにLLMを呼び出したい

これらの要件は、主に次の二つの目的から生まれます。

  1. LLMの精度改善
    たとえばMultiQueryRetrievalやCRAGなどの手法を用いて精度を高めるには、複雑なワークフローを設計する必要があります。そのため、エンジニアリング的な知識が不可欠です。

  2. 人間が行っているワークフローの模倣
    業務上の実際のワークフローをLLMに反映させる場合、業務ドメインに関する深い理解が必要となります。どのようなタスクをどの順番で行うか、どの情報を補完すべきか、といった流れを的確にモデル化するためには、ドメイン知識が欠かせません。

つまりLLMワークフローを作成するだけでも、エンジニアリングとドメインの両面からの知識が求められます。(と私は思っています)

Difyでの開発は、DDDでのメンタルモデルの考え方と同じ

ここまででLLMアプリ開発にはドメイン知識とエンジニアリング知識の両方が必要でそれが割と課題であることをお伝えしてきました。
そんなこと言われずともわかってるわ〜!!!!と思っていらっしゃるかもしれません。
それは本当にそうだと思います。というか、そんなことを言われなくても今までもそうだったのではないでしょうか?
今までのアプリ開発でもドメイン知識もエンジニアリング知識も必要でしたよね。
ドメインエキスパートやビジネスアナリストが策定した要件を、エンジニアが理解・翻訳して実装する際、ドメイン知識の理解が不十分だったり誤解が生じたりすると、最終的な成果物の品質が低下する、という課題は常に存在していました。
こうした問題に対してアジャイルやDDD(ドメイン駆動設計)などの手法が提案されてきたわけです。

DDDでは、ドメインのメンタルモデルを開発の中心に据えることで、この課題にアプローチしてきたと思っています。

P8参照 『関数型ドメインモデリング ドメイン駆動設計とF#でソフトウェアの複雑さに立ち向かおう』

Difyを使ってLLMアプリを構築するで、先ほど挙げた二つの課題を解決できる可能性があります。そしてそうすることは実は、DDDでのドメインのメンタルモデルと同じ考え方なのではないでしょうか?

P8参照の図を一部改変 『関数型ドメインモデリング ドメイン駆動設計とF#でソフトウェアの複雑さに立ち向かおう』

それらを見ていきたいと思います。

Difyで課題1が解決される

課題1: 「ドメイン知識を豊富に含むプロンプトチューニングはかなり高度な知識が必要である」

「プロンプトチューニング」への対処として、従来であればエンジニアがドメインエキスパートのヒアリングを経てプロンプトを調整していく必要がありました。本来はドメイン知識に責務を持つドメインエキスパートがプロンプトチューニングできるべきだと思います。
しかしそれはLLMパートとシステム開発パートが密接でプロンプトだけをドメインエキスパートが調整するのは難易度が高いですよね。

なのでやっぱりエンジニアがドメインエキスパートに話を聞きながらプロンプトを調整するのようなことになっていました。

しかしDifyを使用すると、「LLMパートとシステム開発のパートを分割することができること」に加えて、「Dify自体がノーコードツールでエンジニア以外にも触りやすいこと」でドメインエキスパートが直接プロンプトチューニングすることができるようになります。

こうなることでドメインエキスパートの話をエンジニアが翻訳する必要がなく、素直な問題解決につながる精度の高いプロンプトが作れるようになると思います。
さらにプロンプトは自然言語で書かれているので、エンジニアは業務ドメインを理解しやすいです。

もちろん、PromptLayerなどを使用することでプロンプトだけ別で切り出して触れるようにするだけでもいいのではないかと思っている方もいると思います。
単純に一つのLLMしか使わないや、裏にあるLLMワークフロー自体を修正することがない、などの理由があればそれでもいいのではないかと思っています。

Difyで課題2が解決される

課題2:「LLMワークフローを作成するにはエンジニアリング知識とドメイン知識の両方が必要である」

これは完全にDifyで解決することができます。
Difyは、精度改善のための込み入ったワークフローや、人間が実際に行っている業務フローの模倣も可能にします。

こうなることで、良かったことをつらつらと書いていきますが、

  • ワークフローが視覚化されているので、ドメインエキスパートはレビューやフィードバック、自身で修正などがしやすい
  • ワークフローの作成が割とリアルタイムでできるので、IOの理解などがその場でできてドメインエキスパートとエンジニアのフィードバックサイクルが早くなる。(ただ少し場面は限定的)
  • ドメインエキスパートとエンジニアが一緒に作業ができる場があるので、コミュニケーションが促進される。

何よりもドメインエキスパートとエンジニアが一緒に作業ができる場ができたことが何よりいいことです。
ドメインエキスパートとエンジニアのコミュニケーションの場ができたことに本当に感謝です。
Difyありがとう。

課題1,2の解決がDDDでのメンタルモデルの考え方と同じになるのでは?

Difyを用いることでLLMアプリ開発における2つの課題を解決できる可能性を見てきました。

  • 課題1(ドメイン知識を含むプロンプトチューニングの難しさ)の解決
    Difyを使えば、LLMパートとシステム開発パートを分離し、ノーコード環境でドメインエキスパートが直接プロンプトを調整できるようになります。これにより、エンジニアがドメインエキスパートの意図を翻訳する必要が減り、ドメイン知識を素直にプロンプトに反映可能です。また、エンジニア側にとっても、そのプロンプトを閲覧・理解する過程でドメイン知識を自然と吸収できるため、エンジニアリングチーム全体でのドメイン理解度が高まると思います。

  • 課題2(LLMワークフロー構築におけるエンジニアリング知識とドメイン知識の両立)の解決
    Difyではワークフローが視覚化されており、ドメインエキスパートとエンジニアが共通の“場”を共有できます。これによりリアルタイムでのフィードバックや修正が容易になり、複雑なロジックやビジネスプロセスをお互いが理解しやすい状態で開発を進められます。

実はこれって、ドメイン駆動設計(DDD)における「メンタルモデル」を中心に据えたアプローチにも通じる考え方なのではないでしょうか?
DDDでは、ドメイン特有の概念やルールをチーム全体でユビキタス言語のような形でメンタルモデルを共有することで、誤解や認識のズレを減らし、アプリの設計や本番にリリースされるものの質を高めよう!という取り組みでした。

Difyでも同じように、エンジニアとドメインエキスパート、はたまた他のステークホルダーがDifyという共通の“場”を持ち、同じメンタルモデルを共有することが可能になるわけです。
Dify上のワークフローそのものがビジネスロジックを具現化し、全員が同じ地図(メンタルモデル)をもとにプロダクト開発を進められる状況を実現できるのではないかと私は思っています。

現在苦戦している点

かねがねDifyを使っていて良かったと思っていますが、以下の2点で苦しんでいます。

  • いくら簡略化されているとはいえ、ワークフローの構築部分は、依然としてドメインエキスパートにとってはハードルが高い
  • Difyだけでは、あらゆるビジネスロジックを完全なメンタルモデルとして表現しきれない
  • Dify上でのデバッグやワークフローの細分化がかなり手間になる

これらの理由から、Difyの活用に二の足を踏む方も少なくないのではないかと考えています。

(参考)技術スタック

では最後に参考がてらどんなふうにDifyを使っているかを紹介します。
パターンとしては二つあります。

  1. Difyだけで完結させる
  2. Dify + Next.js + (AI SDK or dify-client)

Difyだけで完結させる

Difyにはアプリ公開機能があるので、簡単なプロトタイプでは基本的にはDifyだけで完結させることがあります。
Difyが機能豊富とはいえできることが限られているので、色々やりたい時は次のパターンでやっています。

Dify + Next.js + (AI SDK or dify-client)

AI SDKはLLMの抽象化レイヤーとして働くので、Difyのチャット系のAPIを使う場合はAI SDKのカスタムプロバイダーを使用するようにしています。
AI SDKのいいところは何と言っても使いやすさです。あのインターフェイスを触ってしまうと、他はあんまり使いたくないです。

https://sdk.vercel.ai/docs/foundations/providers-and-models
とはいえ、Difyのワークフロー系のAPIを使う場合はAI SDKだと相性が良くないと思うので私は公式が出しているdify-clientかAPIを直接実行することが多いです。

最後に

Xやってるのでぜひフォローお願いします。

https://x.com/hudebakonosoto

Discussion