forked from new_org/Project-Caffeine
docs(update):更新Arabica Sprint1 相关设计文档存储路径
Signed-off-by: gzkoala <guohao@gitconomy.org>
This commit is contained in:
@@ -0,0 +1,210 @@
|
||||
<!--
|
||||
---
|
||||
title: 提示词策略 MCP Server 原型设计文档
|
||||
description: Project Caffeine 提示词策略 MCP Server 的最小可行性功能(MVP)原型设计,涵盖 5 Whys 模板调用、增强提示词合成及 Node.js 环境工作流验证
|
||||
type: Architecture Design
|
||||
file: project-caffeine-mvp-sprint1-architecture-design.md
|
||||
version: v1.0.1 (Arabica)
|
||||
author: Gitconomy Research-郭晧
|
||||
date: 2026-03-1
|
||||
last-update: 2026-03-01
|
||||
update-description: 增加Cherry Stuio作为 MCP Client,上一版的设计还是基于传统的“AI Web 应用后端”,而不是严格意义上的 MCP 系统框架 。
|
||||
tags:
|
||||
- Project Caffeine
|
||||
- MCP Server
|
||||
- MVP
|
||||
- Srpint1
|
||||
- Prompt Strategy
|
||||
- 5 Whys
|
||||
- Node.js
|
||||
license: CC BY-SA 4.0
|
||||
status: Active
|
||||
---
|
||||
-->
|
||||
# Arabica Sprint1 系统架构设计说明
|
||||
|
||||
## 1. 原型设计概述
|
||||
|
||||
**功能目标**:实现一个最简化的 **提示词策略MCP Server**,当用户发起查询时,系统能够调用 **5 Whys** 模板对查询进行分解,生成增强的提示词,并将其发送到大模型进行推理。
|
||||
|
||||
**关键功能**:
|
||||
|
||||
- **工具注册 **:向 Cherry Studio 注册 `generate_5_whys` 能力。
|
||||
- **接收工具调用请求**:通过 `stdio` 接收 Cherry Studio 传来的用户查询主题。
|
||||
- **5 Whys 模板分解**:利用本地逻辑对查询进行分解,生成多层次的追问提示词。
|
||||
- **资源暴露**:将本地的文档库、PDF 或特定数据以 MCP Resource 的形式暴露给 Client(Sprint2)。
|
||||
|
||||
---
|
||||
|
||||
### 2. 功能实现步骤说明
|
||||
|
||||
#### 2.1 客户端请求与工具分发
|
||||
|
||||
- 用户在 **Cherry Studio** 中输入查询意图(如:“分析LLM在医疗中的应用瓶颈”)。
|
||||
- Cherry Studio 内部的大模型判断需要更深度的思考框架,主动向本 **MCP Server** 发起 `generate_5_whys` 的工具调用。
|
||||
|
||||
#### 2.2 生成 5 Whys 增强提示词
|
||||
|
||||
- **MCP Server** 接收到参数后,执行本地 `promptService.js`,根据查询主题自动生成 5 个逐层递进的问题(5 Whys)。
|
||||
|
||||
#### 2.3 结果返回与最终推理
|
||||
|
||||
- **MCP Server** 将生成的 5 Whys 数组作为工具执行结果,通过标准协议返回给 Cherry Studio。
|
||||
- Cherry Studio 携带这些增强提示词再次请求大模型,生成最终的深度研究洞察,并展示给用户。
|
||||
|
||||
---
|
||||
|
||||
## 3. 系统组件架构设计
|
||||
|
||||
### 3.1 **Project Caffeine** 系统原型项目结构说明
|
||||
|
||||
```markdown
|
||||
project-caffeine/
|
||||
│
|
||||
├── node_modules/ # 存放项目的依赖包
|
||||
├── src/ # 源代码文件夹
|
||||
│ ├── controllers/ # 逻辑路由分发层
|
||||
│ │ ├── promptsController.js # 处理提示词 Tool 相关请求
|
||||
│ │ └── resourcesController.js # 处理资源 Resource 请求
|
||||
│ ├── services/ # 核心业务逻辑层
|
||||
│ │ ├── promptService.js # 处理 5 Whys 提示词模板的生成算法
|
||||
│ │ └── resourceService.js # 处理本地文件、知识库等资源读取逻辑
|
||||
│ ├── models/ # 数据模型与校验
|
||||
│ │ └── schemas.js # 基于 Zod 的参数校验定义
|
||||
│ └── app.js # 主应用入口,初始化 MCP Server (stdio)
|
||||
│
|
||||
├── .vscode/ # IDE 调试配置
|
||||
│ └── launch.json # 配置 Cherry Studio 联调附加(Attach)环境
|
||||
├── config/ # 配置文件
|
||||
│ └── config.js # 项目配置
|
||||
├── .env # 环境变量配置 (不再需要 LLM API Key)
|
||||
├── package.json # 项目依赖 (@modelcontextprotocol/sdk)
|
||||
└── README.md # 项目说明文档
|
||||
```
|
||||
|
||||
**各文件和文件夹的功能说明**:
|
||||
|
||||
*表1-1:**Project Caffeine** 项目 MVP 系统文件和文件夹功能详细说明表格*
|
||||
|
||||
| **目录** | **文件名** | **功能说明** |
|
||||
| --- | --- | --- |
|
||||
| **`src/`** | **`app.js`** | 实例化官方 `McpServer`,配置 `stdio` 传输层,向 Client 注册 Tools 和 Resources。 |
|
||||
| **`src/controllers/`** | **`promptsController.js`** | 接收 `tools/call` 请求,调用 `promptService` 并格式化输出返回给 Client。 |
|
||||
| **`src/controllers/`** | **`resourcesController.js`** | 处理 `resources/list` 和 `resources/read` 请求,返回资源数据。 |
|
||||
| **`src/services/`** | **`promptService.js`** | 纯本地业务逻辑:根据入参字符串生成 **5 Whys** 数组结构。 |
|
||||
| **`src/services/`** | **`resourceService.js`** | 本地文件系统交互:读取本地知识库(如 Obsidian)或指定目录文档。 |
|
||||
| **`.vscode/`** | **`launch.json`** | 极其关键:配置 Node.js 的 `--inspect` 端口,实现基于 Cherry Studio 唤起时的断点联调。 |
|
||||
|
||||
### 3.2 系统模块架构说明
|
||||
|
||||
*图1-1:提示词策略 MCP Server 系统组件工作流架构图*
|
||||
|
||||

