feat(ai-protocols): add MCP and A2A protocol demos and documentation
docs(ai-protocols): update AI protocols page with visual demos and detailed explanations style(git-demos): improve responsive design and layout for git visualization components refactor(ai-history): simplify and clean up demo components chore: update config to register new AI protocol components
This commit is contained in:
@@ -1,199 +1,50 @@
|
||||
<template>
|
||||
<div class="attention-mechanism-demo">
|
||||
<el-card shadow="hover">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<h4>👁️ 注意力机制演示</h4>
|
||||
<p class="subtitle">
|
||||
点击词语,观察它如何"关注"句子中的其他词
|
||||
</p>
|
||||
<div class="demo-card">
|
||||
<div class="attention-layout">
|
||||
<div class="sentence-col">
|
||||
<div class="col-label">处理「<strong>他</strong>」时的注意力分配:</div>
|
||||
<div class="sentence-box">
|
||||
<span v-for="(word, i) in sentence" :key="i" class="word-token" :class="{ focus: i === focusIdx }">{{ word }}</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<div class="sentence-container">
|
||||
<div class="sentence">
|
||||
<el-tag
|
||||
v-for="(word, index) in sentence"
|
||||
:key="index"
|
||||
:type="activeIndex === index ? 'primary' : 'info'"
|
||||
:effect="activeIndex === index ? 'dark' : 'plain'"
|
||||
class="word-token"
|
||||
@click="selectWord(index)"
|
||||
>
|
||||
{{ word }}
|
||||
</el-tag>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="activeIndex !== null"
|
||||
class="attention-bars"
|
||||
>
|
||||
<div
|
||||
v-for="(attention, index) in attentionWeights"
|
||||
:key="index"
|
||||
class="attention-item"
|
||||
>
|
||||
<div class="word-label">
|
||||
{{ attention.word }}
|
||||
</div>
|
||||
<el-progress
|
||||
:percentage="Math.round(attention.weight * 100)"
|
||||
:status="attention.weight > 0.5 ? 'exception' : ''"
|
||||
:color="customColors"
|
||||
class="attention-progress"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<el-empty
|
||||
v-else
|
||||
description="👆 点击句子中的任意词语开始"
|
||||
:image-size="60"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<el-collapse-transition>
|
||||
<div
|
||||
v-if="activeIndex !== null"
|
||||
class="explanation-panel"
|
||||
>
|
||||
<el-alert
|
||||
type="success"
|
||||
:closable="false"
|
||||
show-icon
|
||||
class="insight-alert"
|
||||
>
|
||||
<template #title>
|
||||
<span class="insight-title">关键洞察</span>
|
||||
</template>
|
||||
<p>{{ getInsight(activeIndex) }}</p>
|
||||
</el-alert>
|
||||
<div class="bars-col">
|
||||
<div class="attention-item" v-for="(item, i) in weights" :key="i">
|
||||
<span class="bar-word" :class="{ focus: i === focusIdx }">{{ item.word }}</span>
|
||||
<div class="bar-bg">
|
||||
<div class="bar-fill" :style="{ width: item.w * 100 + '%', background: barColor(item.w) }"></div>
|
||||
</div>
|
||||
<span class="bar-pct">{{ Math.round(item.w * 100) }}%</span>
|
||||
</div>
|
||||
</el-collapse-transition>
|
||||
</el-card>
|
||||
</div>
|
||||
</div>
|
||||
<div class="caption">
|
||||
「他」虽在句中间,模型却把 65% 注意力精准投向句首的「小明」,跨越距离识别代词指代
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed } from 'vue'
|
||||
|
||||
const sentence = ref(['小明', '把', '苹果', '给了', '他', '的', '母亲'])
|
||||
const activeIndex = ref(null)
|
||||
|
||||
const customColors = [
|
||||
{ color: '#909399', percentage: 20 },
|
||||
{ color: '#e6a23c', percentage: 40 },
|
||||
{ color: '#f56c6c', percentage: 80 },
|
||||
{ color: '#67c23a', percentage: 100 }
|
||||
]
|
||||
|
||||
// 注意力权重矩阵(模拟)
|
||||
const attentionMatrix = {
|
||||
0: [0.15, 0.05, 0.6, 0.05, 0.05, 0.05, 0.05], // 小明 主要关注 苹果、他
|
||||
1: [0.1, 0.1, 0.4, 0.3, 0.05, 0.03, 0.02], // 把 主要关注 苹果、给了
|
||||
2: [0.5, 0.1, 0.15, 0.15, 0.05, 0.03, 0.02], // 苹果 主要关注 小明
|
||||
3: [0.1, 0.1, 0.35, 0.15, 0.2, 0.05, 0.05], // 给了 主要关注 苹果、他
|
||||
4: [0.65, 0.05, 0.1, 0.1, 0.05, 0.03, 0.02], // 他 主要关注 小明
|
||||
5: [0.08, 0.05, 0.07, 0.08, 0.62, 0.05, 0.05], // 的 主要关注 他
|
||||
6: [0.25, 0.1, 0.15, 0.15, 0.2, 0.1, 0.05] // 母亲 关注多个词
|
||||
}
|
||||
|
||||
const insights = {
|
||||
0: '当模型处理"小明"时,它最关注"苹果"(60%),因为这表明是"谁"拥有苹果。',
|
||||
1: '"把"是介词,模型关注"苹果"和"给了",理解动作的对象和方向。',
|
||||
2: '"苹果"作为宾语,主要关注主语"小明",确定归属关系。',
|
||||
3: '"给了"关注"苹果"和"他",理解传递动作的对象。',
|
||||
4: '"他"最关注"小明"(65%),因为"他"指代的就是"小明"!',
|
||||
5: '"的"连接"他"和"母亲",主要关注"他"(62%)。',
|
||||
6: '"母亲"作为句末宾语,关注前面的多个词语来理解完整语境。'
|
||||
}
|
||||
|
||||
const attentionWeights = computed(() => {
|
||||
if (activeIndex.value === null) return []
|
||||
|
||||
return sentence.value.map((word, index) => ({
|
||||
word,
|
||||
weight: attentionMatrix[activeIndex.value][index]
|
||||
}))
|
||||
})
|
||||
|
||||
const selectWord = (index) => {
|
||||
activeIndex.value = index
|
||||
}
|
||||
|
||||
const getInsight = (index) => {
|
||||
return insights[index]
|
||||
}
|
||||
const sentence = ['小明', '把', '苹果', '给了', '他', '的', '母亲']
|
||||
const focusIdx = 4
|
||||
const attn = [0.65, 0.05, 0.10, 0.10, 0.05, 0.03, 0.02]
|
||||
const weights = sentence.map((word, i) => ({ word, w: attn[i] }))
|
||||
const barColor = (v) => v > 0.5 ? '#dc2626' : v > 0.15 ? '#d97706' : v > 0.06 ? '#059669' : 'var(--vp-c-divider)'
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.attention-mechanism-demo {
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.card-header h4 {
|
||||
margin: 0;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
font-size: 13px;
|
||||
color: var(--vp-c-text-2);
|
||||
margin: 4px 0 0;
|
||||
}
|
||||
|
||||
.sentence {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
justify-content: center;
|
||||
margin-bottom: 24px;
|
||||
padding: 16px;
|
||||
background-color: var(--vp-c-bg-alt);
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.word-token {
|
||||
cursor: pointer;
|
||||
font-size: 16px;
|
||||
padding: 8px 16px;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.word-token:hover {
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.attention-bars {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.attention-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.word-label {
|
||||
width: 40px;
|
||||
text-align: right;
|
||||
font-weight: bold;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.attention-progress {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.explanation-panel {
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.insight-title {
|
||||
font-weight: bold;
|
||||
font-size: 14px;
|
||||
}
|
||||
.demo-card { border: 1px solid var(--vp-c-divider); border-radius: 8px; background: var(--vp-c-bg-soft); padding: 1.25rem; margin: 1rem 0; }
|
||||
.attention-layout { display: grid; grid-template-columns: 1fr 1.3fr; gap: 1rem; background: var(--vp-c-bg); border: 1px solid var(--vp-c-divider); border-radius: 6px; padding: 0.9rem; margin-bottom: 0.5rem; }
|
||||
@media (max-width: 560px) { .attention-layout { grid-template-columns: 1fr; } }
|
||||
.col-label { font-size: 0.76rem; color: var(--vp-c-text-2); margin-bottom: 0.5rem; font-weight: bold; }
|
||||
.sentence-box { display: flex; flex-wrap: wrap; gap: 0.35rem; background: var(--vp-c-bg-alt); padding: 0.6rem; border-radius: 5px; border: 1px dashed var(--vp-c-divider); }
|
||||
.word-token { font-size: 0.88rem; font-weight: bold; padding: 0.2rem 0.5rem; background: var(--vp-c-bg); border: 1px solid var(--vp-c-divider); border-radius: 4px; }
|
||||
.word-token.focus { background: var(--vp-c-brand); color: white; border-color: var(--vp-c-brand); }
|
||||
.bars-col { display: flex; flex-direction: column; gap: 0.3rem; justify-content: center; }
|
||||
.attention-item { display: flex; align-items: center; gap: 0.4rem; }
|
||||
.bar-word { width: 30px; text-align: right; font-size: 0.8rem; font-weight: bold; color: var(--vp-c-text-2); flex-shrink: 0; }
|
||||
.bar-word.focus { color: var(--vp-c-brand); }
|
||||
.bar-bg { flex: 1; height: 12px; background: var(--vp-c-bg-alt); border-radius: 6px; overflow: hidden; border: 1px solid var(--vp-c-divider); }
|
||||
.bar-fill { height: 100%; border-radius: 6px; }
|
||||
.bar-pct { font-size: 0.7rem; font-weight: bold; color: var(--vp-c-text-2); width: 30px; flex-shrink: 0; }
|
||||
.caption { font-size: 0.75rem; color: var(--vp-c-text-3); text-align: center; }
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user