文芸的データベース - 文書の作成とそのデータベース化を同時に行なう手法
「文芸的データベース」とは、株式会社Helpfeelのshokai.iconが提唱している、 文書の作成とそのデータベース化を同時に行なう手法で、 文書とデータベースのフィールドをひとつの画面に混在させながら 追加したり修正したりして同時に構築していくことにより、 完全に整合性のとれた文書とデータベースを構築しようというもの こんにちはshokai.icon
shokaiです
コンセプトと機能を考えて実装・運用をしています
右のメニューのStart presentationでスライドになります
今日の話
1. 文芸的データベースとは
2. 機能設計の工夫
3. 実装の面白い所を紹介
既に全てのprojectで使えます
が、もしAPI quota超えた場合はbusiness projectを優先します
各ページから抜き出す項目を宣言すると
せっかくなので実演しますshokai.icon
https://gyazo.com/27108bf1a7ce89a23b122cd0c25e51a8
世によくあるやつ
人間が定型データを入力してテーブル作ると、ドキュメントが大量生成されるシステム
その逆です
人間がドキュメントと項目定義を用意すると、LLMがテーブルを生成してくれる
抜き出された項目をページの右側に表示したもの
本文を更新すると、Infoboxも自動的に更新される
https://gyazo.com/d331ab2f889a31f07d1c0ab2ffdbb578
名前とデザインの元ネタ
Wikipediaの機能である元祖Infobox
2列目以降にプロンプトを書いて、正規化・ソートできる
https://gyazo.com/283da90609b4536c920a49d937cdb2ee
https://gyazo.com/e0f17f6f9e1473624b89678a5e6543d3
これちょっとわかりにくいですが、人間ではなくLLM向けの注釈や作業指示ですshokai.icon
何のために作ったのか
ドキュメントを各自が自由に元気よく書きつつ、
これは現状のCosenseの書き心地を維持したい
つまり
ページを書く時は、そのページに書いてほしいと要望されている項目を意識しろ
面談や議事録、スペック表、仕様検討などに必要な項目をInfoboxの抜き出し項目として定義しておこう 使用例を見ながらデモします
使用例
ガチで書くとこうなる。2列目にプロンプトが書ける
「対応予定時期」を必ず書け
1つのページに複数のInfoboxを設定できる
人物名鑑の例
用途
社内ミーティング、商談、面接、1on1
必ず記載すべき事がずっと右側に表示されていて、書かないと空欄になっている
例:「次回までにやっておく事」
数値、日付、URLなども抜き出せる
未着手、実装中、完了、中止など
人物名鑑、プロダクト名鑑、機能リスト
ちゃんと抜き出されない場合は本文の書き方が悪い
LLM可読ではないドキュメントを人間に読ませるのは失礼 項目定義やプロンプトではなく、本文を書き直すべきshokai.icon
例:システム運用のアイディア出しでは必ず仮説・検証方法・対策を書く
機能設計の工夫
楽しく子機能を使っていたら、便利な親機能の準備が整う
子機能
ページから抜き出された右側がリアルタイムに更新される
抜け漏れチェックできて便利
親要素
抜き出した要素をテーブルにしてソート・フィルタできる
4つの操作がある
1. 項目を宣言する
2. 本文を書く
3. 抜き出し結果を見る
4. テーブルを見る
どういう順番で操作しても破綻しないように作った
ドキュメント作成と項目定義は、どちらを先に行ってもよい
たくさんドキュメントを書いてから、項目定義してもよい
項目定義してから、ドキュメントを書いていってもよい
ドキュメントと項目定義が揃った時点で、即座にテーブルが生成される
保存ボタンも更新ボタンも無い
宣言を書くと抜き出される
宣言を削除すると消える
いつも通り本文を書くだけ
適当なタイミングでInfoboxは更新される
実装の面白い所
Infoboxの更新フロー
code:mmd
sequenceDiagram
participant ブラウザ
participant サーバー
ブラウザ->>サーバー: Infobox更新してください(HTTPリクエスト)
サーバー-->>ブラウザ: 更新しとくよ(HTTPレスポンス)
サーバー->>ブラウザ: 今更新してる(websocket)
ブラウザ->>ブラウザ: spinner回します
サーバー->>ブラウザ: できた(websocket)
ブラウザ->>ブラウザ: spinner止めます
ブラウザ->>サーバー: Infoboxください(HTTPリクエスト)
サーバー-->>ブラウザ: どうぞ(HTTPレスポンス)
「更新中」と「完了」のステータスがサーバーからwebsocketでpush通知される
Infoboxのテキストの取得は、websocketで通知されたブラウザ側からHTTPで取りに行く
なぜこうなっているか
ChatGPTからのレスポンス速度がまちまち
10秒近くかかる事もある
多重実行が起きると順番が入れ替わる
websocketにデカい文字列を流したくない
抜き出し結果のテキストは大きくなる可能性がある
websocketではあまり送りたくない
同時に1000人が見ているページかもしれない
ちょっと古い本文から作られたInfoboxが最終データとして残らないようにしてる
APIのcache
本文+プロンプトのMD5 hashを、cacheのkeyにしている
問題発生
Node.jsのメモリ使用量は大きくなっていないのに、サーバーのメモリ使用量が枯渇した
原因
1 msec 〜 10 msecの間CPUを専有し
HTTPリクエストが処理できなくなり
受信したHTTP / MongoDB / Redis接続のTCP socketは、kernel領域のメモリ空間にたまり続けてしまう
解決
chunkに分けて、細かくevent loopに処理を戻してあげながら、MD5計算するようにした
Infobox定義更新からの全ページ一括更新は、タスクマネジメントをブラウザ側でやってる
サーバーにqueueを持っていない
batch処理もしていない
以下をすべて満たす方法を考えていたら、そうなったshokai.icon
Infobox定義の変更をトリガーとした文芸的データベースの全件更新は
ユーザーの画面に表示されている順に、上から処理したい
負荷をランダムなNode.jsプロセスへ分散もしたい
並列数を上げて高速化もしたい
実行中に追加の変更が来たら再実行もしたい
両立させる
負荷分散・高速化・運用・ユーザー体験
パフォーマンスチューニング大変だった
おわり〜
文芸的データベースとInfoboxを使って、書いてほしい項目を宣言しよう
ドキュメントを各自が自由に元気よく書きつつ、複数人でのコラボレーションも正確にできるはずだ