generated at
文芸的データベース - 文書の作成とそのデータベース化を同時に行なう手法
> 「文芸的データベース」とは、株式会社Helpfeelのshokaiが提唱している、 文書の作成とそのデータベース化を同時に行なう手法で、 文書とデータベースのフィールドをひとつの画面に混在させながら 追加したり修正したりして同時に構築していくことにより、 完全に整合性のとれた文書とデータベースを構築しようというもの


こんにちはshokai
shokaiです
Cosense Cosense プロダクトマネージャー
コンセプトと機能を考えて実装・運用をしています

右のメニューの Start presentation でスライドになります


今日の話
1. 文芸的データベースとは
2. 機能設計の工夫
3. 実装の面白い所を紹介

既に全てのprojectで使えます
が、もしAPI quota超えた場合はbusiness projectを優先します


各ページから抜き出す項目を宣言すると
関連ページリストがテーブル表示モードになる
せっかくなので実演しますshokai
世によくあるやつ
人間が定型データを入力してテーブル作ると、ドキュメントが大量生成されるシステム
その逆です
人間がドキュメントと項目定義を用意すると、LLMがテーブルを生成してくれる

Infoboxとは
抜き出された項目をページの右側に表示したもの
本文を更新すると、Infoboxも自動的に更新される
名前とデザインの元ネタ
Wikipediaの機能である元祖Infobox
そちらはInfobox (wikipedia)を参照


2列目以降にプロンプトを書いて、正規化・ソートできる
これちょっとわかりにくいですが、人間ではなくLLM向けの注釈や作業指示ですshokai


何のために作ったのか
ドキュメントを各自が自由に元気よく書きつつ、
これは現状のCosenseの書き心地を維持したい
つまり
マネージャは、各ドキュメントに書いてほしい項目をしっかり定義しろ
ページを書く時は、そのページに書いてほしいと要望されている項目を意識しろ
面談や議事録、スペック表、仕様検討などに必要な項目をInfoboxの抜き出し項目として定義しておこう


使用例を見ながらデモします

使用例
ガチで書くとこうなる。2列目にプロンプトが書ける
「対応予定時期」を必ず書け
1つのページに複数のInfoboxを設定できる
人物名鑑の例

用途
社内ミーティング、商談、面接、1on1
必ず記載すべき事がずっと右側に表示されていて、書かないと空欄になっている
例:「次回までにやっておく事」
数値、日付、URLなども抜き出せる
未着手、実装中、完了、中止など
人物名鑑、プロダクト名鑑、機能リスト



ちゃんと抜き出されない場合は本文の書き方が悪い
LLMにすら解読不能な意味不明なドキュメントを書いた事を反省しよう
LLM可読ではないドキュメントを人間に読ませるのは失礼
項目定義やプロンプトではなく、本文を書き直すべきshokai
例:システム運用のアイディア出しでは必ず仮説・検証方法・対策を書く



機能設計の工夫

楽しく子機能を使っていたら、便利な親機能の準備が整う
子機能
ページから抜き出された右側がリアルタイムに更新される
抜け漏れチェックできて便利
親要素
抜き出した要素をテーブルにしてソート・フィルタできる

順不同に操作できる
4つの操作がある
1. 項目を宣言する
2. 本文を書く
3. 抜き出し結果を見る
4. テーブルを見る
どういう順番で操作しても破綻しないように作った
ドキュメント作成と項目定義は、どちらを先に行ってもよい
たくさんドキュメントを書いてから、項目定義してもよい
項目定義してから、ドキュメントを書いていってもよい
ドキュメントと項目定義が揃った時点で、即座にテーブルが生成される


保存ボタンも更新ボタンも無い
宣言を書くと抜き出される
宣言を削除すると消える
いつも通り本文を書くだけ
適当なタイミングでInfoboxは更新される


実装の面白い所

Infoboxの更新フロー
mmd
sequenceDiagram participant ブラウザ participant サーバー ブラウザ->>サーバー: Infobox更新してください(HTTPリクエスト) サーバー-->>ブラウザ: 更新しとくよ(HTTPレスポンス) サーバー->>ブラウザ: 今更新してる(websocket) ブラウザ->>ブラウザ: spinner回します サーバー->>ブラウザ: できた(websocket) ブラウザ->>ブラウザ: spinner止めます ブラウザ->>サーバー: Infoboxください(HTTPリクエスト) サーバー-->>ブラウザ: どうぞ(HTTPレスポンス)
「更新中」と「完了」のステータスがサーバーからwebsocketでpush通知される
Infoboxのテキストの取得は、websocketで通知されたブラウザ側からHTTPで取りに行く
なぜこうなっているか
Cosenseは1ページを複数人で同時編集する
ChatGPTからのレスポンス速度がまちまち
10秒近くかかる事もある
多重実行が起きると順番が入れ替わる
websocketにデカい文字列を流したくない
抜き出し結果のテキストは大きくなる可能性がある
websocketではあまり送りたくない
同時に1000人が見ているページかもしれない
サーバー側でmutex lockもかけて多重実行を防いでいる
ちょっと古い本文から作られたInfoboxが最終データとして残らないようにしてる

APIのcache
本文+プロンプトのMD5 hashを、cacheのkeyにしている
問題発生
Node.jsのメモリ使用量は大きくなっていないのに、サーバーのメモリ使用量が枯渇した
原因
デカい文字列のMD5 hash計算が重くてevent loopをロックしてしまう
1 msec 〜 10 msecの間CPUを専有し
HTTPリクエストが処理できなくなり
受信したHTTP / MongoDB / Redis接続のTCP socketは、kernel領域のメモリ空間にたまり続けてしまう
解決
chunkに分けて、細かくevent loopに処理を戻してあげながら、MD5計算するようにした


Infobox定義更新からの全ページ一括更新は、タスクマネジメントをブラウザ側でやってる
サーバーにqueueを持っていない
batch処理もしていない
以下をすべて満たす方法を考えていたら、そうなったshokai
Infobox定義の変更をトリガーとした文芸的データベースの全件更新は
ユーザーの画面に表示されている順に、上から処理したい
負荷をランダムなNode.jsプロセスへ分散もしたい
並列数を上げて高速化もしたい
同時編集による多重実行も防ぎたい
実行中に追加の変更が来たら再実行もしたい
全件更新中のgraceful restartも対応させたい
両立させる
負荷分散・高速化・運用・ユーザー体験
パフォーマンスチューニング大変だった


おわり〜
文芸的データベースとInfoboxを使って、書いてほしい項目を宣言しよう
ドキュメントを各自が自由に元気よく書きつつ、複数人でのコラボレーションも正確にできるはずだ