知らない言葉を調べると知らない言葉が出てくる
みなさんこんにちは。kokurenです。
自分は生成AIからプログラミングや機械学習などに興味を持ったタイプなのですが、AIや既存のもので遊ぶだけではなく、その裏にある数理的な話や具体的な実装などについても学びたいなとずっとなんとなく思っていました。
とは言っても、中々体系立って専門外の何かを学ぶというのは難しく、調べても知らない言葉で説明されている、どこからわかってないのかすらわかっていないといった典型的な勉強できないスパイラルに陥っていました。
これは語学などでも言えることだと思うのですが、人が何かのトピックについて学ぶとき、まず語彙の獲得が識字よりも先立って、識字の獲得の後に多様な文脈に触れることで理解のネットワークが形成されるのかと考えています。
つまり、人が何かを学ぶ上で最優先なのは知らない概念を潰すことなのではないかということです。
しかし、先ほど言ったとおり、何がわからないのかすらわかっていないというのに、どう知らない概念を潰していけばいいのでしょうか。そこで生成AI(簡単なLLMエージェント)が役立つと考えました。
学ぶべき語彙をLLMに挙げさせる
前置きが長くなりましたが本題です。面倒なことはLLMにやらせましょう。
以下のようにMermaid.jsを用いて特定の用語や概念に対するロードマップをツリー状に示させることができます。
上記はPyTorchというワードでの一例です。
上記のように、キーワードをツリー状にまとめさせることで、周辺ワードについて効率よくさらうことができます。
学習用資料をDifyを用いて生成する
今更Difyというツールを触ってみたのですが、なんとも面白かったです。
一応説明しますと、DifyとはオープンソースのLLMアプリケーション開発ツールで、ノードベースでLLMやカスタムコードの入出力を管理してワークフローを組むことができます。
今回は以下のようなフローを組んでみました。
始めに知りたいプログラミングに関するワードを入力すると、LLMノードに渡され、Mermaid.jsの形式で単語をリストアップしてくれます。
次に、LLM2にリストアップされた単語が送られ、配列の形をした文字列に整形されます。
続いて、コードで実際のString型配列に変換され、イテレーションに学ぶべき用語リストの配列が渡され、LLM3で解説のマークダウンが作られ、最後に整形して出力という仕組みです。
そのままmarkdownをpdfやNotion用テキストなどに変換してあげれば、一瞬で自分だけのピンポイントの教材が生成されます。
ワードを"pytorch"にして生成した例。
ドクセルに色々載せているので見てみたら面白いかもです。
おまけ
今回作成したワークフローのyamlを乗っけておきます。
本当はファイルをそのまま共有したかったのですがQiitaには貼れなかったので、以下をテキストエディタにコピペして.yml拡張子で保存し、Difyにインポートしてください。
アディオス。
app:
description: ''
icon: 🤖
icon_background: '#FFEAD5'
mode: workflow
name: programdigger
use_icon_as_answer_icon: false
kind: app
version: 0.1.3
workflow:
conversation_variables: []
environment_variables: []
features:
file_upload:
allowed_file_extensions:
- .JPG
- .JPEG
- .PNG
- .GIF
- .WEBP
- .SVG
allowed_file_types:
- image
allowed_file_upload_methods:
- local_file
- remote_url
enabled: false
fileUploadConfig:
audio_file_size_limit: 50
batch_count_limit: 5
file_size_limit: 15
image_file_size_limit: 10
video_file_size_limit: 100
workflow_file_upload_limit: 10
image:
enabled: false
number_limits: 3
transfer_methods:
- local_file
- remote_url
number_limits: 3
opening_statement: ''
retriever_resource:
enabled: true
sensitive_word_avoidance:
enabled: false
speech_to_text:
enabled: false
suggested_questions: []
suggested_questions_after_answer:
enabled: false
text_to_speech:
enabled: false
language: ''
voice: ''
graph:
edges:
- data:
isInIteration: false
sourceType: start
targetType: llm
id: 1732761278493-source-1732762025290-target
source: '1732761278493'
sourceHandle: source
target: '1732762025290'
targetHandle: target
type: custom
zIndex: 0
- data:
isInIteration: false
sourceType: llm
targetType: llm
id: 1732762025290-source-1732764987274-target
source: '1732762025290'
sourceHandle: source
target: '1732764987274'
targetHandle: target
type: custom
zIndex: 0
- data:
isInIteration: true
iteration_id: '1732764128347'
sourceType: iteration-start
targetType: llm
id: 1732764128347start-source-1732765426680-target
source: 1732764128347start
sourceHandle: source
target: '1732765426680'
targetHandle: target
type: custom
zIndex: 1002
- data:
isInIteration: false
sourceType: llm
targetType: code
id: 1732764987274-source-1732765355941-target
source: '1732764987274'
sourceHandle: source
target: '1732765355941'
targetHandle: target
type: custom
zIndex: 0
- data:
isInIteration: false
sourceType: code
targetType: iteration
id: 1732765355941-source-1732764128347-target
source: '1732765355941'
sourceHandle: source
target: '1732764128347'
targetHandle: target
type: custom
zIndex: 0
- data:
isInIteration: false
sourceType: iteration
targetType: code
id: 1732764128347-source-1732768020473-target
source: '1732764128347'
sourceHandle: source
target: '1732768020473'
targetHandle: target
type: custom
zIndex: 0
- data:
isInIteration: false
sourceType: code
targetType: end
id: 1732768020473-source-1732765086173-target
source: '1732768020473'
sourceHandle: source
target: '1732765086173'
targetHandle: target
type: custom
zIndex: 0
nodes:
- data:
desc: 知りたいprogramming概念
selected: true
title: 開始
type: start
variables:
- label: word
max_length: 48
options: []
required: true
type: text-input
variable: word
height: 117
id: '1732761278493'
position:
x: 134
y: 277
positionAbsolute:
x: 134
y: 277
selected: true
sourcePosition: right
targetPosition: left
type: custom
width: 244
- data:
context:
enabled: false
variable_selector: []
desc: ''
model:
completion_params:
temperature: 0.7
mode: chat
name: gpt-4o
provider: openai
prompt_template:
- id: 8bece6b8-3914-4616-8a08-fdc3cb909887
role: system
text: 'あなたは与えられたキーワードについて学習するためのフローチャートを提供します。
与えられた概念を理解する上で、理解する必要のあるキーワードを、Mermaid.jsを用いてロードマップとして提示してください。
Mermaid.jsによるフローチャートのみ出力し、余計な説明やテキストは出力しないこと。
例:PyTorch
```mermaid
graph TD;
A[PyTorch] --> B[Tensor]
A --> C[Autograd]
A --> D[torch.nn]
A --> E[torch.optim]
A --> F[DataLoader]
A --> G[Dataset]
B --> H[Tensor Operations]
B --> I[CUDA Tensors]
C --> J[Computational Graph]
C --> K[Gradient Descent]
D --> L[Module]
D --> M[Sequential]
D --> N[Loss Function]
E --> O[SGD]
E --> P[Adam]
F --> Q[Batch Processing]
F --> R[Data Augmentation]
G --> S[Custom Dataset]
G --> T[Transforms]
L --> U[Forward Method]
L --> V[Backward Method]
```'
- id: c959467a-0a5e-43f7-a103-927b7be024cf
role: user
text: '{{#1732761278493.word#}}について理解するためのロードマップをMermaid.jsを用いて作成。要素の数は20前後までとする。
基本的には日本語を用いるが、英語の方が一般的な名称や固有名詞は英語を使う。 すべてその分野特有の専門用語であること。'
selected: false
title: LLM
type: llm
variables: []
vision:
enabled: false
height: 97
id: '1732762025290'
position:
x: 431
y: 282
positionAbsolute:
x: 431
y: 282
selected: false
sourcePosition: right
targetPosition: left
type: custom
width: 244
- data:
desc: ''
error_handle_mode: terminated
height: 185
is_parallel: true
iterator_selector:
- '1732765355941'
- result
output_selector:
- '1732765426680'
- text
output_type: array[string]
parallel_nums: 10
selected: false
start_node_id: 1732764128347start
title: イテレーション
type: iteration
width: 388
height: 185
id: '1732764128347'
position:
x: 330.38008978795983
y: 452.3098893252444
positionAbsolute:
x: 330.38008978795983
y: 452.3098893252444
selected: false
sourcePosition: right
targetPosition: left
type: custom
width: 388
zIndex: 1
- data:
desc: ''
isInIteration: true
selected: false
title: ''
type: iteration-start
draggable: false
height: 48
id: 1732764128347start
parentId: '1732764128347'
position:
x: 24
y: 68
positionAbsolute:
x: 354.38008978795983
y: 520.3098893252444
selectable: false
sourcePosition: right
targetPosition: left
type: custom-iteration-start
width: 44
zIndex: 1002
- data:
context:
enabled: false
variable_selector: []
desc: ''
model:
completion_params:
temperature: 0
mode: chat
name: gpt-4o
provider: openai
prompt_template:
- id: 528d5b85-b8ee-49f0-8b6f-f4ed4b1c792a
role: system
text: '与えられたmermaid.jsから階層順にワードを抜き出し、pythonで使用可能なリストの形で出力する。
リストのみを出力すること。
format:
[word1, word2, ...]'
- id: e36c2b43-1e00-454d-ba09-9ce3b0f08229
role: user
text: '{{#1732762025290.text#}}から階層順のワードリストを抽出。リストのみ抽出。
format:
[''word1'', ''word2'', ...]'
selected: false
title: LLM 2
type: llm
variables: []
vision:
enabled: false
height: 97
id: '1732764987274'
position:
x: 715.5675294738476
y: 282
positionAbsolute:
x: 715.5675294738476
y: 282
selected: false
sourcePosition: right
targetPosition: left
type: custom
width: 244
- data:
desc: ''
outputs:
- value_selector:
- '1732768020473'
- result
variable: output
selected: false
title: 終了
type: end
height: 89
id: '1732765086173'
position:
x: 1084.6420494283946
y: 472.2084776588363
positionAbsolute:
x: 1084.6420494283946
y: 472.2084776588363
selected: false
sourcePosition: right
targetPosition: left
type: custom
width: 244
- data:
code: "function main({ wordlist }) {\n let result; // 最終的に返す変数\n\n //\
\ 入力が null または undefined の場合に対応\n if (!wordlist) {\n throw new\
\ TypeError(\"wordlist is null, undefined, or not provided.\");\n }\n\
\n // 入力が文字列の場合\n if (typeof wordlist === 'string') {\n try\
\ {\n // シングルクォートをダブルクォートに変換して JSON としてパース\n result\
\ = JSON.parse(wordlist.replace(/'/g, '\"'));\n } catch (error) {\n\
\ // パースエラーをキャッチ\n throw new TypeError(\"wordlist\
\ is a string but cannot be parsed as JSON.\");\n }\n } \n \
\ // 入力が配列の場合\n else if (Array.isArray(wordlist)) {\n result =\
\ wordlist; // 配列の場合、そのまま代入\n } \n // その他のデータ型はエラー\n else {\n \
\ throw new TypeError(\"wordlist must be a string or an array.\");\n\
\ }\n\n return { result }; // 最終的にオブジェクト形式で result を返す\n}\n"
code_language: javascript
desc: ''
outputs:
result:
children: null
type: array[string]
selected: false
title: コード
type: code
variables:
- value_selector:
- '1732764987274'
- text
variable: wordlist
height: 53
id: '1732765355941'
position:
x: 36.362293722234426
y: 452.3098893252444
positionAbsolute:
x: 36.362293722234426
y: 452.3098893252444
selected: false
sourcePosition: right
targetPosition: left
type: custom
width: 244
- data:
context:
enabled: false
variable_selector: []
desc: ''
isInIteration: true
iteration_id: '1732764128347'
model:
completion_params:
temperature: 0.7
mode: chat
name: gpt-4o
provider: openai
prompt_template:
- id: fd24568a-adb9-45b9-8822-b681613a6494
role: system
text: "あなたはprogrammingやゲーム制作のための教科書作成をしています。\nこちらが提示する概念や用語について、以下の点に留意しながら以下のフォーマットでまとめてください。\n\
\n・本にできるほど詳細かつ厳密に書き記すこと\n・必要に応じて適切な数式記号や数式を用いること(TeX)\n・文中の数式はnotionのインライン数式の形式を使うこと\n\
・大きな式や関数はnotionの/mathに組み込める形にすること\n・主に体言止め形式を使い、常体で書き記すこと\n・数式はKaTexで表示できるように記載\n\
・インライン数式は$で囲み、ブロック数式は$$でかこむ\n・必要に応じてコードスニペットを提供\n・コードスニペットはコードブロックで囲むこと\n\
\n=====\n出力フォーマット\n\n## 提示された概念名\n### 定義や意味\n - ここに厳密な定義や、意味あいについて詳細に書き記す\n\
\ - (あれば)数式による具体例を示す\n### 嚙み砕いた説明\n - わかりやすく嚙み砕いた説明\n - わかりやすさや言葉での具体例を重視\n\
### 実際の応用例\n - その概念がどんな場面で応用されているかの例を挙げる\n - コードスニペットとコメントアウトを用いて具体例を説明する\n\
\ ====="
- id: 21990eab-f4b4-4e87-8092-dbfb3c6fe6c4
role: user
text: '以下のprogramming及びゲーム制作概念{{#1732764128347.item#}}についての解説をマークダウン形式で出力。
数式はKaTexで表示できるように記載。
コードスニペットはコードブロックで囲む。
{{#1732761278493.word#}}に関連しているとなお良し。'
selected: false
title: LLM 3
type: llm
variables: []
vision:
enabled: false
height: 97
id: '1732765426680'
parentId: '1732764128347'
position:
x: 128
y: 68
positionAbsolute:
x: 458.38008978795983
y: 520.3098893252444
selected: false
sourcePosition: right
targetPosition: left
type: custom
width: 244
zIndex: 1002
- data:
code: "\nfunction main({ output }) {\n if (!Array.isArray(output)) {\n\
\ throw new TypeError(\"Expected an array of strings for 'output'\"\
);\n }\n\n // 一連のマークダウンテキストを結合して整形\n const result = output.join(\"\
\\n\\n\");\n\n return {\n result, // 整形されたマークダウンを返す\n };\n}"
code_language: javascript
desc: ''
outputs:
result:
children: null
type: string
selected: false
title: コード 2
type: code
variables:
- value_selector:
- '1732764128347'
- output
variable: output
height: 53
id: '1732768020473'
position:
x: 773.8593053149923
y: 472.2084776588363
positionAbsolute:
x: 773.8593053149923
y: 472.2084776588363
selected: false
sourcePosition: right
targetPosition: left
type: custom
width: 244
viewport:
x: 224.74055136647993
y: 57.26161309864435
zoom: 0.7937005259840996