Unilearning統合オンライン学習基盤
企業・教育機関・個人向けのオンライン学習 SaaS。Go のモジュラーモノリスとして再構築し、8 つの業務ドメイン(auth / cms / eas / ocs / oms / osm / quiz / ai)をプロセス内で集約。6 つのマイクロサービスを 1 バイナリ・1 コンテナに畳み込み、ドメイン間は api 契約のみ、internal の壁はコンパイラが強制します。
マイクロサービスを細かく分割しすぎると、真のコストはサービス間呼び出しに移ります。モジュラーモノリスはその呼び出しを関数呼び出しに戻しつつ、コンパイラでドメイン境界を守ります。
講座の公開から AI 採点まで、学習ループの各段階が独立して進化できる業務ドメインです。
実際に何を解決するのか
4つの主要機能が、4つの実在する業務ニーズに対応します。
講座・教材・時間割・課題・試験・コメントが教える側と学ぶ側の全工程をカバーし、進捗と成績はリアルタイムで照会できます。
8 つの業務ドメインをプロセス内で集約。ドメイン間は api 契約のみを認め、internal の壁は lint や規律ではなくコンパイラが強制します。
教員が 1 件またはクラス単位の AI 採点を発火。ドラフトは拡張属性に置かれ、業務状態には触れません。最終判断は常に人にあります。
バージョン管理された SQL マイグレーションが冪等にアップグレードし、旧システムのデータはワンクリックで取り込み、既存ユーザーは元のパスワードでそのままログインできます。
能力一覧
- 講座ツリー + 学習記録:マテリアライズドパスツリーで、進捗が祖先チェーンに沿って自動集約
- 4 種類の教材:content / page / video / media。進捗記録と途中再開を統一
- 問題バンクと試験:単一選択・複数選択・正誤の 3 問型で試験を構成し、提出と同時に採点・解説
- AI 一次採点:LLM が採点ドラフトを生成し、教員が最終判断。AI が教員の代わりに決めることはありません
- オンラインストア:講座の商品化と取引の閉ループ。注文が購入証明
- 教務・時間割:クラス、メンバー、時間割管理。3 つのフロント経路は旧システムと互換
スライドの中にある製品ではない
以下の数字は unile-go リポジトリの実際のコードから読み出したものです。モジュール、テーブル、エンドポイント、機能項目。
技術スタック
機能一覧
8 の業務ドメイン、48 項目の具体的な機能。どれもコード上に実在する実装に対応します。
講座ツリーと学習記録
cms 域アウトラインはツリーです。1 節終えると、祖先チェーン全体の進捗が自動更新されます。
- マテリアライズドパスツリー:講座アウトラインをパス符号で保存。サブツリークエリに再帰は不要
- 学習記録は祖先チェーンに沿ってバブリング upsert され、親ノードの進捗が自動集約
- ノード型は拡張可能。node_type=quiz で試験をアウトラインに吊り下げ
- RecordService.UpdateAttributes が拡張列にマージ書き込みし、AI ドラフトが業務フィールドを汚さない
- 進捗と成績はリアルタイム照会可能。受講生端と教員端が同じ事実を共有
4 種類の教材
ocs 域content・page・video・media の 4 形態。進捗の扱いは統一です。
- content:テキストと画像のコンテンツ教材
- page:カスタムページ教材
- video:動画教材。途中再開に対応
- media:音声・動画などの他のメディア形態
- 統一された教材学習進捗の記録モデル
教務・時間割
eas 域クラス、メンバー、時間割。教務の日常です。
- ユーザープロフィール:受講生と教員のアイデンティティを統一管理
- クラス管理:クラス CRUD とメンバー関係
- メンバーロール:教員、チューター、受講生の複数ロール
- 時間割:schedules テーブルがクラスとアウトラインノードを関連付け
- expand パラメータの互換:teachers / assistants / students を一度に取得
問題バンクと試験
quiz 域客観問題はその場で採点し、主観問題は教員に残します。
- 問題バンクは講座ごとに分離。単一選択 / 複数選択 / 正誤の 3 問型
- 選択肢と解答は JSONB で保存。選択肢インデックスは 0 始まり
- 試験用紙の構成:quiz_paper_questions が試験用紙と問題を関連付け
- 提出即採点:集合比較の純関数で、サーバー側が自動完了
- 提出即解説:応答が各問の正誤、正解と解説を返す
- 問題取得時の解答分離:受講生用の問題取得インターフェースは answer / analysis を返さない
- 複数回の作答:attempt は履歴を保持し、進捗は最新、点数は最高を採用
- 採点と進捗の書き込みは分離。進捗の失敗は採点をロールバックせず sync_record_failed をマーク
AI 採点
ai 域AI がドラフトを書き、教員が決める——この境界は実装に書き込まれています。
- 単票の発火:POST /tv1/teacher/homeworks/:hid/ai-feedback
- クラス一括:POST /tv1/teacher/classes/:cid/ai-feedback。分割処理、上限 100
- submitted 状態のみ処理し、ドラフト済みは自動スキップ。トークンを二重に焼かない
- 1 件の失敗で一括を中断しない。件ごとに error を報告し、次回自動リトライ
- ドラフトは record.attributes.ai_feedback に書き込み、業務状態列には触れない
- 最終審査は既存の feedback インターフェースを通る。AI が教員の代わりに決めることはない
- LLM クライアントは標準ライブラリのみで OpenAI 互換プロトコルを実装。GLM / DeepSeek / ローカル Ollama いずれも可
- 未設定時は 501 を返し、他の機能には影響しません
コメントとコミュニティ
oms 域スレッド式コメント。サブツリーは 1 クエリで取得します。
- スレッドツリー構造:root / path / depth の 3 項目が階層を支える
- サブツリークエリ:1 回のクエリでツリー全体を取得
- コメントは講座とノードに紐付け
- 旧システムから移植し、中核アルゴリズムはユニットテストでカバー
オンラインストア
osm 域講座が商品になり、注文が購入の証明になります。
- 商品管理:講座スナップショット式の商品。価格は最小通貨単位で管理
- 商品状態機械:draft → on_sale ⇄ off_sale
- 受講生端の棚は on_sale の商品のみ表示
- 注文:商品スナップショットを保存。注文が証明
- 注文状態機械:pending → paid | cancelled、paid → refunded
- 管理端はオフラインでの入金確認(MarkPaid)と返金が可能
- 注文に削除インターフェースはなく、財務証憑として保持
アイデンティティと移行
auth 域 · serverエンジンを換えてもタイヤは変えない。旧システムのデータはそのまま使えます。
- local モード:bcrypt + HS256 JWT を内蔵。導入後すぐに使用可能
- remote モード:UIAM への切替。edge と各ドメインのコードは変更不要
- バージョン管理 SQL マイグレーション:ドメインごとに pg / mysql の方言ファイル群を持ち、起動時に冪等で自動アップグレード
- 移行バージョンは DB 内の unile_migrations テーブルに記録。適用済みは自動スキップ
- legacy-import ツール:旧 DB をワンクリック取り込み。既存ユーザーは bcrypt の元パスワードで直接ログイン
- OSS STS 資格情報インターフェース:実際の AssumeRole と static の 2 モードに対応
API コントラクト
12 の代表的エンドポイント。ここに列挙するのは公開契約の骨格であり、完全な定義は導入時に提供します。
/uv1/auth/login受講生端ログイン:local モードは bcrypt、remote モードは UIAM へ委譲
/uv1/courses/{id}/outline講座ツリーのアウトライン。マテリアライズドパスでサブツリー全体を一度に取得
/uv1/records学習記録の提出。進捗はマテリアライズドパスの祖先チェーンに沿って自動バブリング
/uv1/nodes/{id}/paper問題取得:サーバーが answer / analysis を取り除いてから返す
/uv1/nodes/{id}/attempts提出:同一トランザクションで採点し、各問の解説を返す
/tv1/teacher/homeworks/{hid}/ai-feedback単票の AI 採点。ドラフトは attributes 拡張列に書き込み
/tv1/teacher/classes/{cid}/ai-feedbackクラス一括の AI 採点。分割処理、1 回の上限 100
/tv1/teacher/homeworks/{hid}/feedback教員の最終審査。決定権は常に人にあります
/admv1/shop/products管理端の商品管理。draft → on_sale ⇄ off_sale の状態機械
/uv1/orders注文:商品スナップショットを保存。注文が購入の証明
/admv1/orders/{id}/mark-paid対面決済の確認。注文状態機械を遷移
/uv1/nodes/{id}/commentsスレッド式コメント:root / path / depth のツリー構造
実際の呼び出し
エンドポイントがどのようなものかは、一覧よりも雄弁です。
01$ curl -X POST https://learn.zhenbei.tech/uv1/nodes/146/attempts \02 -d '{"answers":[{"qid":9,"choice":[0,2]},{"qid":10,"choice":[1]}]}'0304{ "score": 50, "total": 100, "graded": "instant",05 "detail": [ { "qid": 9, "ok": false, "answer": [0,1], "analysis": "…" },06 { "qid": 10, "ok": true } ],07 "progress": { "node": 146, "bubbled": 12 } }契約の規律
インターフェースは約束であり、実装詳細の晒しではありません。この3つの規則を守り続けています。
破壊的変更はメジャーバージョンで行い、1リリース前に告知します。公開済みのエンドポイントが内部リファクタリングで意味を変えることはありません。
エラーコードは曖昧な 500 ではなく意味を持たせ、呼び出し側(AI Agent を含む)がリトライか断念かを判断できます。
人間向けのテキストではなく、既定で構造化データを返します。AI が直接読め、人がスクリーンショットで中継する必要はありません。
モジュール
5 グループ・11 のコードモジュール。すべて unile-go リポジトリの実際のディレクトリ構造に基づきます。
server/ と各ドメインモジュール何を教え、何を学び、どこまで学んだか。
cms講座ツリー(マテリアライズドパス)と学習記録。進捗は祖先チェーンに沿ってバブリング upsert
cms/internal/bizocs4 種類の教材:content / page / video / media、および教材の学習進捗
ocs/internal/biz誰が教え、誰が学び、いつ授業をするか。
eas教務:users、classes、class_user_relations、schedules の 4 テーブルを全量カバー
eas/internal/biz学んだかどうかは、検証する手段が必要です。
quiz問題バンク(単一選択 / 複数選択 / 正誤、options / answer は JSONB)+ 試験用紙の構成 + 採点
quiz/internal/bizaiLLM 採点:OpenAI 互換プロトコルを標準ライブラリのみで実装。新規依存ゼロ
ai/internal/biz学習は孤独ではなく、講座は売り買いできます。
omsスレッド式コメント:root / path / depth のツリー構造 + サブツリークエリ
oms/internal/bizosmオンラインストア:商品出店、注文、決済、返金、注文管理
osm/internal/biz境界はドキュメントではなくコンパイラが守ります。
authアイデンティティ:local モードの bcrypt + HS256 JWT を内蔵。remote へ滑らかに切替えて UIAM と接続
auth/internal/bizedge集約層:uv1 / tv1 / admv1 の 3 端ルート。パスは旧フロントエンドと互換を維持
edge/base共通型:ページング、Attribute 拡張列、統一エラーコード。外部依存ゼロ
base/serverアセンブリ層:設定、マイグレーションランナー、依存性注入と起動
server/レイヤー設計
アクセスからランタイムまで、各層の責務と実装技術。
server:設定、マイグレーション、依存性注入と起動。Dockerfile で単一バイナリ提供
edge:uv1 受講生端 / tv1 教員端 / admv1 管理端。ドメイン横断の編成はここにだけ書く
cms の講座ツリーと学習記録 · ocs の 4 種類の教材と学習進捗 · eas の教務・時間割
oms のスレッド式コメント · osm の講座ストア · quiz の問題バンクと試験 · ai の LLM 採点
auth:local の bcrypt + HS256 JWT を内蔵。remote へ切り替えて UIAM と接続可能
base:ページング、Attribute、エラーコード。外部依存ゼロ
PostgreSQL / MySQL の双方言。ドメインごとのバージョン管理マイグレーションが起動時に自動適用
主要フロー
最も重要ないくつかの経路を、ステップごとに分解して見ていきます。
受講生が 1 節を学び終える
1 回の提出で、アウトラインツリー全体の進捗が同期更新されます。
- 1
受講生が uv1 でノードの学習記録を提出
- 2
cms がノードの帰属と講座権限を検証
- 3
学習記録テーブルへ upsert
- 4
進捗がマテリアライズドパスの祖先チェーンに沿って上方バブリング
- 5
親ノードと講座レベルの進捗が同期リフレッシュ
- 6
受講生端のアウトラインビューと教員端の進捗ビューの両方に新進捗が即座に反映
オンライン試験は提出即採点
客観問題は先生を待ちません。
- 1
受講生が quiz を吊り下げたノードを要求。サーバーは解答と解説を取り除いてから返す
- 2
受講生が /uv1/.../attempts へ作答を提出
- 3
edge がノードに試験用紙が本当に吊り下がっているかを検証し、quiz ドメインへ引き渡す
- 4
quiz ドメインが集合比較の純関数で各問を採点(未作答 = 不正解、0 点)
- 5
attempt と全問の明細を同一トランザクションで保存。total は提出時のスナップショット
- 6
cms Records.Save が点数と完了状態を書き込み、進捗は祖先チェーンをバブリング
- 7
応答は完全な採点明細を返す:各問の正誤、正解と解説
AI 採点と教員の最終審査
AI が速度を出し、決定権は人にあります。
- 1
受講生が課題を提出し、状態は submitted
- 2
教員が課題ビューから単票またはクラス一括の AI 採点を発火
- 3
edge がコンテキストを組み立てる:講座、ノード、課題要件、教材タイトル
- 4
ai ドメインが LLM を呼んで採点提案を生成(ドラフト済みはスキップ)
- 5
ドラフトは record.attributes.ai_feedback に書き込み、業務状態列は変更なし
- 6
教員が課題ビューで AI ドラフトを確認
- 7
教員は既存の feedback インターフェースで最終審査。ドラフトは拡張列に残り、照会可能
技術スタック
性能と規模
これらの数字は推定ではなく、コードと実行構成から読み出したものです。宣伝文句と誤解されないよう、各項目に実際の意味を注記しています。
unile-goauth / cms / eas / ocs / oms / osm / quiz / ai をプロセス内で集約
従来の 6 マイクロサービスを 1 バイナリ・1 コンテナに畳み込み
ドメイン間は api 契約のみ。internal の壁はコンパイラが強制
PostgreSQL を優先しつつ MySQL も同等サポート。マイグレーションはディレクトリ別管理
両データベースで通過し、主要な教学経路をカバー
教材 121、クラス 10、ユーザー 40 を含み、ID は全件保持
リポジトリで数えられる事実
以下の各項目は unile-go で照合できます。モジュール、テーブル、エンドポイント、機能項目。「完了したか」の判断は、これらの数字が動いたかどうかで行います。
セキュリティとコンプライアンスの実装ポイント
Unilearning がセキュリティとして具体的に何をし、境界をどこに引いたか。各項目に実装箇所を明記し、検証できるようにしています。
受講生用の問題取得インターフェースは answer / analysis を返しません。正解はクライアントに配布されません。
quiz ドメインの問題取得インターフェースドメイン横断では相手の api 契約だけを import でき、越境はドキュメントの違反ではなくコンパイル失敗になります。
Go の internal 機構local モードは bcrypt + JWT を内蔵。remote への切替で UIAM と接続し、他のドメインのコードは変更不要です。
auth ドメインの local / remoteドメインごとの方言マイグレーションファイル群。バージョンは DB 内に記録し、適用済みは自動スキップ、失敗時は巻き戻せます。
unile_migrations テーブルOSS STS 資格情報インターフェースが実際の AssumeRole に対応し、長期鍵のハードコードを避けます。
OSS STS インターフェース3 端ルート(uv1 / tv1 / admv1)の認証はすべて補完済み。旧版では一部ルートに認証がありませんでした。
edge 集約層データがどこで止まるか
データ境界は製品の形で決まり、気軽に切り替えられるスイッチではありません。これは4つの事業ラインに共通する判断です。
端末製品の最小境界です。この層のデータは設計上、アップロード経路を持ちません。スイッチで切っているわけではありません。
- legdger のすべての記帳データ:端末内で暗号化保存し、クラウドには暗号文のみ
- legdger の端末内 AI 集計と Q&A:推論はデバイス内で完結
- NewTool のデスクトップと wasm 形態:アルゴリズムカーネルに IO がなく、データはプロセスから出ない
- pxc のキャプチャトラフィック:カーネルは端末上で動作し、第三者サービスを経由しない
プライベート導入の境界です。モデル、ベクトル、業務データ、監査記録のすべてが顧客自身のネットワーク内に配備されます。
- Uniclaw の記憶と知識ベクトル:Milvus を自社構築し、社内網から出ない
- Uniclaw のモデルサービス:プライベート配備の互換プロトコルサービスに接続可能
- UIAM のアイデンティティと監査データ:全体が顧客のネットワーク境界内に配備され、完全なオフライン稼働も可能
- Uniscrm の素材とメディア:オブジェクトストレージは顧客自身の OSS に接続可能
- Unilearning の教材と学習記録:単一コンテナで提供し、データは顧客が掌握
外部ネットワークを必要とするのは同期と外部チャネルのみで、流れる内容は暗号文か、すでに匿名化されたメッセージです。
- legdger のデバイス間同期:最新の暗号文のみを送信し、サーバーは履歴を蓄積しない
- Uniscrm の WeCom チャネル:WeCom 公式インターフェースと通信し、公式のアーカイブ機能を利用
- Uniclaw のチャネル:Feishu / DingTalk の push API。内容はテナント単位で分離
- NewTool のリモート呼び出し:MCP 経由で伝送し、アルゴリズムカーネル自体はネットワーク要求を発行しない
会社レベルのセキュリティ原則
どの事業ラインにおいても、この6つは共通の譲れない一線です。
コンパイラ、フレームワーク、クエリ層に埋め込める制約は、ドキュメントに書いて人に覚えさせません。テナント分離はクエリ層のリスナーが強制し、ドメイン境界は Go の internal 機構がコンパイル時に拒否します。
jOOQ TenantScopeVisitListener · Go internal 墙機密データは既定でユーザーの端末、または顧客ネットワーク内に留まります。4 つの事業ラインすべてがプライベート導入に対応し、端末製品 legdger は AI 分析すらデバイスから出しません。
legdger 端侧 AI · Uniclaw 自建 Milvus · Unilearning 单容器エージェントが人間の資格情報を共有することはなく、サーバーは長期鍵をハードコードせず、端末からの接続は失効可能なトークンを使います。どの資格情報も、他の主体に影響を与えず単独で失効できます。
UIAM MACHINE 主体 · OSS STS AssumeRole · ledger-cli 令牌認証、認可、ツール呼び出し、キャプチャデバッグのすべてが構造化記録を生みます。コンプライアンスのためではなく、事故のときに再生できるようにするためです。
uiam-audit · collaboration-logger · pxc 会话记录委任関係は act claim で「誰が誰を代表するか」を表現し、権限はホップごとに積集合を取ります。監査では、どのユーザーがどのエージェントを認可し、どのツールを呼び、どの権限を使ったかまで答えられます。
RFC 8693 Token Exchange · agent_tools 注册表データベースの変更はバージョン管理されたマイグレーションで行い、再実行しても結果は同一です。アプリのリリースは単一イメージの差し替えで、ロールバックは前のイメージに戻すだけです。
Liquibase · 各域方言迁移 · Docker 单镜像デプロイと連携
すべてのプロダクトラインがプライベート導入に対応します。具体的な形態は製品ごとに異なります。
1 バイナリ、1 コンテナ。十数のコンテナが 1 になります。
- make docker && docker run -p 8080:8080
- GOWORK=off は各 go.mod の replace で解決
- 起動時に各ドメインのバージョン管理マイグレーションを自動実行
PostgreSQL を優先しつつ、MySQL も同様にサポートします。
- config.yaml の driver で二択
- マイグレーションは pg / mysql でディレクトリを分けて管理
- 17 項目のエンドツーエンドスモークが両データベースで通過
6 つの旧マイクロサービスからスムーズに切り替え。フロントエンドは変更不要です。
- uv1 / tv1 / admv1 のルートパスはフロントエンド互換を維持
- legacy-import が旧 DB を取り込み、ID は全件保持
- 既存ユーザーは bcrypt の元パスワードで直接ログイン
単独で動くことも、UIAM に任せることもできます。
- local モード:内蔵の bcrypt + JWT。外部依存ゼロ
- remote モード:auth 実装を差し替えるだけで UIAM と接続。他のドメインは変更不要
- 3 端ルートの認証はすべて補完済み(旧版では一部ルートに認証がなかった)
比較
同じことを、異なるやり方で。左欄が私たちの選択、右欄は一般的な代替案です。違いは通常機能表ではなく、境界をどこに引くかにあります。
誰が変化を感じるか
機能一覧では人は動きません。ロール視点が動かします。以下は、4種類のロールが接続前後で感じた実際の違いです。
研修は終わったのに、誰が本当に学び終えたのか、どこで躓いたのか分からない
学習進捗はアウトラインツリーに沿って自動集約。完了率と躓きポイントをリアルタイム照会できる
1 クラスに数十の課題。主観問題の採点は深夜に及び、漏れも出る
AI が採点ドラフトを生成し、教員は最終判断だけ。反復労働が大幅に減ります
動画の途中で切れると、続きの場所が分からず、進捗も合わない
4 種類の教材が進捗の扱いを統一し、途中再開に対応。アウトラインビューはリアルタイム同期
マイクロサービスの大量コンテナ。1 箇所の変更にクラスタ全体のローリングアップグレード
単一コンテナ提供。起動時に自動の冪等マイグレーション。ロールバックは前イメージへの差し戻し
バージョンとロードマップ
リリース済みは何を納品したか、開発中は何を進めているか、計画中は何をする予定かを明記します。リリース済みの項目が覆ることはありません。
v1.0リリース済み教学カーネル- 8 業務ドメインのモジュラーモノリス
- 講座ツリーと学習記録のバブリング
- 4 種類の教材と途中再開
- 問題バンクの構成と提出即採点
v1.1リリース済みAI と取引- 単票 / クラス一括の AI 採点
- オンラインストアと注文状態機械
- スレッド式コメントコミュニティ
- 旧システムの legacy-import
v1.3開発中学習体験- 学習経路のレコメンド
- 証明書と単位体系
- ライブ配信教材
- モバイルのオフライン学習
v2.0計画中マルチテナント- 多機関のマルチテナント分離
- オープン API とプラグインエコシステム
- 学習データ分析ダッシュボード
- UIAM との完全なフェデレーション
連携と接続対象
Unilearning がどの相手と、どの方式で接続するか。
優先方言。マイグレーションは pg ディレクトリで管理し、17 項目のスモークテストをすべて通過
同等サポート。業務クエリは双方言互換を維持
標準ライブラリのみで実装。GLM / DeepSeek / ローカル Ollama いずれも可
remote モードで auth 実装を差し替えるだけで接続完了。他のドメインは変更不要
教材とメディアリソース。実際の AssumeRole 一時資格情報に対応
旧 DB と旧アイデンティティ DB をワンクリック取り込み。ID 保持、元パスワードが使用可能
導入シーン
これらが実際の業務でどう使われるのか。
新入社員研修、コンプライアンス試験、職位認定を一本の経路に。
- 講座ツリーが研修アウトラインを編成
- 問題バンク試験がコンプライアンス評価を担う
- 学習進捗ダッシュボードが完了率を追跡
講座を売り、受講生を管理し、先生は課題を採点する。
- osm ストアが講座販売の閉ループを完成
- クラスと時間割で対面 / オンラインのクラスを管理
- AI 採点が教員の反復労働を軽減
1 人でも回せる講座ビジネスです。
- 単一コンテナ配備で運用コストは極小
- ストアと注文は最初から利用可能
- コメントコミュニティが受講生の交流を蓄積
すでに動いている旧基盤を、作り直さずに改善します。
- フロントエンドのルートパスは互換を維持
- 旧データはワンクリック取り込み、元パスワードがそのまま使える
- 移行はドメイン別に推進し、リスクは管理可能
よくある質問
旧システムは 6 つのマイクロサービスが HTTP + URL 設定で相互呼び出ししており、真のコストはサービス間呼び出しと配備の複雑さにありました。モジュラーモノリスは呼び出しをプロセス内の関数呼び出しに戻しつつ、Go の internal 機構でドメイン横断の import をコンパイルエラーにします。境界は lint や規律ではなく、コンパイラが守ります。
アイデンティティ・エージェント・プライベートドメインの複雑さを、統治可能なひとつのカーネルへ
既存の IAM の置き換え、エージェント基盤の構築、あるいはプライベートドメイン運用の本格化——まずは 30 分のアーキテクチャ相談から始めましょう。私たちが得意とする種類の問題かを先に判断し、適さない場合は率直にお伝えします。