AI Agent 系統
系統開發文件
專案名稱: AI Agent 系統
版本: 4.0
日期: 2026-03-17
撰寫人: 張書銘(David_Chang)
───────────────────────────────────────────────────────────────────────
目錄
- 專案背景與目標
- 系統架構 (含需開發的模組)
- 業務流程分析
- Use case分析
- 資料庫設計
- API 規格設計
- 前端設計規格
- MCP 工具設計
- 安全設計
- 離線環境部署指南
- 專案結構
1. 專案概述
1.1 專案背景
機構設計整合部的研發同仁日常以 SolidWorks、CATIA 等 CAD 軟體進行機構設計作業,需頻繁查閱指令手冊、功能說明及教育訓練資料。現有資料散落於各處文件,查閱效率低落,且無法支援自然語言提問。
本系統目標是在完全離線的內網環境中,建構一套以 AI Agent 為核心的知識輔助系統,部署於研發同仁的 OA 筆電,向量資料庫部署於 Remote Server。
1.2 專案目標
|
目標 |
說明 |
|
📖 CAD 知識問答 |
自然語言查詢 CAD 指令、快捷鍵、操作步驟 |
|
📁 知識庫管理 |
批次匯入技術文件(PDF/Word/圖片)並自動向量化 |
|
🔧 MCP 工具整合 |
透過 MCP 協議整合 CAD 工具與專家知識 |
|
🔒 資料在地化 |
所有資料與運算皆留存於機構內網,不外傳 |
|
🛠️ 可維護可擴展 |
全開源技術棧,任何具備 Python 基礎的人員可維護 |
1.3 專案範圍-核心功能
2. 系統架構設計
2.1 整體架構
2.2 需開發的模組
2.2.1 Client端
前端
|
技術 |
用途 |
選擇理由 |
|
React |
前端介面框架 |
組件生態成熟,TypeScript 型別安全支援佳 |
|
TypeScript |
前端靜態型別 |
提升程式碼可維護性並減少執行期錯誤 |
|
Vite |
前端建置工具 |
極速 HMR,開發體驗優於 Webpack |
|
React Router |
路由管理 |
宣告式路由、巢狀路由支援 |
|
Axios |
HTTP 請求 |
攔截器支援、自動轉換JSON |
後端
|
技術 |
用途 |
選擇理由 |
|
Python |
後端執行環境 |
穩定 LTS 版本,AI/ML 生態系最完整 |
|
FastAPI |
後端 API 框架 |
原生 async/await,自動產生 OpenAPI 文件 |
|
Uvicorn |
ASGI 伺服器 |
高效能 async HTTP,配合 FastAPI 的最佳選擇 |
|
LangGraph |
Agent 狀態機引擎 |
以圖結構管理多步 Agent 流程,支援 Checkpoint;負責多輪對話狀態與條件路由 |
|
LangChain |
RAG / LLM 整合框架 |
提供 RAG Chain(檢索→壓縮→生成)、LLM-as-Judge 品質評估、統一工具介面 |
|
langchain-community |
LangChain 社群擴充(RAG 文件載入) |
PyMuPDFLoader、UnstructuredLoader 等文件載入器,用於 RAG 索引管線 |
|
langchain-postgres |
PGVector 向量儲存(RAG 檢索) |
官方維護的 PostgreSQL 向量儲存 LangChain 整合,封裝 pgvector 相似度搜尋 |
|
langchain-mcp-adapters |
MCP 工具整合 |
橋接 MCP 協定與 LangChain Agent 工具介面 |
|
llama.cpp server |
LLM 本地推理引擎 |
MIT 授權、輕量單執行檔、GGUF 量化支援最完整 |
|
SQLite |
對話記錄、快取、MCP metadata |
零依賴;輕量;適合單機場景 |
|
Qwen3.5:9b |
對話語言模型 / 推理 |
Qwen 3.5,混合 Thinking Mode(可 toggle),推理與中文表現優於 Qwen2.5 |
|
nomic-embed-text |
Embedding, 274MB |
高品質,繁中支援良好,MIT 授權 |
|
BAAI/bge-reranker-v2-m3 |
Reranker 模型, 2.27GB |
推薦選用,繁中效果佳,MIT 授權 |
對話 LLM 模型選擇
|
模型 |
量化版本 |
預估 VRAM |
Size |
|
Qwen3.5:9b |
Q4_K_M |
~7.28 GB |
5.68GB |
|
Qwen3.5:4b |
Q4_K_M |
~3.85 GB |
2.74GB |
|
Qwen3.5:2b |
Q4_K_M |
~2.44GB |
1.28GB |
MCP Tools
|
技術 |
用途 |
選擇理由 |
|
mcp SDK |
MCP 伺服器通訊 |
官方 MCP Python SDK,提供標準工具呼叫協定 |
2.2.2 Remote端
文件匯入排程
|
技術 |
用途 |
選擇理由 |
|
pymupdf4llm |
PDF 解析 |
將 PDF 直接轉為 LLM 友好的 Markdown 格式 |
|
unstructured |
非結構化文件解析 |
支援多種文件格式的統一解析介面 |
|
Tesseract OCR |
圖片 OCR 文字識別 |
開源 OCR 引擎,支援中文識別,離線完整運作 |
|
Pillow |
圖片前處理 |
輕量圖片處理庫,用於 OCR 前的影像預處理 |
2.2.3 其他元件
資料庫
|
技術 |
用途 |
選擇理由 |
|
PostgreSQL |
關聯式資料庫 + 向量儲存 |
單一資料庫同時承擔結構化資料與向量搜尋 |
|
pgvector |
向量搜尋擴充 |
PostgreSQL 原生向量索引,無需額外向量資料庫服務 |
|
SQLAlchemy |
ORM 框架 |
成熟 ORM,支援 async 模式與 Alembic 遷移整合 |
|
Alembic |
資料庫遷移管理 |
SQLAlchemy 官方遷移工具,版本控制 schema 變更 |
開發工具 (Development Tools)
|
技術 |
版本 |
用途 |
選擇理由 |
|
Git |
latest |
版本控制 |
將 PDF 直接轉為 LLM 友好的 Markdown 格式 |
|
Jenkins/GitLab CI |
0.14+ |
CI/CD 自動化 |
支援多種文件格式的統一解析介面 |
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 autocad-mcp(AutoCAD 自動化) |
§3.4 |
|
3.5 |
Context 管理與 Token 預算控制 |
manage_context、AsyncPostgresSaver |
§3.5 |
|
3.6 |
批次文件匯入與向量化流程 |
排程執行 document_import.py → pgvector |
§3.6 |
|
3.7 |
稽核日誌記錄流程 |
audit_logs 資料表 |
§3.7 |
3.1 對話主流程
3.2 意圖分類與工具路由
3.3 RAG 知識檢索流程
RAG 實作框架
|
層次 |
框架 / 元件 |
責責 |
|
序列化 / 切分 |
LangChain RecursiveCharacterTextSplitter |
文件分塊與內容清理 |
|
Embedding + 檢索 |
llama.cpp nomic-embed-text + langchain-postgres (pgvector) |
向量化與 pgvector 余弦相似度搜尋 |
|
RAG Chain |
LangChain RunnablePassthrough + PromptTemplate |
檢索→壓縮→生成 pipeline 組裝 |
|
Reranker |
LangChain CrossEncoderReranker(sentence-transformers) |
Post-retrieval 語意重排 |
|
品質評估 |
LangChain LLM-as-Judge(assess_retrieval 節點) |
Self-RAG 檢索品質判斷 |
|
多輪迭代 |
LangGraph Conditional Edges + should_continue 迴圈邊 |
複雜問題多輪檢索,自動重寫 query |
|
狀態持久化 |
LangGraph AsyncSqliteSaver |
對話 Checkpoint,支援機器重啟復原 |
RAG 核心策略說明
|
策略 |
說明 |
實作方式 |
|
Standard RAG(分塊檢索) |
對長文件進行 chunking,向量搜尋取相關片段 |
RecursiveCharacterTextSplitter + pgvector |
|
Pre-retrieval 篩選 |
以 metadata 縮小檢索範圍,避免無關文件干擾 |
rag_retrieve 節點前置條件 + SQLite pre_filter_index |
|
Post-retrieval Rerank |
對 top-k 召回片段進行語意重排 |
LangChain CrossEncoderReranker(sentence-transformers) |
|
Contextual Compression |
壓縮召回內容,精確控制送入 LLM 的 token 量 |
LangChain LLMChainExtractor / compress_context 節點 |
|
Multi-turn / Iterative Retrieval |
複雜問題採多輪迭代檢索與 query 重寫 |
LangGraph Conditional Edges(should_continue 迴圈) |
|
Self-RAG |
Agent 自我評估召回結果品質,決定是否重新檢索 |
LangChain LLM-as-Judge,assess_retrieval 評估節點 |
|
GraphRAG(進階,選用) |
知識圖結構,支援多跳推理(複雜 CAD 關聯分析) |
NetworkX 知識圖 + pgvector 混合搜尋 |
3.4 CAD 工具呼叫流程
3.5 Context 管理與 Token 預算控制
3.6 批次文件匯入與向量化流程
3.7 稽核日誌記錄流程
4. Use Case 分析
4.1 Use Case Diagram
4.2 核心功能清單
|
UC-ID |
Use Case 名稱 |
主要 Actor |
|
UC-01 |
自然語言多輪對話 |
研發同仁 |
|
UC-02 |
CAD 指令查詢 |
研發同仁 |
|
UC-03 |
RAG 知識庫問答 |
研發同仁 |
|
UC-04 |
對話歷史管理 |
研發同仁 |
|
UC-05 |
批次文件匯入 |
管理員 |
|
UC-06 |
系統狀態監控 |
管理員 |
5. 資料庫設計
資料庫引擎:PostgreSQL 16 + pgvector 擴充套件 ORM:SQLAlchemy 2.0(Async 模式)
5.1 Schema 總覽
|
資料表 |
所在端 |
主鍵型別 |
關聯 |
負責模組 |
說明 |
|
documents |
Remote |
UUID |
→document_chunks (1:N) |
document-import |
匯入文件的元資料(檔名、狀態、統計) |
|
document_chunks |
Remote |
UUID |
FK documents |
document-import |
向量化後的文件段落(含 pgvector 向量欄位) |
|
batch_jobs |
Remote |
UUID |
獨立 |
document-import |
批次匯入任務狀態追蹤(排程程式維護) |
|
conversations |
Client |
TEXT(UUID) |
→messages (1:N) |
backend |
對話工作階段(Session)紀錄 |
|
messages |
Client |
TEXT(UUID) |
FK conversations |
backend |
每則對話訊息(含 Agent 中間步驟) |
|
audit_logs |
Client |
TEXT(UUID) |
獨立 |
backend |
所有操作的稽核紀錄 |
|
langgraph_checkpoints |
Client |
框架管理 |
獨立 |
backend (LangGraph) |
LangGraph 對話狀態 Checkpoint(框架自動管理) |
5.2 資料表詳細定義
(Remote PostgreSQL)documents
- 目的:記錄批次匯入文件的元資料,包含檔名、類型、儲存路徑、處理狀態(pending processing completed / failed)及分段數量統計。
- 關聯:一個文件對應多筆 document_chunks(向量段落);由 Remote 排程匯入程式寫入,無使用者外鍵。
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 餘弦相似度搜尋。
-- 需先啟用 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 為間接關係(批次任務產生多筆文件記錄,透過應用層對應)。
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。
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 建立索引加速查詢。
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,無使用者外鍵。
- 關聯:獨立資料表,無外鍵依賴。
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 向量搜尋查詢範例
-- 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 |
6.2 Chat API
POST /chat/stream — 串流對話(Server-Sent Events)
// 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 — 取得對話列表
// 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 — 取得對話訊息
// 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/batch-import — 批次匯入(資料夾路徑,伺服器本地路徑)
// 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} — 查詢批次任務狀態
// 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 — 系統狀態
// Response 200
{
"llama_cpp": {
"status": "running",
"models": [
{"name": "qwen3.5:9b", "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 工具清單
// 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"
}
}
]
}
7. 前端設計規格
7.1 頁面架構
/ 主頁面(重新導向至 /chat)
/chat 對話主頁
/chat/:id 特定對話工作階段
/documents 文件管理頁
7.2 主要元件
|
元件 |
說明 |
|
<ChatWindow /> |
對話主要介面,支援串流輸出顯示 |
|
<MessageItem /> |
單則訊息,支援 Markdown 渲染、引用來源顯示 |
|
<Sidebar /> |
對話歷史清單 |
8. MCP 工具設計
8.1 MCP 架構說明
MCP(Model Context Protocol)是 Anthropic 制定的開放協議,讓 LLM 透過標準化介面呼叫外部工具。puran-water/autocad-mcp 為MCP 工具伺服器,負責對 AutoCAD 執行自動化操作(繪圖、圖層、區塊、標注等)。
LangGraph 透過 langchain-mcp-adapters 套件整合 MCP Server,使 Agent 可動態呼叫工具。
8.2 AutoCAD MCP Server(開源採用 — puran-water/autocad-mcp)
工具清單
|
工具類別 |
主要操作(File IPC / ezdxf) |
說明 |
|
drawing |
create, open, save, save_as_dxf, plot_pdf, purge, get_variables, undo, redo |
圖紙管理:建立、開啟、儲存、匯出 PDF/DXF、還原 |
|
entity |
create_line/circle/polyline/rectangle/arc/ellipse/mtext/hatch;list, get, copy, move, rotate, scale, mirror, erase |
幾何實體建立、查詢與修改 |
|
layer |
list, create, set_current, set_properties, freeze, thaw, lock, unlock |
圖層管理全套操作 |
|
block |
list, insert, insert_with_attributes, get_attributes, update_attribute, define |
圖塊插入與屬性管理 |
|
annotation |
create_text, create_dimension_linear/aligned/angular/radius, create_leader |
文字標注與尺寸標記 |
|
pid |
setup_layers, insert_symbol, draw_process_line, connect_equipment, add_equipment_tag |
PID 管線儀器圖(需 CTO 符號庫) |
|
view |
zoom_extents, zoom_window, get_screenshot |
視圖縮放與截圖 |
|
system |
status, health, execute_lisp |
伺服器健康狀態;execute_lisp 執行任意 AutoLISP |
8.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 節點,無需額外包裝
9. 安全設計
9.1 輸入安全
|
威脅 |
防護措施 |
|
Prompt Injection |
System Prompt 明確限制 Agent 行為範圍;使用者輸入與指令分開 |
|
路徑穿越攻擊 |
批次匯入路徑僅允許管理員操作,且限制在白名單目錄內 |
|
超大檔案 |
API 層限制上傳檔案大小(預設 50MB) |
|
惡意 PDF |
使用 pymupdf 的安全模式解析,避免 PDF 注入 |
9.2 稽核日誌
以下操作都會寫入 Client 機本的 audit_logs 資料表:
- 對話建立、訊息傳送
- 文件匹配觸發(RAG 检索)
- 系統設定變更、MCP 工具異動
9.3 資料隔離
- 對話紀錄儲存於 Client 本機 SQLite,筆電間自然隔離,無跨機器資料決漏風險
- 向量知識庫(Remote PostgreSQL)為全域共享(機構內部知識庫),不限制特定使用者
9.4 網路與 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)限制為內網,不對外開放 |
9.5 備份與加密策略
|
項目 |
策略 |
|
資料庫備份 |
每日排程執行 pg_dump mechdesign_ai > backup_YYYYMMDD.sql,保留 30 天 |
|
向量資料備份 |
document_chunks 向量欄位隨 pg_dump 一併備份,恢復時重新建立 HNSW 索引 |
|
原始文件備份 |
D:\mechdesign-ai\storage\documents\ 目錄定期複製至備援硬碟 |
|
磁碟加密(選用) |
視機構安全規範,可對伺服器磁碟啟用 BitLocker 加密 |
|
欄位加密(選用) |
高敏感欄位可加入 SQLAlchemy 欄位層加密 |
10. 離線環境部署指南
📌 所有軟體需預先下載至安裝媒介(USB 隨身碟),在離線環境中安裝。 📌 本指南假設作業系統為 Windows 11(Client 端與 Server 端皆適用)。 📌 部署分工:PostgreSQL 安裝於 Server 端(整合部專用伺服器);llama.cpp、FastAPI、LangGraph、MCP Servers、前端皆安裝於 Client 端(研發繪圖筆電)。
10.1 Server 端安裝步驟(PostgreSQL)
Step 1:安裝 PostgreSQL 16
- 下載 PostgreSQL 16 Windows 安裝檔(.exe)
- 安裝時設定: - Port: 5432 - 超級使用者密碼:建議使用強密碼
- 安裝完成後,以 psql 啟用 pgvector:
-- 以 postgres 超級使用者連入
CREATE DATABASE mechdesign_ai;
\c mechdesign_ai
CREATE EXTENSION IF NOT EXISTS vector;
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
- 安裝 pgvector Windows 版本:下載 pgvector releases 的 Windows 二進位包,複製 .dll 至 PostgreSQL 的 lib 目錄,複製 .control 和 .sql 至 share/extension 目錄。
10.2 Client 端安裝步驟(研發繪圖筆電)
Step 1:安裝 Python 3.11
- 下載 Python 3.11 Windows 安裝檔
- 安裝時勾選「Add Python to PATH」
- 確認安裝:python --version
Step 2:安裝 llama.cpp server
- 從 llama.cpp GitHub Releases 下載 Windows 預編譯二進位包(llama-*-bin-win-cuda*.zip)
- 解壓縮至目標目錄(如 D:\llama.cpp\)
- 匯入模型(需在有網路的機器預先下載 GGUF 格式):
# 有網路環境下載模型(使用 huggingface-cli 或直接下載 .gguf 檔)
# 例:Qwen3.5-9B-Instruct-Q4_K_M.gguf
# 複製 .gguf 檔至離線機器的 D:\models\ 目錄
- 啟動 llama.cpp server(監聽所有 IP):
# 在系統服務或開機腳本中執行
D:\llama.cpp\llama-server.exe `
--model D:\models\qwen3.5-9b-q4_k_m.gguf `
Step 3:安裝 Node.js(前端建構用)
- 下載 Node.js LTS(v20+)
- 確認安裝:node --version
Step 4:安裝後端 Python 依賴
# 在有網路的環境先下載所有套件
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:設定環境變數並初始化資料庫
# 設定環境變數 .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=qwen3.5:9b
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 服務:
# 下載 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:建構前端
cd D:\mechdesign-ai\frontend
# 離線安裝前端依賴(需預先下載 node_modules)
npm install --offline
# 建構生產版本
npm run build
# dist/ 目錄即為靜態網頁,可由 FastAPI 提供靜態服務
# 或設定 Nginx 提供服務
10.3 客戶端(繪圖筆電)日常使用方式
完成 11.2 節安裝後,日常使用僅需啟動以下服務後開啟瀏覽器:
# 1. llama.cpp server 與 FastAPI 已設為 Windows 服務(開機自動啟動)
# 2. 在瀏覽器開啟:
http://localhost:8000
# 或從其他筆電透過 IP 存取(需開放 Port 8000):
http://<Client-筆電-IP>:8000
建議使用 Chrome 或 Edge 最新版本。
10.4 設定防火牆
Client 端(研發繪圖筆電)防火牆設定
|
Port |
用途 |
|
8000 |
FastAPI(主要 API 服務,允許內網其他筆電存取) |
|
8080 |
llama.cpp server(推理服務,限 localhost,不對外) |
|
8100 |
CAD MCP Server(限 localhost,不對外) |
Server 端(整合部專用伺服器)防火牆設定
|
Port |
用途 |
|
5432 |
PostgreSQL(僅限內網 Client 筆電存取,不對外開放) |
11. 專案結構與開發計畫
11.1 專案目錄結構
專案依功能職責拆分為四個獨立子專案,可分別部署與維護:
ai-agent-frontend/ # Web UI(研發繪圖筆電)
├── src/
│ ├── components/
│ │ ├── ChatWindow.tsx # 對話主介面(SSE 串流顯示)
│ │ ├── MessageItem.tsx # 訊息渲染(Markdown + 引用來源)
│ │ └── Sidebar.tsx # 對話歷史側欄
│ ├── hooks/
│ │ └── useChat.ts # SSE 串流 hook
│ ├── lib/
│ │ └── api.ts # API 呼叫封裝
│ └── App.tsx
├── package.json
└── vite.config.ts
ai-agent-backend/ # FastAPI + LangGraph Agent(研發繪圖筆電)
├── app/
│ ├── main.py # FastAPI 入口
│ ├── routers/
│ │ ├── chat.py # /chat/stream、/chat/conversations
│ │ └── admin.py # /admin/system-status
│ ├── agent/
│ │ ├── graph.py # LangGraph 狀態機主流程
│ │ ├── state.py # AgentState 型別定義
│ │ └── nodes/
│ │ ├── classifier.py # 意圖分類節點
│ │ ├── retriever.py # RAG 檢索節點(含 Rerank)
│ │ ├── assessor.py # Self-RAG 品質評估節點
│ │ ├── context_mgr.py # Token 預算 / Context 管理
│ │ └── generator.py # LLM 回應生成節點
│ ├── mcp/
│ │ └── client.py # MultiServerMCPClient 初始化
│ ├── rag/
│ │ ├── retriever.py # langchain-postgres pgvector 封裝
│ │ └── reranker.py # CrossEncoderReranker 封裝
│ ├── llm/
│ │ └── llama_client.py # llama.cpp server 整合
│ └── storage/
│ ├── db.py # SQLAlchemy async session
│ ├── models.py # SQLite ORM models
│ └── migrations/ # Alembic migration scripts
├── config.py # 環境變數 / 設定(LLM_MODEL_PATH 等)
└── requirements.txt
ai-agent-mcptools/ # MCP 工具伺服器集合
├── autocad-mcp/ # AutoCAD 自動化:drawing/entity/layer/block/annotation/system
├── markitdown/ # markdown轉換
├── mcp-mysql/ # mysql讀寫
├── other-tools/ # 其他工具
└── README.md # 指向 https://github.com/puran-water/autocad-mcp
data_import/ # 文件匯入排程程式(整合部 Server)
├── main.py # 排程入口(Windows 工作排程器 / cron)
├── pipeline/
│ ├── scanner.py # 掃描 File Storage 新增文件
│ ├── parser.py # pymupdf4llm / python-docx / Tesseract OCR
│ ├── chunker.py # RecursiveCharacterTextSplitter
│ └── embedder.py # nomic-embed-text via llama.cpp API
├── storage/
│ ├── db.py # PostgreSQL + pgvector 連線(SQLAlchemy async)
│ └── models.py # documents / document_chunks / batch_jobs ORM
├── db/
│ └── schema.sql # 初始 schema(documents, document_chunks, batch_jobs)
├── config.py # PG_DSN、FILE_STORAGE_PATH、EMBED_MODEL_URL 等
└── requirements.txt
Comments...
No Comments Yet...