diff --git a/.obsidian/plugins/recent-files-obsidian/data.json b/.obsidian/plugins/recent-files-obsidian/data.json
index 899dfa3..5e59087 100644
--- a/.obsidian/plugins/recent-files-obsidian/data.json
+++ b/.obsidian/plugins/recent-files-obsidian/data.json
@@ -1,13 +1,37 @@
{
"recentFiles": [
+ {
+ "basename": "jinja",
+ "path": "000-inbox/jinja.md"
+ },
+ {
+ "basename": "20260328124189",
+ "path": "000-Inbox/20260328124189.md"
+ },
+ {
+ "basename": "Qwen3.5(通义千问 3.5)系列的多模态图文大模型(Vision-Language Models)",
+ "path": "resource/ai/大模型安装笔记/Qwen3.5(通义千问 3.5)系列的多模态图文大模型(Vision-Language Models).md"
+ },
{
"basename": "x-csrf-token",
- "path": "000-inbox/x-csrf-token.md"
+ "path": "work/移动杭研/业务梳理/x-csrf-token.md"
},
{
"basename": "需求-命中率计算",
"path": "000-inbox/需求-命中率计算.md"
},
+ {
+ "basename": "Docker 核心知识与实战笔记",
+ "path": "000-inbox/Docker 核心知识与实战笔记.md"
+ },
+ {
+ "basename": "GNU Screen 命令全解析",
+ "path": "resource/系统/GNU Screen 命令全解析.md"
+ },
+ {
+ "basename": "结构化输出和工具调用",
+ "path": "resource/ai/大模型安装笔记/结构化输出和工具调用.md"
+ },
{
"basename": "如何成为一个 React 工程师呢?",
"path": "resource/前端/如何成为一个 React 工程师呢?.md"
@@ -28,18 +52,6 @@
"basename": "开发笔记",
"path": "work/移动杭研/开发记录/7.19.0/开发笔记.md"
},
- {
- "basename": "结构化输出和工具调用",
- "path": "000-inbox/结构化输出和工具调用.md"
- },
- {
- "basename": "jinja",
- "path": "000-inbox/jinja.md"
- },
- {
- "basename": "Qwen3.5(通义千问 3.5)系列的多模态图文大模型(Vision-Language Models)",
- "path": "resource/ai/大模型安装笔记/Qwen3.5(通义千问 3.5)系列的多模态图文大模型(Vision-Language Models).md"
- },
{
"basename": "IBS 智能体具体落实技术方案",
"path": "work/移动杭研/AI 项目/IBS 智能体具体落实技术方案.md"
@@ -84,14 +96,6 @@
"basename": "函数调用 和 工具调用",
"path": "resource/ai/大模型安装笔记/函数调用 和 工具调用.md"
},
- {
- "basename": "GNU Screen 命令全解析",
- "path": "000-inbox/GNU Screen 命令全解析.md"
- },
- {
- "basename": "Docker 核心知识与实战笔记",
- "path": "000-inbox/Docker 核心知识与实战笔记.md"
- },
{
"basename": "ubuntu",
"path": "resource/系统/ubuntu.md"
@@ -191,14 +195,6 @@
{
"basename": "ibs-ai 项目梳理",
"path": "work/移动杭研/AI 项目/ibs-ai 项目梳理.md"
- },
- {
- "basename": "Prompt 01 COSMIC 需求扩写",
- "path": "resource/ai/prompts/cosmic/Prompt 01 COSMIC 需求扩写.md"
- },
- {
- "basename": "Prompt 06 COSMIC 锐评",
- "path": "resource/ai/prompts/cosmic/Prompt 06 COSMIC 锐评.md"
}
],
"omittedPaths": [
diff --git a/.obsidian/workspace.json b/.obsidian/workspace.json
index 5371f2b..b1a8a0b 100644
--- a/.obsidian/workspace.json
+++ b/.obsidian/workspace.json
@@ -4,22 +4,17 @@
"type": "split",
"children": [
{
- "id": "0e5febf7350f0399",
+ "id": "907e9a7a1202bddd",
"type": "tabs",
"children": [
{
- "id": "bf3ca11320d7a83e",
+ "id": "b38877d81f5d7556",
"type": "leaf",
"state": {
- "type": "markdown",
- "state": {
- "file": "000-inbox/x-csrf-token.md",
- "mode": "source",
- "source": false,
- "backlinks": false
- },
+ "type": "empty",
+ "state": {},
"icon": "lucide-file",
- "title": "x-csrf-token"
+ "title": "新标签页"
}
}
]
@@ -114,13 +109,12 @@
"state": {
"type": "outline",
"state": {
- "file": "000-inbox/x-csrf-token.md",
"followCursor": true,
"showSearch": false,
"searchQuery": ""
},
"icon": "lucide-list",
- "title": "x-csrf-token 的大纲"
+ "title": "大纲"
}
},
{
@@ -217,7 +211,8 @@
}
],
"direction": "horizontal",
- "width": 300.5
+ "width": 300.5,
+ "collapsed": true
},
"left-ribbon": {
"hiddenItems": {
@@ -231,34 +226,34 @@
"obsidian-excalidraw-plugin:New drawing": false
}
},
- "active": "bf3ca11320d7a83e",
+ "active": "c8718c0c63702202",
"lastOpenFiles": [
+ "000-inbox/jinja.md",
+ "000-inbox/20260328124189.md",
+ "000-Inbox/20260328124189.md",
+ "resource/ai/大模型安装笔记/Qwen3.5(通义千问 3.5)系列的多模态图文大模型(Vision-Language Models).md",
"calendar/diary/2026-03-27.md",
+ "work/移动杭研/业务梳理/x-csrf-token.md",
+ "calendar/diary/2026-03-26.md",
"000-inbox/需求-命中率计算.md",
+ "000-inbox/Docker 核心知识与实战笔记.md",
+ "resource/系统/GNU Screen 命令全解析.md",
+ "resource/ai/大模型安装笔记/结构化输出和工具调用.md",
"resource/前端/如何成为一个 React 工程师呢?.md",
"000-inbox/20260327101490.md",
"000-Inbox/20260327113359.md",
"000-Inbox/20260327151942.md",
"000-inbox/20260327151942.md",
- "000-inbox/x-csrf-token.md",
"000-Inbox/20260327105648.md",
"calendar/diary/2026-03-02.md",
"000-Inbox/20260327101490.md",
"calendar/diary/2026-03-23.md",
"calendar/diary/2026-03-20.md",
"calendar/diary/2026-03-21.md",
- "calendar/diary/2026-03-26.md",
"calendar/diary/2026-03-25.md",
"calendar/diary/2026-03-24.md",
"calendar/diary/2026-03-19.md",
"calendar/diary/2026-03-18.md",
- "calendar/diary/2026-03-17.md",
- "calendar/diary/2026-03-16.md",
- "calendar/diary/2026-03-13.md",
- "calendar/diary/2026-03-12.md",
- "calendar/diary/2026-03-11.md",
- "calendar/diary/2026-03-10.md",
- "calendar/diary/2026-03-09.md",
"attachment/image-20260325224201537.png",
"attachment/image-20260325224152205.png",
"attachment/image-20260325224141721.png",
diff --git a/000-inbox/需求-命中率计算.md b/000-inbox/需求-命中率计算.md
index b5fb338..23fd976 100644
--- a/000-inbox/需求-命中率计算.md
+++ b/000-inbox/需求-命中率计算.md
@@ -22,3 +22,23 @@ com.cmcc.cdn.platform.selfservice.controller.StatisticsController#getHitRatio
给我梳理下这个接口的功能,输出一个 markdown 文档到项目的根目录。
主要是用到哪些参数,有哪些校验,有没有参数转换和默认值。掉了哪些三方接口,调了接口后做了哪些事情。尽量清晰。注意细节。
+
+---
+
+com.cmcc.cdn.platform.selfservice.controller.StatisticsController#getHitRatio
+
+getHitRatio接口分析.md 是我 getHitRatio 命中率接口的梳理,是在跑的业务。我现在给你安排一个艰巨的任务。
+
+ 因为我们有一个 MCP 注册中心。我要接入进去。接入我们只需要提供标准的 http 接口就行了。所以按照这个接口做 3 个新接口出来:
+
+1. 请求数
+2. 命中请求数
+3. 计算命中率(命中率 = 命中请求数 / 总请求数)的接口。
+
+controller 在 ibs-portal\cdn-web\src\main\java\com\cmcc\cdn\platform 下建一个 mcp 文件夹写。
+
+service 在 ibs-portal\cdn-service\src\main\java\com\cmcc\cdn\platform 下建一个 mcp 文件夹写。
+
+因为是新接口代码一定要标准易读清晰,不要用原来的垃圾逻辑。
+
+再帮我额外提供一个接口。可以实现比如 AI 获取 请求数 然后获取 命中请求数 。然后可以计算他们两个得出命中率的工具接口。方便我测试是调用一次计算命中率比较好,还是调用 请求数 然后调用 命中请求数 然后调用计算工具计算合适。
diff --git a/calendar/diary/2026-03-27.md b/calendar/diary/2026-03-27.md
index 87ecee9..4a0f194 100644
--- a/calendar/diary/2026-03-27.md
+++ b/calendar/diary/2026-03-27.md
@@ -1,8 +1,8 @@
# 任务
- [x] 开发:参加 IBS 项目晨会,同步昨日问题跟进事项。(李春良 0.5)
-- [x] 项目:内容网络IBS系统研发项目_IBS子项目3月任务清单。(李春良 1)
-- [ ] 开发:请求命中率计算问题。
+- [x] 项目:内容网络IBS系统研发项目_IBS子项目3月任务清单。(李春良 1.5)
+- [x] 开发:MCP统计接口服务实现,请求命中率计算问题。(张鹏豪 6)
# 日志
@@ -42,3 +42,5 @@
完成BPM对接接口规范扩展需求开发自测,具备联调条件
# 总结
+
+早晨思考了一些关于 LLM 性能的问题,更新了 OpenClaw,下午写了两个接口,感觉最近集赞了很多东西没有消化了。
diff --git a/000-inbox/结构化输出和工具调用.md b/resource/ai/大模型安装笔记/结构化输出和工具调用.md
similarity index 100%
rename from 000-inbox/结构化输出和工具调用.md
rename to resource/ai/大模型安装笔记/结构化输出和工具调用.md
diff --git a/000-inbox/GNU Screen 命令全解析.md b/resource/系统/GNU Screen 命令全解析.md
similarity index 100%
rename from 000-inbox/GNU Screen 命令全解析.md
rename to resource/系统/GNU Screen 命令全解析.md
diff --git a/000-inbox/x-csrf-token.md b/work/移动杭研/业务梳理/x-csrf-token.md
similarity index 55%
rename from 000-inbox/x-csrf-token.md
rename to work/移动杭研/业务梳理/x-csrf-token.md
index 134d367..aed3f9f 100644
--- a/000-inbox/x-csrf-token.md
+++ b/work/移动杭研/业务梳理/x-csrf-token.md
@@ -1,20 +1,14 @@
-`x-csrf-token` 是 Spring Security CSRF 防护机制 的一部分,用于防止跨站请求伪造(CSRF)攻击。
+`x-csrf-token` 是 Spring Security CSRF 防护机制 的一部分,用于防止跨站请求伪造(CSRF)攻击。后端接口需要通过请求头接收前端携带的 CSRF token,以验证请求的合法性。
-后端接口需要通过请求头接收前端携带的 CSRF token,以验证请求的合法性。
+其中 IBSCsrfTokenRepository 管理 CSRF token,本质是一个 `UUID.randomUUID().toString()` 随机字符串。
-其中 IBSCsrfTokenRepository 管理 CSRF token,是一个 `UUID.randomUUID().toString()` 随机字符串
+登录成功后,`SecurityConfig.writeLoginSuccessResult()(SecurityConfig.java:482)` 会将 token 存入 session。
-登录成功后,SecurityConfig.writeLoginSuccessResult()(SecurityConfig.java:482)会将 token 存入 session:request.getSession().setAttribute(IBSCsrfTokenRepository.class.getName() + ".CSRF_TOKEN", token)
-
-同时通过 /admin/getCurrentUser 接口返回给前端:userVO.setCsrfToken(csrfToken.getToken())
+前端获取 Token,前端有两套机制,取决于环境:
```
-前端获取 Token
-前端有两套机制,取决于环境:
-
生产环境(cdn-web 模板):页面通过 Thymeleaf 模板将 token 渲染到 HTML meta 标签中
-
前端通过 getCsrfHeaderFromMeta() 读取这两个 meta 标签,动态设置请求头。
@@ -22,19 +16,13 @@
非生产环境(IBS-web):通过调用 /admin/getCurrentUser 接口获取 token 并缓存在 window.XTOKEN 中。
```
-后端 Filter 链验证 Token
-
-RequestReplaceFilter
+后端 Filter 链验证 Token RequestReplaceFilter
```
-response.setHeader("Access-Control-Allow-Headers",
- "content-type,x-requested-with,Authorization, x-request-with,x-ui-request,lang,x-csrf-token,csrf-token");
-
+response.setHeader("Access-Control-Allow-Headers", "content-type,x-requested-with,Authorization, x-request-with,x-ui-request,lang,x-csrf-token,csrf-token");
```
```
-在 SecurityConfig.csrf() 配置中(SecurityConfig.java:211-218),以下路径不进行 CSRF 校验:
-
// CSRF
String[] ignorePathes = {"/v1/**", "/v2/**", "/v1.0/**", "/analyzer/**", "/puppet/**", "/api/**",
"/sso/**", "/ssoapi/**", "/dss/prohibit/**", "/dss/v1/log/subscribe/callback", "/portal/**",
@@ -43,10 +31,10 @@ response.setHeader("Access-Control-Allow-Headers",
"/action/js", "/content/delivery/**", "/information/**","/testAction","/api/v2/**",
"/home/page/help/Doc/**", "/home/page/security/**", "/query/cmcc/party/**", "/query/enterprise/domain/info", "/v2.0/log/template/**"};
http.csrf().ignoringAntMatchers(ignorePathes)
- .csrfTokenRepository(new IBSCsrfTokenRepository(Arrays.asList(ignorePathes)));//不塞在cookie中
+ .csrfTokenRepository(new IBSCsrfTokenRepository(Arrays.asList(ignorePathes)));
```
-如果请求路径在 ignorePathes 列表中(如 /v1/**, /api/**, /action, /actionpm 等),loadToken 返回硬编码的 "1111111111",此时:
+如果请求路径在 ignorePathes 列表中(如 /v1/, /api/, /action, /actionpm 等),loadToken 返回硬编码的 "1111111111",此时:
请求带 X-CSRF-TOKEN: 1111111111 → 可以通过