211 lines
7.3 KiB
TypeScript
211 lines
7.3 KiB
TypeScript
/**
|
||
* Demo F — 真实 Anthropic Skills(从 SKILL.md 解析)
|
||
*
|
||
* 场景:用户请求帮助完成网页应用的 Playwright 测试,
|
||
* Agent 检测到合适 skill 并建议触发 /webapp-testing。
|
||
*
|
||
* 关键展示:
|
||
* 1. Skills 使用了真实的 Anthropic SKILL.md 格式
|
||
* 2. parseSkillMarkdown() 解析 YAML frontmatter → SkillItem
|
||
* 3. SkillsView 渐进式披露 L1→L2→L3,L3 显示原始 SKILL.md body
|
||
* 4. Agent 以工具调用方式触发 skill
|
||
* 5. 触发后 SKILL.md body 以 tool_call_result 返回并注入上下文(f-4)
|
||
* 6. 对话中展示 static_var 展开(日期、用户身份)
|
||
*/
|
||
|
||
import type { PromptEnvelope } from '../../types/protocol'
|
||
import { getRealSkills } from '../skills-loader'
|
||
|
||
const now = Date.now()
|
||
|
||
export const demoF: PromptEnvelope = {
|
||
version: '1.0',
|
||
model: 'claude-opus-4-8',
|
||
messages: [
|
||
// --- System message: 加载真实 Anthropic skills ---
|
||
{
|
||
id: 'f-1',
|
||
role: 'system',
|
||
segments: [
|
||
{
|
||
kind: 'static_var',
|
||
name: 'current_date',
|
||
value: '2026年6月7日',
|
||
description: '当前对话日期',
|
||
},
|
||
{
|
||
kind: 'system_prompt',
|
||
content: `你是 Claude,具备 Anthropic Skills 机制的 HCI 研究助手。
|
||
|
||
你加载了以下从官方 skills 仓库的 SKILL.md 文件解析得到的 skills。
|
||
每个 skill 的 YAML frontmatter(name + description)始终在你的上下文中可用;
|
||
当 skill 被触发时,SKILL.md 的完整 body 会被加载。`,
|
||
collapsed: true,
|
||
},
|
||
{
|
||
kind: 'skills',
|
||
description:
|
||
'以下 skills 来自 Anthropic 官方 skills 仓库,通过 parseSkillMarkdown() 从 SKILL.md 文件解析。name 和 description 取自 YAML frontmatter(L1),body 作为完整指令(L2/L3)。',
|
||
items: getRealSkills(['webapp-testing', 'pdf', 'doc-coauthoring', 'mcp-builder']),
|
||
collapsed: false, // 默认展开展示解析效果
|
||
},
|
||
{
|
||
kind: 'tool_overview',
|
||
items: [
|
||
{
|
||
name: 'run_skill',
|
||
description: '执行一个 Skill',
|
||
parameters: 'skill_name: string, input: string',
|
||
schema: {
|
||
type: 'object',
|
||
properties: {
|
||
skill_name: { type: 'string', description: 'Skill 名称' },
|
||
input: { type: 'string', description: '传递给 skill 的输入' },
|
||
},
|
||
required: ['skill_name', 'input'],
|
||
},
|
||
},
|
||
],
|
||
collapsed: true,
|
||
},
|
||
],
|
||
timestamp: now - 360000,
|
||
},
|
||
// --- User 提出测试需求 ---
|
||
{
|
||
id: 'f-2',
|
||
role: 'user',
|
||
segments: [
|
||
{
|
||
kind: 'static_var',
|
||
name: 'user_name',
|
||
value: '小明',
|
||
description: '当前用户名',
|
||
},
|
||
{
|
||
kind: 'text',
|
||
content: `我在做一个 HCI 课程项目——一个 React 聊天界面。本地 dev server 在 http://localhost:5173 运行。
|
||
|
||
我想验证几个功能:
|
||
1. 页面是否正常加载
|
||
2. 场景切换按钮是否响应点击
|
||
3. 右侧的 Protocol Panel 是否正确显示 JSON
|
||
|
||
能帮我自动化测试一下吗?`,
|
||
},
|
||
],
|
||
timestamp: now - 300000,
|
||
},
|
||
// --- Assistant 识别需求,触发 webapp-testing skill ---
|
||
{
|
||
id: 'f-3',
|
||
role: 'assistant',
|
||
segments: [
|
||
{
|
||
kind: 'text',
|
||
content: `你的测试需求非常适合用 **/webapp-testing** skill 来处理——它正是为本地 web 应用的 Playwright 自动化测试设计的。
|
||
|
||
让我触发这个 skill 来生成测试脚本。它来自 Anthropic 官方 skills 仓库,通过 \`parseSkillMarkdown()\` 解析 SKILL.md 的 YAML frontmatter 和 Markdown body:
|
||
|
||
> **解析结构:**
|
||
> - **L1** — \`name: webapp-testing\` + \`description\`(从 frontmatter 提取)
|
||
> - **L2** — body 摘要(前 10 行 + 统计信息)
|
||
> - **L3** — 完整 SKILL.md 原始内容(点击「查看原始 SKILL.md」展开)`,
|
||
},
|
||
{
|
||
kind: 'tool_call_request',
|
||
toolName: 'run_skill',
|
||
arguments: {
|
||
skill_name: 'webapp-testing',
|
||
input: 'Test a React chat app at http://localhost:5173. Verify: (1) page loads correctly, (2) demo scenario buttons respond to clicks, (3) the right-side Protocol Panel displays JSON correctly. Use Playwright with the reconnaissance-then-action pattern.',
|
||
},
|
||
collapsed: false,
|
||
},
|
||
],
|
||
timestamp: now - 280000,
|
||
},
|
||
// --- Skill body 加载:SKILL.md 作为 tool 结果返回 ---
|
||
{
|
||
id: 'f-4',
|
||
role: 'assistant',
|
||
segments: [
|
||
{
|
||
kind: 'tool_call_result',
|
||
toolName: 'run_skill',
|
||
success: true,
|
||
result: `[/webapp-testing] SKILL.md 已加载
|
||
以下完整 body 已注入上下文,agent 将基于这些指令执行:
|
||
|
||
# Web Application Testing
|
||
|
||
To test local web applications, write native Python Playwright scripts.
|
||
|
||
**Helper Scripts Available**:
|
||
- \`scripts/with_server.py\` - Manages server lifecycle (supports multiple servers)
|
||
|
||
**Always run scripts with \`--help\` first** to see usage.
|
||
|
||
## Decision Tree: Choosing Your Approach
|
||
|
||
\`\`\`
|
||
User task → Is it static HTML?
|
||
├─ Yes → Read HTML file directly to identify selectors
|
||
│ ├─ Success → Write Playwright script using selectors
|
||
│ └─ Fails/Incomplete → Treat as dynamic (below)
|
||
│
|
||
└─ No (dynamic webapp) → Is the server already running?
|
||
├─ No → Run: python scripts/with_server.py --help
|
||
│ Then use the helper + write simplified Playwright script
|
||
│
|
||
└─ Yes → Reconnaissance-then-action:
|
||
1. Navigate and wait for networkidle
|
||
2. Take screenshot or inspect DOM
|
||
3. Identify selectors from rendered state
|
||
4. Execute actions with discovered selectors
|
||
\`\`\`
|
||
|
||
## Reconnaissance-Then-Action Pattern
|
||
|
||
1. **Inspect rendered DOM** — take screenshot + page.content() + locate elements
|
||
2. **Identify selectors** from inspection results
|
||
3. **Execute actions** using discovered selectors
|
||
|
||
(完整 body 共 96 行,详见上方 skills 面板 L3)`,
|
||
collapsed: false,
|
||
},
|
||
],
|
||
timestamp: now - 270000,
|
||
},
|
||
// --- Assistant 总结 ---
|
||
{
|
||
id: 'f-5',
|
||
role: 'assistant',
|
||
segments: [
|
||
{
|
||
kind: 'text',
|
||
content: `## 测试结果:全部通过 ✅
|
||
|
||
\`/webapp-testing\` skill 使用了 **reconnaissance-then-action** 模式:
|
||
|
||
1. 先截图 + 检查 DOM 获取真实渲染状态
|
||
2. 从渲染结果中识别选择器(而非猜测)
|
||
3. 用发现的选择器执行操作
|
||
|
||
### 关于 Skills 的 HCI 应用
|
||
|
||
这个 demo 展示了 **Anthropic Skills 格式的关键优势**:
|
||
|
||
| 层级 | 内容 | HCI 意义 |
|
||
|------|------|---------|
|
||
| L1 | name + description | **识别**(recognition over recall) |
|
||
| L2 | body 摘要 + 触发条件 | **评估**(用户判断 skill 是否适用) |
|
||
| L3 | 完整 SKILL.md body | **理解**(透明化——用户可审阅完整指令) |
|
||
|
||
这种设计直接对应 Shneiderman 的 "Overview first, zoom and filter, then details-on-demand" 信息可视化 mantra。`,
|
||
},
|
||
],
|
||
timestamp: now - 240000,
|
||
},
|
||
],
|
||
}
|