# AI Agent 系統
## 系統分析文件(SA Document)
| 欄位 | 內容 |
| ------------------ | -------------- |
| **文件版本** | v2 |
| **撰寫日期** | 2026-03-06 |
| **負責單位** | 機構設計整合部 |
| **系統代號** | MEC-AI |
| **機密等級** | 機構內部文件 |
---
## 目錄
1. [專案背景與目標](#1-專案背景與目標)
2. [系統架構](#3-系統架構設計)
3. [業務流程分析](#7-關鍵流程設計)
4. [技術選型分析](#4-技術選型分析)
5. [資料庫設計](#5-資料庫設計)
6. [API 規格設計](#6-api-規格設計)
7. [前端設計規格](#8-前端設計規格)
8. [MCP 工具設計](#9-mcp-工具設計)
9. [安全設計](#10-安全設計)
10. [離線環境部署指南](#11-離線環境部署指南)
11. [專案結構與開發計畫](#12-專案結構與開發計畫)
12. [可替代/降級策略](#13-可替代降級策略)
13. [待調查事項與後續建議](#14-待調查事項與後續建議)
14. [附錄:Mermaid 圖例清單](#15-附錄mermaid-圖例清單)
---
---
## 1. 專案概述
### 1.1 專案背景
機構設計整合部的研發同仁日常以 SolidWorks、CATIA 等 CAD 軟體進行機構設計作業,需頻繁查閱指令手冊、功能說明及教育訓練資料。現有資料散落於各處文件,查閱效率低落,且無法支援自然語言提問。
本系統目標是在**完全離線的內網環境**中,建構一套以 AI Agent 為核心的知識輔助系統,部署於研發同仁的 OA 筆電,向量資料庫部署於 Remote Server。
## 1.2 專案目標
| 目標 | 說明 |
| ----------------- | ----------------------------------------------- |
| 📖 CAD 知識問答 | 自然語言查詢 CAD 指令、快捷鍵、操作步驟 |
| 📁 知識庫管理 | 批次匯入技術文件(PDF/Word/圖片)並自動向量化 |
| 🔧 MCP 工具整合 | 透過 MCP 協議整合 CAD 工具與專家知識 |
| 🔒 資料在地化 | 所有資料與運算皆留存於機構內網,不外傳 |
| 🛠️ 可維護可擴展 | 全開源技術棧,任何具備 Python 基礎的人員可維護 |
## 1.3 核心功能
### FR-01:多輪對話問答
- 使用者可透過桌面應用程式與 AI Agent 進行自然語言對話,無需登入
- 支援上下文記憶,多輪對話保持脈絡
- 支援串流輸出,逐字顯示回應以降低等待感
### FR-02:CAD 工具輔助
- Agent 可自動識別 CAD 相關查詢,並呼叫對應工具取得專業回應
- 涵蓋指令名稱、功能說明、操作步驟與快捷鍵查詢
### FR-03:知識庫 RAG 問答
- 匯入的技術文件可透過語意搜尋供 Agent 引用
- 回答附帶引用來源(文件名稱、頁碼)
### FR-04:多模態輸入
- Agent 可接收使用者上傳的圖片,分析圖片內容並結合知識庫回答
### FR-05:稽核日誌
- 所有操作(對話、文件匯入、系統設定變更)皆記錄至稽核日誌,便於稽核追蹤
---
## 2. 系統架構設計
### 2.1 整體架構
02_architecture_system.mmd
### 2.2 元件說明
#### 2.2.1 Client Layer(研發繪圖筆電)
#### 前端
| 技術 | 版本 | 用途 | 選擇理由 |
| ----------- | ------ | -------------- | --------------------------------------- |
| React | 18 | 前端介面框架 | 組件生態成熟,TypeScript 型別安全支援佳 |
| TypeScript | 5.x | 前端靜態型別 | 提升程式碼可維護性並減少執行期錯誤 |
| Vite | 5.x | 前端建置工具 | 極速 HMR,開發體驗優於 Webpack |
| TailwindCSS | 3.x | 前端樣式框架 | Utility-first 設計,快速建構一致 UI |
| shadcn/ui | latest | 前端 UI 元件庫 | 無綁定設計系統,可完全自訂的 Radix 元件 |
#### 後端
| 技術 | 版本 | 用途 | 選擇理由 |
| ---------------------- | ------ | ------------------- | ------------------------------------------------- |
| FastAPI Service | | | |
| Python | 3.11 | 後端執行環境 | 穩定 LTS 版本,AI/ML 生態系最完整 |
| FastAPI | 0.111+ | 後端 API 框架 | 原生 async/await,自動產生 OpenAPI 文件 |
| Uvicorn | 0.29+ | ASGI 伺服器 | 高效能 async HTTP,配合 FastAPI 的最佳選擇 |
| Agent | | | |
| LangGraph | 0.3+ | Agent 狀態機引擎 | 以圖結構管理多步 Agent 流程,支援 Checkpoint |
| LangChain | 0.3+ | LLM 整合框架 | 統一 LLM/Tool/Memory 介面,生態豐富 |
| langchain-community | 0.3+ | LangChain 社群擴充 | 提供 PDF loader、文件處理器等現成工具 |
| langchain-postgres | 0.0.x | PGVector 整合 | 官方維護的 PostgreSQL 向量儲存 LangChain 整合 |
| langchain-mcp-adapters | latest | MCP 工具整合 | 橋接 MCP 協定與 LangChain Agent 工具介面 |
| llama.cpp Server | | | |
| llama.cpp server | latest | LLM 本地推理引擎 | MIT 授權、輕量單執行檔、GGUF 量化支援最完整 |
| 模型 | | | |
| Qwen2.5-VL | 7B | 對話 + 視覺語言模型 | 中文能力強,支援圖文多模態,7B 可在 4GB VRAM 執行 |
| nomic-embed-text | - | Embedding | 高品質,繁中支援良好,MIT 授權 |
##### MCP Tools
| 技術 | 版本 | 用途 | 選擇理由 |
| ------- | ------ | -------------- | ----------------------------------------- |
| mcp SDK | latest | MCP 伺服器通訊 | 官方 MCP Python SDK,提供標準工具呼叫協定 |
#### 2.2.2 Server Layer(整合部專用伺服器)
#### 資料庫
| 技術 | 版本 | 用途 | 選擇理由 |
| ---------- | ---- | ----------------------- | ----------------------------------------------- |
| PostgreSQL | 16 | 關聯式資料庫 + 向量儲存 | 單一資料庫同時承擔結構化資料與向量搜尋 |
| pgvector | 0.7+ | 向量搜尋擴充 | PostgreSQL 原生向量索引,無需額外向量資料庫服務 |
| SQLAlchemy | 2.0 | ORM 框架 | 成熟 ORM,支援 async 模式與 Alembic 遷移整合 |
| Alembic | 1.x | 資料庫遷移管理 | SQLAlchemy 官方遷移工具,版本控制 schema 變更 |
#### 文件匯入
| 技術 | 版本 | 用途 | 選擇理由 |
| ------------- | ------ | ----------------- | ----------------------------------------- |
| pymupdf4llm | latest | PDF 解析 | 將 PDF 直接轉為 LLM 友好的 Markdown 格式 |
| unstructured | 0.14+ | 非結構化文件解析 | 支援多種文件格式的統一解析介面 |
| Tesseract OCR | 5.x | 圖片 OCR 文字識別 | 開源 OCR 引擎,支援中文識別,離線完整運作 |
| Pillow | 10.x | 圖片前處理 | 輕量圖片處理庫,用於 OCR 前的影像預處理 |
---
## 3. **業務流程分析**
本章依系統業務範疇,由整體到局部依序說明各主要流程的步驟、決策點與相關元件。
---
### 3.0 整體業務流程總覽
本系統為部署於研發繪圖筆電的**桌面應用程式**,使用者啟動應用程式後即可直接使用,無需登入認證。系統涵蓋兩大業務主線:**使用者對話**為核心高頻路徑,**知識庫文件匯入**為後台維運路徑(由管理人員定期執行)。
**各流程對應章節一覽**
| 編號 | 業務流程 | 涉及主要元件 | 對應小節 |
| ---- | ----------------------------- | ------------------------------------------------ | -------- |
| 3.1 | 對話主流程(整體) | Desktop App → FastAPI → LangGraph Agent → LLM | §3.1 |
| 3.2 | 意圖分類與工具路由 | LangGraph `classify_intent` 節點 | §3.2 |
| 3.3 | RAG 知識檢索流程 | pgvector、Reranker、Context 壓縮 | §3.3 |
| 3.4 | CAD 工具呼叫流程 | MCP Server `cad_command_query` | §3.4 |
| 3.5 | 視覺分析流程 | Qwen2.5-VL + RAG 混合 | §3.5 |
| 3.6 | Context 管理與 Token 預算控制 | `manage_context`、`AsyncPostgresSaver` | §3.6 |
| 3.3 | 批次文件匯入與向量化流程 | 排程執行 `document_import.py` → pgvector | §3.3 |
| 3.8 | 稽核日誌記錄流程 | `audit_logs` 資料表 | §3.8 |
---
### 3.1 對話主流程
使用者啟動桌面應用程式後,直接在 `ChatWindow` 輸入問題(可附帶圖片)。系統以 Server-Sent Events(SSE)串流方式逐字回傳 LLM 回應,回應完成後附帶引用文件來源。
> 流程圖:`docs/diagrams/03_flowchart_chat_main.mmd`
#### SSE 事件格式
| 事件類型 | 說明 | 範例 |
| ----------- | ------------------------- | ------------------------------------------------------------------------ |
| `token` | 每一個輸出 token | `{"type":"token","content":"要"}` |
| `sources` | 引用文件來源列表 | `{"type":"sources","documents":[{"filename":"SW手冊.pdf","page":42}]}` |
| `done` | 完成訊號,附帶 session_id | `{"type":"done","session_id":"550e8400-..."}` |
| `error` | 發生錯誤時推送 | `{"type":"error","message":"..."}` |
---
### 3.2 意圖分類與工具路由
`classify_intent` 節點根據使用者輸入的語意特徵與是否含有圖片,決定後續應呼叫哪一條工具路徑。
> 流程圖:`docs/diagrams/03_flowchart_intent_classify.mmd`
#### 意圖分類規則
| 意圖類別 | 觸發條件 | 後續路徑 |
| ------------ | --------------------------------------------------------------------------- | --------------------------------- |
| `cad_tool` | 問句包含「指令」「快捷鍵」「操作步驟」「功能」等關鍵詞,且指向特定 CAD 動作 | → §3.4 CAD 工具呼叫 |
| `rag` | 問句涉及「如何」「說明」「什麼是」「教學」等,需要文件知識 | → §3.3 RAG 知識檢索 |
| `vision` | `image_base64` 非空(使用者上傳了圖片) | → §3.5 視覺分析(可再銜接 RAG) |
| `general` | 一般問候、閒聊、簡單計算等,不需要外部資料 | → 直接 `generate_response` |
> **複合意圖**:`cad_tool` 與 `rag` 可同時啟動——MCP 工具取得結構化指令資料後,可進一步由 RAG 補充說明文件,兩者輸出合併後再送入 LLM。
---
### 3.3 RAG 知識檢索流程
RAG 流程以多層策略從 pgvector 知識庫取回最相關的文件片段,並在送入 LLM 前完成品質篩選與 token 預算控制。
> 流程圖:`docs/diagrams/03_flowchart_rag_retrieval.mmd`
#### RAG 核心策略說明
| 策略 | 說明 | 實作方式 |
| ------------------------------------------ | --------------------------------------------- | ----------------------------------------------------------- |
| **Standard RAG(分塊檢索)** | 對長文件進行 chunking,向量搜尋取相關片段 | `RecursiveCharacterTextSplitter` + pgvector |
| **Pre-retrieval 篩選** | 以 metadata 縮小檢索範圍,避免無關文件干擾 | `rag_retrieve` 節點前置條件 + SQLite `pre_filter_index` |
| **Post-retrieval Rerank** | 對 top-k 召回片段進行語意重排 | Cross-encoder 評分(`rerank_node`) |
| **Contextual Compression** | 壓縮召回內容,精確控制送入 LLM 的 token 量 | `compress_context` 節點(`langextract` 類工具) |
| **Multi-turn / Iterative Retrieval** | 複雜問題採多輪迭代檢索與 query 重寫 | LangGraph 迴圈邊(conditional loop) |
| **Self-RAG** | Agent 自我評估召回結果品質,決定是否重新檢索 | `assess_retrieval` 評估節點 |
| **GraphRAG(進階,選用)** | 知識圖結構,支援多跳推理(複雜 CAD 關聯分析) | NetworkX 知識圖 + pgvector 混合搜尋 |
#### Prompt 組裝與輸出
成功完成檢索後,將以下資訊組裝為最終 Prompt:
- **召回片段**:Rerank+壓縮後的文件段落
- **MCP Skill 輸出**(若 `cad_tool` 與 `rag` 複合觸發)
- **對話歷史**:`manage_context` 處理後的 context window
LLM 回應完成後,記錄引用來源(文件名稱、頁碼)與信心度,一併以 SSE `sources` 事件推送給前端。
---
### 3.4 CAD 工具呼叫流程
當意圖為 `cad_tool` 時,LangGraph 透過 MCP Client 呼叫 CAD Tools MCP Server(Port 8100),取得結構化的指令資料。
> 流程圖:`docs/diagrams/03_flowchart_cad_tool.mmd`
#### MCP 工具清單
| 工具名稱 | 說明 | 必填參數 |
| ----------------------- | --------------------------------------------- | ------------------------- |
| `cad_command_query` | 查詢 CAD 指令名稱、快捷鍵、操作步驟與功能說明 | `software`、`keyword` |
| `cad_shortcut_lookup` | 查詢 CAD 軟體特定動作的鍵盤快捷鍵 | `software`、`action` |
---
### 3.5 視覺分析流程
當使用者上傳圖片時(`image_base64` 非空),系統以 Qwen2.5-VL 視覺語言模型分析圖片,並可選擇性地結合 RAG 補充知識庫資料。
> 流程圖:`docs/diagrams/03_flowchart_vision.mmd`
---
### 3.6 Context 管理與 Token 預算控制
每一輪 LLM 呼叫前,`manage_context` 節點負責確保送入 LLM 的 context 不超過 token 上限,並根據剩餘預算動態決定 RAG 的 `top_k` 值。對話狀態以 `AsyncSqliteSaver` 持久化至 Client 本機 SQLite,支援應用程式重新啟動後恢復對話。
> 流程圖:`docs/diagrams/03_flowchart_context_mgmt.mmd`
#### SQLite 本機快取整合
在 `rag_retrieve` 節點執行前,先查詢 Client 端 SQLite 的 `pre_filter_index` 快取:
| 情況 | 處理方式 |
| --------------------------- | ---------------------------------------------------------- |
| 快取命中(TTL 未過期) | 直接使用本機 doc_ids,減少遠端 pgvector 查詢成本 |
| 快取未命中或 TTL 過期 | 向 Server 端 pgvector 執行完整向量搜尋,結果非同步寫回快取 |
| Server 無法連線(離線模式) | 使用最後一次快取結果(降級模式),待連線恢復後批次同步 |
---
### 3.3 批次文件匯入與向量化流程
知識庫文件由管理員透過**排程自動執行**的獨立匯入程式(`document_import.py`)維護,定期掃描 Server 端指定目錄,逐檔完成解析、切分、Embedding 並寫入 pgvector。此程式不依賴 FastAPI 服務,可獨立排程執行(如 Windows 工作排程器 / Linux cron)。
> 流程圖:`docs/diagrams/03_flowchart_batch_import.mmd`
#### 觸發方式
| 方式 | 說明 |
| ------------------------------ | --------------------------------------------------------- |
| **排程自動執行**(主要) | 由 Windows 工作排程器或 cron 定期觸發,例如每日凌晨 02:00 |
| **手動執行**(需要時) | 管理員於 Server 端直接執行 `python document_import.py` |
#### 支援的文件格式
| 格式 | 解析工具 | 備註 |
| --------------- | ----------------------- | ---------------------------------------- |
| PDF | `pymupdf`(安全模式) | 支援純文字 PDF 與帶圖 PDF;防止 PDF 注入 |
| Word(.docx) | `python-docx` | 提取段落與表格文字 |
| Markdown(.md) | 直接讀取 | 保留結構標記 |
| 純文字(.txt) | 直接讀取 | — |
---
### 3.8 稽核日誌記錄流程
所有會改變系統狀態的操作,均會在操作完成後非同步寫入 `audit_logs` 資料表,不阻塞主要業務流程。
> 流程圖:`docs/diagrams/03_flowchart_audit_log.mmd`
#### 觸發寫入的操作清單
| 操作類別 | 具體事件 | 記錄欄位 |
| -------- | --------------------------- | --------------------------------- |
| 對話 | 建立 Conversation、傳送訊息 | session_id, action, timestamp |
| 文件 | 批次匯入啟動、完成、失敗 | job_id, action, detail, timestamp |
| 管理 | 系統設定變更、MCP 工具異動 | action, detail, timestamp |
---
## 4. Use Case 分析
### 4.1 Use Case Diagram
01_use_case.mmd
---
### 4.2 核心功能清單
| UC-ID | Use Case 名稱 | 主要 Actor |
| ----- | ---------------- | ---------- |
| UC-01 | 自然語言多輪對話 | 研發同仁 |
| UC-02 | CAD 指令查詢 | 研發同仁 |
| UC-03 | RAG 知識庫問答 | 研發同仁 |
| UC-04 | 視覺圖片分析 | 研發同仁 |
| UC-05 | 對話歷史管理 | 研發同仁 |
| UC-06 | 批次文件匯入 | 管理員 |
| UC-07 | 系統狀態監控 | 管理員 |
---
## 5. 資料庫設計
> **Remote(PostgreSQL 16 + pgvector)**:部署於整合部 Server,儲存知識庫向量索引與批次匯入任務狀態。
> **Client(SQLite)**:部署於研發繪圖筆電,儲存對話歷史、訊息紀錄、稽核日誌與 LangGraph 狀態。
> ORM:**SQLAlchemy 2.0**(Async 模式)
### 5.1 資料表清單
#### Remote(PostgreSQL 16,整合部 Server)
| 資料表 | 說明 |
| ------------------ | ------------------------------------------ |
| `documents` | 匯入文件的元資料(檔名、狀態、統計) |
| `document_chunks` | 向量化後的文件段落(含 pgvector 向量欄位) |
| `batch_jobs` | 批次匯入任務狀態追蹤(排程程式維護) |
#### Client(SQLite,研發繪圖筆電)
| 資料表 | 說明 |
| ----------------------- | --------------------------------------------- |
| `conversations` | 對話工作階段(Session)紀錄 |
| `messages` | 每則對話訊息(含 Agent 中間步驟) |
| `audit_logs` | 所有操作的稽核紀錄 |
| `langgraph_checkpoints` | LangGraph 對話狀態 Checkpoint(框架自動管理) |
### 5.2 資料表詳細定義
---
#### (Remote PostgreSQL)`documents`
- **目的**:記錄批次匯入文件的元資料,包含檔名、類型、儲存路徑、處理狀態(`pending` `processing` `completed` / `failed`)及分段數量統計。
- **關聯**:一個文件對應多筆 `document_chunks`(向量段落);由 Remote 排程匯入程式寫入,無使用者外鍵。
```sql
CREATE TABLE documents (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
filename VARCHAR(512) NOT NULL,
file_type VARCHAR(32) NOT NULL, -- 'pdf' | 'docx' | 'md' | 'txt' | 'image'
file_path TEXT NOT NULL,
file_size INTEGER NOT NULL, -- bytes
status VARCHAR(32) NOT NULL DEFAULT 'pending',
-- 'pending' | 'processing' | 'completed' | 'failed'
chunk_count INTEGER DEFAULT 0,
metadata JSONB DEFAULT '{}', -- 自訂標籤、分類等
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
```
#### (Remote PostgreSQL)`document_chunks`(核心向量表)
- **目的**:將文件切分後的段落與對應 768 維向量(`nomic-embed-text`)一起存放,為 RAG 檢索的核心資料來源;支援文字、圖片描述、表格等多種段落類型。
- **關聯**:`document_id` `documents`(ON DELETE CASCADE);以 HNSW 索引(`vector_cosine_ops`)加速 pgvector 餘弦相似度搜尋。
```sql
-- 需先啟用 pgvector:CREATE EXTENSION IF NOT EXISTS vector;
CREATE TABLE document_chunks (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
document_id UUID NOT NULL REFERENCES documents(id) ON DELETE CASCADE,
content TEXT NOT NULL,
embedding VECTOR(768), -- nomic-embed-text 維度為 768
chunk_index INTEGER NOT NULL,
page_number INTEGER,
chunk_type VARCHAR(32) DEFAULT 'text', -- 'text' | 'image_description' | 'table'
metadata JSONB DEFAULT '{}',
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
-- 向量相似度索引(HNSW,適合中小型資料集)
CREATE INDEX idx_doc_chunks_embedding
ON document_chunks
USING hnsw (embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 64);
CREATE INDEX idx_doc_chunks_document_id ON document_chunks(document_id);
```
#### (Remote PostgreSQL)`batch_jobs`
- **目的**:追蹤 Remote 端排程批次文件匯入任務的執行狀態,記錄總檔案數、已處理數、失敗數及錯誤明細,供管理員查閱。
- **關聯**:與 `documents` 為間接關係(批次任務產生多筆文件記錄,透過應用層對應)。
```sql
CREATE TABLE batch_jobs (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
status VARCHAR(32) NOT NULL DEFAULT 'pending',
-- 'pending' | 'processing' | 'completed' | 'failed'
source_path TEXT NOT NULL,
total_files INTEGER NOT NULL DEFAULT 0,
processed_files INTEGER NOT NULL DEFAULT 0,
failed_files INTEGER NOT NULL DEFAULT 0,
error_log JSONB DEFAULT '[]',
started_at TIMESTAMPTZ,
completed_at TIMESTAMPTZ,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
```
---
#### (Client SQLite)`conversations`
- **目的**:記錄對話工作階段(Session),可儲存自訂 `system_prompt` 以調整 Agent 行為;儲存於 Client 本機 SQLite,無需登入即可使用。
- **關聯**:一個對話包含多則 `messages`。
```sql
CREATE TABLE conversations (
id TEXT PRIMARY KEY, -- UUID 字串(SQLite 無原生 UUID)
title TEXT NOT NULL DEFAULT '新對話',
system_prompt TEXT,
created_at TEXT NOT NULL DEFAULT (datetime('now')),
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
);
```
#### (Client SQLite)`messages`
- **目的**:儲存對話中每一則訊息,角色涵蓋 `user`、`assistant`、`system`、`tool`;`metadata` 欄位可附加 RAG 引用來源、工具呼叫結果等附加資訊;儲存於 Client 本機 SQLite。
- **關聯**:`conversation_id` `conversations`(ON DELETE CASCADE);以 `conversation_id` 與 `created_at` 建立索引加速查詢。
```sql
CREATE TABLE messages (
id TEXT PRIMARY KEY,
conversation_id TEXT NOT NULL REFERENCES conversations(id) ON DELETE CASCADE,
role TEXT NOT NULL, -- 'user' | 'assistant' | 'system' | 'tool'
content TEXT NOT NULL,
metadata TEXT DEFAULT '{}', -- JSON 字串,含引用來源、工具呼叫結果
created_at TEXT NOT NULL DEFAULT (datetime('now'))
);
CREATE INDEX idx_messages_conversation_id ON messages(conversation_id);
CREATE INDEX idx_messages_created_at ON messages(created_at);
```
#### (Client SQLite)`audit_logs`
- **目的**:記錄本機操作行為(對話建立、文件匹配觸發、系統設定變更等),提供稽核追蹤;儲存於 Client 本機 SQLite,無使用者外鍵。
- **關聯**:獨立資料表,無外鍵依賴。
```sql
CREATE TABLE audit_logs (
id TEXT PRIMARY KEY,
action TEXT NOT NULL, -- 'chat', 'upload', 'delete', etc.
resource_type TEXT,
resource_id TEXT,
details TEXT DEFAULT '{}', -- JSON 字串
created_at TEXT NOT NULL DEFAULT (datetime('now'))
);
CREATE INDEX idx_audit_logs_created_at ON audit_logs(created_at);
```
### 5.3 向量搜尋查詢範例
```sql
-- RAG 檢索:以 query_embedding 搜尋最相似的 5 個文件段落
SELECT
dc.content,
dc.metadata,
d.filename,
dc.page_number,
1 - (dc.embedding <=> $1::vector) AS similarity
FROM document_chunks dc
JOIN documents d ON dc.document_id = d.id
WHERE d.status = 'completed'
ORDER BY dc.embedding <=> $1::vector
LIMIT 5;
```
---
## 6. API 規格設計
> Base URL: `http://localhost:8000/api/v1`(Client 本機服務)
> 認證方式:無需登入,無 Token
> 回應格式:`Content-Type: application/json`
### 6.0 API 總覽
| 編號 | API 端點 | Method | 操作 | 說明 | 對應資料表 |
| ----- | ------------------------------------- | ------ | ---------------- | ------------------------------------------ | ---------------------------------------------------------- |
| 6.2.1 | `/chat/stream` | POST | 串流對話 | SSE 串流回傳 AI 回應,支援圖片輸入 | `conversations`, `messages`, `langgraph_checkpoints` |
| 6.2.2 | `/chat/conversations` | GET | 取得對話列表 | 查詢本機所有對話工作階段 | `conversations` |
| 6.2.3 | `/chat/conversations/{id}/messages` | GET | 取得對話訊息 | 查詢指定對話的所有訊息紀錄 | `messages` |
| 6.3.2 | `/documents/batch-import` | POST | 批次匯入 | 指定伺服器本地資料夾路徑進行批次匯入 | `documents`, `document_chunks`, `batch_jobs` |
| 6.3.3 | `/documents/batch-jobs/{job_id}` | GET | 查詢批次任務狀態 | 查詢批次匯入任務的進度與錯誤狀況 | `batch_jobs` |
| 6.4.1 | `/admin/system-status` | GET | 系統狀態 | 查詢 llama.cpp、資料庫、MCP 工具的運行狀態 | `documents`, `document_chunks`, `mcp_tools` |
---
#### `POST /chat/stream` — 串流對話(Server-Sent Events)
```json
// Request
{
"session_id": "550e8400-...", // 可選,不傳則建立新對話
"message": "SolidWorks 如何建立曲面特徵?",
"image_base64": null // 可選,含圖片時帶入 base64
}
// Response (SSE stream)
data: {"type": "token", "content": "要"}
data: {"type": "token", "content": "在"}
data: {"type": "token", "content": "SolidWorks"}
...
data: {"type": "sources", "documents": [{"filename": "SW手冊.pdf", "page": 42}]}
data: {"type": "done", "session_id": "550e8400-..."}
```
#### `GET /chat/conversations` — 取得對話列表
```json
// Response 200
{
"conversations": [
{
"id": "550e8400-...",
"title": "SolidWorks 曲面特徵詢問",
"updated_at": "2026-03-03T10:30:00Z",
"message_count": 5
}
],
"total": 12,
"page": 1
}
```
#### `GET /chat/conversations/{id}/messages` — 取得對話訊息
```json
// Response 200
{
"messages": [
{
"id": "...",
"role": "user",
"content": "SolidWorks 如何建立曲面特徵?",
"created_at": "2026-03-03T10:30:00Z"
},
{
"id": "...",
"role": "assistant",
"content": "要在 SolidWorks 建立曲面特徵...",
"metadata": {
"sources": [{"filename": "SW手冊.pdf", "page": 42}],
"tool_used": "rag"
},
"created_at": "2026-03-03T10:30:05Z"
}
]
}
```
---
### 6.3 Document API
#### `POST /documents/upload` — 單一文件上傳
```
// Request (multipart/form-data)
Content-Type: multipart/form-data
file: <binary>
metadata: {"category": "SolidWorks", "tags": ["曲面", "特徵"]}
// Response 202
{
"document_id": "550e8400-...",
"filename": "SW曲面特徵手冊.pdf",
"status": "processing",
"job_id": "job-uuid"
}
```
#### `POST /documents/batch-import` — 批次匯入(資料夾路徑,伺服器本地路徑)
```json
// Request
{
"source_path": "D:\\documents\\cad_manuals\\",
"file_extensions": ["pdf", "docx", "md"],
"metadata": {"category": "CAD手冊"}
}
// Response 202
{
"job_id": "batch-job-uuid",
"total_files": 23,
"status": "processing"
}
```
#### `GET /documents/batch-jobs/{job_id}` — 查詢批次任務狀態
```json
// Response 200
{
"job_id": "batch-job-uuid",
"status": "processing",
"total_files": 23,
"processed_files": 10,
"failed_files": 1,
"progress_percent": 43,
"estimated_completion": "2026-03-03T10:45:00Z"
}
```
---
### 6.4 Admin API
#### `GET /admin/system-status` — 系統狀態
```json
// Response 200
{
"llama_cpp": {
"status": "running",
"models": [
{"name": "qwen2.5-vl:7b", "size_gb": 4.4, "loaded": true},
{"name": "nomic-embed-text", "size_gb": 0.3, "loaded": true}
]
},
"database": {
"status": "connected",
"document_count": 145,
"chunk_count": 8230
},
"mcp_tools": [
{"name": "cad_command_query", "status": "running"}
]
}
```
#### `GET /admin/tools` — MCP 工具清單
```json
// Response 200
{
"tools": [
{
"name": "cad_command_query",
"description": "查詢 CAD 軟體的指令、快捷鍵與操作步驟",
"server_url": "http://localhost:8100",
"is_active": true,
"parameters": {
"software": "string (solidworks|catia|autocad)",
"keyword": "string"
}
}
]
}
```
---
## 8. 前端設計規格
### 8.1 頁面架構
```
/ 主頁面(重新導向至 /chat)
/chat 對話主頁
/chat/:id 特定對話工作階段
/documents 文件管理頁
```
### 8.2 主要元件
| 元件 | 說明 |
| -------------------------------- | ------------------------------------------ |
| `<ChatWindow />` | 對話主要介面,支援串流輸出顯示 |
| `<MessageItem />` | 單則訊息,支援 Markdown 渲染、引用來源顯示 |
| `<Sidebar />` | 對話歷史清單 |
---
## 9. MCP 工具設計
### 9.1 MCP 架構說明
MCP(Model Context Protocol)是 Anthropic 制定的開放協議,用於讓 LLM 呼叫外部工具。LangGraph 透過 `langchain-mcp-adapters` 套件整合 MCP Server,使 Agent 可動態呼叫工具。
### 9.2 CAD Tools MCP Server(Port 8100)
**MCP Server 設計規格**(`backend/mcp_servers/cad_tools/server.py`):
- Server 名稱:`"cad-tools"`,以 `mcp.server.Server` 建立實例
- 實作兩個 handler:`list_tools()`(回傳工具清單及 JSON Schema)與 `call_tool()`(依工具名稱路由至對應查詢邏輯)
**工具清單(Tools)**:
| 工具名稱 | 說明 | 必填參數 |
| ----------------------- | --------------------------------------------------- | ------------------------------------------------------------------------------------- |
| `cad_command_query` | 查詢 CAD 軟體的指令名稱、快捷鍵、操作步驟與功能說明 | `software`(`solidworks` \| `catia` \| `autocad`)、`keyword`(指令關鍵字) |
| `cad_shortcut_lookup` | 查詢 CAD 軟體的鍵盤快捷鍵 | `software`、`action`(動作名稱) |
### 9.3 LangGraph 中的 MCP 整合
**MCP Client 整合規格**(`backend/app/mcp/client.py`):
- 使用 `langchain-mcp-adapters` 的 `MultiServerMCPClient`,支援同時連接多個 MCP Server
- 連線設定格式:`{ server_name: { url: str, transport: str } }`,`transport` 使用 `"streamable_http"`
- `client.get_tools()` 自動將所有 MCP Tools 轉換為 `LangChain BaseTool` 格式
- 轉換後的工具可直接注入 LangGraph Agent 節點,無需額外包裝
---
## 10. 安全設計
### 10.1 認證與授權
| 機制 | 說明 |
| ---------------------------- | ------------------------------------------------------------------------------------------------------- |
| **JWT Token** | 登入後取得 JWT,每個 API 請求需帶入 `Authorization: Bearer <token>` |
| **Token 有效期** | 預設 8 小時,可在 `config.py` 中調整 |
| **密碼儲存** | 使用 `passlib[bcrypt]` 進行 hash,不儲存明文密碼 |
| **角色控制** | `user` 可對話與上傳文件;`admin` 額外可管理使用者與系統設定 |
### 10.2 輸入安全
| 威脅 | 防護措施 |
| ----------------------------------- | ----------------------------------------------------------- |
| **Prompt Injection** | System Prompt 明確限制 Agent 行為範圍;使用者輸入與指令分開 |
| **路徑穿越攻擊** | 批次匯入路徑僅允許管理員操作,且限制在白名單目錄內 |
| **超大檔案** | API 層限制上傳檔案大小(預設 50MB) |
| **惡意 PDF** | 使用 pymupdf 的安全模式解析,避免 PDF 注入 |
### 10.3 稽核日誌
以下操作都會寫入 Client 機本的 `audit_logs` 資料表:
- 對話建立、訊息傳送
- 文件匹配觸發(RAG 检索)
- 系統設定變更、MCP 工具異動
### 10.4 資料隔離
- 對話紀錄儲存於 Client 本機 SQLite,筆電間自然隔離,無跨機器資料決漏風險
- 向量知識庫(Remote PostgreSQL)為全域共享(機構內部知識庫),不限制特定使用者
### 10.5 網路與 TLS 安全
| 機制 | 說明 |
| -------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **內網隔離** | FastAPI 服務(Port 8000)與 llama.cpp server(Port 8080)在 Client 端本機執行,僅供筆電本機存取;不對外廣播 |
| **TLS(內部 CA)** | 建議以機構內部 CA 簽發 HTTPS 憑證,加密 Client ↔ PostgreSQL 通訊 |
| **端點最小開放** | Client 端防火牆僅開放 Port 8000(API,供 Browser 存取);Port 8080(llama.cpp server)限制為 localhost;Server 端 Port 5432(PostgreSQL)限制為內網,不對外開放 |
### 10.6 備份與加密策略
| 項目 | 策略 |
| --------------------------------- | ----------------------------------------------------------------------------------------------- |
| **資料庫備份** | 每日排程執行 `pg_dump mechdesign_ai > backup_YYYYMMDD.sql`,保留 30 天 |
| **向量資料備份** | `document_chunks` 向量欄位隨 `pg_dump` 一併備份,恢復時重新建立 HNSW 索引 |
| **原始文件備份** | `D:\mechdesign-ai\storage\documents\` 目錄定期複製至備援硬碟 |
| **磁碟加密(選用)** | 視機構安全規範,可對伺服器磁碟啟用 BitLocker 加密 |
| **欄位加密(選用)** | 高敏感欄位可加入 SQLAlchemy 欄位層加密 |
---
## 11. 離線環境部署指南
> 📌 所有軟體需預先下載至安裝媒介(USB 隨身碟),在離線環境中安裝。
> 📌 本指南假設作業系統為 **Windows 11**(Client 端與 Server 端皆適用)。
> 📌 **部署分工**:PostgreSQL 安裝於 Server 端(整合部專用伺服器);llama.cpp、FastAPI、LangGraph、MCP Servers、前端皆安裝於 **Client 端(研發繪圖筆電)**。
### 11.1 Server 端安裝步驟(PostgreSQL)
#### Step 1:安裝 PostgreSQL 16
1. 下載 [PostgreSQL 16 Windows 安裝檔](https://www.postgresql.org/download/windows/)(`.exe`)
2. 安裝時設定:
- Port: `5432`
- 超級使用者密碼:建議使用強密碼
3. 安裝完成後,以 psql 啟用 pgvector:
```sql
-- 以 postgres 超級使用者連入
CREATE DATABASE mechdesign_ai;
\c mechdesign_ai
CREATE EXTENSION IF NOT EXISTS vector;
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
```
4. 安裝 pgvector Windows 版本:下載 [pgvector releases](https://github.com/pgvector/pgvector/releases) 的 Windows 二進位包,複製 `.dll` 至 PostgreSQL 的 `lib` 目錄,複製 `.control` 和 `.sql` 至 `share/extension` 目錄。
---
### 11.2 Client 端安裝步驟(研發繪圖筆電)
#### Step 1:安裝 Python 3.11
1. 下載 [Python 3.11 Windows 安裝檔](https://www.python.org/downloads/windows/)
2. 安裝時勾選「Add Python to PATH」
3. 確認安裝:`python --version`
#### Step 2:安裝 llama.cpp server
1. 從 [llama.cpp GitHub Releases](https://github.com/ggml-org/llama.cpp/releases) 下載 Windows 預編譯二進位包(`llama-*-bin-win-cuda*.zip`)
2. 解壓縮至目標目錄(如 `D:\llama.cpp\`)
3. 匯入模型(需在有網路的機器預先下載 GGUF 格式):
```powershell
# 有網路環境下載模型(使用 huggingface-cli 或直接下載 .gguf 檔)
# 例:Qwen2.5-VL-7B-Instruct-Q4_K_M.gguf
# 複製 .gguf 檔至離線機器的 D:\models\ 目錄
```
4. 啟動 llama.cpp server(監聽所有 IP):
```powershell
# 在系統服務或開機腳本中執行
D:\llama.cpp\llama-server.exe `
--model D:\models\qwen2.5-vl-7b-q4_k_m.gguf `
--ctx-size 8192 --n-gpu-layers 35 `
--host 0.0.0.0 --port 8080 --parallel 4
```
#### Step 3:安裝 Node.js(前端建構用)
1. 下載 [Node.js LTS](https://nodejs.org/)(v20+)
2. 確認安裝:`node --version`
#### Step 4:安裝後端 Python 依賴
```powershell
# 在有網路的環境先下載所有套件
pip download -r requirements.txt -d ./offline_packages
# 在離線環境安裝
pip install --no-index --find-links=./offline_packages -r requirements.txt
```
**`requirements.txt`**:
```
fastapi
uvicorn[standard]
langchain
langgraph
langchain-community
langchain-openai
langchain-postgres
langchain-mcp-adapters
mcp
psycopg[binary,pool]
pgvector
sqlalchemy
alembic
pymupdf4llm
unstructured[pdf]
pillow
python-multipart
python-jose[cryptography]
passlib[bcrypt]
pydantic-settings
httpx
python-dotenv
```
#### Step 5:設定環境變數並初始化資料庫
```powershell
# 設定環境變數 .env(DATABASE_URL 指向 Server 端 PostgreSQL IP)
DATABASE_URL=postgresql+psycopg://postgres:yourpassword@<Server-IP>:5432/mechdesign_ai
LLAMA_CPP_BASE_URL=http://localhost:8080
SECRET_KEY=your-32-char-secret-key-here
CHAT_MODEL=qwen2.5-vl:7b
EMBED_MODEL=nomic-embed-text
STORAGE_PATH=D:\mechdesign-ai\storage
# 執行資料庫初始化
python scripts/init_db.py
```
#### Step 6:設定 Windows 服務自動啟動
使用 NSSM(Non-Sucking Service Manager)將後端服務設定為 Windows 服務:
```powershell
# 下載 NSSM,然後:
nssm install MechDesignAI-Backend "python" "-m uvicorn app.main:app --host 0.0.0.0 --port 8000"
nssm set MechDesignAI-Backend AppDirectory "D:\mechdesign-ai\backend"
nssm start MechDesignAI-Backend
# MCP Servers 同理
nssm install MechDesignAI-CAD-MCP "python" "mcp_servers/cad_tools/server.py"
nssm start MechDesignAI-CAD-MCP
```
#### Step 7:建構前端
```powershell
cd D:\mechdesign-ai\frontend
# 離線安裝前端依賴(需預先下載 node_modules)
npm install --offline
# 建構生產版本
npm run build
# dist/ 目錄即為靜態網頁,可由 FastAPI 提供靜態服務
# 或設定 Nginx 提供服務
```
---
### 11.3 客戶端(繪圖筆電)日常使用方式
完成 11.2 節安裝後,日常使用僅需啟動以下服務後開啟瀏覽器:
```powershell
# 1. llama.cpp server 與 FastAPI 已設為 Windows 服務(開機自動啟動)
# 2. 在瀏覽器開啟:
http://localhost:8000
# 或從其他筆電透過 IP 存取(需開放 Port 8000):
http://<Client-筆電-IP>:8000
```
> 建議使用 Chrome 或 Edge 最新版本。
---
### 11.4 設定防火牆
#### Client 端(研發繪圖筆電)防火牆設定
| Port | 用途 |
| ---- | ------------------------------------------------------------ |
| 8000 | FastAPI(主要 API 服務,允許內網其他筆電存取) |
| 8080 | llama.cpp server(推理服務,**限 localhost,不對外**) |
| 8100 | CAD MCP Server(**限 localhost,不對外**) |
#### Server 端(整合部專用伺服器)防火牆設定
| Port | 用途 |
| ---- | ------------------------------------------------------------ |
| 5432 | PostgreSQL(**僅限內網 Client 筆電存取,不對外開放**) |
---
## 12. 專案結構與開發計畫
### 12.1 專案目錄結構
```
mechdesign-ai/
├── backend/
│ ├── app/
│ │ ├── __init__.py
│ │ ├── main.py # FastAPI 應用入口
│ │ ├── config.py # 設定(從 .env 讀取)
│ │ ├── api/
│ │ │ ├── deps.py # 依賴注入(JWT 驗證、DB Session)
│ │ │ └── v1/
│ │ │ ├── auth.py # 認證 API
│ │ │ ├── chat.py # 對話 API(含 SSE 串流)
│ │ │ ├── documents.py # 文件管理 API
│ │ │ └── admin.py # 管理 API
│ │ ├── agent/
│ │ │ ├── graph.py # LangGraph 狀態機定義
│ │ │ ├── nodes.py # 各節點函數實作
│ │ │ ├── state.py # AgentState TypedDict
│ │ │ └── prompts.py # System Prompts
│ │ ├── rag/
│ │ │ ├── retriever.py # pgvector 向量搜尋
│ │ │ └── chunker.py # 文字分塊邏輯
│ │ ├── ingestion/
│ │ │ ├── pdf_processor.py # PDF 解析(含視覺描述)
│ │ │ └── batch_importer.py # 批次匯入排程
│ │ ├── mcp/
│ │ │ └── client.py # MCP Client 初始化
│ │ ├── services/
│ │ │ └── llama_cpp_service.py # llama.cpp API 封裝
│ │ └── models/
│ │ ├── database.py # SQLAlchemy ORM 模型
│ │ └── schemas.py # Pydantic Request/Response
│ ├── mcp_servers/
│ │ └── cad_tools/
│ │ ├── server.py # CAD Tools MCP Server
│ │ └── cad_data/
│ │ ├── solidworks.json # SolidWorks 指令資料庫
│ │ ├── catia.json
│ │ └── autocad.json
│ ├── migrations/
│ │ └── init.sql # 初始化 SQL 腳本
│ ├── scripts/
│ │ ├── setup_windows.ps1 # Windows 一鍵環境設定腳本
│ │ ├── init_db.py # 資料庫初始化
│ │ └── batch_import.py # CLI 批次匯入工具
│ ├── .env.example # 環境變數範本
│ └── requirements.txt
├── frontend/
│ ├── src/
│ │ ├── App.tsx
│ │ ├── components/
│ │ │ ├── ChatWindow.tsx
│ │ │ ├── MessageItem.tsx
│ │ │ ├── ImageUpload.tsx
│ │ │ ├── DocumentList.tsx
│ │ │ ├── BatchImportForm.tsx
│ │ │ └── Sidebar.tsx
│ │ ├── pages/
│ │ │ ├── Chat.tsx
│ │ │ ├── Documents.tsx
│ │ │ └── Admin.tsx
│ │ └── api/
│ │ ├── client.ts # axios/fetch 基礎設定
│ │ ├── chat.ts
│ │ └── documents.ts
│ ├── package.json
│ └── vite.config.ts
└── docs/
├── SA文件_機構設計AI_Agent系統.md ← 本文件
└── diagrams/
├── 01_use_case.mmd
├── 02_uml_class.mmd
├── 03_database_schema.mmd
├── 04_sequence_rag.mmd
└── 05_sequence_upload.mmd
```
### 12.2 開發階段規劃
#### M1(第 0–2 週):需求確認與環境準備
- 明確 Client 與 Remote 的資源預算、network policy 與驗證方式
- Client 端環境安裝:llama.cpp server + Python 虛擬環境 + Node.js
- Server 端環境安裝:PostgreSQL 16 + pgvector
- 評估並在測試環境安裝 Foundry Local / LM Studio CLI,比較推理效能與 API 相容性
- FastAPI 框架搞建:骨架 API、Task Queue(DB table 實作)
- LangGraph Agent 基礎版(單輪問答,無 RAG)
- 資料庫 Schema 建立,Alembic 遷移管理
- **交付物**:可問答的基礎 API 服務
#### M2(第 3–6 週):文件匯入服務與批次上傳
- PDF 解析服務(pymupdf4llm + Tesseract OCR 掃描文件支援)
- 圖片視覺描述(Qwen2.5-VL),描述合併回 Markdown
- 文字分塊(RecursiveCharacterTextSplitter,chunk_size=512, overlap=64)
- Embedding 向量化(nomic-embed-text)並批次寫入 pgvector
- 完成 `POST /documents/upload` 與 `POST /documents/batch-import`
- 批次任務進度追蹤 `GET /documents/batch-jobs/{job_id}`
- **交付物**:可查詢內部文件的 RAG 問答 API(90% 批次成功率)
#### M3(第 7–10 週):RAG Pipeline 與 MCP/Skill 框架
- RAG 向量搜尋整合至 LangGraph(含 Pre-retrieval 篩選與 Post-retrieval Rerank)
- CAD Tools MCP Server 開發(SolidWorks 指令資料庫)
- CATIA、AutoCAD 指令資料庫建置
- LangGraph MCP 工具呼叫節點、意圖分類路由完整實作
- Client Local Agent Runtime 基礎版(SQLite 快取、MCP 工具清單 Metadata 管理)
- **交付物**:完整 Agent(RAG + MCP 工具選用)
#### M4(第 11–14 週):多模態支援與上下文策略
- 圖像 Embedding 支援(CLIP 或 Qwen2.5-VL 作為多模態 Encoder)
- React 對話介面、串流輸出顯示、圖片上傳功能
- 文件管理頁面(上傳、批次匯入、狀態追蹤)、系統管理頁面
- 上下文管理驗證(Pre/Post Retrieval、Iterative Retrieval、Self-RAG)
- 評估 `langextract` 類工具作為 token 濃縮步驟
- **交付物**:完整前後端整合版本
#### M5(第 15–18 週):安全性、備份與文件化
- TLS(內部 CA)設定、網路隔離確認
- 備份策略落地(pg_dump 排程、原始文件備份)
- 整合測試(各流程端到端)、效能調優
- Windows 一鍵部署腳本 `setup_windows.ps1`
- 使用者說明文件、部署手冊
- **交付物**:可交付的完整系統
### 12.3 里程碑概覽
| 里程碑 | 週次 | 說明 |
| ---------------- | -------- | ------------------------------------------------- |
| M1:環境就緒 | W0–W2 | llama.cpp server + PostgreSQL + pgvector 基礎問答 |
| M2:RAG 問答可用 | W3–W6 | 文件上傳、向量化、OCR、RAG 對話 |
| M3:Agent 完整 | W7–W10 | MCP 工具整合、多模態支援、Local Agent Runtime |
| M4:前端完整 | W11–W14 | UI 全功能、上下文管理策略驗證 |
| M5:正式部署 | W15–W18 | 安全設定、備份、測試通過,離線環境部署完成 |
---
Comments...
No Comments Yet...