diff --git a/docs/STUDIO_PROTOTYPE_SCHEMA.sql b/docs/STUDIO_PROTOTYPE_SCHEMA.sql
new file mode 100644
index 0000000..39b7235
--- /dev/null
+++ b/docs/STUDIO_PROTOTYPE_SCHEMA.sql
@@ -0,0 +1,228 @@
+-- Common Agent Studio prototype schema draft.
+-- These tables extend the current RAG, model-provider and agent_definition data model
+-- without replacing existing core entities.
+
+CREATE TABLE IF NOT EXISTS studio_project (
+ id BIGSERIAL PRIMARY KEY,
+ project_code VARCHAR(100) NOT NULL,
+ project_name VARCHAR(200) NOT NULL,
+ environment VARCHAR(50) NOT NULL DEFAULT 'DEV',
+ publish_status VARCHAR(50) NOT NULL DEFAULT 'DRAFT',
+ current_version VARCHAR(50),
+ version INTEGER NOT NULL DEFAULT 1,
+ create_time TIMESTAMP,
+ update_time TIMESTAMP,
+ remark VARCHAR(500) DEFAULT '',
+ create_by VARCHAR(64),
+ update_by VARCHAR(64),
+ CONSTRAINT uk_studio_project_code UNIQUE (project_code)
+);
+
+CREATE TABLE IF NOT EXISTS workflow_definition (
+ id BIGSERIAL PRIMARY KEY,
+ project_id BIGINT,
+ workflow_code VARCHAR(100) NOT NULL,
+ workflow_name VARCHAR(200) NOT NULL,
+ description VARCHAR(1000),
+ bound_agent_id BIGINT,
+ status VARCHAR(50) NOT NULL DEFAULT 'DRAFT',
+ version INTEGER NOT NULL DEFAULT 1,
+ create_time TIMESTAMP,
+ update_time TIMESTAMP,
+ remark VARCHAR(500) DEFAULT '',
+ create_by VARCHAR(64),
+ update_by VARCHAR(64),
+ CONSTRAINT uk_workflow_definition_code UNIQUE (workflow_code),
+ CONSTRAINT fk_workflow_definition_project_id FOREIGN KEY (project_id) REFERENCES studio_project (id),
+ CONSTRAINT fk_workflow_definition_agent_id FOREIGN KEY (bound_agent_id) REFERENCES agent_definition (id)
+);
+
+CREATE TABLE IF NOT EXISTS workflow_version (
+ id BIGSERIAL PRIMARY KEY,
+ workflow_id BIGINT NOT NULL,
+ version_no INTEGER NOT NULL,
+ snapshot_name VARCHAR(100) NOT NULL,
+ graph_json JSONB NOT NULL DEFAULT '{}'::jsonb,
+ publish_status VARCHAR(50) NOT NULL DEFAULT 'DRAFT',
+ published_time TIMESTAMP,
+ version INTEGER NOT NULL DEFAULT 1,
+ create_time TIMESTAMP,
+ update_time TIMESTAMP,
+ remark VARCHAR(500) DEFAULT '',
+ create_by VARCHAR(64),
+ update_by VARCHAR(64),
+ CONSTRAINT uk_workflow_version_no UNIQUE (workflow_id, version_no),
+ CONSTRAINT fk_workflow_version_workflow_id FOREIGN KEY (workflow_id) REFERENCES workflow_definition (id)
+);
+
+CREATE TABLE IF NOT EXISTS workflow_run (
+ id BIGSERIAL PRIMARY KEY,
+ request_id VARCHAR(64) NOT NULL,
+ workflow_id BIGINT,
+ workflow_version_id BIGINT,
+ agent_id BIGINT,
+ run_source VARCHAR(50) NOT NULL,
+ status VARCHAR(50) NOT NULL,
+ input_json JSONB NOT NULL DEFAULT '{}'::jsonb,
+ output_json JSONB NOT NULL DEFAULT '{}'::jsonb,
+ duration_ms INTEGER,
+ estimated_cost NUMERIC(14, 8),
+ version INTEGER NOT NULL DEFAULT 1,
+ create_time TIMESTAMP,
+ update_time TIMESTAMP,
+ remark VARCHAR(500) DEFAULT '',
+ create_by VARCHAR(64),
+ update_by VARCHAR(64),
+ CONSTRAINT uk_workflow_run_request_id UNIQUE (request_id),
+ CONSTRAINT fk_workflow_run_workflow_id FOREIGN KEY (workflow_id) REFERENCES workflow_definition (id),
+ CONSTRAINT fk_workflow_run_version_id FOREIGN KEY (workflow_version_id) REFERENCES workflow_version (id),
+ CONSTRAINT fk_workflow_run_agent_id FOREIGN KEY (agent_id) REFERENCES agent_definition (id)
+);
+
+CREATE TABLE IF NOT EXISTS workflow_run_step (
+ id BIGSERIAL PRIMARY KEY,
+ run_id BIGINT NOT NULL,
+ node_id VARCHAR(100) NOT NULL,
+ node_type VARCHAR(50) NOT NULL,
+ node_name VARCHAR(200),
+ status VARCHAR(50) NOT NULL,
+ input_json JSONB NOT NULL DEFAULT '{}'::jsonb,
+ output_json JSONB NOT NULL DEFAULT '{}'::jsonb,
+ duration_ms INTEGER,
+ error_message VARCHAR(1000),
+ version INTEGER NOT NULL DEFAULT 1,
+ create_time TIMESTAMP,
+ update_time TIMESTAMP,
+ remark VARCHAR(500) DEFAULT '',
+ create_by VARCHAR(64),
+ update_by VARCHAR(64),
+ CONSTRAINT fk_workflow_run_step_run_id FOREIGN KEY (run_id) REFERENCES workflow_run (id)
+);
+
+CREATE TABLE IF NOT EXISTS mcp_server (
+ id BIGSERIAL PRIMARY KEY,
+ server_code VARCHAR(100) NOT NULL,
+ server_name VARCHAR(200) NOT NULL,
+ import_type VARCHAR(50) NOT NULL,
+ endpoint_url VARCHAR(500),
+ package_name VARCHAR(200),
+ manifest_json JSONB NOT NULL DEFAULT '{}'::jsonb,
+ auth_type VARCHAR(50),
+ secret_ref VARCHAR(200),
+ health_status VARCHAR(50) NOT NULL DEFAULT 'UNKNOWN',
+ enabled BOOLEAN NOT NULL DEFAULT TRUE,
+ version INTEGER NOT NULL DEFAULT 1,
+ create_time TIMESTAMP,
+ update_time TIMESTAMP,
+ remark VARCHAR(500) DEFAULT '',
+ create_by VARCHAR(64),
+ update_by VARCHAR(64),
+ CONSTRAINT uk_mcp_server_code UNIQUE (server_code)
+);
+
+CREATE TABLE IF NOT EXISTS mcp_capability (
+ id BIGSERIAL PRIMARY KEY,
+ server_id BIGINT NOT NULL,
+ capability_code VARCHAR(150) NOT NULL,
+ capability_name VARCHAR(200) NOT NULL,
+ capability_type VARCHAR(50) NOT NULL,
+ schema_json JSONB NOT NULL DEFAULT '{}'::jsonb,
+ enabled BOOLEAN NOT NULL DEFAULT TRUE,
+ version INTEGER NOT NULL DEFAULT 1,
+ create_time TIMESTAMP,
+ update_time TIMESTAMP,
+ remark VARCHAR(500) DEFAULT '',
+ create_by VARCHAR(64),
+ update_by VARCHAR(64),
+ CONSTRAINT uk_mcp_capability_code UNIQUE (server_id, capability_code),
+ CONSTRAINT fk_mcp_capability_server_id FOREIGN KEY (server_id) REFERENCES mcp_server (id)
+);
+
+CREATE TABLE IF NOT EXISTS skill_definition (
+ id BIGSERIAL PRIMARY KEY,
+ skill_code VARCHAR(100) NOT NULL,
+ skill_name VARCHAR(200) NOT NULL,
+ skill_type VARCHAR(50) NOT NULL,
+ description VARCHAR(1000),
+ status VARCHAR(50) NOT NULL DEFAULT 'DRAFT',
+ version INTEGER NOT NULL DEFAULT 1,
+ create_time TIMESTAMP,
+ update_time TIMESTAMP,
+ remark VARCHAR(500) DEFAULT '',
+ create_by VARCHAR(64),
+ update_by VARCHAR(64),
+ CONSTRAINT uk_skill_definition_code UNIQUE (skill_code)
+);
+
+CREATE TABLE IF NOT EXISTS skill_version (
+ id BIGSERIAL PRIMARY KEY,
+ skill_id BIGINT NOT NULL,
+ version_no INTEGER NOT NULL,
+ prompt_text TEXT,
+ code_text TEXT,
+ config_json JSONB NOT NULL DEFAULT '{}'::jsonb,
+ variable_schema_json JSONB NOT NULL DEFAULT '{}'::jsonb,
+ test_result_json JSONB NOT NULL DEFAULT '{}'::jsonb,
+ publish_status VARCHAR(50) NOT NULL DEFAULT 'DRAFT',
+ published_time TIMESTAMP,
+ version INTEGER NOT NULL DEFAULT 1,
+ create_time TIMESTAMP,
+ update_time TIMESTAMP,
+ remark VARCHAR(500) DEFAULT '',
+ create_by VARCHAR(64),
+ update_by VARCHAR(64),
+ CONSTRAINT uk_skill_version_no UNIQUE (skill_id, version_no),
+ CONSTRAINT fk_skill_version_skill_id FOREIGN KEY (skill_id) REFERENCES skill_definition (id)
+);
+
+CREATE TABLE IF NOT EXISTS agent_session (
+ id BIGSERIAL PRIMARY KEY,
+ session_code VARCHAR(100) NOT NULL,
+ agent_id BIGINT NOT NULL,
+ workflow_run_id BIGINT,
+ title VARCHAR(200),
+ status VARCHAR(50) NOT NULL DEFAULT 'ACTIVE',
+ metadata_json JSONB NOT NULL DEFAULT '{}'::jsonb,
+ version INTEGER NOT NULL DEFAULT 1,
+ create_time TIMESTAMP,
+ update_time TIMESTAMP,
+ remark VARCHAR(500) DEFAULT '',
+ create_by VARCHAR(64),
+ update_by VARCHAR(64),
+ CONSTRAINT uk_agent_session_code UNIQUE (session_code),
+ CONSTRAINT fk_agent_session_agent_id FOREIGN KEY (agent_id) REFERENCES agent_definition (id),
+ CONSTRAINT fk_agent_session_run_id FOREIGN KEY (workflow_run_id) REFERENCES workflow_run (id)
+);
+
+CREATE TABLE IF NOT EXISTS agent_message (
+ id BIGSERIAL PRIMARY KEY,
+ session_id BIGINT NOT NULL,
+ role VARCHAR(50) NOT NULL,
+ content TEXT NOT NULL,
+ citation_json JSONB NOT NULL DEFAULT '[]'::jsonb,
+ token_count INTEGER,
+ version INTEGER NOT NULL DEFAULT 1,
+ create_time TIMESTAMP,
+ update_time TIMESTAMP,
+ remark VARCHAR(500) DEFAULT '',
+ create_by VARCHAR(64),
+ update_by VARCHAR(64),
+ CONSTRAINT fk_agent_message_session_id FOREIGN KEY (session_id) REFERENCES agent_session (id)
+);
+
+CREATE TABLE IF NOT EXISTS agent_capability_binding (
+ id BIGSERIAL PRIMARY KEY,
+ owner_type VARCHAR(50) NOT NULL,
+ owner_id BIGINT NOT NULL,
+ capability_type VARCHAR(50) NOT NULL,
+ capability_id BIGINT NOT NULL,
+ enabled BOOLEAN NOT NULL DEFAULT TRUE,
+ config_json JSONB NOT NULL DEFAULT '{}'::jsonb,
+ version INTEGER NOT NULL DEFAULT 1,
+ create_time TIMESTAMP,
+ update_time TIMESTAMP,
+ remark VARCHAR(500) DEFAULT '',
+ create_by VARCHAR(64),
+ update_by VARCHAR(64),
+ CONSTRAINT uk_agent_capability_binding UNIQUE (owner_type, owner_id, capability_type, capability_id)
+);
diff --git a/frontend/src/data/studioMock.ts b/frontend/src/data/studioMock.ts
new file mode 100644
index 0000000..c2a983d
--- /dev/null
+++ b/frontend/src/data/studioMock.ts
@@ -0,0 +1,143 @@
+export type PipelineStatus = 'done' | 'running' | 'blocked' | 'idle';
+
+export interface LifecycleStep {
+ name: string;
+ description: string;
+ status: PipelineStatus;
+}
+
+export interface RecentRun {
+ id: string;
+ name: string;
+ type: string;
+ status: string;
+ latency: string;
+ cost: string;
+}
+
+export interface KnowledgeDocument {
+ id: string;
+ name: string;
+ parseStatus: string;
+ indexStatus: string;
+ chunks: number;
+ updatedAt: string;
+}
+
+export interface WorkflowNode {
+ id: string;
+ type: string;
+ label: string;
+ description: string;
+ x: number;
+ y: number;
+}
+
+export interface WorkflowEdge {
+ from: string;
+ to: string;
+}
+
+export interface TraceStep {
+ node: string;
+ status: string;
+ duration: string;
+ output: string;
+}
+
+export const lifecycleSteps: LifecycleStep[] = [
+ { name: '知识接入', description: '上传、解析、切片、向量化', status: 'done' },
+ { name: '能力编排', description: 'Workflow 连接模型、工具与 Skill', status: 'running' },
+ { name: '对话调试', description: '验证引用、成本、延迟与回答质量', status: 'running' },
+ { name: '发布观测', description: '版本快照、运行追踪、异常排查', status: 'idle' },
+];
+
+export const readinessChecklist = [
+ { label: '知识库已绑定 Embedding 模型', done: true },
+ { label: 'Workflow 草稿存在未发布节点变更', done: false },
+ { label: 'Agent 已绑定默认知识库与 Skill', done: true },
+ { label: '生产环境路由规则仍需压测', done: false },
+];
+
+export const recentRuns: RecentRun[] = [
+ { id: 'run-1842', name: '售前问答 Agent', type: 'Agent', status: '成功', latency: '1.42s', cost: '¥0.018' },
+ { id: 'run-1841', name: '合同知识召回', type: 'Workflow', status: '成功', latency: '860ms', cost: '¥0.006' },
+ { id: 'run-1840', name: 'MCP: jira.search', type: 'MCP', status: '重试', latency: '2.8s', cost: '¥0.000' },
+];
+
+export const knowledgeStores = [
+ { id: '1001', name: '产品制度库', docs: 128, health: 96, status: '可检索' },
+ { id: '1002', name: '交付项目资料', docs: 64, health: 82, status: '索引中' },
+ { id: '1003', name: '客服 FAQ', docs: 214, health: 91, status: '可检索' },
+];
+
+export const knowledgeDocuments: KnowledgeDocument[] = [
+ { id: 'doc-01', name: '售前方案模板.pdf', parseStatus: 'PARSED', indexStatus: 'INDEXED', chunks: 42, updatedAt: '10分钟前' },
+ { id: 'doc-02', name: '项目实施手册.docx', parseStatus: 'PARSED', indexStatus: 'INDEXING', chunks: 88, updatedAt: '23分钟前' },
+ { id: 'doc-03', name: '服务条款更新.md', parseStatus: 'FAILED', indexStatus: 'PENDING', chunks: 0, updatedAt: '今天 09:12' },
+ { id: 'doc-04', name: '客服高频问题.xlsx', parseStatus: 'PARSED', indexStatus: 'INDEXED', chunks: 119, updatedAt: '昨天' },
+];
+
+export const ingestionSteps: LifecycleStep[] = [
+ { name: '上传', description: '4 个文件已入库 sys_attachment', status: 'done' },
+ { name: '解析', description: 'Tika 抽取文本并保存快照', status: 'done' },
+ { name: '切片', description: '固定长度 800 / overlap 120', status: 'running' },
+ { name: '向量化', description: 'Qwen3 Embedding 1024 维', status: 'idle' },
+ { name: '可检索', description: '等待索引任务完成', status: 'idle' },
+];
+
+export const workflowNodes: WorkflowNode[] = [
+ { id: 'start', type: 'START', label: 'Start', description: '接收用户问题', x: 4, y: 42 },
+ { id: 'retrieve', type: 'KNOWLEDGE_RETRIEVAL', label: 'Knowledge Retrieval', description: 'TopK=6 / score>0.72', x: 25, y: 18 },
+ { id: 'llm', type: 'LLM', label: 'LLM', description: 'RAG_ANSWER 路由', x: 47, y: 42 },
+ { id: 'mcp', type: 'MCP_TOOL', label: 'MCP Tool', description: 'jira.search / docs.lookup', x: 47, y: 70 },
+ { id: 'skill', type: 'SKILL', label: 'Skill', description: '答案审校与引用整理', x: 69, y: 42 },
+ { id: 'answer', type: 'ANSWER', label: 'Answer', description: '返回回答与引用', x: 88, y: 42 },
+];
+
+export const workflowEdges: WorkflowEdge[] = [
+ { from: 'start', to: 'retrieve' },
+ { from: 'retrieve', to: 'llm' },
+ { from: 'llm', to: 'skill' },
+ { from: 'mcp', to: 'skill' },
+ { from: 'skill', to: 'answer' },
+];
+
+export const traceSteps: TraceStep[] = [
+ { node: 'Start', status: '完成', duration: '4ms', output: '用户问题已标准化' },
+ { node: 'Knowledge Retrieval', status: '完成', duration: '218ms', output: '召回 6 个切片' },
+ { node: 'LLM', status: '完成', duration: '1.12s', output: '生成 612 tokens' },
+ { node: 'Skill', status: '完成', duration: '88ms', output: '引用格式已校验' },
+];
+
+export const chatMessages = [
+ { role: 'user', content: '如果客户要求私有化部署,售前方案里必须说明哪些内容?' },
+ {
+ role: 'assistant',
+ content: '建议说明部署拓扑、模型服务商、知识库索引策略、权限边界、日志留存周期和故障恢复方式。当前回答引用了 3 个知识切片。',
+ },
+];
+
+export const citations = [
+ { title: '售前方案模板.pdf', score: '0.91', text: '私有化部署章节应覆盖基础设施、网络、安全与运维边界。' },
+ { title: '项目实施手册.docx', score: '0.87', text: '交付计划需包含数据导入、索引重建与验收标准。' },
+ { title: '服务条款更新.md', score: '0.82', text: '客户数据默认不出域,模型调用日志需保留审计字段。' },
+];
+
+export const mcpCapabilities = [
+ { name: 'jira.search', type: 'tool', status: '已启用', description: '按项目、状态、负责人检索任务' },
+ { name: 'docs.lookup', type: 'resource', status: '已启用', description: '读取外部文档中心条目' },
+ { name: 'deploy.trigger', type: 'tool', status: '待授权', description: '触发测试环境部署流水线' },
+];
+
+export const skillVersions = [
+ { version: 'v4', status: 'Draft', updatedAt: '刚刚', note: '增加引用一致性检查' },
+ { version: 'v3', status: 'Published', updatedAt: '昨天', note: '生产环境当前版本' },
+ { version: 'v2', status: 'Archived', updatedAt: '5天前', note: '旧版回答润色策略' },
+];
+
+export const modelRoutes = [
+ { task: 'RAG_ANSWER', primary: 'qwen-plus', fallback: 'deepseek-v3', latency: '1800ms', status: '启用' },
+ { task: 'RAG_EMBEDDING', primary: 'Qwen3-Embedding', fallback: '无', latency: '900ms', status: '启用' },
+ { task: 'AGENT_PLAN', primary: 'gpt-4.1', fallback: 'qwen-max', latency: '3200ms', status: '草稿' },
+];
diff --git a/frontend/src/layouts/AdminLayout.vue b/frontend/src/layouts/AdminLayout.vue
index be658f7..c27b71c 100644
--- a/frontend/src/layouts/AdminLayout.vue
+++ b/frontend/src/layouts/AdminLayout.vue
@@ -1,64 +1,71 @@
-
-