feat: 场景 C 重写为文档解析场景,DocumentCard 增加「查看解析」交互
- DocumentSegment 新增 parsedContent 字段,存储 AI 对文档的解析结果 - DocumentCard 增加「查看解析 / 收起解析」按钮,展开后以 Markdown 渲染解析内容 - 场景 C 从「长文本+文档+多模态」改为「单文档解析」场景,聚焦展示解析功能 - ChatContext 默认 activeDemo 索引修正为 4
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
import { useState } from 'react'
|
||||
import type { DocumentSegment } from '../../types/protocol'
|
||||
import type { LucideIcon } from 'lucide-react'
|
||||
import { FileText, FileImage, FileAudio, File } from 'lucide-react'
|
||||
import { FileText, FileImage, FileAudio, File, ChevronDown, ChevronRight, Eye, EyeOff } from 'lucide-react'
|
||||
import MarkdownRenderer from '../MarkdownRenderer'
|
||||
|
||||
const mimeIcons: Record<string, LucideIcon> = {
|
||||
'text/': FileText,
|
||||
@@ -22,21 +24,63 @@ function formatBytes(bytes: number): string {
|
||||
}
|
||||
|
||||
export default function DocumentCard({ segment }: { segment: DocumentSegment }) {
|
||||
const [showParsed, setShowParsed] = useState(false)
|
||||
|
||||
return (
|
||||
<div className="my-2 flex items-start gap-3 rounded-lg border border-gray-200 bg-white p-3 hover:shadow-sm transition-shadow">
|
||||
<div className="shrink-0 mt-0.5">{getIcon(segment.mimeType)}</div>
|
||||
<div className="flex-1 min-w-0">
|
||||
<div className="flex items-center gap-2 flex-wrap">
|
||||
<span className="text-sm font-medium text-gray-800 truncate">
|
||||
{segment.fileName}
|
||||
</span>
|
||||
<span className="text-xs text-gray-400">{formatBytes(segment.sizeBytes)}</span>
|
||||
<div className="my-2 rounded-lg border border-gray-200 bg-white overflow-hidden hover:shadow-sm transition-shadow">
|
||||
{/* 文档信息卡片 */}
|
||||
<div className="flex items-start gap-3 p-3">
|
||||
<div className="shrink-0 mt-0.5">{getIcon(segment.mimeType)}</div>
|
||||
<div className="flex-1 min-w-0">
|
||||
<div className="flex items-center gap-2 flex-wrap">
|
||||
<span className="text-sm font-medium text-gray-800 truncate">
|
||||
{segment.fileName}
|
||||
</span>
|
||||
<span className="text-xs text-gray-400">{formatBytes(segment.sizeBytes)}</span>
|
||||
</div>
|
||||
<p className="text-xs text-gray-400 mt-0.5">{segment.mimeType}</p>
|
||||
{!showParsed && (
|
||||
<p className="text-xs text-gray-500 mt-1.5 line-clamp-3 italic">
|
||||
{segment.snippet}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
<p className="text-xs text-gray-400 mt-0.5">{segment.mimeType}</p>
|
||||
<p className="text-xs text-gray-500 mt-1.5 line-clamp-3 italic">
|
||||
{segment.snippet}
|
||||
</p>
|
||||
|
||||
{/* 查看解析按钮 */}
|
||||
{segment.parsedContent && (
|
||||
<button
|
||||
onClick={() => setShowParsed(!showParsed)}
|
||||
className="shrink-0 flex items-center gap-1 px-2.5 py-1.5 rounded-md text-xs font-medium transition-colors
|
||||
bg-blue-50 text-blue-600 hover:bg-blue-100"
|
||||
>
|
||||
{showParsed ? (
|
||||
<><EyeOff size={13} /> 收起解析</>
|
||||
) : (
|
||||
<><Eye size={13} /> 查看解析</>
|
||||
)}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* 解析结果展开区 */}
|
||||
{showParsed && segment.parsedContent && (
|
||||
<div className="border-t border-gray-100">
|
||||
<div className="flex items-center gap-1.5 px-3 pt-2 pb-1">
|
||||
<FileText size={12} className="text-blue-400" />
|
||||
<span className="text-[11px] font-medium text-blue-500">解析结果</span>
|
||||
<div className="flex-1" />
|
||||
<button
|
||||
onClick={() => setShowParsed(false)}
|
||||
className="text-gray-400 hover:text-gray-600"
|
||||
>
|
||||
<ChevronDown size={14} />
|
||||
</button>
|
||||
</div>
|
||||
<div className="px-3 pb-3 max-h-80 overflow-y-auto text-sm">
|
||||
<MarkdownRenderer content={segment.parsedContent} />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -13,8 +13,8 @@ interface ChatContextValue {
|
||||
const ChatContext = createContext<ChatContextValue | null>(null)
|
||||
|
||||
export function ChatProvider({ children }: { children: ReactNode }) {
|
||||
const [activeDemo, setActiveDemo] = useState(5) // Default: Real Skills Demo F
|
||||
const [envelope, setEnvelope] = useState<PromptEnvelope>(demos[5].envelope)
|
||||
const [activeDemo, setActiveDemo] = useState(4) // Default: Scene F
|
||||
const [envelope, setEnvelope] = useState<PromptEnvelope>(demos[4].envelope)
|
||||
|
||||
const switchDemo = (i: number) => {
|
||||
setActiveDemo(i)
|
||||
|
||||
+4
-4
@@ -28,8 +28,8 @@ export const demos: DemoScenario[] = [
|
||||
},
|
||||
{
|
||||
id: 'c',
|
||||
label: '场景 C',
|
||||
description: '长文本 + 文档附件 + 多模态',
|
||||
label: '场景 C 📄',
|
||||
description: '文档解析:点击「查看解析」看 AI 如何提取文档内容',
|
||||
envelope: demoC,
|
||||
},
|
||||
{
|
||||
@@ -40,8 +40,8 @@ export const demos: DemoScenario[] = [
|
||||
},
|
||||
{
|
||||
id: 'e',
|
||||
label: '场景 E 🧪',
|
||||
description: 'Skills 渐进式披露 + Agent 主动触发 /deep-research',
|
||||
label: '场景 E 🔍',
|
||||
description: '日志分析:异常检测 + 安全审计 + 性能分析',
|
||||
envelope: demoE,
|
||||
},
|
||||
{
|
||||
|
||||
+91
-57
@@ -1,57 +1,66 @@
|
||||
/**
|
||||
* Demo C — 文档解析(核心展示)
|
||||
*
|
||||
* 场景:用户上传多份文档请求 AI 进行解析,展示文档上传后 AI 如何
|
||||
* 提取、结构化理解其中的内容。
|
||||
*
|
||||
* 关键展示:
|
||||
* 1. 一份 PDF 文档,右上角有「查看解析」按钮
|
||||
* 2. 点击后展开显示 AI 对文档的解析结果(Markdown 渲染)
|
||||
* 3. Assistant 基于解析结果给出分析回答
|
||||
* 4. 无 long_text / media / 多文档干扰 —— 聚焦单文档解析体验
|
||||
*/
|
||||
|
||||
import type { PromptEnvelope } from '../../types/protocol'
|
||||
import { getSkills } from '../skills'
|
||||
|
||||
const now = Date.now()
|
||||
|
||||
const longArticleContent_C = `# 大语言模型交互中的上下文透明性问题
|
||||
/** PDF 市场调研报告的解析结果 */
|
||||
const marketReportParsed = `## 文档概览
|
||||
|
||||
## 摘要
|
||||
| 字段 | 内容 |
|
||||
|------|------|
|
||||
| 标题 | 2026 年 Q2 智能助手市场研究报告 |
|
||||
| 作者 | 市场分析部 · 陈敏 |
|
||||
| 日期 | 2026 年 5 月 28 日 |
|
||||
| 页数 | 42 页 |
|
||||
| 语言 | 中文(简体) |
|
||||
|
||||
近年来,以 ChatGPT 为代表的对话式 AI 产品迅速普及。然而,这些产品的交互设计普遍存在"上下文不透明"的问题——用户无法了解模型在生成回复时参考了哪些信息、使用了哪些工具、被施加了怎样的约束。
|
||||
## 核心发现
|
||||
|
||||
## 1. 问题定义
|
||||
### 1. 市场规模
|
||||
2026 年 Q2 全球智能助手市场规模预计达到 **187 亿美元**,同比增长 **34.2%**。
|
||||
|
||||
当前的聊天界面(chatbox UI)将 LLM 的完整上下文封装在黑盒之中。用户看到的是一个"魔法对话框":输入问题,得到回答。但这个过程掩盖了大量关键信息:
|
||||
主要增长驱动力:
|
||||
- 企业级 AI 助手采纳率从 2025 年的 38% 提升至 56%
|
||||
- 多模态能力(图像/语音/代码)推动使用场景扩展
|
||||
- 开源模型的成熟降低了部署门槛
|
||||
|
||||
- **System Prompt**:模型的行为准则和角色设定,直接决定了回复的风格和边界
|
||||
- **User Memory**:跨对话持久化的用户信息,可能包含过时或不准确的记忆
|
||||
- **Tools & Skills**:模型可调用的外部能力,用户可能完全不知道它们的存在
|
||||
- **Variable Injection**:模板变量在用户不知情的情况下被替换为具体值
|
||||
### 2. 竞争格局
|
||||
|
||||
这种不透明性导致了一系列用户体验问题:信任缺失、纠错困难、意外行为难以解释。
|
||||
| 厂商 | 市场份额 | QoQ 变化 | 核心优势 |
|
||||
|------|---------|---------|---------|
|
||||
| OpenAI | 41% | +2.3% | 品牌认知度 + 开发者生态 |
|
||||
| Anthropic | 18% | +5.1% | 安全对齐 + 长上下文 |
|
||||
| Google | 15% | -1.2% | 搜索整合 + 多模态 |
|
||||
| Meta | 12% | +3.8% | 开源策略 + 成本优势 |
|
||||
| 其他 | 14% | — | 垂直领域玩家 |
|
||||
|
||||
## 2. 设计目标
|
||||
### 3. 用户需求变化
|
||||
- **可信度**成为用户选择助手的第一要素(47% 受访者提及)
|
||||
- **上下文窗口大小**的优先级从 2025 年的第 7 位跃升至第 3 位
|
||||
- 企业用户对 \`system prompt\` 透明度的需求同比增长 **82%**
|
||||
- 工具调用(Function Calling)的使用率从 23% 增长到 51%
|
||||
|
||||
本文提出一套"Prompt Envelope Protocol"——一种结构化的 prompt 表达格式,使得:
|
||||
|
||||
1. 每种上下文元素都有明确的视觉呈现
|
||||
2. 用户可以按需展开或折叠细节
|
||||
3. 协议可以无损导出为标准 API 格式
|
||||
4. 视觉语言保持简约,不增加认知负荷
|
||||
|
||||
## 3. 核心设计原则
|
||||
|
||||
### 3.1 信息密度梯度
|
||||
|
||||
核心对话文本始终可见,元信息默认折叠。用户不会在每次对话中都被无关的 system prompt 和工具列表淹没。
|
||||
|
||||
### 3.2 颜色编码系统
|
||||
|
||||
每种上下文类型有独立的颜色标记,形成可学习的视觉语言:
|
||||
- 蓝色 = 变量
|
||||
- 灰色 = 系统指令
|
||||
- 紫色 = 用户记忆
|
||||
- 绿色 = 技能
|
||||
- 橙色 = 工具
|
||||
|
||||
### 3.3 协议即视图
|
||||
|
||||
折叠状态存储在协议数据中而非 UI 状态中。这意味着相同的协议数据在任何渲染器下都产生相同的视图——协议本身就是 view model。`
|
||||
### 4. 关键趋势
|
||||
> "智能助手的竞争从模型能力转向体验设计。用户不再只关心'能不能答对',更关心'我能不能理解你为什么这么回答'。"——报告结语`
|
||||
|
||||
export const demoC: PromptEnvelope = {
|
||||
version: '1.0',
|
||||
model: 'gpt-4-turbo',
|
||||
messages: [
|
||||
// --- System message ---
|
||||
{
|
||||
id: 'c-1',
|
||||
role: 'system',
|
||||
@@ -72,58 +81,83 @@ export const demoC: PromptEnvelope = {
|
||||
kind: 'system_prompt',
|
||||
content: `当前日期:{{current_date}},回复语言:{{language}}。
|
||||
|
||||
你是文档审阅助手。帮助用户分析长文档、提取要点、回答关于文档内容的问题。`,
|
||||
你是文档解析助手。帮助用户分析上传的文档、提取关键信息、回答关于文档内容的问题。
|
||||
|
||||
解析文档后,你会输出结构化的解析结果,并在回复中注明关键发现。`,
|
||||
collapsed: true,
|
||||
},
|
||||
{
|
||||
kind: 'skills',
|
||||
description:
|
||||
'Skills 是模型可调用的内置能力(slash commands)。输入 / 开头即可触发,无需等待模型推理。当前对话中启用以下 skills:',
|
||||
'Skills 是模型可调用的内置能力(slash commands)。当前对话中启用以下 skills:',
|
||||
items: getSkills(['summarize', 'translate', 'qa']),
|
||||
collapsed: true,
|
||||
},
|
||||
],
|
||||
timestamp: now - 150000,
|
||||
},
|
||||
// --- User 上传文档请求解析 ---
|
||||
{
|
||||
id: 'c-2',
|
||||
role: 'user',
|
||||
segments: [
|
||||
{
|
||||
kind: 'text',
|
||||
content: '帮我审阅这篇论文草稿,看看结构上有什么问题:',
|
||||
},
|
||||
{
|
||||
kind: 'long_text',
|
||||
content: longArticleContent_C,
|
||||
charCount: longArticleContent_C.length,
|
||||
collapsed: true,
|
||||
content: '帮我解析这份市场研究报告,看看有什么关键发现。',
|
||||
},
|
||||
{
|
||||
kind: 'document',
|
||||
fileName: 'hci-paper-draft.pdf',
|
||||
fileName: '2026-Q2-智能助手市场报告.pdf',
|
||||
mimeType: 'application/pdf',
|
||||
snippet:
|
||||
'# 大语言模型交互中的上下文透明性问题\n\n## 摘要\n\n近年来,以 ChatGPT 为代表的对话式 AI 产品迅速普及。然而,这些产品的交互设计普遍存在"上下文不透明"的问题——用户无法了解模型在生成回复时参考了哪些信息...',
|
||||
sizeBytes: 245760,
|
||||
},
|
||||
{
|
||||
kind: 'media',
|
||||
mediaType: 'image',
|
||||
url: '',
|
||||
altText: '论文框架图:Context Layers 分层示意图',
|
||||
sizeBytes: 2_845_000,
|
||||
snippet: '# 2026 年 Q2 智能助手市场研究报告\n\n## 摘要\n\n2026 年 Q2 全球智能助手市场规模预计达到 187 亿美元,同比增长 34.2%。主要增长驱动力包括企业级 AI 助手采纳率提升…',
|
||||
parsedContent: marketReportParsed,
|
||||
},
|
||||
],
|
||||
timestamp: now - 120000,
|
||||
},
|
||||
// --- Assistant 综合回复 ---
|
||||
{
|
||||
id: 'c-3',
|
||||
role: 'assistant',
|
||||
segments: [
|
||||
{
|
||||
kind: 'text',
|
||||
content:
|
||||
'我读完了你的草稿。整体框架很清晰,但有几个建议:\n\n1. **第3节的设计原则**是目前最强的部分,可以考虑将这部分提前到第2节\n2. "信息密度梯度"这个概念很有原创性,建议在摘要中就提及\n3. 缺少用户研究部分——如果你有做可用性测试的计划,可以加一节"4. 评估方法"\n4. 颜色编码系统部分写得很好,可以加一个视觉化的表格来展示颜色-类型映射\n\n需要我展开其中某一点吗?',
|
||||
content: `文档已解析完成。以下是报告中的关键发现:
|
||||
|
||||
---
|
||||
|
||||
## 📊 核心发现
|
||||
|
||||
### 1. 市场规模与增长
|
||||
2026 年 Q2 全球智能助手市场规模预计达到 **187 亿美元**,同比增长 **34.2%**。
|
||||
|
||||
主要驱动力:
|
||||
- 企业级 AI 助手采纳率从 38% 提升至 **56%**
|
||||
- 多模态能力推动使用场景扩展
|
||||
- 开源模型降低了部署门槛
|
||||
|
||||
### 2. 竞争格局变化
|
||||
|
||||
| 厂商 | 份额 | 环比变化 | 核心优势 |
|
||||
|------|------|---------|---------|
|
||||
| OpenAI | 41% | +2.3% | 品牌 + 开发者生态 |
|
||||
| Anthropic | 18% | **+5.1%** | 安全对齐 + 长上下文 |
|
||||
| Google | 15% | -1.2% | 搜索整合 + 多模态 |
|
||||
| Meta | 12% | +3.8% | 开源 + 成本优势 |
|
||||
|
||||
Anthropic 的增长最快(+5.1%),说明 **安全对齐** 正在成为关键竞争力。
|
||||
|
||||
### 3. 值得关注的趋势
|
||||
|
||||
- **可信度** 是用户选择助手的首要因素(47% 受访者提及)
|
||||
- 企业用户对 \`system prompt\` 透明度的需求同比增长 **82%**
|
||||
- 工具调用(Function Calling)使用率从 23% 增长到 51%
|
||||
- 报告结语指出:**竞争正从模型能力转向体验设计**
|
||||
|
||||
---
|
||||
|
||||
需要我深入分析某个方面吗?点击文档的 **「查看解析」** 按钮可以看到 AI 提取的完整结构化内容。`,
|
||||
},
|
||||
],
|
||||
timestamp: now - 60000,
|
||||
|
||||
+280
-134
@@ -1,13 +1,53 @@
|
||||
/**
|
||||
* Demo E — 日志分析(无文档传入)
|
||||
*
|
||||
* 场景:用户分享一段 Nginx 访问日志,请求 AI 助手帮忙分析
|
||||
* 异常模式和潜在安全风险。
|
||||
*
|
||||
* 关键展示:
|
||||
* 1. long_text 用于展示原始日志全文(折叠态仅显示前2行)
|
||||
* 2. tool_call_request/result 展示日志分析工具的调用过程
|
||||
* 3. static_var 注入服务器环境和分析参数
|
||||
* 4. memory 记录用户的系统环境和分析偏好
|
||||
* 5. 无 document/media 段 —— 突出"纯文本日志分析"场景
|
||||
*/
|
||||
|
||||
import type { PromptEnvelope } from '../../types/protocol'
|
||||
import { getSkills } from '../skills'
|
||||
|
||||
const now = Date.now()
|
||||
|
||||
const sampleLog = `192.168.1.10 - - [07/Jun/2026:10:15:23 +0800] "GET /api/users HTTP/1.1" 200 1234 "-" "curl/7.88.1"
|
||||
192.168.1.20 - - [07/Jun/2026:10:15:25 +0800] "POST /api/login HTTP/1.1" 302 0 "-" "Mozilla/5.0"
|
||||
10.0.0.5 - - [07/Jun/2026:10:15:28 +0800] "GET /health HTTP/1.1" 200 2 "-" "Kubernetes/1.28"
|
||||
192.168.1.10 - - [07/Jun/2026:10:16:01 +0800] "GET /api/orders HTTP/1.1" 200 8921 "-" "curl/7.88.1"
|
||||
203.0.113.42 - - [07/Jun/2026:10:16:05 +0800] "GET /admin HTTP/1.1" 403 189 "-" "python-requests/2.31.0"
|
||||
203.0.113.42 - - [07/Jun/2026:10:16:06 +0800] "GET /admin/config HTTP/1.1" 404 153 "-" "python-requests/2.31.0"
|
||||
203.0.113.42 - - [07/Jun/2026:10:16:07 +0800] "POST /admin/login HTTP/1.1" 401 198 "-" "python-requests/2.31.0"
|
||||
203.0.113.42 - - [07/Jun/2026:10:16:08 +0800] "POST /admin/login HTTP/1.1" 401 198 "-" "python-requests/2.31.0"
|
||||
203.0.113.42 - - [07/Jun/2026:10:16:09 +0800] "POST /admin/login HTTP/1.1" 401 198 "-" "python-requests/2.31.0"
|
||||
203.0.113.42 - - [07/Jun/2026:10:16:10 +0800] "POST /admin/login HTTP/1.1" 401 198 "-" "python-requests/2.31.0"
|
||||
203.0.113.42 - - [07/Jun/2026:10:16:11 +0800] "POST /admin/login HTTP/1.1" 401 198 "-" "python-requests/2.31.0"
|
||||
192.168.1.30 - - [07/Jun/2026:10:17:00 +0800] "GET /api/products?page=1 HTTP/1.1" 200 15420 "-" "Mozilla/5.0"
|
||||
192.168.1.30 - - [07/Jun/2026:10:17:02 +0800] "GET /api/products?page=2 HTTP/1.1" 200 14893 "-" "Mozilla/5.0"
|
||||
192.168.1.30 - - [07/Jun/2026:10:17:04 +0800] "GET /api/products?page=3 HTTP/1.1" 200 15102 "-" "Mozilla/5.0"
|
||||
198.51.100.7 - - [07/Jun/2026:10:18:30 +0800] "GET / HTTP/1.1" 200 5678 "-" "Mozilla/5.0"
|
||||
198.51.100.7 - - [07/Jun/2026:10:18:32 +0800] "GET /static/css/main.css HTTP/1.1" 200 28491 "-" "Mozilla/5.0"
|
||||
198.51.100.7 - - [07/Jun/2026:10:18:33 +0800] "GET /static/js/app.js HTTP/1.1" 200 128034 "-" "Mozilla/5.0"
|
||||
10.0.0.5 - - [07/Jun/2026:10:20:00 +0800] "GET /health HTTP/1.1" 200 2 "-" "Kubernetes/1.28"
|
||||
192.168.1.10 - - [07/Jun/2026:10:21:15 +0800] "GET /api/users HTTP/1.1" 200 1234 "-" "curl/7.88.1"
|
||||
192.168.1.10 - - [07/Jun/2026:10:21:16 +0800] "GET /api/orders HTTP/1.1" 200 8921 "-" "curl/7.88.1"
|
||||
192.168.1.10 - - [07/Jun/2026:10:21:17 +0800] "GET /api/products HTTP/1.1" 200 15420 "-" "curl/7.88.1"
|
||||
10.0.0.6 - - [07/Jun/2026:10:22:00 +0800] "GET /health HTTP/1.1" 503 57 "-" "Kubernetes/1.28"
|
||||
10.0.0.6 - - [07/Jun/2026:10:22:05 +0800] "GET /health HTTP/1.1" 503 57 "-" "Kubernetes/1.28"
|
||||
10.0.0.6 - - [07/Jun/2026:10:22:10 +0800] "GET /health HTTP/1.1" 503 57 "-" "Kubernetes/1.28"
|
||||
10.0.0.6 - - [07/Jun/2026:10:22:15 +0800] "GET /health HTTP/1.1" 200 2 "-" "Kubernetes/1.28"`
|
||||
|
||||
export const demoE: PromptEnvelope = {
|
||||
version: '1.0',
|
||||
model: 'claude-opus-4-8',
|
||||
messages: [
|
||||
// --- System message: 加载 skills + memory + tools ---
|
||||
// --- System message ---
|
||||
{
|
||||
id: 'e-1',
|
||||
role: 'system',
|
||||
@@ -20,45 +60,56 @@ export const demoE: PromptEnvelope = {
|
||||
},
|
||||
{
|
||||
kind: 'static_var',
|
||||
name: 'language',
|
||||
value: '中文(简体)',
|
||||
description: '模型回复的首选语言',
|
||||
name: 'server_name',
|
||||
value: 'production-api-01',
|
||||
description: '目标服务器名称',
|
||||
},
|
||||
{
|
||||
kind: 'static_var',
|
||||
name: 'knowledge_cutoff',
|
||||
value: '2026年1月',
|
||||
description: '模型训练数据截止日期',
|
||||
name: 'analysis_depth',
|
||||
value: '全面(异常检测 + 安全审计 + 性能分析)',
|
||||
description: '日志分析的范围深度',
|
||||
},
|
||||
{
|
||||
kind: 'system_prompt',
|
||||
content: `当前日期:{{current_date}}
|
||||
回复语言:{{language}}
|
||||
知识截止:{{knowledge_cutoff}}
|
||||
目标服务器:{{server_name}}
|
||||
分析范围:{{analysis_depth}}
|
||||
|
||||
你是 HCI 课程设计助手,具备 Anthropic Skills 机制。
|
||||
你是日志分析专家助手。你的核心能力:
|
||||
|
||||
你有以下 skills 可用。用户输入以 / 开头的命令时会直接触发对应 skill。你也可以在分析用户意图后,主动建议合适的 skill。
|
||||
1. **异常检测** — 识别错误状态码(4xx/5xx)、请求突增、响应时间异常
|
||||
2. **安全审计** — 发现暴力破解尝试、路径探测、SQL 注入尝试
|
||||
3. **性能分析** — 统计端点响应分布、慢请求排查、热点资源识别
|
||||
4. **趋势报告** — 按时间窗口聚合,生成可读性高的分析摘要
|
||||
|
||||
回复风格:简洁、有结构、给出可操作建议。`,
|
||||
分析原则:
|
||||
- 优先发现模式而非孤立事件
|
||||
- 区分误报和真正的问题
|
||||
- 每个发现标注严重等级和置信度
|
||||
- 在工具调用中执行计算分析,回复中给出解读`,
|
||||
collapsed: true,
|
||||
},
|
||||
{
|
||||
kind: 'memory',
|
||||
description:
|
||||
'以下是从过往对话中总结的关于你的信息,模型会参考这些记忆来个性化回复。',
|
||||
'以下是你对用户的了解,参考这些记录来提供个性化的日志分析服务。',
|
||||
items: [
|
||||
{
|
||||
title: '用户背景',
|
||||
content: '小明,设计系研二,HCI 方向。正在做课程设计,课题是 LLM 上下文透明性。',
|
||||
title: '用户身份',
|
||||
content: '小陈,后端开发工程师,负责生产环境的运维监控。',
|
||||
},
|
||||
{
|
||||
title: '当前进度',
|
||||
content: '已完成 MVP 开发(React + TypeScript 聊天界面),展示了 9 种 Segment 的差异化渲染。',
|
||||
title: '系统环境',
|
||||
content: 'Kubernetes 集群上的微服务架构,API 网关使用 Nginx。生产环境有三台节点。',
|
||||
},
|
||||
{
|
||||
title: '关注点',
|
||||
content: '关心 Anthropic Skills 的渐进式披露机制能否作为 HCI 课程中的交互设计案例。',
|
||||
title: '分析偏好',
|
||||
content: '偏好先看整体概览再深入细节。对安全相关告警特别敏感,需要高亮标注。',
|
||||
},
|
||||
{
|
||||
title: '上次分析记录',
|
||||
content: '上周分析过同一台服务器的日志,发现了一个定时任务导致的 503 抖动。',
|
||||
},
|
||||
],
|
||||
collapsed: true,
|
||||
@@ -66,190 +117,285 @@ export const demoE: PromptEnvelope = {
|
||||
{
|
||||
kind: 'skills',
|
||||
description:
|
||||
'Skills 是模型可调用的内置能力。输入 / 触发,或根据对话上下文由 Agent 自动判断并调用。当前可用以下 skills:',
|
||||
items: getSkills(['deep-research', 'code-review', 'verify', 'simplify', 'loop']),
|
||||
'以下是可用的技能助手,通过 /skill_name 触发:',
|
||||
items: getSkills(['summarize', 'qa', 'translate']),
|
||||
collapsed: true,
|
||||
},
|
||||
{
|
||||
kind: 'tool_overview',
|
||||
items: [
|
||||
{
|
||||
name: 'run_skill',
|
||||
description: '执行一个 Skill(slash command)',
|
||||
parameters: 'skill_name: string, input: string',
|
||||
name: 'run_code',
|
||||
description: '在沙箱中执行 Python/Shell 代码进行日志解析和统计',
|
||||
parameters: 'language: string, code: string',
|
||||
schema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
skill_name: { type: 'string', description: 'Skill 名称' },
|
||||
input: { type: 'string', description: '传递给 skill 的用户输入' },
|
||||
language: { type: 'string', enum: ['python', 'bash'], description: '执行语言' },
|
||||
code: { type: 'string', description: '要执行的代码' },
|
||||
},
|
||||
required: ['skill_name', 'input'],
|
||||
required: ['language', 'code'],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'search_knowledge',
|
||||
description: '搜索已知的漏洞模式和安全公告',
|
||||
parameters: 'query: string',
|
||||
schema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
query: { type: 'string', description: '搜索关键词' },
|
||||
},
|
||||
required: ['query'],
|
||||
},
|
||||
},
|
||||
],
|
||||
collapsed: true,
|
||||
},
|
||||
],
|
||||
timestamp: now - 360000,
|
||||
timestamp: now - 600000,
|
||||
},
|
||||
// --- User message: 触发 research 需求 ---
|
||||
// --- User 请求日志分析 ---
|
||||
{
|
||||
id: 'e-2',
|
||||
role: 'user',
|
||||
segments: [
|
||||
{
|
||||
kind: 'text',
|
||||
content: '我想深入了解 Anthropic Skills 的渐进式披露机制(Progressive Disclosure),作为我的 HCI 课程论文的案例研究对象。请帮我调研一下这个机制的设计原理、交互模式和学术界相关讨论。',
|
||||
content: '生产环境 API 服务器刚刚的访问日志,帮我看一下有没有异常。我自己扫了一遍,感觉有几个可疑的 IP 在尝试访问 /admin 路径,但不太确定是不是误报。另外 /health 端点偶尔返回 503 的情况也需要你分析一下。',
|
||||
},
|
||||
{
|
||||
kind: 'long_text',
|
||||
content: sampleLog,
|
||||
charCount: sampleLog.length,
|
||||
collapsed: true,
|
||||
},
|
||||
],
|
||||
timestamp: now - 300000,
|
||||
timestamp: now - 500000,
|
||||
},
|
||||
// --- Assistant: 判断需要 research,主动触发 /deep-research ---
|
||||
// --- Assistant 初始分析回复 ---
|
||||
{
|
||||
id: 'e-3',
|
||||
role: 'assistant',
|
||||
segments: [
|
||||
{
|
||||
kind: 'text',
|
||||
content: `你的课程论文选题很棒!Anthropic Skills 的渐进式披露机制确实是一个很好的 HCI 案例分析对象——它以 **三阶段信息展开**(overview → detail → full instructions)来降低认知负荷,同时保持功能的可发现性。
|
||||
content: `我来分析这份日志。先快速概览一下整体情况:
|
||||
|
||||
让我用 \`/deep-research\` skill 做一个系统性调研:`,
|
||||
从格式看是标准的 Nginx combined 格式,时间窗口约 **10:15–10:22**(约 7 分钟),共 **25 条**请求记录。几家不同的客户端:
|
||||
|
||||
- **192.168.1.10** — 内部 API 调用(curl)
|
||||
- **192.168.1.20** — 正常浏览器登录
|
||||
- **10.0.0.5** — K8s 健康检查
|
||||
- **192.168.1.30** — 浏览器浏览商品页面
|
||||
- **198.51.100.7** — 正常用户访问首页
|
||||
- **10.0.0.6** — 另一台节点的健康检查
|
||||
- **203.0.113.42** — ⚠️ 可疑 IP
|
||||
|
||||
我先用 \`run_code\` 对请求做聚合统计,确认模式后再深入分析可疑流量。`,
|
||||
},
|
||||
{
|
||||
kind: 'tool_call_request',
|
||||
toolName: 'run_skill',
|
||||
toolName: 'run_code',
|
||||
arguments: {
|
||||
skill_name: 'deep-research',
|
||||
input: 'Anthropic Skills progressive disclosure mechanism — design principles, interaction patterns, HCI academic discussions, related concepts (progressive disclosure in UX, Nielsen\'s heuristics, information architecture patterns for AI interfaces)',
|
||||
language: 'python',
|
||||
code: `from collections import Counter, defaultdict
|
||||
import re
|
||||
|
||||
log_text = """192.168.1.10 - - [07/Jun/2026:10:15:23 +0800] "GET /api/users HTTP/1.1" 200 1234 "-" "curl/7.88.1"
|
||||
192.168.1.20 - - [07/Jun/2026:10:15:25 +0800] "POST /api/login HTTP/1.1" 302 0 "-" "Mozilla/5.0"
|
||||
10.0.0.5 - - [07/Jun/2026:10:15:28 +0800] "GET /health HTTP/1.1" 200 2 "-" "Kubernetes/1.28"
|
||||
192.168.1.10 - - [07/Jun/2026:10:16:01 +0800] "GET /api/orders HTTP/1.1" 200 8921 "-" "curl/7.88.1"
|
||||
203.0.113.42 - - [07/Jun/2026:10:16:05 +0800] "GET /admin HTTP/1.1" 403 189 "-" "python-requests/2.31.0"
|
||||
203.0.113.42 - - [07/Jun/2026:10:16:06 +0800] "GET /admin/config HTTP/1.1" 404 153 "-" "python-requests/2.31.0"
|
||||
203.0.113.42 - - [07/Jun/2026:10:16:07 +0800] "POST /admin/login HTTP/1.1" 401 198 "-" "python-requests/2.31.0"
|
||||
203.0.113.42 - - [07/Jun/2026:10:16:08 +0800] "POST /admin/login HTTP/1.1" 401 198 "-" "python-requests/2.31.0"
|
||||
203.0.113.42 - - [07/Jun/2026:10:16:09 +0800] "POST /admin/login HTTP/1.1" 401 198 "-" "python-requests/2.31.0"
|
||||
203.0.113.42 - - [07/Jun/2026:10:16:10 +0800] "POST /admin/login HTTP/1.1" 401 198 "-" "python-requests/2.31.0"
|
||||
203.0.113.42 - - [07/Jun/2026:10:16:11 +0800] "POST /admin/login HTTP/1.1" 401 198 "-" "python-requests/2.31.0"
|
||||
192.168.1.30 - - [07/Jun/2026:10:17:00 +0800] "GET /api/products?page=1 HTTP/1.1" 200 15420 "-" "Mozilla/5.0"
|
||||
192.168.1.30 - - [07/Jun/2026:10:17:02 +0800] "GET /api/products?page=2 HTTP/1.1" 200 14893 "-" "Mozilla/5.0"
|
||||
192.168.1.30 - - [07/Jun/2026:10:17:04 +0800] "GET /api/products?page=3 HTTP/1.1" 200 15102 "-" "Mozilla/5.0"
|
||||
198.51.100.7 - - [07/Jun/2026:10:18:30 +0800] "GET / HTTP/1.1" 200 5678 "-" "Mozilla/5.0"
|
||||
198.51.100.7 - - [07/Jun/2026:10:18:32 +0800] "GET /static/css/main.css HTTP/1.1" 200 28491 "-" "Mozilla/5.0"
|
||||
198.51.100.7 - - [07/Jun/2026:10:18:33 +0800] "GET /static/js/app.js HTTP/1.1" 200 128034 "-" "Mozilla/5.0"
|
||||
10.0.0.5 - - [07/Jun/2026:10:20:00 +0800] "GET /health HTTP/1.1" 200 2 "-" "Kubernetes/1.28"
|
||||
192.168.1.10 - - [07/Jun/2026:10:21:15 +0800] "GET /api/users HTTP/1.1" 200 1234 "-" "curl/7.88.1"
|
||||
192.168.1.10 - - [07/Jun/2026:10:21:16 +0800] "GET /api/orders HTTP/1.1" 200 8921 "-" "curl/7.88.1"
|
||||
192.168.1.10 - - [07/Jun/2026:10:21:17 +0800] "GET /api/products HTTP/1.1" 200 15420 "-" "curl/7.88.1"
|
||||
10.0.0.6 - - [07/Jun/2026:10:22:00 +0800] "GET /health HTTP/1.1" 503 57 "-" "Kubernetes/1.28"
|
||||
10.0.0.6 - - [07/Jun/2026:10:22:05 +0800] "GET /health HTTP/1.1" 503 57 "-" "Kubernetes/1.28"
|
||||
10.0.0.6 - - [07/Jun/2026:10:22:10 +0800] "GET /health HTTP/1.1" 503 57 "-" "Kubernetes/1.28"
|
||||
10.0.0.6 - - [07/Jun/2026:10:22:15 +0800] "GET /health HTTP/1.1" 200 2 "-" "Kubernetes/1.28"""
|
||||
|
||||
# 解析日志
|
||||
pattern = r'(\\S+) - - \\[(.+?)\\] "(.+?)" (\\d+) (\\d+) ".*?" "(.*?)"'
|
||||
records = []
|
||||
for line in log_text.strip().split('\\n'):
|
||||
m = re.match(pattern, line)
|
||||
if m:
|
||||
records.append({
|
||||
'ip': m.group(1),
|
||||
'time': m.group(2),
|
||||
'request': m.group(3),
|
||||
'status': int(m.group(4)),
|
||||
'size': int(m.group(5)),
|
||||
'ua': m.group(6)
|
||||
})
|
||||
|
||||
# 1. IP 统计
|
||||
print("=== 按 IP 请求量统计 ===")
|
||||
ip_counter = Counter(r['ip'] for r in records)
|
||||
for ip, count in ip_counter.most_common():
|
||||
print(f" {ip:20s} → {count} 次请求")
|
||||
|
||||
# 2. 状态码分布
|
||||
print("\\n=== 状态码分布 ===")
|
||||
status_counter = Counter(r['status'] for r in records)
|
||||
for code, count in sorted(status_counter.items()):
|
||||
print(f" {code} → {count} 次")
|
||||
|
||||
# 3. 可疑 IP 分析
|
||||
print("\\n=== 可疑 IP: 203.0.113.42 的请求序列 ===")
|
||||
for r in records:
|
||||
if r['ip'] == '203.0.113.42':
|
||||
print(f" [{r['time']}] {r['request']} → {r['status']}")
|
||||
|
||||
# 4. /health 端点分析
|
||||
print("\\n=== /health 端点状态 ===")
|
||||
for r in records:
|
||||
if '/health' in r['request']:
|
||||
print(f" {r['ip']:15s} [{r['time']}] → {r['status']} (UA: {r['ua']})")
|
||||
|
||||
# 5. 非 2xx 占比
|
||||
total = len(records)
|
||||
errors = sum(1 for r in records if r['status'] >= 400)
|
||||
print(f"\\n=== 总结 ===")
|
||||
print(f" 总请求数: {total}")
|
||||
print(f" 错误请求: {errors} ({errors/total*100:.1f}%)")
|
||||
print(f" 正常请求: {total - errors} ({(total-errors)/total*100:.1f}%)")`,
|
||||
},
|
||||
collapsed: false,
|
||||
},
|
||||
],
|
||||
timestamp: now - 280000,
|
||||
timestamp: now - 480000,
|
||||
},
|
||||
// --- Skill 触发:指令以 tool_call_result 形式追加到对话 ---
|
||||
// --- Tool 调用结果 ---
|
||||
{
|
||||
id: 'e-4',
|
||||
role: 'assistant',
|
||||
segments: [
|
||||
{
|
||||
kind: 'tool_call_result',
|
||||
toolName: 'run_skill',
|
||||
toolName: 'run_code',
|
||||
success: true,
|
||||
result: `[/deep-research 已触发]
|
||||
result: `=== 按 IP 请求量统计 ===
|
||||
192.168.1.10 → 5 次请求
|
||||
203.0.113.42 → 7 次请求
|
||||
198.51.100.7 → 3 次请求
|
||||
10.0.0.5 → 2 次请求
|
||||
10.0.0.6 → 4 次请求
|
||||
192.168.1.20 → 1 次请求
|
||||
192.168.1.30 → 3 次请求
|
||||
|
||||
深度研究工作流程:
|
||||
1. 分析用户问题,拆解为 3-5 个子问题
|
||||
2. 对每个子问题执行多源搜索(学术 + 行业 + 新闻)
|
||||
3. 抓取高相关性页面全文
|
||||
4. 交叉验证:至少两个独立来源确认同一关键事实
|
||||
5. 生成报告格式:摘要 → 分项发现 → 证据表 → 限定说明
|
||||
6. 每声明标注来源和可信度评级`,
|
||||
collapsed: true,
|
||||
=== 状态码分布 ===
|
||||
200 → 14 次
|
||||
302 → 1 次
|
||||
401 → 5 次
|
||||
403 → 1 次
|
||||
404 → 1 次
|
||||
503 → 3 次
|
||||
|
||||
=== 可疑 IP: 203.0.113.42 的请求序列 ===
|
||||
[07/Jun/2026:10:16:05 +0800] GET /admin → 403
|
||||
[07/Jun/2026:10:16:06 +0800] GET /admin/config → 404
|
||||
[07/Jun/2026:10:16:07 +0800] POST /admin/login → 401
|
||||
[07/Jun/2026:10:16:08 +0800] POST /admin/login → 401
|
||||
[07/Jun/2026:10:16:09 +0800] POST /admin/login → 401
|
||||
[07/Jun/2026:10:16:10 +0800] POST /admin/login → 401
|
||||
[07/Jun/2026:10:16:11 +0800] POST /admin/login → 401
|
||||
|
||||
=== /health 端点状态 ===
|
||||
10.0.0.5 [07/Jun/2026:10:15:28 +0800] → 200 (UA: Kubernetes/1.28)
|
||||
10.0.0.5 [07/Jun/2026:10:20:00 +0800] → 200 (UA: Kubernetes/1.28)
|
||||
10.0.0.6 [07/Jun/2026:10:22:00 +0800] → 503 (UA: Kubernetes/1.28)
|
||||
10.0.0.6 [07/Jun/2026:10:22:05 +0800] → 503 (UA: Kubernetes/1.28)
|
||||
10.0.0.6 [07/Jun/2026:10:22:10 +0800] → 503 (UA: Kubernetes/1.28)
|
||||
10.0.0.6 [07/Jun/2026:10:22:15 +0800] → 503 (UA: Kubernetes/1.28)
|
||||
|
||||
=== 总结 ===
|
||||
总请求数: 25
|
||||
错误请求: 10 (40.0%)
|
||||
非 2xx 响应占比高达 40%,
|
||||
主要集中在两个异常模式上。`,
|
||||
collapsed: false,
|
||||
},
|
||||
],
|
||||
timestamp: now - 270000,
|
||||
timestamp: now - 460000,
|
||||
},
|
||||
// --- Skill execution result ---
|
||||
// --- Assistant 综合报告 ---
|
||||
{
|
||||
id: 'e-5',
|
||||
role: 'assistant',
|
||||
segments: [
|
||||
{
|
||||
kind: 'tool_call_result',
|
||||
toolName: 'run_skill',
|
||||
success: true,
|
||||
result: `[/deep-research] 执行完成 · 搜索 12 个来源 · 抓取 8 篇全文 · 交叉验证通过
|
||||
|
||||
## 摘要
|
||||
|
||||
Anthropic Skills 的渐进式披露机制是一种三层信息架构,专门为 AI 代理的可扩展功能系统设计。核心思想:"仅在用户需要时才展示细节",与 Nielsen 的经典可用性原则高度一致。
|
||||
|
||||
## 分项发现
|
||||
|
||||
### 1. 三层披露模型
|
||||
|
||||
| 层次 | 内容 | 触发时机 |
|
||||
|------|------|---------|
|
||||
| L1 概览 | 名称 + 一句话描述 | 始终可见(skills 面板) |
|
||||
| L2 详情 | 功能说明 + 触发条件 + 参数 | 用户点击展开 |
|
||||
| L3 指令 | 完整 system prompt 正文 | 用户再次点击"查看注入指令" |
|
||||
|
||||
**设计原理**:这是 "information on demand" 模式的实现——信息存在但不喧嚣。L1 提供识别(recognition),L2 提供评估(evaluation),L3 提供理解(understanding)。
|
||||
|
||||
### 2. 与经典 HCI 理论的对应
|
||||
|
||||
- **Nielsen 的 Flexibility & Efficiency heuristics**:L1 满足新手(可识别),L3 满足专家(可审阅)
|
||||
- **Shneiderman 的 Visual Information Seeking Mantra**:"Overview first, zoom and filter, then details-on-demand"——三层模型完美映射到 overview → zoom → details 流程
|
||||
- **Cognitive Load Theory (Sweller)**:L1 层只占用工作记忆的极小空间,L2/L3 按需加载
|
||||
|
||||
### 3. 与其他 AI 产品的对比
|
||||
|
||||
- **OpenAI GPTs**:配置页是扁平表单,缺乏渐进式展开 → 认知负荷高
|
||||
- **Gemini Gems**:类似 GPTs,所有配置信息同时可见
|
||||
- **Anthropic Skills**:三层的文件系统式浏览——/ 触发、描述预览、then 深入
|
||||
|
||||
### 4. 交互模式创新
|
||||
|
||||
Skills 采用了 **slash command + 自然语言** 的双模触发:
|
||||
- 显式触发:用户输入 \`/skill-name\`
|
||||
- 隐式触发:Agent 根据对话上下文判断并建议使用 skill
|
||||
|
||||
这在 HCI 上称为 "mixed-initiative interaction"。
|
||||
|
||||
### 5. 学术相关文献
|
||||
|
||||
1. "Progressive Disclosure in Mobile UI" (CHI 2016) — 实验证明渐进式展开减少 37% 的错误操作
|
||||
2. "Designing for Mixed-Initiative Interaction" (TOCHI 2020) — Agent 主动建议 vs 用户显式触发的用户偏好研究
|
||||
3. "Information Scent in AI Interfaces" (CSCW 2024) — 讨论了 skills 描述如何帮助用户形成"信息气味"
|
||||
|
||||
## 证据表
|
||||
|
||||
| 声明 | 来源 | 可信度 |
|
||||
|------|------|--------|
|
||||
| 三层披露模型 | Anthropic Agent SDK 文档 | ★★★★★ |
|
||||
| 37% 错误减少 | CHI 2016 实验 | ★★★★ |
|
||||
| Mixed-initiative | TOCHI 2020 | ★★★★ |
|
||||
|
||||
## 限定说明
|
||||
|
||||
Anthropic Skills 机制仍在快速迭代中。上述分析基于 2026 年 6 月的公开文档和代码。建议在论文中标注版本时间。`,
|
||||
collapsed: false,
|
||||
},
|
||||
],
|
||||
timestamp: now - 260000,
|
||||
},
|
||||
// --- Assistant: 综合报告 ---
|
||||
{
|
||||
id: 'e-6',
|
||||
role: 'assistant',
|
||||
segments: [
|
||||
{
|
||||
kind: 'text',
|
||||
content: `## 调研结论
|
||||
content: `## 日志分析报告
|
||||
|
||||
基于 \`/deep-research\` 的交叉验证结果,我建议你的论文从以下角度分析 Skills 渐进式披露:
|
||||
### 🔴 高危:暴力破解尝试
|
||||
|
||||
### 🎯 最佳分析框架
|
||||
**IP: 203.0.113.42**(来源:外部,UA: python-requests)
|
||||
|
||||
**Shneiderman 的 "Overview first, zoom and filter, then details-on-demand"** 是最贴切的理论框架——Skills 的三层模型几乎是对这个 mantra 的精确工程实现。
|
||||
在 **10:16:05–10:16:11** 的 6 秒内向 /admin 路径连续发送了 **7 次请求**,典型的暴力破解模式:
|
||||
|
||||
### 📐 可量化的 HCI 指标
|
||||
| 时间 | 请求 | 状态 | 说明 |
|
||||
|------|------|------|------|
|
||||
| +0s | GET /admin | 403 | 探路——发现 /admin 存在 |
|
||||
| +1s | GET /admin/config | 404 | 试图访问敏感配置 |
|
||||
| +2~6s | POST /admin/login ×5 | 401 | 连续尝试登录——5 次均失败 |
|
||||
|
||||
1. **信息可发现性**:L1 概览层——用户能否快速识别需要的 skill(recognition over recall)
|
||||
2. **认知负荷**:对比"全量展示"vs"渐进式披露"的工作记忆占用
|
||||
3. **操作效率**:slash command 显式触发 vs Agent 隐式建议的完成时间对比
|
||||
**建议措施:**
|
||||
- 🔒 立即对该 IP 加入 WAF 黑名单
|
||||
- 📋 检查 fail2ban 或类似自动封禁机制是否正常运行
|
||||
- 🚨 确认 admin 端点的访问控制策略(当前 403 正确拦截,但暴力破解仍消耗服务器资源)
|
||||
|
||||
### 🔗 建议引用的关键文献
|
||||
---
|
||||
|
||||
- CHI 2016 的渐进式披露实验(有量化数据支持你的设计论点)
|
||||
- TOCHI 2020 的 mixed-initiative 研究(对应双模触发机制)
|
||||
- Anthropic 2025 的 Skills Architecture RFC(一手来源)
|
||||
### 🟡 中危:/health 端点间歇 503
|
||||
|
||||
需要我帮你生成论文的文献综述部分吗?`,
|
||||
**节点 10.0.0.6** 在 **10:22:00–10:22:10** 的 10 秒内连续返回 503,随后恢复 200。而 **10.0.0.5** 一直正常。
|
||||
|
||||
这与上周分析中定时任务导致的 503 抖动模式一致。建议检查该节点上是否在整点前后有定时任务(如日志轮转、缓存预热等)。
|
||||
|
||||
**建议措施:**
|
||||
- ⏰ 检查 10.0.0.6 的 cron 配置
|
||||
- 📊 添加更细粒度的 /health 监控(响应耗时 + 组件健康分别上报)
|
||||
- 🔄 考虑滚动重启使两个节点的健康检查窗口错开
|
||||
|
||||
---
|
||||
|
||||
### 🟢 常规观察
|
||||
|
||||
- **192.168.1.10** — 内部 API 客户端,访问模式正常(用户/订单/商品查询)
|
||||
- **192.168.1.20** — 一次正常登录(POST /api/login → 302 重定向)
|
||||
- **198.51.100.7** — 正常用户访问,加载了首页 + CSS + JS
|
||||
- **192.168.1.30** — 分页浏览商品,行为正常
|
||||
- 无性能异常(无超时记录或慢请求)
|
||||
|
||||
---
|
||||
|
||||
### 📋 总结优先级
|
||||
|
||||
| 优先级 | 问题 | 影响 |
|
||||
|--------|------|------|
|
||||
| P0 | 203.0.113.42 暴力破解 | 安全风险,立即封禁 |
|
||||
| P1 | 10.0.0.6 间歇 503 | 稳定性风险,排查定时任务 |
|
||||
| P3 | 整体 40% 非 2xx | 排除以上两者后正常 |
|
||||
|
||||
需要我进一步分析某个方面吗?比如用 search_knowledge 查询 203.0.113.42 是否在已知攻击数据库中出现过?`,
|
||||
},
|
||||
],
|
||||
timestamp: now - 240000,
|
||||
timestamp: now - 420000,
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
@@ -132,6 +132,7 @@ export interface DocumentSegment {
|
||||
mimeType: string
|
||||
snippet: string // 前 200 字符预览
|
||||
sizeBytes: number
|
||||
parsedContent?: string // 解析后的完整文本内容(点击"查看解析"时展示)
|
||||
}
|
||||
|
||||
export interface LongTextSegment {
|
||||
|
||||
Reference in New Issue
Block a user