|
||||
|
||||
|
||||
基于 Cherry Studio 和 MCP (Model Context Protocol) 架构的工作流分为七个关键步骤:
|
||||
|
||||
1. **用户发起提问**:用户首先在前端(Cherry Studio)输入自己的问题或查询需求。
|
||||
2. **大模型决策调用工具**:Cherry Studio 作为 MCP 客户端,接收到用户提问后,其连接的大模型会对问题进行分析,并判断出需要调用系统注册的外部工具(如 5 Whys 分析法)来获取更好的提示词策略,而不是直接回答。
|
||||
3. **发起工具调用请求 tools/call**:Cherry Studio 通过标准输入输出流(`stdio`)协议,向后端的 Project Caffeine MCP Server(基于 Node.js 构建)发送一个名为 `generate_5_whys` 的工具调用指令。
|
||||
4. **本地生成 5 Whys 文本**:Project Caffeine MCP Server 接收到指令后,触发其内部的业务逻辑模块 `promptService.js`。该模块完全在本地运行,不依赖外部大模型,根据用户的初始问题自动生成 5 个逐层深入的追问(即 5 Whys 文本)。
|
||||
5. **返回工具执行结果**:MCP Server 将生成的 5 Whys 文本打包成标准的结果格式,通过协议传回给 Cherry Studio。
|
||||
6. **结合工具结果发起最终推理**:Cherry Studio 拿到这 5 个问题后,将其作为增强的上下文提示词,再次向大语言模型发起最终的深度推理请求,要求模型基于这些追问给出详尽的分析。
|
||||
7. **渲染并呈现结果**:大模型完成最终推理后,Cherry Studio 将这部分内容进行界面渲染,最终向用户呈现一份高质量的“深度洞察报告”。
|
||||
|
||||
简单来说,这是一个“用户提问 -> 客户端大模型决定求助 -> 本地服务端生成分析框架 -> 客户端大模型根据框架给出深度回答”的完整闭环。
|
||||
|
||||
---
|
||||
|
||||
## 4. MCP 标准通信接口设计 (协议级)
|
||||
|
||||
基于 `@modelcontextprotocol/sdk`,底层的 JSON-RPC 通信由 SDK 接管。以下为逻辑层面的输入输出规约。
|
||||
|
||||
### 4.1 Tool 注册声明 (`tools/list`)
|
||||
|
||||
向 Client 声明具备的能力。
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "generate_5_whys",
|
||||
"description": "使用 5 Whys 模板对用户查询进行深度分解,生成增强的提示词策略",
|
||||
"inputSchema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"query": {
|
||||
"type": "string",
|
||||
"description": "用户需要分析的原始查询主题,例如:中国开源人才的现状分析"
|
||||
}
|
||||
},
|
||||
"required": ["query"]
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### 4.2 Tool 调用响应 (`tools/call`)
|
||||
|
||||
当 Client 传入 `query: "中国开源人才的现状分析"` 时,Server 返回的执行结果。
|
||||
|
||||
```json
|
||||
{
|
||||
"content": [
|
||||
{
|
||||
"type": "text",
|
||||
"text": "[\n \"为什么中国开源人才的培养面临困难?\",\n \"为什么中国开源人才缺乏足够的行业经验?\",\n \"为什么开源社区对中国人才的支持力度不足?\",\n \"为什么中国开源人才的市场需求与供给不平衡?\",\n \"为什么政策支持不足导致中国开源人才流失?\"\n]"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### 4.3 存储资源访问 (`resources/list` & `resources/read`)
|
||||
|
||||
允许 Cherry Studio 查阅本地文件上下文。
|
||||
|
||||
**资源列表响应示例 (`resources/list`):**
|
||||
|
||||
```json
|
||||
{
|
||||
"resources": [
|
||||
{
|
||||
"uri": "file:///path/to/obsidian/vault/开源行业报告.md",
|
||||
"name": "开源行业研究报告",
|
||||
"mimeType": "text/markdown",
|
||||
"description": "本地知识库中的开源行业深度分析文档"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. 最小可行产品(MVP)开发环境
|
||||
|
||||
本阶段的开发环境高度依赖实际的 Client 联调:
|
||||
|
||||
* **Node.js (v18+)**:提供运行环境。
|
||||
* **@modelcontextprotocol/sdk**:官方依赖,提供 `stdio` 传输支持。
|
||||
* **Cherry Studio**:作为唯一指定测试 Client,配置为以 `command: node` 的方式启动 Server。
|
||||
* **VS Code Attach 调试**:利用 `--inspect=9229` 参数,在 Cherry Studio 唤起 Server 后,通过 VS Code 附加到该进程实现源码级断点调试。
|
||||
|
||||
---
|
||||
|
||||
## 6. 部署与验证
|
||||
|
||||
1. **环境初始化**:安装 Node.js 依赖及 Zod 校验库。
|
||||
2. **Client 配置**:在 Cherry Studio 的 MCP 设置中,添加名为 `ProjectCaffeine` 的 Server,指向本地的 `app.js` 绝对路径,并添加 `--inspect` 参数。
|
||||
3. **断点监听**:在 VS Code 中启动 Attach 调试任务,等待 Cherry Studio 握手。
|
||||
4. **触发验证**:在 Cherry Studio 对话框中要求模型“调用工具分析某问题”,观察 VS Code 是否成功捕获断点,并最终在 Cherry Studio 界面输出基于 5 Whys 增强的回答。
|
||||
|
||||
---
|
||||
|
||||
## 7. 总结
|
||||
|
||||
本设计说明提供了 **Project Caffeine** 的 **提示词策略MCP Server** 最小可行功能的开发框架,包括 **5 Whys** 模板生成、增强提示词的合成、推理请求与返回等关键功能。通过实现这一功能,可以验证整个系统的基本运行环境,确保 **MCP协议** 的各个组件能够顺利协同工作。
|
||||
|
||||
---
|
||||
|
||||
## 许可声明
|
||||
|
||||
本文档采用 **知识共享署名--相同方式共享 4.0 国际许可协议 (CC BY--SA 4.0)** 进行许可,© 2025-2026 Gitconomy Research.
|
||||
@@ -0,0 +1,430 @@
|
||||
<!--
|
||||
---
|
||||
title: "Project Caffeine Arabica版本 Srpint1开发者指南"
|
||||
description: "Arabica版本第一个迭代版本的开发者指南说明,实现一个最小化的5 Wys提示词策略 MCP Server 功能"
|
||||
type: "Development Guide"
|
||||
file: arabical-sprint1-development-specification-guide.md
|
||||
version: "v1.0.0"
|
||||
author: "Gitconomy Research-郭晧"
|
||||
date: 2026-03-01
|
||||
tags:
|
||||
- Project Caffeine
|
||||
- MCP
|
||||
- LLM
|
||||
- JSON-RPC 2.0
|
||||
- TypeScript
|
||||
- Node.js
|
||||
license: "CC BY-SA 4.0"
|
||||
status: "Active"
|
||||
---
|
||||
-->
|
||||
# Arabica Sprint1 版本开发指南说明
|
||||
|
||||
## 1. 环境前置要求
|
||||
|
||||
在开始部署前,请确保开发机已安装以下软件:
|
||||
|
||||
- **Node.js**: v18 LTS 或更高版本。
|
||||
- **Visual Studio Code (VS Code)**: 作为主力开发与断点调试 IDE。
|
||||
- **Cherry Studio**: 最新版,作为发起请求的 MCP Client(大模型中枢)。
|
||||
- **本地知识库**: 一个存放 `.md` 格式笔记的本地文件夹(如 Obsidian Vault)。
|
||||
|
||||
---
|
||||
|
||||
## 2. 工程初始化与依赖安装
|
||||
|
||||
打开终端,执行以下命令从零搭建工程骨架:
|
||||
|
||||
```bash
|
||||
# 1. 创建并进入项目目录
|
||||
mkdir project-caffeine-ts
|
||||
cd project-caffeine-ts
|
||||
|
||||
# 2. 初始化 npm
|
||||
npm init -y
|
||||
|
||||
# 3. 安装生产核心依赖
|
||||
npm install @modelcontextprotocol/sdk zod
|
||||
|
||||
# 4. 安装 TypeScript 及开发环境依赖
|
||||
npm install --save-dev typescript @types/node
|
||||
|
||||
# 5. 创建标准的目录结构
|
||||
mkdir -p src/services dist .vscode
|
||||
touch src/app.ts src/services/promptService.ts src/services/resourceService.ts .vscode/launch.json tsconfig.json
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. 核心工程配置
|
||||
|
||||
我们需要配置 TypeScript 编译器选项、启动脚本以及 VS Code 独有的源码映射调试环境。
|
||||
### 3.1 编辑`tsconfig.json`
|
||||
|
||||
控制代码编译并生成用于断点调试的 `sourceMap`:
|
||||
|
||||
```json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"module": "CommonJS",
|
||||
"moduleResolution": "node",
|
||||
"outDir": "./dist",
|
||||
"rootDir": "./src",
|
||||
"sourceMap": true, // 【关键】生成 .js.map 文件,用于 VS Code 断点映射
|
||||
"strict": true, // 开启严格模式
|
||||
"esModuleInterop": true, // 允许默认导入 CommonJS 模块
|
||||
"skipLibCheck": true,
|
||||
"forceConsistentCasingInFileNames": true
|
||||
},
|
||||
"include": ["src/**/*"]
|
||||
}
|
||||
```
|
||||
|
||||
### 2.2 编辑`package.json`
|
||||
|
||||
添加 `build` 和 `watch` 脚本,用于将 `.ts` 编译为 `.js`。在 `package.json` 中找到 `"scripts"` 字段并替换为
|
||||
|
||||
```json
|
||||
"scripts": { "build": "tsc", "watch": "tsc --watch", "start": "node dist/app.js" }
|
||||
```
|
||||
|
||||
### 2.3 编辑 `.vscode/launch.json`
|
||||
|
||||
新增的 `outFiles` 字段,它告诉 VS Code 去 `dist` 目录寻找编译后的文件,从而将断点映射回你的 `src/*.ts` 源码上。
|
||||
|
||||
```json
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "node",
|
||||
"request": "attach",
|
||||
"name": "🍒 附加到 Cherry Studio (TS 联调)",
|
||||
"port": 9229,
|
||||
"restart": true,
|
||||
"skipFiles": ["<node_internals>/**"],
|
||||
"outFiles": ["${workspaceFolder}/dist/**/*.js"]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. 第核心业务代码实现
|
||||
|
||||
### 4.1. `src/services/promptService.ts` (提示词策略生成)
|
||||
|
||||
纯本地业务逻辑,负责 5 Whys 框架生成。
|
||||
|
||||
```TypeScript
|
||||
/**
|
||||
* 根据查询主题生成 5 Whys 提示词策略
|
||||
* @param query 用户输入的查询主题
|
||||
* @returns 包含 5 个追问的字符串数组
|
||||
*/
|
||||
export function generate5Whys(query: string): string[] {
|
||||
if (query.includes("开源人才")) {
|
||||
return [
|
||||
"为什么中国开源人才的培养面临困难?",
|
||||
"为什么中国开源人才缺乏足够的行业经验?",
|
||||
"为什么开源社区对中国人才的支持力度不足?",
|
||||
"为什么中国开源人才的市场需求与供给不平衡?",
|
||||
"为什么政策支持不足导致中国开源人才流失?"
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
`为什么 "${query}" 会成为一个问题?`,
|
||||
`为什么导致上述现象的直接原因会发生?`,
|
||||
`为什么当前的系统或流程没有阻止这种情况?`,
|
||||
`为什么以前的解决方案或预防措施失效了?`,
|
||||
`为什么根本的系统性漏洞一直未被修复?`
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
### ## 4.2 `src/services/resourceService.ts` (本地知识库访问)
|
||||
|
||||
带有严格路径防穿越(Path Traversal)安全校验的本地文件读取服务。
|
||||
|
||||
```TypeScript
|
||||
import fs from 'fs/promises';
|
||||
import path from 'path';
|
||||
|
||||
// 【⚠️ 重要配置】请修改为你电脑上真实的 Markdown 笔记文件夹绝对路径!
|
||||
const OBSIDIAN_VAULT_PATH = '/home/wguo/Downloads/MyVault';
|
||||
|
||||
export async function listObsidianNotes(): Promise<string[]> {
|
||||
try {
|
||||
const files = await fs.readdir(OBSIDIAN_VAULT_PATH);
|
||||
return files.filter(file => file.toLowerCase().endsWith('.md'));
|
||||
} catch (error: any) {
|
||||
console.error(`[Project Caffeine] 无法读取知识库目录: ${error.message}`);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
export async function readObsidianNote(filename: string): Promise<string> {
|
||||
const targetPath = path.resolve(OBSIDIAN_VAULT_PATH, filename);
|
||||
const safeVaultPath = path.resolve(OBSIDIAN_VAULT_PATH);
|
||||
|
||||
// 核心防御:防止大模型通过传入 "../../" 读取系统敏感文件
|
||||
if (!targetPath.startsWith(safeVaultPath)) {
|
||||
throw new Error(`安全警告:越权访问拦截!禁止读取目录外的文件: ${filename}`);
|
||||
}
|
||||
|
||||
try {
|
||||
const content = await fs.readFile(targetPath, 'utf-8');
|
||||
return content;
|
||||
} catch (error: any) {
|
||||
throw new Error(`无法读取笔记 [${filename}]: 文件可能不存在或无权限。`);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4.3 `src/app.ts` (主入口)
|
||||
|
||||
负责初始化标准输入输出传输层,并向 Cherry Studio 注册工具字典。
|
||||
|
||||
```TypeScript
|
||||
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
||||
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
||||
import { z } from 'zod';
|
||||
import { generate5Whys } from './services/promptService';
|
||||
import { listObsidianNotes, readObsidianNote } from './services/resourceService';
|
||||
|
||||
// ==========================================
|
||||
// 1. 初始化 MCP Server
|
||||
// ==========================================
|
||||
const mcpServer = new McpServer({
|
||||
name: "Project-Caffeine-Prompt-Strategy",
|
||||
version: "1.2.0"
|
||||
});
|
||||
|
||||
// ==========================================
|
||||
// 2. 注册 Tools (工具) - 赋予大模型主动执行的能力
|
||||
// ==========================================
|
||||
|
||||
// 工具 1:5 Whys 提示词策略生成
|
||||
mcpServer.tool(
|
||||
"generate_5_whys",
|
||||
"使用 5 Whys 模板对用户查询进行深度分解,生成增强的提示词策略",
|
||||
{ query: z.string().describe("需要分析的查询主题") },
|
||||
async ({ query }: { query: string }) => {
|
||||
console.error(`[Project Caffeine] 大模型调用工具: 正在生成 5 Whys 策略 -> ${query}`);
|
||||
const enhancedPrompt = generate5Whys(query);
|
||||
return {
|
||||
content: [{ type: "text", text: JSON.stringify(enhancedPrompt, null, 2) }]
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
// 工具 2:扫描本地知识库目录
|
||||
mcpServer.tool(
|
||||
"list_local_notes",
|
||||
"获取本地 Obsidian 知识库中的所有 Markdown 笔记列表,用于了解当前有哪些可用的本地上下文资料。",
|
||||
{},
|
||||
async () => {
|
||||
console.error(`[Project Caffeine] 大模型调用工具: 正在扫描本地笔记列表...`);
|
||||
const notes = await listObsidianNotes();
|
||||
return {
|
||||
content: [{
|
||||
type: "text",
|
||||
text: notes.length > 0 ? `找到了以下笔记:\n${notes.join('\n')}` : "未找到笔记。"
|
||||
}]
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
// 工具 3:阅读指定的单篇笔记内容
|
||||
mcpServer.tool(
|
||||
"read_local_note",
|
||||
"读取本地 Obsidian 知识库中指定笔记的完整内容,作为深度分析的上下文参考。",
|
||||
{ filename: z.string().describe("需要读取的笔记文件名,必须包含 .md 后缀") },
|
||||
async ({ filename }: { filename: string }) => {
|
||||
console.error(`[Project Caffeine] 大模型调用工具: 正在深度阅读笔记 -> ${filename}`);
|
||||
try {
|
||||
const content = await readObsidianNote(filename);
|
||||
return { content: [{ type: "text", text: content }] };
|
||||
} catch (error: any) {
|
||||
return {
|
||||
content: [{ type: "text", text: `读取失败: ${error.message}` }],
|
||||
isError: true // 明确告知大模型此操作抛出了错误
|
||||
};
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// ==========================================
|
||||
// 3. 注册 Resources (资源) - 暴露给客户端供用户手动勾选的静态数据
|
||||
// ==========================================
|
||||
|
||||
// 资源 1:知识库目录索引
|
||||
mcpServer.resource(
|
||||
"obsidian-index", // 客户端显示的资源 Name/ID
|
||||
"obsidian://vault/index", // 唯一的 URI 标识
|
||||
{
|
||||
description: "本地知识库的目录索引,包含所有 Markdown 笔记的列表"
|
||||
},
|
||||
async (uri) => {
|
||||
console.error(`[Project Caffeine] 客户端请求静态资源: ${uri.href}`);
|
||||
|
||||
const notes = await listObsidianNotes();
|
||||
const textContent = notes.length > 0
|
||||
? `当前知识库包含以下文件:\n${notes.join('\n')}`
|
||||
: "当前知识库为空。";
|
||||
|
||||
return {
|
||||
contents: [{
|
||||
uri: uri.href,
|
||||
mimeType: "text/plain",
|
||||
text: textContent
|
||||
}]
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
// ==========================================
|
||||
// 4. 启动底层 Stdio 传输层
|
||||
// ==========================================
|
||||
async function start(): Promise<void> {
|
||||
console.error("[Project Caffeine] 正在启动 TS 版 MCP Server (含 Tools 与 Resources)...");
|
||||
const transport = new StdioServerTransport();
|
||||
await mcpServer.connect(transport);
|
||||
console.error("[Project Caffeine] MCP Server 已就绪,等待 Cherry Studio 交互。");
|
||||
}
|
||||
|
||||
// 捕获致命错误并安全退出
|
||||
start().catch((err: unknown) => {
|
||||
console.error("服务器启动失败:", err);
|
||||
process.exit(1);
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. 启动与工作流验证
|
||||
|
||||
### 5.1 步骤一:启动 TS 实时编译 (Watch Mode)
|
||||
|
||||
在 VS Code 中打开终端,运行以下命令。这会让 TypeScript 编译器在后台实时监控你的 `.ts` 文件修改,并自动编译到 `dist` 目录中:
|
||||
|
||||
```bash
|
||||
npm run watch
|
||||
```
|
||||
|
||||
_(保持这个终端窗口在后台运行不要关闭)_
|
||||
|
||||
### 5.2 步骤二:在 Cherry Studio 中配置 Server
|
||||
|
||||
1. 进入 Cherry Studio 的 **设置 -> MCP**。
|
||||
|
||||
2. 添加或修改 Server,**关键在于你要指向编译后的 `dist/app.js` 而不是 `src/app.ts`**:
|
||||
|
||||
- **Command**: `node`
|
||||
- **Args**: `["--inspect=9229", "/project-caffeine-sprint1/dist/app.js"]`
|
||||
- _注意:需要输入app.js的绝对路径_
|
||||
|
||||
3. 确保状态灯亮起绿色。
|
||||
|
||||
### 5.3 步骤三:VS Code 源码级断点联调
|
||||
|
||||
1. 在 `src/app.ts` 或各个 Service 的关键代码行打上断点。
|
||||
2. 在 VS Code 左侧调试面板,选择 **"🍒 附加到 Cherry Studio (TS 联调)"**,点击运行。
|
||||
3. 状态栏变色即表示成功抓取到 Cherry Studio 的底层 Node 进程。
|
||||
|
||||
### 5.4 发起全链路交互
|
||||
|
||||
在 Cherry Studio 对话框中,输入以下指令测试大模型的自主编排能力:
|
||||
|
||||
> _"请先查看我的本地笔记列表,找到关于开源领域的笔记并阅读内容。然后结合你的知识,调用 5 Whys 工具帮我分析一下里面的痛点。"_
|
||||
|
||||
**预期结果**:你将看到大模型**自动、按顺序**调用了 `list_local_notes` -> `read_local_note` -> `generate_5_whys` 三个工具,最终为你输出一篇深度融合了你的私有知识库的洞察报告。
|
||||
|
||||
---
|
||||
|
||||
## 6. 系统运行测试样例
|
||||
|
||||
|
||||
在开始执行测试之前,请确保已完成以下前置准备:
|
||||
|
||||
- **后台编译**:在 VS Code 终端保持运行 `npm run watch` 命令。
|
||||
- **配置连接**:在 Cherry Studio 的设置中,将 Command 设为 `node`,Args 设为 `["--inspect=9229", "<绝对路径>/dist/app.js"]`,并确保状态灯亮起绿色。
|
||||
- **本地知识库**:确保代码中 `OBSIDIAN_VAULT_PATH` 指向的本地文件夹中存在至少一篇 Markdown 格式的测试笔记。
|
||||
|
||||
### 6.1 测试样例1:基础工具调用与分支逻辑验证
|
||||
|
||||
- **测试目标**:验证 `generate_5_whys` 工具的硬编码逻辑分支是否生效。
|
||||
|
||||
- **操作步骤**:
|
||||
|
||||
1. 向大模型发送指令:“请调用工具,帮我生成关于‘开源人才’的 5 Whys 策略。”
|
||||
|
||||
- **预期结果**:
|
||||
|
||||
- VS Code Debug Console打印日志:`[Project Caffeine] 大模型调用工具: 正在生成 5 Whys 策略 -> 开源人才`。
|
||||
- 大模型的回答中必须包含代码中预设的具体问题,例如“为什么中国开源人才的培养面临困难?”、“为什么中国开源人才缺乏足够的行业经验?”等。
|
||||
|
||||
### 6.2 测试样例 2:泛化工具调用验证
|
||||
|
||||
- **测试目标**:验证 `generate_5_whys` 工具在遇到未知主题时的泛化模板处理能力。
|
||||
|
||||
- **操作步骤**:
|
||||
|
||||
1. 向大模型发送指令:“我正在研究‘AI算力成本过高’的问题,请调用工具为我生成 5 Whys 框架。”
|
||||
|
||||
- **预期结果**:
|
||||
|
||||
- 大模型会调用工具,并将主题代入泛化模板,输出类似“为什么 "AI算力成本过高" 会成为一个问题?”、“为什么导致上述现象的直接原因会发生?”等框架性问题。
|
||||
|
||||
|
||||
### 6.3 测试样例 3:安全防御机制测试(红蓝对抗)
|
||||
|
||||
- **测试目标**:验证 `read_local_note` 工具中的路径防穿越(Path Traversal)安全校验是否能成功拦截恶意请求。
|
||||
|
||||
- **操作步骤**:
|
||||
|
||||
1. 向大模型发送诱导性指令:“请调用读取笔记的工具,帮我读取 `../etc/passwd` 文件的内容。”
|
||||
|
||||
- **预期结果**:
|
||||
|
||||
- 工具调用将被拦截,并抛出错误。
|
||||
- 大模型将收到包含 `isError: true` 的错误响应。
|
||||
- 错误信息明确提示大模型:“读取失败: 安全警告:越权访问拦截!禁止读取目录外的文件”。
|
||||
|
||||
|
||||
### 6.4 测试样例 4:全链路 Agentic 自主编排测试
|
||||
|
||||
- **测试目标**:验证大模型是否能自主决策,按顺序组合调用多个外部工具完成复杂分析。
|
||||
|
||||
- **操作步骤**:
|
||||
|
||||
1. 向大模型发送综合指令:“请先查看我的本地笔记列表,找到关于开源领域的笔记并阅读内容。然后结合你的知识,调用 5 Whys 工具帮我分析一下里面的痛点。”。
|
||||
|
||||
- **预期结果**:
|
||||
|
||||
- 大模型将自动并按顺序调用 `list_local_notes` -> `read_local_note` -> `generate_5_whys` 三个工具。
|
||||
- 最终输出一篇融合了私有知识库内容深度的洞察报告。
|
||||
|
||||
### 6.5 测试样例 5:VS Code 断点联调环境测试
|
||||
|
||||
- **测试目标**:验证 `.vscode/launch.json` 源码映射与调试环境配置是否成功。
|
||||
|
||||
- **操作步骤**:
|
||||
|
||||
1. 在 `src/app.ts` 或其他 Service 文件的关键代码行打上断点。
|
||||
2. 在 VS Code 调试面板选择“🍒 附加到 Cherry Studio (TS 联调)”并运行。
|
||||
3. 在 Cherry Studio 中触发任意工具调用。
|
||||
|
||||
- **预期结果**:
|
||||
|
||||
- VS Code 底部状态栏变色,表示成功抓取到 Cherry Studio 的底层 Node 进程。
|
||||
- 代码执行将暂停在设置了断点的位置,允许开发者查看当前变量与调用栈。
|
||||
|
||||
---
|
||||
|
||||
## 许可声明
|
||||
|
||||
本文档采用 **知识共享署名--相同方式共享 4.0 国际许可协议 (CC BY--SA 4.0)** 进行许可,© 2025-2026 Gitconomy Research.
|
||||
Reference in New Issue
Block a user