以下のようなチャットアプリを作ろうと思っています。エージェントはVercelAI SDK ラッパーのMastraを使用。 --- 以下は、これまでの議論内容をすべて統合し、今後の拡張(請求書、契約書、見積書の各アーティファクツ対応)を見据えた、必要となりそうなデータ分析を踏まえたデータベーススキーマの詳細設計書のサンプルです。 --- ## 2. データベーススキーマ詳細設計 アプリ全体では、ユーザー、チャットセッション、各種アーティファクツ(文書)のデータ、バージョン管理、テンプレート情報、操作ログなどを管理します。以下は主なテーブルと各カラムの例です。 ### 2.1. Users テーブル | カラム名 | データ型 | 説明 | 制約・備考 | |-------------------|-----------------|---------------------------------------------------------|-------------------------------------| | user_id | UUID | ユーザーの一意識別子 | PRIMARY KEY | | username | VARCHAR(50) | ユーザー名 | NOT NULL, UNIQUE | | email | VARCHAR(100) | メールアドレス | NOT NULL, UNIQUE | | hashed_password | VARCHAR(255) | パスワードのハッシュ | NOT NULL | | role | VARCHAR(20) | ユーザーの権限(例:admin, user) | DEFAULT 'user' | | created_at | TIMESTAMP | アカウント作成日時 | DEFAULT CURRENT_TIMESTAMP | | updated_at | TIMESTAMP | 更新日時 | | ### 2.2. ChatSessions テーブル | カラム名 | データ型 | 説明 | 制約・備考 | |-------------------|-----------------|---------------------------------------------------------|-------------------------------------| | session_id | UUID | チャットセッションの一意識別子 | PRIMARY KEY | | user_id | UUID | ユーザーID(Usersテーブルへの外部キー) | FOREIGN KEY (user_id) | | chat_id | VARCHAR(50) | チャットID(画面上に表示する識別子) | UNIQUE, NOT NULL | | started_at | TIMESTAMP | セッション開始日時 | DEFAULT CURRENT_TIMESTAMP | | ended_at | TIMESTAMP | セッション終了日時(任意) | | | status | VARCHAR(20) | セッション状態(active, closedなど) | DEFAULT 'active' | ### 2.3. ChatMessages テーブル | カラム名 | データ型 | 説明 | 制約・備考 | |-------------------|-----------------|---------------------------------------------------------|-------------------------------------| | message_id | UUID | メッセージの一意識別子 | PRIMARY KEY | | session_id | UUID | チャットセッションID(ChatSessionsテーブルへの外部キー) | FOREIGN KEY (session_id) | | user_id | UUID | 発信者のユーザーID(システムメッセージの場合はNULL可) | FOREIGN KEY (user_id) | | message_content | TEXT | チャットメッセージの内容 | NOT NULL | | message_type | VARCHAR(20) | メッセージ種別(user, system, agent_response) | DEFAULT 'user' | | created_at | TIMESTAMP | メッセージ送信日時 | DEFAULT CURRENT_TIMESTAMP | ### 2.4. Artifacts テーブル(共通) 各文書(請求書、契約書、見積書)は、共通のArtifactsテーブルで管理し、タイプ別に分岐させることを想定します。 | カラム名 | データ型 | 説明 | 制約・備考 | |-------------------|-----------------|---------------------------------------------------------|-------------------------------------| | artifact_id | UUID | アーティファクトの一意識別子 | PRIMARY KEY | | user_id | UUID | 作成者のユーザーID | FOREIGN KEY (user_id) | | artifact_type | VARCHAR(20) | 文書のタイプ('invoice', 'contract', 'estimate' 等) | NOT NULL | | current_version_id| UUID | 現在のバージョン(ArtifactVersionsテーブルへの外部キー) | | | metadata | JSONB | 各種メタ情報(タイトル、説明、タグなど) | | | created_at | TIMESTAMP | アーティファクト作成日時 | DEFAULT CURRENT_TIMESTAMP | | updated_at | TIMESTAMP | 更新日時 | | ### 2.5. ArtifactVersions テーブル 各編集操作で生成されるバージョン情報を管理します。 | カラム名 | データ型 | 説明 | 制約・備考 | |-------------------|-----------------|---------------------------------------------------------|-------------------------------------| | version_id | UUID | バージョンの一意識別子 | PRIMARY KEY | | artifact_id | UUID | 関連するアーティファクトID(Artifactsテーブルへの外部キー)| FOREIGN KEY (artifact_id) | | version_number | INTEGER | バージョン番号(自動インクリメント) | NOT NULL | | artifact_data | JSONB | 編集時点の全体状態(Excelシートの構造、セル値、計算式など)| NOT NULL | | changes_summary | TEXT | 変更内容の概要(差分の説明など) | | | created_by | UUID | 編集を行ったユーザーID | FOREIGN KEY (user_id) | | created_at | TIMESTAMP | バージョン作成日時 | DEFAULT CURRENT_TIMESTAMP | ### 2.6. テンプレート(Templates)テーブル ユーザーまたはシステムがアップロードする各文書用テンプレートを管理します。 | カラム名 | データ型 | 説明 | 制約・備考 | |-------------------|-----------------|---------------------------------------------------------|-------------------------------------| | template_id | UUID | テンプレートの一意識別子 | PRIMARY KEY | | user_id | UUID | アップロード者のユーザーID(システム標準テンプレートの場合はNULL可) | FOREIGN KEY (user_id) | | artifact_type | VARCHAR(20) | 対象文書のタイプ('invoice', 'contract', 'estimate') | NOT NULL | | file_path | VARCHAR(255) | テンプレートファイルの保存パスまたはストレージ参照情報 | NOT NULL | | template_metadata | JSONB | テンプレートに関するメタ情報(レイアウト、必須項目など) | | | created_at | TIMESTAMP | テンプレート登録日時 | DEFAULT CURRENT_TIMESTAMP | | updated_at | TIMESTAMP | 更新日時 | | ### 2.7. 請求書専用テーブル(InvoiceDetails) 請求書文書固有の詳細情報を管理します。※Artifacts テーブルの artifact_type が 'invoice' の場合に紐づくと想定。 | カラム名 | データ型 | 説明 | 制約・備考 | |-------------------|-----------------|---------------------------------------------------------|-------------------------------------| | invoice_id | UUID | 請求書固有のID(Artifacts.artifact_idと1:1) | PRIMARY KEY, FOREIGN KEY (artifact_id) | | invoice_number | VARCHAR(50) | 請求書番号 | NOT NULL, UNIQUE | | issue_date | DATE | 発行日 | NOT NULL | | due_date | DATE | 支払い期限 | NOT NULL | | customer_name | VARCHAR(100) | 顧客名 | NOT NULL | | customer_address | TEXT | 顧客住所 | | | items | JSONB | 請求項目リスト(各項目:説明、数量、単価、合計金額等) | NOT NULL | | subtotal | DECIMAL(12,2) | 小計 | NOT NULL | | tax | DECIMAL(12,2) | 税額 | NOT NULL | | total_amount | DECIMAL(12,2) | 請求合計金額 | NOT NULL | | status | VARCHAR(20) | ステータス(draft, sent, paid, overdue 等) | DEFAULT 'draft' | | created_at | TIMESTAMP | 作成日時 | DEFAULT CURRENT_TIMESTAMP | | updated_at | TIMESTAMP | 更新日時 | | ### 2.8. 契約書専用テーブル(ContractDetails) 契約書文書固有の詳細情報を管理します。 | カラム名 | データ型 | 説明 | 制約・備考 | |-------------------|-----------------|---------------------------------------------------------|-------------------------------------| | contract_id | UUID | 契約書固有のID(Artifacts.artifact_idと1:1) | PRIMARY KEY, FOREIGN KEY (artifact_id) | | contract_number | VARCHAR(50) | 契約番号 | NOT NULL, UNIQUE | | start_date | DATE | 契約開始日 | NOT NULL | | end_date | DATE | 契約終了日 | NOT NULL | | parties_involved | JSONB | 契約当事者リスト(各当事者の名称、連絡先等) | NOT NULL | | terms | TEXT | 契約条件(詳細な条項) | NOT NULL | | contract_value | DECIMAL(12,2) | 契約金額 | NOT NULL | | status | VARCHAR(20) | ステータス(draft, active, terminated など) | DEFAULT 'draft' | | created_at | TIMESTAMP | 作成日時 | DEFAULT CURRENT_TIMESTAMP | | updated_at | TIMESTAMP | 更新日時 | | ### 2.9. 見積書専用テーブル(EstimateDetails) 見積書文書固有の詳細情報を管理します。 | カラム名 | データ型 | 説明 | 制約・備考 | |-------------------|-----------------|---------------------------------------------------------|-------------------------------------| | estimate_id | UUID | 見積書固有のID(Artifacts.artifact_idと1:1) | PRIMARY KEY, FOREIGN KEY (artifact_id) | | estimate_number | VARCHAR(50) | 見積書番号 | NOT NULL, UNIQUE | | valid_until | DATE | 有効期限 | NOT NULL | | customer_name | VARCHAR(100) | 顧客名 | NOT NULL | | items | JSONB | 見積項目リスト(各項目:説明、数量、単価、合計金額等) | NOT NULL | | subtotal | DECIMAL(12,2) | 小計 | NOT NULL | | tax | DECIMAL(12,2) | 税額 | NOT NULL | | total_amount | DECIMAL(12,2) | 合計金額 | NOT NULL | | status | VARCHAR(20) | ステータス(draft, approved, rejected 等) | DEFAULT 'draft' | | created_at | TIMESTAMP | 作成日時 | DEFAULT CURRENT_TIMESTAMP | | updated_at | TIMESTAMP | 更新日時 | | ### 2.10. ActivityLogs テーブル(分析・運用用) ユーザー操作やシステム内の重要なアクションのログを記録し、ダッシュボードでのデータ分析や将来的なレポート作成に活用します。 | カラム名 | データ型 | 説明 | 制約・備考 | |-------------------|-----------------|---------------------------------------------------------|-------------------------------------| | log_id | UUID | ログの一意識別子 | PRIMARY KEY | | user_id | UUID | 操作を行ったユーザーID(Usersテーブルへの外部キー) | FOREIGN KEY (user_id) | | action | VARCHAR(100) | 実行されたアクション名(例:'upload_template', 'chat_command', 'artifact_update' など) | NOT NULL | | details | JSONB | アクションの詳細情報(変更内容、対象IDなどの追加情報) | | | timestamp | TIMESTAMP | ログ記録日時 | DEFAULT CURRENT_TIMESTAMP | --- ## 3. まとめ 本設計書では、以下のポイントを詳細に定義しています。 - **ディレクトリ構成** - `/app` 配下に `/chat`, `/dashboard`, `/setting` というルートを設けるとともに、文書タイプ別(請求書、契約書、見積書)のアーティファクツ用ディレクトリを配置。 - 共通コンポーネント、APIエンドポイント、ユーティリティなども分離し、今後の機能追加や保守性向上を図る。 - **データベーススキーマ** - ユーザー、チャットセッション、チャットメッセージの基本テーブルに加え、各種文書(アーティファクツ)の共通管理テーブルと、請求書、契約書、見積書それぞれの詳細情報テーブルを用意。 - 各編集操作に対するバージョン管理(ArtifactVersions テーブル)や、テンプレート管理、システムログ・分析用のテーブルも詳細に設計。 この設計により、各文書タイプごとの将来的な機能拡張、リアルタイムな編集・バージョン管理、またダッシュボードでのデータ分析まで網羅した、堅牢かつ拡張性の高いシステムを実現することが可能となります。 --- MastraとVercel AI SDKを活用して、階層的なAIエージェントフレームワークを設計し、請求書や契約書などの文書生成を自然言語で制御できるシステムを構築する手順を以下に示します。 ## 1. AIエージェントの階層構造設計 オーケストレーター(Orchestrator)とワーカー(Worker)の2層構造を採用します。オーケストレーターはユーザーからの自然言語入力を解析し、適切なワーカーを呼び出します。ワーカーは特定のタスク(例:請求書生成)を専門的に処理します。 ### オーケストレーターの役割 - **ユーザー入力の解析**:自然言語処理を用いてユーザーの意図を理解します。 - **ワーカーの選択と呼び出し**:解析結果に基づき、適切なワーカーを選択し、必要なパラメータを渡して呼び出します。 ### ワーカーの役割 - **タスクの実行**:特定の文書生成やデータ処理を行います。 - **結果の返却**:処理結果をオーケストレーターに返します。 ## 2. Mastraを用いたエージェントの実装 MastraはTypeScriptベースのAIエージェントフレームワークで、ワークフロー、エージェント、RAG(Retrieval-Augmented Generation)、統合、評価などの機能を提供します。 citeturn0search16 ### オーケストレーターの実装例 ```typescript import { Agent } from 'mastra'; const orchestrator = new Agent({ name: 'Orchestrator', instructions: 'ユーザーの入力を解析し、適切なワーカーを呼び出します。', model: openai('gpt-4o'), tools: [invoiceWorker, contractWorker, estimateWorker], memory, }); ``` ### ワーカーの実装例(請求書生成) ```typescript const invoiceWorker = new Agent({ name: 'InvoiceWorker', instructions: '請求書を生成します。', model: openai('gpt-4o'), tools: [generateInvoice], memory, }); ``` ## 3. Vercel AI SDKを用いたクライアント・サーバー間の状態管理 Vercel AI SDKは、AIを活用したユーザーインターフェイスの構築に役立つツールで、Server-Sent Events(SSE)を使ってChatGPTのようにテキストをパラパラ表示するUIを簡単に実装できます。 citeturn0search7 ### クライアントサイドでの状態管理 `useChat`フックを使用して、チャットの状態を管理します。 ```typescript 'use client'; import { useChat } from 'ai/react'; export default function ChatComponent() { const { messages, input, handleSubmit, handleInputChange } = useChat(); return ( <div> {messages.map((message) => ( <div key={message.id}> <div>{message.role}</div> <div>{message.content}</div> </div> ))} <form onSubmit={handleSubmit}> <input value={input} onChange={handleInputChange} /> <button type="submit">送信</button> </form> </div> ); } ``` ### サーバーサイドでの状態管理 `streamText`関数を使用して、サーバーからのストリーミングレスポンスを管理します。 ```typescript import { streamText } from 'ai'; import { openai } from '@ai-sdk/openai'; export async function POST(req: Request) { const { messages } = await req.json(); const result = streamText({ model: openai('gpt-4o'), system: 'あなたは役立つアシスタントです。', messages, }); return result.toDataStreamResponse(); } ``` ## 4. Structured Outputを用いた請求書内容の生成 Vercel AI SDKの`generateObject`関数を使用して、Zodスキーマに一致する構造化オブジェクトを生成します。 citeturn0search7 ```typescript import { generateObject } from 'ai'; import { z } from 'zod'; const invoiceSchema = z.object({ invoiceNumber: z.string(), issueDate: z.string(), dueDate: z.string(), customerName: z.string(), items: z.array( z.object({ description: z.string(), quantity: z.number(), unitPrice: z.number(), total: z.number(), }) ), subtotal: z.number(), tax: z.number(), totalAmount: z.number(), }); const { object: invoice } = await generateObject({ model: openai('gpt-4o'), schema: invoiceSchema, prompt: '請求書の内容を生成してください。', }); ``` ## 5. 自然言語によるAIツールの制御 ユーザーが「請求書を作成したい」と入力した場合、オーケストレーターがその意図を解析し、請求書生成ワーカーを呼び出します。これにより、自然言語での指示に基づいて適切なAIツールが実行されます。 この設計により、MastraとVercel AI SDKを組み合わせて、階層的なAIエージェントフレームワークを構築し、自然言語での制御が可能なシステムを実現できます。 それではバックエンドのmastraは別で構築するのでまずはフロントエンドをステップバイステップで作成してください。コンポーネントは細分化して管理しやすくすること。
Loading...
Loading...