ai-agent-book 精选快照(<2MB 代码与文档,来自 github.com/bojieli/ai-agent-book)
Build latest book artifacts / build (push) Canceled after 0s
dependency resolution / resolve (3.11) (push) Canceled after 0s
dependency resolution / resolve (3.13) (push) Canceled after 0s
deploy-pages / build (push) Canceled after 0s
deploy-pages / deploy (push) Canceled after 0s
i18n consistency check / check (push) Canceled after 0s
provider adoption tests / test (chapter2/context-compression) (push) Canceled after 0s
provider adoption tests / test (chapter2/prompt-injection) (push) Canceled after 0s
provider adoption tests / test (chapter2/system-hint) (push) Canceled after 0s
provider adoption tests / test (chapter3/log-sanitization) (push) Canceled after 0s
web-search-agent tests / test (push) Canceled after 0s
web-search-agent tests / agentbook (push) Canceled after 0s
Build latest book artifacts / build (push) Canceled after 0s
dependency resolution / resolve (3.11) (push) Canceled after 0s
dependency resolution / resolve (3.13) (push) Canceled after 0s
deploy-pages / build (push) Canceled after 0s
deploy-pages / deploy (push) Canceled after 0s
i18n consistency check / check (push) Canceled after 0s
provider adoption tests / test (chapter2/context-compression) (push) Canceled after 0s
provider adoption tests / test (chapter2/prompt-injection) (push) Canceled after 0s
provider adoption tests / test (chapter2/system-hint) (push) Canceled after 0s
provider adoption tests / test (chapter3/log-sanitization) (push) Canceled after 0s
web-search-agent tests / test (push) Canceled after 0s
web-search-agent tests / agentbook (push) Canceled after 0s
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
# Chapter 2 experiment requirement/evidence ledger
|
||||
|
||||
`book/chapter2.md` is the acceptance source. “Passed” below means the frozen
|
||||
experiment was actually exercised with the named real model/runtime and raw
|
||||
artifacts were retained; it does not mean every historical directional result
|
||||
was reproduced. A legacy proxy or mechanism-only demo never closes a row.
|
||||
|
||||
| Experiment | Exact manuscript gate | Status | Canonical evidence / qualification |
|
||||
|---|---|---|---|
|
||||
| 2-1 | Local ~0.6B model; raw token/thinking stream; parallel tools; ReAct; streaming; >100 tok/s observation and matched cache-hit/miss TTFT | Passed | `local_llm_serving/runs/exp2-1-qwen3-0.6b-20260730-v2/manifest.json` hashes the Ollama Qwen3 evidence; both tools, follow-up answer, 106.7 tok/s, and five matched TTFT pairs are retained. |
|
||||
| 2-2 | Real attention heatmaps showing causal triangle, attention sink, reasoning/output regions, and position measurements | Passed | `attention_visualization/validation/latest.json` points to `runs/exp2-2-qwen3-0.6b-20260730-v3`: pinned Qwen revision, exact Beijing prompt, lossless first/middle/last-layer matrices, generated `<think>` + answer regions, and hash-addressed heatmaps. |
|
||||
| 2-3 | Correct stable prefix versus dynamic system/profile, shuffled tools, sliding window, and flattened text; TTFT/cache/behavior effects | Passed | The six `kv-cache/result_*_20260718_kimi_k2_6.json` real Kimi K2.6 receipts retain per-iteration TTFT, cached/prompt tokens, calls, and completion behavior. Sliding-window failure and reduced caching from shuffled tools are observed; other magnitudes are reported rather than forced. |
|
||||
| 2-4 | Same Tau-Bench tasks across tone, organization, and tool-description ablations; objective reward, efficiency, and real receipts | Passed, historical percentages not reproduced | `prompt-engineering/validation/latest.json` points to the completed 6 × 10 Kimi K3 campaign. The observed directions differ from the prose’s historical 30%/45% point estimates, and that is explicitly qualified. |
|
||||
| 2-5 | Three attack channels × four progressive defenses; repeated trials; real filesystem/outbox/memory effects; attack success rates | Passed | `prompt-injection/validation/latest.json` hashes the complete 3 × 4 × 5 Kimi K3 campaign. All observed attack success rates were 0%, including baseline; the experiment is complete even though the model resisted every attack. |
|
||||
| 2-6 | Pinned official Anthropic PPTX Skill + real paper, executed by any skills-capable runtime (runtime-agnostic author policy 2026-07-31: Claude Code or an equivalent such as Kimi Code); progressive disclosure; official scripts; 10–15 slides; three source visuals; reopen/thumbnail inspection | Passed | `agent-skills-ppt/runs/exp2-6-kimi-pptx-20260731-v1/manifest.json` passes all 15 gates: Kimi Code CLI (`kimi-code/k3`) invoked the pinned official Skill (Skill metadata → `SKILL.md` → `html2pptx.md` → official `html2pptx.js`/`thumbnail.py`), built a 13-slide deck from the hash-pinned *Attention Is All You Need* PDF with four PDF-cropped visuals byte-identical to embedded media, and LibreOffice reopens the deck; the credential-free raw stream is retained. Earlier Claude Code attempts (v2–v4) stayed blocked on Anthropic credentials and are kept as fail-closed evidence; the old python-pptx proxy remains non-acceptance evidence. |
|
||||
| 2-7 | 从个人范文创建“去 AI 味”写作 Skill;检查触发条件、核心规则、示例、作用域与例外 | 设计 | 轻量正文实验,不依赖独立代码项目;自动从多条反馈提炼规则的验收仍保留在第八章 `ai-style-skill` 补充项目。 |
|
||||
| 2-8 | Same Xfinity trajectory with/without exact 3/3 status block; real small-model decisions and attention tensors | Passed | `attention_visualization/runs/exp2-7-qwen3-0.6b-20260730-v2/manifest.json`: three generations per arm, lossless tensors, region measurements, and heatmap. Control refused 2/3 and status refused 3/3; no response-conditioned gate was used. The run directory retains its historical `exp2-7` identifier. |
|
||||
| 2-9 | Timestamp, tool counter, TODO, detailed error, system state, and combined on/off controls using a real Agent | Passed, historical percentages not reproduced | `system-hint/runs/exp2-8-kimi-k3-20260730-v1/manifest.json` hashes all 65 preregistered Kimi K3 runs. Current-suite effects, including null/negative findings, are retained separately from the prose’s historical 15-vs-21 and 60%-vs-95% claims. The run directory retains its historical `exp2-8` identifier. |
|
||||
| 2-10 | Same founder-research task under six compression strategies with 128K limit; token, iteration, compression, overflow, citation, and adaptive-window behavior | Passed | `context-compression/results/kimi_k3_real_20260718.json` retains all six real Kimi K3 arms: no-compression overflow plus five completed strategies and their manuscript metrics. |
|
||||
|
||||
## Evidence policy
|
||||
|
||||
- A provider refusal before any model token is `blocked`, not a failed model
|
||||
outcome and not a reason to accept a local proxy.
|
||||
- Completion gates validate design execution, model/runtime identity, raw
|
||||
receipts, artifact integrity, and credential scanning. Scientific hypotheses
|
||||
and historical percentages are reported as outcomes, never completion gates.
|
||||
- Result directories from failed or partial attempts remain evidence and are
|
||||
not overwritten; the path in this ledger identifies the latest canonical run.
|
||||
@@ -0,0 +1,36 @@
|
||||
# الفصل الثاني · هندسة السياق
|
||||
|
||||
> يحدد السياق سقف قدرة الوكيل. ويتعمق الفصل في بنية السياق لواجهات LLM، والتصميم الملائم لذاكرة KV المخبأة، وهندسة الموجّهات، والموجّهات الديناميكية، ومهارات الوكيل، وبيانات شريط الحالة، واستراتيجيات ضغط السياق.
|
||||
|
||||
← [العودة إلى الملف التمهيدي الرئيسي](../docs/ar/README.md) · 📖 [قراءة نص الفصل](../book-ar/chapter2.ar.md)
|
||||
|
||||
## كيفية قراءة التجارب
|
||||
|
||||
يستخدم النص هياكل آلية قصيرة لشرح تدفق التحكم؛ ويحتوي دليل التجارب على محولات SDK الكاملة والسجلات والاختبارات وأدلة القبول. لا حاجة لقراءة كل ملف سطرًا سطرًا.
|
||||
|
||||
- **Starter:** ابدأ بالهدف والأمر الأدنى وشروط القبول؛ وابدأ من [context-compression](context-compression/);
|
||||
- **Builder:** تتبّع نقطة الدخول والحلقة الأساسية ومخطط الحالة/الرسائل والأدوات وأداة التحقق.
|
||||
- **Maintainer:** ثم اقرأ الاختبارات وmanifest الأدلة ومعالجة الأعطال ومسارات التراجع ومحولات المزوّد.
|
||||
|
||||
في القراءة الأولى يمكنك تجاوز بيانات الاعتماد وطبقة العرض وتوافق المزوّد؛ عُد إليها عند إعادة إنتاج رقم.
|
||||
|
||||
## المشاريع المصاحبة
|
||||
|
||||
| التجربة | المشروع | النوع | الوصف |
|
||||
| :--: | --- | :--: | --- |
|
||||
| 2-1 | [local_llm_serving](local_llm_serving/) | ✅ | حل نشر LLM محلي عبر الأنظمة الأساسية يقوم تلقائيًا بتحديد أفضل واجهة خلفية (vLLM أو Ollama). يوضح أنه حتى النموذج الصغير الذي يبلغ حجمه 0.6B يمكنه تحقيق إمكانات ممتازة لاستدعاء الأدوات من خلال التصميم الجيد للنظام. يدعم الاستجابات المتدفقة لعرض عملية التفكير في الوقت الحقيقي. |
|
||||
| 2-2، 2-7 | [انتباه_التصور](attention_visualization/) | ✅ | تصور تسلسل رمز الإدخال/الإخراج الكامل وتوزيع وزن الانتباه لـ LLM، مما يوفر نظرة عميقة حول كيفية معالجة النموذج للسياق وتنفيذ الاستدلال واستدعاء الأدوات. |
|
||||
| 2-3 | [كف-ذاكرة التخزين المؤقت](kv-cache/) | ✅ | يستكشف تأثير أوضاع إدارة السياق المختلفة على KV Cache، مما يوضح كيف تؤدي أنماط الأخطاء الشائعة إلى تدمير كفاءة ذاكرة التخزين المؤقت. يوضح من خلال التجارب كيف يمكن لتصميم السياق المناسب أن يقلل بشكل كبير من زمن الوصول والتكلفة. |
|
||||
| 2-4 | [هندسة الموجّهات](prompt-engineering/) | ✅ | يوسع إطار Tau-Bench لقياس أثر عناصر هندسة الموجّهات في أداء الوكيل عبر دراسات استئصال منهجية. ويوضح تأثير الأسلوب وتنظيم التعليمات وأوصاف الأدوات في معدلات إنجاز المهام. |
|
||||
| 2-5 | [حقن الموجّهات](prompt-injection/) | ✅ | يبني تجربة مضبوطة تضم ثلاثة سيناريوهات للهجوم (الحقن المباشر، والحقن غير المباشر، وحقن الذاكرة) وأربعة إعدادات دفاعية (دون دفاع، وتحصين الموجّه، ووسم المصدر، ودفاع مركب). ويستخدم قواعد حتمية لحساب معدلات نجاح الهجوم، فيوضح بصريًا أثر الدفاع متعدد الطبقات. |
|
||||
| 2-6 | [مهارات-الوكيل-ppt](agent-skills-ppt/) | ✅ | إعادة إنتاج مفهوم "الكشف التدريجي" لمهارات الوكيل: يرى الوكيل في البداية فقط دليل المهارات الرفيع. فقط بعد تحديد أن المهمة تتطلب مهارة `pptx`، يتم تحميل سير العمل الكامل والوثائق التفصيلية والبرامج النصية المجمعة بشكل تدريجي، مما يؤدي في النهاية إلى إنشاء ملف `.pptx` حقيقي باستخدام python-pptx. |
|
||||
| 2-7 | تجربة نصية | 🚧 | إنشاء مهارة كتابة خفيفة من نماذج شخصية، مع تحديد شروط التفعيل والقواعد والأمثلة والنطاق والصيانة التكرارية. |
|
||||
| 2-8 | [إرشادات النظام](system-hint/) | ✅ | يدرس أثر إرشادات النظام في سلوك الوكيل، ويبحث في تحسين الأداء عبر تنقيح موجّهات النظام. |
|
||||
| 2-9 | [ضغط السياق](context-compression/) | ✅ | ينفذ ويقارن استراتيجيات ضغط السياق المتعددة، بما في ذلك التلخيص واستخراج المعلومات الأساسية والضغط الدلالي. يقلل من استخدام الرمز المميز مع الحفاظ على قدرات الوكيل. |
|
||||
## أنواع المشاريع
|
||||
|
||||
| الأيقونة | النوع | المعنى |
|
||||
| :--: | --- | --- |
|
||||
| ✅ | **مستقل** | شفرة كاملة قابلة للتشغيل في هذا المستودع بعد إعداد مفتاح API |
|
||||
| 📖 | **دليل إعادة الإنتاج** | وثائق تفصيلية تعتمد على مستودع خارجي يُجلب باستخدام `git clone` |
|
||||
| 🚧 | **وثيقة التصميم** | وثيقة تصميم وخطة تنفيذ؛ أما الشفرة القابلة للتشغيل فما تزال قيد التطوير |
|
||||
@@ -0,0 +1,36 @@
|
||||
# Chapter 2 · Context Engineering
|
||||
|
||||
> Context determines the upper bound of Agent capabilities. Delves into the context structure of LLM APIs, KV Cache-friendly design, prompt engineering, dynamic prompts and Agent Skills, status bar meta-information, and context compression strategies.
|
||||
|
||||
← [Back to main README](../docs/en/README.md) · 📖 [Read chapter text](../book-en/chapter2.md)
|
||||
|
||||
## How to Read the Experiments
|
||||
|
||||
The prose uses short mechanism skeletons to explain control flow; the experiment directory contains complete SDK adapters, logs, tests, and acceptance evidence. You do not need to read every file line by line.
|
||||
|
||||
- **Starter:** Start with the goal, minimum command, and acceptance conditions; begin with [context-compression](context-compression/);
|
||||
- **Builder:** Follow the entry point, core loop, state/message schema, tools, and verifier.
|
||||
- **Maintainer:** Then read tests, evidence manifests, failure handling, rollback paths, and provider adapters.
|
||||
|
||||
On a first pass, skip credential loading, presentation code, and provider-compatibility layers; return when reproducing a number.
|
||||
|
||||
## Companion Projects
|
||||
|
||||
| Exp. | Project | Type | Description |
|
||||
| :--: | --- | :--: | --- |
|
||||
| 2-1 | [local_llm_serving](local_llm_serving/) | ✅ | A cross-platform local LLM deployment solution that automatically selects the best backend (vLLM or Ollama). Demonstrates that even a 0.6B small model can achieve excellent tool calling capabilities through good system design. Supports streaming responses for real-time thought process display. |
|
||||
| 2-2, 2-8 | [attention_visualization](attention_visualization/) | ✅ | Visualizes the complete input/output token sequence and attention weight distribution of an LLM, providing deep insight into how the model processes context, performs reasoning, and calls tools. |
|
||||
| 2-3 | [kv-cache](kv-cache/) | ✅ | Explores the impact of different context management modes on KV Cache, demonstrating how common error patterns destroy cache efficiency. Shows through experiments how proper context design can significantly reduce latency and cost. |
|
||||
| 2-4 | [prompt-engineering](prompt-engineering/) | ✅ | Extends the Tau-Bench framework to quantify the impact of different prompt engineering factors on Agent performance through systematic ablation experiments. Shows how factors like tone, instruction organization, and tool descriptions affect task completion rates. |
|
||||
| 2-5 | [prompt-injection](prompt-injection/) | ✅ | Constructs a controlled experiment with 3 attack scenarios (direct injection, indirect injection, memory injection) × 4 defense configurations (no defense, prompt hardening, source tagging, combined defense). Uses deterministic rules to calculate attack success rates, visually demonstrating how layered defenses significantly reduce injection success rates. |
|
||||
| 2-6 | [agent-skills-ppt](agent-skills-ppt/) | ✅ | Reproduces the "progressive disclosure" concept of Agent Skills: the Agent initially sees only a thin Skill directory. Only after identifying that the task requires the `pptx` Skill does it progressively load its complete workflow, detailed documentation, and bundled scripts, ultimately generating a real `.pptx` file using python-pptx. |
|
||||
| 2-7 | Text experiment | 🚧 | Creates a lightweight writing Skill from personal examples, covering trigger conditions, rules, examples, scope, and iterative maintenance. |
|
||||
| 2-9 | [system-hint](system-hint/) | ✅ | Studies the impact of System Hints on Agent behavior, exploring how to improve performance by optimizing system prompts. |
|
||||
| 2-10 | [context-compression](context-compression/) | ✅ | Implements and compares multiple context compression strategies, including summarization, key information extraction, and semantic compression. Reduces token usage while maintaining Agent capabilities. |
|
||||
## Project Types
|
||||
|
||||
| Icon | Type | Meaning |
|
||||
| :--: | --- | --- |
|
||||
| ✅ | **Standalone** | Full code in this repo, runs after configuring API Key |
|
||||
| 📖 | **Reproduction Guide** | Detailed doc depending on **external repos** to `git clone` |
|
||||
| 🚧 | **Design Doc** | Architecture/implementation plan only, runnable code still WIP |
|
||||
@@ -0,0 +1,37 @@
|
||||
# Capítulo 2 · Ingeniería de Contexto
|
||||
|
||||
> El contexto limita la capacidad del Agente: KV Cache, ingeniería de prompts, Agent Skills, compresión de contexto
|
||||
|
||||
← [Volver al README principal](../docs/es/README.md) · 📖 [Leer texto del capítulo](../book-es/chapter2.es.md)
|
||||
|
||||
## Cómo leer los experimentos
|
||||
|
||||
El texto usa skeletons breves para explicar el flujo de control; el directorio de experimentos contiene adaptadores SDK completos, registros, pruebas y evidencias de aceptación. No hace falta leer cada archivo línea por línea.
|
||||
|
||||
- **Starter:** Empieza por el objetivo, el comando mínimo y la aceptación; comienza con [context-compression](context-compression/);
|
||||
- **Builder:** Sigue el punto de entrada, el bucle central, el esquema de estado/mensajes, las herramientas y el verificador.
|
||||
- **Maintainer:** Después revisa pruebas, manifiestos, fallos, rollback y adaptadores de proveedores.
|
||||
|
||||
En la primera pasada puedes omitir credenciales, presentación y compatibilidad de proveedores; vuelve al reproducir una cifra.
|
||||
|
||||
## Proyectos Complementarios
|
||||
|
||||
| Exp. | Proyecto | Tipo | Descripción |
|
||||
| :--: | --- | :--: | --- |
|
||||
| 2-1 | [local_llm_serving](local_llm_serving/) | ✅ | Despliegue local multiplataforma de LLM con selección automática de backend vLLM/Ollama |
|
||||
| 2-2, 2-7 | [attention_visualization](attention_visualization/) | ✅ | Visualización de la secuencia completa de tokens y pesos de atención de LLM |
|
||||
| 2-3 | [kv-cache](kv-cache/) | ✅ | Exploración del impacto de diferentes patrones de gestión de contexto en la eficiencia de KV Cache |
|
||||
| 2-4 | [prompt-engineering](prompt-engineering/) | ✅ | Extensión de Tau-Bench para cuantificar el impacto del estilo, organización de instrucciones y descripciones de herramientas |
|
||||
| 2-5 | [prompt-injection](prompt-injection/) | ✅ | Experimento comparativo de 3 escenarios de ataque × 4 configuraciones de defensa contra inyecciones de prompts |
|
||||
| 2-6 | [agent-skills-ppt](agent-skills-ppt/) | ✅ | Reproducción de "divulgación progresiva" de Agent Skills para generar archivos `.pptx` con python-pptx |
|
||||
| 2-7 | Experimento de texto | 🚧 | Crea un Skill de escritura ligero a partir de ejemplos personales, con condiciones de activación, reglas, ejemplos, alcance y mantenimiento iterativo. |
|
||||
| 2-8 | [system-hint](system-hint/) | ✅ | Estudio del impacto de los prompts de sistema en el comportamiento del Agente |
|
||||
| 2-9 | [context-compression](context-compression/) | ✅ | Comparación de estrategias de resumen, extracción de información clave y compresión semántica de contexto |
|
||||
|
||||
## Tipos de Proyectos
|
||||
|
||||
| Icono | Tipo | Significado |
|
||||
| :--: | --- | --- |
|
||||
| ✅ | **Autónomo** | Código completo en este repositorio, se ejecuta tras configurar la Clave API |
|
||||
| 📖 | **Guía de Reproducción** | Documento detallado que depende de **repositorios externos** para realizar `git clone` |
|
||||
| 🚧 | **Documento de Diseño** | Solo arquitectura/plan de implementación, el código ejecutable aún está en desarrollo |
|
||||
@@ -0,0 +1,37 @@
|
||||
# 2. fejezet · Kontextustervezés
|
||||
|
||||
> A kontextus határozza meg az ágens képességeinek felső korlátját: API-struktúra, KV Cache-barát tervezés, prompttervezés, Agent Skills, állapotsáv és kontextustömörítés.
|
||||
|
||||
← [Vissza a magyar főoldalhoz](../docs/hu/README.md) · 📖 [A fejezet olvasása](../book-hu/chapter2.md)
|
||||
|
||||
## Hogyan olvassuk a kísérleteket?
|
||||
|
||||
A törzsszöveg rövid mechanizmus-skeletonokkal magyarázza a vezérlési folyamatot; a kísérleti könyvtárakban találhatók a teljes SDK-adapterek, naplók, tesztek és átvételi bizonyítékok. Nem kell minden fájlt sorról sorra elolvasni.
|
||||
|
||||
- **Starter:** Kezdje a céllal, a minimális paranccsal és az átvételi feltételekkel; induljon innen: [context-compression](context-compression/);
|
||||
- **Builder:** Kövesse a belépési pontot, a fő ciklust, az állapot-/üzenetsémát, az eszközöket és az ellenőrzőt.
|
||||
- **Maintainer:** Végül olvassa el a teszteket, a bizonyíték-manifeszteket, a hibakezelést, a visszaállítási útvonalakat és a provider-adaptereket.
|
||||
|
||||
Első olvasáskor átugorható a hitelesítő adatok betöltése, a megjelenítési réteg és a provider-kompatibilitás; a számok reprodukálásakor térjen vissza.
|
||||
|
||||
## Kapcsolódó projektek
|
||||
|
||||
| Kísérlet | Projekt | Típus | Leírás |
|
||||
| :--: | --- | :--: | --- |
|
||||
| 2-1 | [local_llm_serving](local_llm_serving/) | ✅ | Platformfüggetlen helyi LLM-telepítést biztosít vLLM vagy Ollama háttérrendszerrel. |
|
||||
| 2-2, 2-7 | [attention_visualization](attention_visualization/) | ✅ | Megjeleníti a bemeneti és kimeneti tokeneket, valamint a modell figyelmi súlyainak eloszlását. |
|
||||
| 2-3 | [kv-cache](kv-cache/) | ✅ | Összehasonlítja a kontextuskezelési mintákat és azok KV Cache-hatékonyságra gyakorolt hatását. |
|
||||
| 2-4 | [prompt-engineering](prompt-engineering/) | ✅ | Szisztematikus ablációs kísérletekkel méri a prompt különböző elemeinek hatását. |
|
||||
| 2-5 | [prompt-injection](prompt-injection/) | ✅ | Három támadási forgatókönyvet vet össze négy rétegzett védelmi konfigurációval. |
|
||||
| 2-6 | [agent-skills-ppt](agent-skills-ppt/) | ✅ | Az Agent Skills fokozatos feltárását alkalmazza valódi PPTX-prezentáció létrehozására. |
|
||||
| 2-7 | Szöveges kísérlet | 🚧 | Könnyű írási Skillt készít személyes példákból, aktiválási feltételekkel, szabályokkal, példákkal, hatókörrel és iteratív karbantartással. |
|
||||
| 2-8 | [system-hint](system-hint/) | ✅ | A System Hints ágensviselkedésre és teljesítményre gyakorolt hatását vizsgálja. |
|
||||
| 2-9 | [context-compression](context-compression/) | ✅ | Több tömörítési stratégiát hasonlít össze a tokenhasználat csökkentésére az alapvető képességek megőrzése mellett. |
|
||||
|
||||
## Projekttípusok
|
||||
|
||||
| Ikon | Típus | Jelentés |
|
||||
| :--: | --- | --- |
|
||||
| ✅ | **Önálló** | A teljes kód a repository-ban található, és az API-kulcsok beállítása után futtatható. |
|
||||
| 📖 | **Reprodukciós útmutató** | Külső repository szükséges, amelyet külön kell `git clone` paranccsal letölteni. |
|
||||
| 🚧 | **Folyamatban** | Az implementáció vagy az elfogadási bizonyíték még nem teljes. |
|
||||
@@ -0,0 +1,37 @@
|
||||
# Bab 2 · Rekayasa Context
|
||||
|
||||
> Context menentukan batas atas kemampuan Agent: struktur API, desain ramah KV Cache, prompt engineering, Agent Skills, status bar, dan kompresi context.
|
||||
|
||||
← [Kembali ke README utama](../docs/id/README.md) · 📖 [Baca bab](../book-id/chapter2.md)
|
||||
|
||||
## Cara Membaca Eksperimen
|
||||
|
||||
Teks utama memakai skeleton mekanisme singkat untuk menjelaskan alur kontrol; direktori eksperimen berisi adapter SDK lengkap, log, pengujian, dan bukti penerimaan. Anda tidak perlu membaca setiap berkas baris demi baris.
|
||||
|
||||
- **Starter:** Mulai dari tujuan, perintah minimum, dan syarat penerimaan; awali dengan [context-compression](context-compression/);
|
||||
- **Builder:** Telusuri titik masuk, loop inti, skema status/pesan, alat, dan verifier.
|
||||
- **Maintainer:** Terakhir, baca pengujian, manifest bukti, penanganan kegagalan, rollback, dan adapter provider.
|
||||
|
||||
Pada pembacaan pertama, lewati kredensial, presentasi, dan kompatibilitas provider; kembali saat mereproduksi angka.
|
||||
|
||||
## Proyek Pendamping
|
||||
|
||||
| Eksperimen | Proyek | Jenis | Deskripsi |
|
||||
| :--: | --- | :--: | --- |
|
||||
| 2-1 | [local_llm_serving](local_llm_serving/) | ✅ | Menyediakan deployment LLM lokal lintas platform dengan backend vLLM atau Ollama. |
|
||||
| 2-2, 2-7 | [attention_visualization](attention_visualization/) | ✅ | Memvisualisasikan token input/output dan distribusi bobot attention model. |
|
||||
| 2-3 | [kv-cache](kv-cache/) | ✅ | Membandingkan pola pengelolaan context dan dampaknya terhadap efisiensi KV Cache. |
|
||||
| 2-4 | [prompt-engineering](prompt-engineering/) | ✅ | Mengukur pengaruh unsur prompt melalui eksperimen ablasi yang sistematis. |
|
||||
| 2-5 | [prompt-injection](prompt-injection/) | ✅ | Membandingkan tiga skenario serangan dengan empat konfigurasi pertahanan berlapis. |
|
||||
| 2-6 | [agent-skills-ppt](agent-skills-ppt/) | ✅ | Mempraktikkan progressive disclosure pada Agent Skills untuk menghasilkan presentasi PPTX. |
|
||||
| 2-7 | Eksperimen teks | 🚧 | Membuat Skill penulisan ringan dari contoh pribadi, mencakup kondisi pemicu, aturan, contoh, cakupan, dan pemeliharaan iteratif. |
|
||||
| 2-8 | [system-hint](system-hint/) | ✅ | Menguji pengaruh System Hints terhadap perilaku dan kinerja Agent. |
|
||||
| 2-9 | [context-compression](context-compression/) | ✅ | Membandingkan beberapa strategi kompresi untuk mengurangi token tanpa kehilangan kemampuan utama. |
|
||||
|
||||
## Jenis Proyek
|
||||
|
||||
| Ikon | Jenis | Arti |
|
||||
| :--: | --- | --- |
|
||||
| ✅ | **Mandiri** | Kode lengkap tersedia di repositori dan dapat dijalankan setelah API Key dikonfigurasi. |
|
||||
| 📖 | **Panduan Reproduksi** | Memerlukan repositori eksternal yang harus di-`git clone`. |
|
||||
| 🚧 | **Dalam Proses** | Implementasi atau bukti penerimaan belum lengkap. |
|
||||
@@ -0,0 +1,36 @@
|
||||
# 第2章 · コンテキストエンジニアリング
|
||||
|
||||
> コンテキストは Agent 能力の上限を決定する。LLM API のコンテキスト構造、KV Cache に優しい設計、プロンプトエンジニアリング、動的プロンプトと Agent Skills、ステータスバーのメタ情報、コンテキスト圧縮戦略について掘り下げる。
|
||||
|
||||
← [メイン README に戻る](../docs/ja/README.md) · 📖 [章の本文を読む](../book-ja/chapter2.ja.md)
|
||||
|
||||
## 実験の読み方
|
||||
|
||||
本文では短い mechanism skeleton で制御フローを説明し、実験ディレクトリには完全な SDK アダプター、ログ、テスト、受け入れ証拠を置きます。すべてのファイルを一行ずつ読む必要はありません。
|
||||
|
||||
- **Starter:** 目的・最小コマンド・受け入れ条件から始め、まず [context-compression](context-compression/);
|
||||
- **Builder:** エントリポイント、中心ループ、状態/メッセージ schema、ツール、検証器を追います。
|
||||
- **Maintainer:** 最後にテスト、証拠 manifest、失敗処理、rollback 経路、provider adapter を読みます。
|
||||
|
||||
初読では認証情報、表示層、provider 互換層を飛ばし、数値を再現するときに戻ってください。
|
||||
|
||||
## 付随プロジェクト
|
||||
|
||||
| 実験 | プロジェクト | 種類 | 説明 |
|
||||
| :--: | --- | :--: | --- |
|
||||
| 2-1 | [local_llm_serving](local_llm_serving/) | ✅ | 最適なバックエンド(vLLM または Ollama)を自動選択するクロスプラットフォームのローカル LLM デプロイソリューション。優れたシステム設計により、0.6B の小型モデルでも優れたツール呼び出し能力を実現できることを示す。リアルタイムの思考プロセス表示のためストリーミング応答をサポートする。 |
|
||||
| 2-2, 2-7 | [attention_visualization](attention_visualization/) | ✅ | LLM の入出力トークンシーケンス全体とアテンション重み分布を可視化し、モデルがコンテキストをどのように処理し、推論を行い、ツールを呼び出すかを深く洞察できるようにする。 |
|
||||
| 2-3 | [kv-cache](kv-cache/) | ✅ | 異なるコンテキスト管理モードが KV Cache に与える影響を探り、よくあるエラーパターンがどのようにキャッシュ効率を破壊するかを示す。適切なコンテキスト設計がレイテンシとコストを大幅に削減できることを実験を通じて示す。 |
|
||||
| 2-4 | [prompt-engineering](prompt-engineering/) | ✅ | Tau-Bench フレームワークを拡張し、体系的なアブレーション(実験)を通じて、異なるプロンプトエンジニアリング要因が Agent 性能に与える影響を定量化する。トーン、指示の構成、ツールの説明といった要因がタスク完了率にどう影響するかを示す。 |
|
||||
| 2-5 | [prompt-injection](prompt-injection/) | ✅ | 3 つの攻撃シナリオ(直接インジェクション、間接インジェクション、メモリインジェクション)× 4 つの防御構成(防御なし、プロンプト強化、ソースタグ付け、複合防御)による制御実験を構築する。決定論的なルールを用いて攻撃成功率を算出し、多層防御がインジェクション成功率をいかに大幅に低下させるかを視覚的に示す。 |
|
||||
| 2-6 | [agent-skills-ppt](agent-skills-ppt/) | ✅ | Agent Skills の「段階的開示」という概念を再現する。Agent は最初、薄い Skill ディレクトリしか見えない。タスクに `pptx` Skill が必要だと識別して初めて、その完全なワークフロー、詳細ドキュメント、同梱スクリプトを段階的に読み込み、最終的に python-pptx を使って実際の `.pptx` ファイルを生成する。 |
|
||||
| 2-7 | 本文実験 | 🚧 | 個人の例文から軽量な文章作成 Skill を作り、発動条件、ルール、例、適用範囲、反復的な保守を確認する。 |
|
||||
| 2-8 | [system-hint](system-hint/) | ✅ | System Hint が Agent の挙動に与える影響を研究し、システムプロンプトの最適化によって性能を向上させる方法を探る。 |
|
||||
| 2-9 | [context-compression](context-compression/) | ✅ | 要約、重要情報抽出、意味的圧縮を含む複数のコンテキスト圧縮戦略を実装・比較する。Agent 能力を維持しながらトークン使用量を削減する。 |
|
||||
## プロジェクトの種類
|
||||
|
||||
| アイコン | 種類 | 意味 |
|
||||
| :--: | --- | --- |
|
||||
| ✅ | **単独実行** | このリポジトリに完全なコードがあり、API キーを設定すれば実行できる |
|
||||
| 📖 | **再現ガイド** | `git clone` が必要な**外部リポジトリ**に依存する詳細ドキュメント |
|
||||
| 🚧 | **設計ドキュメント** | アーキテクチャ/実装計画のみで、実行可能なコードは未完成 |
|
||||
@@ -0,0 +1,37 @@
|
||||
# 제2장 · 컨텍스트 엔지니어링
|
||||
|
||||
> 컨텍스트는 에이전트 역량의 상한을 결정합니다. LLM API의 컨텍스트 구조, KV Cache에 유리한 설계, 프롬프트 엔지니어링, 동적 프롬프트와 Agent Skills, 상태 표시줄 메타 정보, 컨텍스트 압축 전략을 깊이 살펴봅니다.
|
||||
|
||||
← [한국어 메인 README로 돌아가기](../docs/ko/README.md) · 📖 [제2장 본문 읽기](../book-ko/chapter2.ko.md)
|
||||
|
||||
## 실험 읽는 방법
|
||||
|
||||
본문은 짧은 메커니즘 skeleton으로 제어 흐름을 설명하고, 실험 디렉터리에는 완전한 SDK 어댑터·로그·테스트·검수 증거를 둡니다. 모든 파일을 줄 단위로 읽을 필요는 없습니다.
|
||||
|
||||
- **Starter:** 목표, 최소 명령, 검수 조건부터 시작하고 다음에서 출발하세요: [context-compression](context-compression/);
|
||||
- **Builder:** 진입점, 핵심 루프, 상태/메시지 스키마, 도구와 verifier를 따라갑니다.
|
||||
- **Maintainer:** 마지막으로 테스트, 증거 manifest, 실패 처리, rollback 경로와 provider adapter를 읽습니다.
|
||||
|
||||
첫 읽기에서는 credential, UI, provider 호환 계층을 건너뛰고 수치를 재현할 때 돌아오세요.
|
||||
|
||||
## 연계 프로젝트
|
||||
|
||||
| 실험 | 프로젝트 | 유형 | 설명 |
|
||||
| :--: | --- | :--: | --- |
|
||||
| 2-1 | [local_llm_serving](local_llm_serving/) | ✅ | 환경에 가장 적합한 백엔드(vLLM 또는 Ollama)를 자동으로 선택하는 크로스 플랫폼 로컬 LLM 배포 솔루션입니다. 좋은 시스템 설계를 통해 0.6B 소형 모델도 뛰어난 도구 호출 능력을 발휘할 수 있음을 보여 주며, 실시간 사고 과정 표시를 위한 스트리밍 응답도 지원합니다. |
|
||||
| 2-2, 2-7 | [attention_visualization](attention_visualization/) | ✅ | LLM의 전체 입력·출력 토큰 시퀀스와 어텐션 가중치 분포를 시각화해, 모델이 컨텍스트를 처리하고 사고하며 도구를 호출하는 방식을 깊이 이해할 수 있게 합니다. |
|
||||
| 2-3 | [kv-cache](kv-cache/) | ✅ | 여러 컨텍스트 관리 방식이 KV Cache에 미치는 영향을 살펴보고, 흔한 잘못된 패턴이 캐시 효율을 어떻게 무너뜨리는지 보여 줍니다. 올바른 컨텍스트 설계가 지연 시간과 비용을 크게 줄일 수 있음을 실험으로 확인합니다. |
|
||||
| 2-4 | [prompt-engineering](prompt-engineering/) | ✅ | Tau-Bench 프레임워크를 확장하고 체계적인 구성 요소 제거 실험을 통해 프롬프트 엔지니어링 요소가 에이전트 성능에 미치는 영향을 정량화합니다. 어조, 지침 구성, 도구 설명 등이 작업 완료율을 어떻게 바꾸는지 보여 줍니다. |
|
||||
| 2-5 | [prompt-injection](prompt-injection/) | ✅ | 세 가지 공격 시나리오(직접 인젝션, 간접 인젝션, 메모리 인젝션)와 네 가지 방어 설정(방어 없음, 프롬프트 강화, 출처 태깅, 결합 방어)을 조합한 통제 실험을 구성합니다. 결정론적 규칙으로 공격 성공률을 계산해 계층화된 방어가 인젝션 성공률을 크게 낮추는 모습을 시각적으로 보여 줍니다. |
|
||||
| 2-6 | [agent-skills-ppt](agent-skills-ppt/) | ✅ | Agent Skills의 ‘점진적 공개’ 개념을 재현합니다. 처음에는 간소한 Skill 디렉터리만 보여 주고, 작업에 `pptx` Skill이 필요하다고 판단한 뒤에만 전체 워크플로, 상세 문서, 번들 스크립트를 단계적으로 불러옵니다. 마지막에는 python-pptx로 실제 `.pptx` 파일을 생성합니다. |
|
||||
| 2-7 | 본문 실험 | 🚧 | 개인 예시에서 가벼운 글쓰기 Skill을 만들고, 트리거 조건·규칙·예시·범위와 반복 유지 관리를 다룹니다. |
|
||||
| 2-8 | [system-hint](system-hint/) | ✅ | System Hint가 에이전트 행동에 미치는 영향을 살펴보고, 시스템 프롬프트를 최적화해 성능을 높이는 방법을 탐구합니다. |
|
||||
| 2-9 | [context-compression](context-compression/) | ✅ | 요약, 핵심 정보 추출, 의미 기반 압축 등 여러 컨텍스트 압축 전략을 구현하고 비교합니다. 에이전트 역량을 유지하면서 토큰 사용량을 줄입니다. |
|
||||
|
||||
## 프로젝트 유형
|
||||
|
||||
| 아이콘 | 유형 | 의미 |
|
||||
| :--: | --- | --- |
|
||||
| ✅ | **독립 실행** | 전체 코드가 이 저장소에 있으며, API 키를 설정하면 실행할 수 있습니다. |
|
||||
| 📖 | **재현 가이드** | **외부 저장소**를 `git clone`해야 하는 상세 안내 문서입니다. |
|
||||
| 🚧 | **설계 문서** | 아키텍처와 구현 계획만 있으며, 실행 가능한 코드는 아직 작성 중입니다. |
|
||||
@@ -0,0 +1,41 @@
|
||||
# 第 2 章 · 上下文工程
|
||||
|
||||
> 上下文决定能力上限:KV Cache、提示工程、Agent Skills、上下文压缩
|
||||
|
||||
← [返回主目录](../README.md) · 📖 [读本章正文](../book/chapter2.md)
|
||||
|
||||
逐项正文验收条件、真实运行状态及规范证据路径见
|
||||
[EXPERIMENT_LEDGER.md](EXPERIMENT_LEDGER.md)。项目“可运行”不代表历史数值已复现,
|
||||
也不代表外部凭证阻塞的正式路径可以由本地 proxy 替代。
|
||||
|
||||
## 如何阅读实验
|
||||
|
||||
正文保留完整 API 循环;实验提供可运行的上下文管理实现。无需逐行读每个文件:
|
||||
|
||||
- **Starter**:先运行 [context-compression](context-compression/) 的单策略 smoke,确认输入、轨迹和压缩结果;
|
||||
- **Builder**:阅读 [kv-cache](kv-cache/) 的请求前缀/动态状态划分,再对照 [prompt-engineering](prompt-engineering/) 的变量与评估;
|
||||
- **Maintainer**:查看 token 计数、溢出处理、缓存命中证据和回归测试。
|
||||
|
||||
首次可跳过 provider adapter、可视化和样式代码;正文的 API 循环、缓存边界和压缩门控才是第一遍需要掌握的代码地图。
|
||||
|
||||
## 配套项目
|
||||
|
||||
| 编号 | 项目 | 类型 | 一句话说明 |
|
||||
| :--: | --- | :--: | --- |
|
||||
| 2-1 | [local_llm_serving](local_llm_serving/) | ✅ | 跨平台本地 LLM 部署,自动选 vLLM/Ollama 后端,展示 0.6B 小模型也能有出色工具调用 |
|
||||
| 2-2, 2-8 | [attention_visualization](attention_visualization/) | ✅ | 可视化 LLM 完整 token 序列与注意力权重分布,理解模型如何处理上下文、推理与调用工具 |
|
||||
| 2-3 | [kv-cache](kv-cache/) | ✅ | 探索不同上下文管理模式对 KV Cache 的影响,演示错误模式如何破坏缓存效率 |
|
||||
| 2-4 | [prompt-engineering](prompt-engineering/) | ✅ | 扩展 Tau-Bench,量化语气风格、指令组织、工具描述等因素对任务完成率的影响 |
|
||||
| 2-5 | [prompt-injection](prompt-injection/) | ✅ | 3 种攻击场景 × 4 种防御配置的对照实验,直观展示逐层叠加防御后注入成功率下降 |
|
||||
| 2-6 | [agent-skills-ppt](agent-skills-ppt/) | ✅ | 固定 Anthropic 官方 PPTX Skill + 真实论文 PDF,运行时可为 Claude Code 或等价的 Kimi Code CLI(已实测通过:13 页演示文稿、4 张论文原图、完整渐进式披露轨迹),旧 python-pptx 同构 demo 不作为正文验收 |
|
||||
| 2-7 | 正文实验 | 🚧 | 从个人范文创建“去 AI 味”写作 Skill;练习 Skill 的触发条件、规则、示例、作用域与迭代维护,不依赖独立代码项目 |
|
||||
| 2-9 | [system-hint](system-hint/) | ✅ | 研究系统提示对 Agent 行为的影响,探索如何通过优化系统提示提升性能 |
|
||||
| 2-10 | [context-compression](context-compression/) | ✅ | 实现并对比摘要、关键信息提取、语义压缩等多种策略,保持能力的同时减少 token |
|
||||
|
||||
## 项目类型说明
|
||||
|
||||
| 图标 | 类型 | 含义 |
|
||||
| :--: | --- | --- |
|
||||
| ✅ | **可独立运行** | 本仓库自带完整代码,配置好 API Key 即可运行 |
|
||||
| 📖 | **复现指南** | 依赖需自行 `git clone` 的**外部仓库**(训练框架、评测基准等) |
|
||||
| 🚧 | **设计文档** | 仅包含架构与实现方案,可运行代码仍在完善中 |
|
||||
@@ -0,0 +1,36 @@
|
||||
# Глава 2 · Инженерия контекста
|
||||
|
||||
> Контекст определяет верхнюю границу возможностей агента. Подробно разбираются структура контекста в API LLM, дружественный к KV Cache дизайн, инженерия промптов, динамические промпты и Agent Skills, метаинформация строки состояния и стратегии сжатия контекста.
|
||||
|
||||
← [К оглавлению](../docs/ru/README.md) · 📖 [Читать главу](../book-ru/chapter2.md)
|
||||
|
||||
## Как читать эксперименты
|
||||
|
||||
В основном тексте короткие скелеты механизмов объясняют поток управления; в каталогах экспериментов находятся полные адаптеры SDK, журналы, тесты и приёмочные доказательства. Читать каждый файл построчно не требуется.
|
||||
|
||||
- **Starter:** Начните с цели, минимальной команды и условий приёмки; начните с [context-compression](context-compression/);
|
||||
- **Builder:** Проследите точку входа, основной цикл, схему состояния/сообщений, инструменты и проверяющий модуль.
|
||||
- **Maintainer:** Затем изучите тесты, манифесты доказательств, обработку сбоев, откат и адаптеры провайдеров.
|
||||
|
||||
При первом чтении можно пропустить ключи, слой представления и совместимость провайдеров; вернитесь при воспроизведении чисел.
|
||||
|
||||
## Сопутствующие проекты
|
||||
|
||||
| Эксп. | Проект | Тип | Описание |
|
||||
| :--: | --- | :--: | --- |
|
||||
| 2-1 | [local_llm_serving](local_llm_serving/) | ✅ | Кроссплатформенное решение для локального развёртывания LLM, автоматически выбирающее лучший бэкенд (vLLM или Ollama). Показывает, что даже модель на 0.6B при хорошем системном дизайне отлично вызывает инструменты. Поддерживает потоковые ответы с отображением процесса рассуждения в реальном времени. |
|
||||
| 2-2, 2-7 | [attention_visualization](attention_visualization/) | ✅ | Визуализирует полную входную/выходную последовательность токенов и распределение весов внимания LLM, давая глубокое понимание того, как модель обрабатывает контекст, рассуждает и вызывает инструменты. |
|
||||
| 2-3 | [kv-cache](kv-cache/) | ✅ | Исследует влияние разных режимов управления контекстом на KV Cache, демонстрируя, как типичные ошибки разрушают эффективность кэша. На экспериментах показывает, как грамотный дизайн контекста значительно снижает задержку и стоимость. |
|
||||
| 2-4 | [prompt-engineering](prompt-engineering/) | ✅ | Расширяет фреймворк Tau-Bench, чтобы через систематические абляционные эксперименты количественно оценить влияние разных факторов инженерии промптов на качество агента. Показывает, как тон, организация инструкций и описания инструментов влияют на долю выполненных задач. |
|
||||
| 2-5 | [prompt-injection](prompt-injection/) | ✅ | Строит контролируемый эксперимент: 3 сценария атаки (прямая инъекция, косвенная инъекция, инъекция в память) × 4 конфигурации защиты (без защиты, усиление промпта, маркировка источников, комбинированная защита). Детерминированными правилами вычисляет долю успешных атак, наглядно показывая, как эшелонированная защита значительно снижает успех инъекций. |
|
||||
| 2-6 | [agent-skills-ppt](agent-skills-ppt/) | ✅ | Воспроизводит идею «постепенного раскрытия» Agent Skills: сначала агент видит лишь тонкий каталог навыков. Только определив, что задача требует навыка `pptx`, он постепенно подгружает его полный сценарий, подробную документацию и связанные скрипты, в итоге создавая реальный файл `.pptx` через python-pptx. |
|
||||
| 2-7 | Текстовый эксперимент | 🚧 | Создаёт лёгкий Skill для письма на основе личных примеров: условия активации, правила, примеры, область применения и итеративное сопровождение. |
|
||||
| 2-8 | [system-hint](system-hint/) | ✅ | Изучает влияние системных подсказок (System Hints) на поведение агента, исследуя, как повысить качество за счёт оптимизации системного промпта. |
|
||||
| 2-9 | [context-compression](context-compression/) | ✅ | Реализует и сравнивает несколько стратегий сжатия контекста: суммаризацию, извлечение ключевой информации и семантическое сжатие. Снижает расход токенов, сохраняя возможности агента. |
|
||||
## Типы проектов
|
||||
|
||||
| Значок | Тип | Значение |
|
||||
| :--: | --- | --- |
|
||||
| ✅ | **Автономный** | Полный код в этом репозитории, запускается после настройки API-ключа |
|
||||
| 📖 | **Гайд по воспроизведению** | Подробный документ, зависящий от **внешних репозиториев** через `git clone` |
|
||||
| 🚧 | **Проектный документ** | Только архитектура/план реализации, рабочий код ещё в разработке |
|
||||
@@ -0,0 +1,37 @@
|
||||
# அத்தியாயம் 2 · சூழல் பொறியியல்
|
||||
|
||||
> சூழல் ஏஜெண்டின் திறனின் மேல் வரம்பைத் தீர்மானிக்கிறது. பெரிய மாதிரி API இன் சூழல் அமைப்பு, KV Cache நட்பு வடிவமைப்பு, விரைவு பொறியியல் (prompt engineering), மாறும் விரைவுகள் மற்றும் Agent Skills, நிலைப் பட்டை மேல்தரவு (metadata), மற்றும் சூழல் சுருக்க உத்திகள் ஆகியவற்றை ஆழமாக ஆராய்கிறது.
|
||||
|
||||
← [முக்கிய README க்குத் திரும்பு](../docs/ta/README.md) · 📖 [அத்தியாய உரையைப் படி](../book-ta/chapter2.ta.md)
|
||||
|
||||
## சோதனைகளை எப்படிப் படிப்பது
|
||||
|
||||
முதன்மை உரை குறுகிய mechanism skeleton-களால் control flow-ஐ விளக்குகிறது; முழு SDK adapters, logs, tests, acceptance evidence ஆகியவை experiment கோப்பகத்தில் உள்ளன. ஒவ்வொரு கோப்பையும் வரி வரியாகப் படிக்க வேண்டியதில்லை.
|
||||
|
||||
- **Starter:** இலக்கு, குறைந்தபட்ச கட்டளை, ஏற்றுக்கொள்ளும் நிபந்தனைகளில் தொடங்குங்கள்; முதலில் [context-compression](context-compression/);
|
||||
- **Builder:** நுழைவுப் புள்ளி, மையச் சுழற்சி, state/message schema, கருவிகள், verifier ஆகியவற்றைப் பின்தொடருங்கள்.
|
||||
- **Maintainer:** பின்னர் tests, evidence manifest, தோல்வி கையாளல், rollback பாதை, provider adapter ஆகியவற்றைப் படியுங்கள்.
|
||||
|
||||
முதல் வாசிப்பில் credentials, UI, provider-compatibility அடுக்குகளைத் தவிர்க்கலாம்; முடிவுகளை மீண்டும் உருவாக்கும்போது திரும்பிப் பாருங்கள்.
|
||||
|
||||
## துணை திட்டங்கள்
|
||||
|
||||
| சோதனை | Project | Type | Description |
|
||||
| :--: | --- | :--: | --- |
|
||||
| 2-1 | [local_llm_serving](local_llm_serving/) | ✅ | பல்தட (cross-platform) உள்ளூர் LLM பயன்பாட்டுத் தீர்வு; சிறந்த பின்தங்கியை (vLLM அல்லது Ollama) தானாகத் தேர்ந்தெடுக்கிறது. 0.6B போன்ற சிறிய மாதிரியும் நல்ல அமைப்பு வடிவமைப்பின் மூலம் சிறந்த கருவி அழைப்புத் திறனை அடைய முடியும் என்பதைக் காட்டுகிறது. ஸ்ட்ரீமிங் பதில்களை ஆதரித்து, சிந்தனை செயல்முறையை நிகழ்நேரத்தில் காட்டுகிறது. |
|
||||
| 2-2, 2-7 | [attention_visualization](attention_visualization/) | ✅ | LLM இன் முழுமையான உள்ளீடு-வெளியீடு token வரிசைகள் மற்றும் கவன எடை விநியோகத்தைக் காட்சிப்படுத்தி, மாதிரி எவ்வாறு சூழலைச் செயலாக்குகிறது, பகுத்தறிகிறது மற்றும் கருவிகளை அழைக்கிறது என்பதை ஆழமாகப் புரிந்துகொள்ள உதவுகிறது. |
|
||||
| 2-3 | [kv-cache](kv-cache/) | ✅ | வெவ்வேறு சூழல் மேலாண்மை முறைகள் KV Cache மீது ஏற்படுத்தும் தாக்கத்தை ஆராய்ந்து, பொதுவான தவறான முறைகள் கேச் செயல்திறனை எவ்வாறு சீரழிக்கின்றன என்பதை நிரூபிக்கிறது. சரியான சூழல் வடிவமைப்பு தாமதம் மற்றும் செலவை எவ்வாறு கணிசமாகக் குறைக்கிறது என்பதைச் சோதனைகள் மூலம் காட்டுகிறது. |
|
||||
| 2-4 | [prompt-engineering](prompt-engineering/) | ✅ | Tau-Bench கட்டமைப்பை விரிவாக்கி, முறையான அப்லேஷன் பரிசோதனைகள் மூலம் வெவ்வேறு வழிகாட்டி பொறியியல் காரணிகள் ஏஜென்ட் செயல்திறனில் ஏற்படுத்தும் தாக்கத்தை அளவிடுகிறது. தொனி பாணி, வழிமுறை ஒழுங்கமைப்பு, கருவி விளக்கங்கள் போன்ற காரணிகள் பணி நிறைவு விகிதத்தை எவ்வாறு பாதிக்கின்றன என்பதைக் காட்டுகிறது. |
|
||||
| 2-5 | [prompt-injection](prompt-injection/) | ✅ | 3 வகை தாக்குதல் சூழ்நிலைகள் (நேரடி செலுத்துதல், மறைமுக செலுத்துதல், நினைவக செலுத்துதல்) × 4 வகை பாதுகாப்பு உள்ளமைவுகள் (பாதுகாப்பு இல்லை, வழிகாட்டி வலுப்படுத்தல், மூலக் குறிப்பு, இணைந்த பாதுகாப்பு) கொண்ட ஒப்பீட்டுப் பரிசோதனைகளை உருவாக்கி, தீர்மான விதிகளால் தாக்குதல் வெற்றி விகிதத்தைக் கணக்கிட்டு, அடுக்கடுக்காகப் பாதுகாப்பைச் சேர்த்த பிறகு செலுத்துதல் வெற்றி விகிதம் எவ்வாறு கணிசமாகக் குறைகிறது என்பதை நேரடியாகக் காட்டுகிறது. |
|
||||
| 2-6 | [agent-skills-ppt](agent-skills-ppt/) | ✅ | Agent Skills இன் "படிப்படியான வெளிப்படுத்தல்" (progressive disclosure) கருத்தை மீண்டும் உருவாக்குகிறது: ஏஜென்ட் தொடங்கும்போது ஒரு மெல்லிய Skill அட்டவணையை மட்டுமே காண்கிறது; பணிக்கு `pptx` Skill தேவை என்பதை அடையாளம் கண்ட பிறகே அதன் முழுமையான செயல்முறை, விவரமான ஆவணங்கள் மற்றும் இணைக்கப்பட்ட ஸ்கிரிப்டுகளை அடுக்கடுக்காக ஏற்றி, இறுதியாக python-pptx மூலம் உண்மையான `.pptx` கோப்பை உருவாக்குகிறது. |
|
||||
| 2-7 | உரை பரிசோதனை | 🚧 | தனிப்பட்ட எடுத்துக்காட்டுகளிலிருந்து இலகுவான எழுத்து Skill-ஐ உருவாக்கி, தூண்டல் நிபந்தனைகள், விதிகள், எடுத்துக்காட்டுகள், வரம்பு மற்றும் தொடர்ச்சியான பராமரிப்பைச் சோதிக்கிறது. |
|
||||
| 2-8 | [system-hint](system-hint/) | ✅ | கணினி வழிகாட்டி (System Hint) ஏஜென்ட் நடத்தையில் ஏற்படுத்தும் தாக்கத்தை ஆராய்ந்து, கணினி வழிகாட்டியை உகப்பாக்குவதன் மூலம் செயல்திறனை எவ்வாறு மேம்படுத்தலாம் என்பதை அறிகிறது. |
|
||||
| 2-9 | [context-compression](context-compression/) | ✅ | சுருக்கம், முக்கிய தகவல் பிரித்தெடுப்பு, சொற்பொருள் சுருக்கம் உட்படப் பல சூழல் சுருக்க உத்திகளைச் செயல்படுத்தி ஒப்பிடுகிறது. ஏஜென்ட் திறன்களைத் தக்கவைத்துக்கொண்டே token பயன்பாட்டைக் குறைக்கிறது. |
|
||||
|
||||
## திட்ட வகைகள்
|
||||
|
||||
| சின்னம் | வகை | பொருள் |
|
||||
| :--: | --- | --- |
|
||||
| ✅ | **தனித்து இயங்கும்** | முழு குறியீடு இந்த களஞ்சியத்தில், API Key உள்ளமைத்தவுடன் இயங்கும் |
|
||||
| 📖 | **மறு உருவாக்க வழிகாட்டி** | **வெளிப்புற களஞ்சியங்களை** `git clone` செய்ய வேண்டிய விரிவான ஆவணம் |
|
||||
| 🚧 | **வடிவமைப்பு ஆவணம்** | கட்டமைப்பு/செயலாக்கத் திட்டம் மட்டும், இயங்கும் குறியீடு இன்னும் WIP |
|
||||
@@ -0,0 +1,37 @@
|
||||
# Bölüm 2 · Bağlam Mühendisliği
|
||||
|
||||
> Context, Agent yeteneklerinin üst sınırını belirler. LLM API'lerinin context yapısına, KV Cache dostu tasarıma, prompt mühendisliğine, dinamik promptlara ve Agent Skills'e, durum çubuğu meta-bilgisine ve context sıkıştırma stratejilerine iner.
|
||||
|
||||
← [Ana README'ye dön](../README.tr.md) · 📖 [Bölüm metnini oku](../book-tr/chapter2.tr.md)
|
||||
|
||||
## Deneyler nasıl okunur
|
||||
|
||||
Metin, kontrol akışını açıklamak için kısa mekanizma skeleton'ları kullanır; deney dizininde tam SDK adaptörleri, günlükler, testler ve kabul kanıtı bulunur. Her dosyayı satır satır okumanız gerekmez.
|
||||
|
||||
- **Starter:** Hedef, en kısa komut ve kabul koşullarıyla başlayın; önce [context-compression](context-compression/);
|
||||
- **Builder:** Giriş noktasını, ana döngüyü, durum/mesaj şemasını, araçları ve doğrulayıcıyı izleyin.
|
||||
- **Maintainer:** Son olarak testleri, kanıt manifestlerini, hata işlemeyi, rollback yollarını ve sağlayıcı adaptörlerini okuyun.
|
||||
|
||||
İlk okumada kimlik bilgisi yükleme, sunum katmanı ve sağlayıcı uyumluluğunu atlayıp sayıları yeniden üretirken dönün.
|
||||
|
||||
## Eşlik Eden Projeler
|
||||
|
||||
| Proje | Tür | Açıklama |
|
||||
| --- | :--: | --- |
|
||||
| [local_llm_serving](local_llm_serving/) | ✅ | En iyi arka ucu (vLLM veya Ollama) otomatik seçen platformlar arası yerel LLM dağıtım çözümü. İyi sistem tasarımıyla 0,6B'lik küçük bir modelin bile mükemmel araç çağırma yeteneği gösterebildiğini kanıtlar. Düşünce sürecinin gerçek zamanlı gösterimi için akış (streaming) yanıtları destekler. |
|
||||
| [attention_visualization](attention_visualization/) | ✅ | Bir LLM'in tam girdi/çıktı token dizisini ve dikkat ağırlığı dağılımını görselleştirir; modelin context'i nasıl işlediğine, muhakeme yaptığına ve araç çağırdığına derinlemesine bir bakış sunar. |
|
||||
| [kv-cache](kv-cache/) | ✅ | Farklı context yönetimi modlarının KV Cache üzerindeki etkisini araştırır, yaygın hata örüntülerinin önbellek verimliliğini nasıl bozduğunu gösterir. Uygun context tasarımının gecikme ve maliyeti nasıl önemli ölçüde azaltabileceğini deneylerle gösterir. |
|
||||
| [context-compression](context-compression/) | ✅ | Özetleme, anahtar bilgi çıkarımı ve anlamsal sıkıştırma dahil birden çok context sıkıştırma stratejisini uygular ve karşılaştırır. Agent yeteneklerini korurken token kullanımını azaltır. |
|
||||
| [prompt-engineering](prompt-engineering/) | ✅ | Tau-Bench çerçevesini genişleterek, sistematik ablasyon deneyleriyle farklı prompt mühendisliği faktörlerinin Agent performansı üzerindeki etkisini nicelleştirir. Ton, talimat organizasyonu ve araç açıklamaları gibi faktörlerin görev tamamlama oranlarını nasıl etkilediğini gösterir. |
|
||||
| [system-hint](system-hint/) | ✅ | System Hint'lerin (sistem ipuçlarının) Agent davranışı üzerindeki etkisini inceler, sistem istemlerini optimize ederek performansın nasıl artırılabileceğini araştırır. |
|
||||
| [prompt-injection](prompt-injection/) | ✅ | 3 saldırı senaryosu (doğrudan enjeksiyon, dolaylı enjeksiyon, bellek enjeksiyonu) × 4 savunma yapılandırması (savunmasız, prompt sertleştirme, kaynak etiketleme, birleşik savunma) içeren kontrollü bir deney kurar. Saldırı başarı oranlarını hesaplamak için deterministik kurallar kullanır, katmanlı savunmaların enjeksiyon başarı oranlarını nasıl önemli ölçüde azalttığını görsel olarak gösterir. |
|
||||
| [agent-skills-ppt](agent-skills-ppt/) | ✅ | Agent Skills'in "kademeli açığa çıkarma" (progressive disclosure) kavramını yeniden üretir: Agent başlangıçta yalnızca ince bir Skill dizini görür. Görevin `pptx` Skill'ini gerektirdiğini belirledikten sonra ancak tam iş akışını, ayrıntılı dokümantasyonu ve paketlenmiş betikleri kademeli olarak yükler; sonunda python-pptx kullanarak gerçek bir `.pptx` dosyası üretir. |
|
||||
| **Metin deneyi** | 🚧 | Kişisel örneklerden hafif bir yazma Skill'i oluşturmayı; tetikleme koşullarını, kuralları, örnekleri, kapsamı ve yinelemeli bakımı ele almayı dener. |
|
||||
|
||||
## Proje Türleri
|
||||
|
||||
| İkon | Tür | Anlamı |
|
||||
| :--: | --- | --- |
|
||||
| ✅ | **Bağımsız** | Bu depoda tam kod, API Key yapılandırıldıktan sonra çalışır |
|
||||
| 📖 | **Yeniden Üretim Rehberi** | `git clone` ile **harici depolara** bağımlı ayrıntılı belge |
|
||||
| 🚧 | **Tasarım Belgesi** | Yalnızca mimari/uygulama planı, çalıştırılabilir kod henüz hazır değil |
|
||||
@@ -0,0 +1,37 @@
|
||||
# Chương 2 · Kỹ thuật ngữ cảnh
|
||||
|
||||
> ngữ cảnh quyết định trần năng lực của Agent. Đi sâu vào cấu trúc ngữ cảnh của API mô hình lớn, thiết kế thân thiện với KV Cache, prompt engineering, prompt động và Agent Skills, siêu thông tin trên thanh trạng thái, cũng như các chiến lược nén ngữ cảnh.
|
||||
|
||||
← [Về README chính](../docs/vi/README.md) · 📖 [Đọc nội dung chương](../book-vi/chapter2.vi.md)
|
||||
|
||||
## Cách đọc các thí nghiệm
|
||||
|
||||
Phần văn bản dùng skeleton cơ chế ngắn để giải thích luồng điều khiển; thư mục thí nghiệm chứa adapter SDK đầy đủ, log, kiểm thử và bằng chứng nghiệm thu. Không cần đọc từng tệp theo từng dòng.
|
||||
|
||||
- **Starter:** Bắt đầu từ mục tiêu, lệnh tối thiểu và điều kiện nghiệm thu; hãy bắt đầu với [context-compression](context-compression/);
|
||||
- **Builder:** Lần theo điểm vào, vòng lặp lõi, schema trạng thái/tin nhắn, công cụ và verifier.
|
||||
- **Maintainer:** Sau đó đọc test, manifest bằng chứng, xử lý lỗi, đường rollback và adapter nhà cung cấp.
|
||||
|
||||
Lần đầu có thể bỏ qua credential, lớp trình bày và tương thích provider; quay lại khi cần tái tạo số liệu.
|
||||
|
||||
## Dự án đi kèm
|
||||
|
||||
| Thí nghiệm | Project | Type | Description |
|
||||
| :--: | --- | :--: | --- |
|
||||
| 2-1 | [local_llm_serving](local_llm_serving/) | ✅ | Giải pháp triển khai LLM cục bộ đa nền tảng, tự động chọn backend tối ưu (vLLM hoặc Ollama). Cho thấy ngay cả mô hình nhỏ 0.6B cũng có thể đạt năng lực gọi công cụ xuất sắc nhờ thiết kế hệ thống tốt. Hỗ trợ phản hồi streaming và hiển thị quá trình suy nghĩ theo thời gian thực. |
|
||||
| 2-2, 2-7 | [attention_visualization](attention_visualization/) | ✅ | Trực quan hóa toàn bộ chuỗi token đầu vào/đầu ra và phân bố trọng số attention của LLM, giúp hiểu sâu cách mô hình xử lý ngữ cảnh, suy luận và gọi công cụ. |
|
||||
| 2-3 | [kv-cache](kv-cache/) | ✅ | Khám phá ảnh hưởng của các chế độ quản lý ngữ cảnh khác nhau lên KV Cache, minh họa các mẫu sai phổ biến làm phá hỏng hiệu quả cache. Thông qua thí nghiệm, dự án cho thấy thiết kế ngữ cảnh đúng có thể giảm đáng kể độ trễ và chi phí. |
|
||||
| 2-4 | [prompt-engineering](prompt-engineering/) | ✅ | Mở rộng framework Tau-Bench, dùng thí nghiệm ablation có hệ thống để định lượng ảnh hưởng của các yếu tố prompt engineering khác nhau lên hiệu năng Agent. Cho thấy giọng điệu, tổ chức chỉ dẫn, mô tả công cụ và các yếu tố khác ảnh hưởng thế nào tới tỷ lệ hoàn thành nhiệm vụ. |
|
||||
| 2-5 | [prompt-injection](prompt-injection/) | ✅ | Xây dựng thí nghiệm đối chứng với 3 kịch bản tấn công (tiêm trực tiếp, tiêm gián tiếp, tiêm qua bộ nhớ) × 4 cấu hình phòng thủ (không phòng thủ, gia cố prompt, đánh dấu nguồn, phòng thủ kết hợp), dùng quy tắc xác định để thống kê tỷ lệ tấn công thành công, trực quan cho thấy tỷ lệ tiêm lệnh giảm mạnh khi phòng thủ được chồng lớp. |
|
||||
| 2-6 | [agent-skills-ppt](agent-skills-ppt/) | ✅ | Tái hiện tư tưởng “tiết lộ tăng dần” của Agent Skills: khi khởi động, Agent chỉ thấy một thư mục Skill mỏng; sau khi nhận diện nhiệm vụ cần Skill `pptx`, nó mới tải dần quy trình đầy đủ, tài liệu chi tiết và script đóng gói, cuối cùng dùng python-pptx tạo file `.pptx` thật. |
|
||||
| 2-7 | Thí nghiệm văn bản | 🚧 | Tạo một Skill viết nhẹ từ các bài mẫu cá nhân, bao gồm điều kiện kích hoạt, quy tắc, ví dụ, phạm vi và bảo trì lặp lại. |
|
||||
| 2-8 | [system-hint](system-hint/) | ✅ | Nghiên cứu ảnh hưởng của System Hint tới hành vi Agent, khám phá cách tối ưu system prompt để nâng cao hiệu năng. |
|
||||
| 2-9 | [context-compression](context-compression/) | ✅ | Triển khai và so sánh nhiều chiến lược nén ngữ cảnh, bao gồm tóm tắt, trích xuất thông tin then chốt, nén ngữ nghĩa, v.v. Mục tiêu là giảm lượng token sử dụng trong khi vẫn giữ năng lực của Agent. |
|
||||
|
||||
## Phân loại dự án
|
||||
|
||||
| Biểu tượng | Loại | Ý nghĩa |
|
||||
| :--: | --- | --- |
|
||||
| ✅ | **Chạy độc lập** | Có mã đầy đủ trong kho, chạy được sau khi cấu hình API Key |
|
||||
| 📖 | **Hướng dẫn tái hiện** | Tài liệu chi tiết, cần `git clone` **kho ngoài** |
|
||||
| 🚧 | **Tài liệu thiết kế** | Chỉ có kiến trúc/phương án, mã chạy được đang hoàn thiện |
|
||||
@@ -0,0 +1,37 @@
|
||||
# 第 2 章 · 上下文工程
|
||||
|
||||
> 上下文決定能力上限:KV Cache、提示工程、Agent Skills、上下文壓縮
|
||||
|
||||
← [返回主目錄](../docs/zh-TW/README.md) · 📖 [讀本章正文](../book/chapter2.md)
|
||||
|
||||
## 如何閱讀實驗
|
||||
|
||||
正文用短小的機制 skeleton 說明控制流;實驗目錄放完整的 SDK 適配、日誌、測試與驗收證據,不需要逐行讀完每個檔案。
|
||||
|
||||
- **Starter:** 先讀目標、最小指令與驗收條件;可從 [context-compression](context-compression/);
|
||||
- **Builder:** 沿著入口、核心迴圈、狀態/訊息 schema、工具與驗證器閱讀。
|
||||
- **Maintainer:** 最後再看測試、證據 manifest、失敗處理、回滾路徑與 provider adapter。
|
||||
|
||||
第一次閱讀可先跳過憑證載入、展示層和 provider 相容層;要重現數字時再回來查看。
|
||||
|
||||
## 配套專案
|
||||
|
||||
| 編號 | 專案 | 型別 | 一句話說明 |
|
||||
| :--: | --- | :--: | --- |
|
||||
| 2-1 | [local_llm_serving](local_llm_serving/) | ✅ | 跨平台本地 LLM 部署,自動選 vLLM/Ollama 後端,展示 0.6B 小模型也能有出色工具呼叫 |
|
||||
| 2-2, 2-8 | [attention_visualization](attention_visualization/) | ✅ | 視覺化 LLM 完整 token 序列與注意力權重分佈,理解模型如何處理上下文、推理與呼叫工具 |
|
||||
| 2-3 | [kv-cache](kv-cache/) | ✅ | 探索不同上下文管理模式對 KV Cache 的影響,示範錯誤模式如何破壞快取效率 |
|
||||
| 2-4 | [prompt-engineering](prompt-engineering/) | ✅ | 擴充 Tau-Bench,量化語氣風格、指令組織、工具描述等因素對任務完成率的影響 |
|
||||
| 2-5 | [prompt-injection](prompt-injection/) | ✅ | 3 種攻擊場景 × 4 種防禦設定的對照實驗,直觀展示逐層疊加防禦後注入成功率下降 |
|
||||
| 2-6 | [agent-skills-ppt](agent-skills-ppt/) | ✅ | 復現 Agent Skills「漸進式揭露」,按需載入完整流程後用 python-pptx 產生真實 `.pptx` |
|
||||
| 2-7 | 正文實驗 | 🚧 | 從個人範文建立「去 AI 味」寫作 Skill;練習觸發條件、規則、示例、作用域與迭代維護,不依賴獨立程式專案 |
|
||||
| 2-9 | [system-hint](system-hint/) | ✅ | 研究系統提示對 Agent 行為的影響,探索如何透過最佳化系統提示提升效能 |
|
||||
| 2-10 | [context-compression](context-compression/) | ✅ | 實作並對比摘要、關鍵資訊擷取、語意壓縮等多種策略,保持能力的同時減少 token |
|
||||
|
||||
## 專案型別說明
|
||||
|
||||
| 圖示 | 型別 | 含義 |
|
||||
| :--: | --- | --- |
|
||||
| ✅ | **可獨立執行** | 本倉庫自帶完整程式碼,設定好 API Key 即可執行 |
|
||||
| 📖 | **復現指南** | 依賴需自行 `git clone` 的**外部倉庫**(訓練框架、評測基準等) |
|
||||
| 🚧 | **設計文件** | 僅包含架構與實作方案,可執行程式碼仍在完善中 |
|
||||
@@ -0,0 +1,16 @@
|
||||
/output/
|
||||
external/
|
||||
__pycache__/
|
||||
*.pyc
|
||||
.env
|
||||
# Official-run workspace noise: dependency installs and runtime skill symlinks
|
||||
# (the pinned Skill itself is verifiable via external/official_skill_receipt.json).
|
||||
runs/*/workspace/**/node_modules/
|
||||
runs/*/workspace/kimi-skills/
|
||||
runs/*/workspace/.claude/
|
||||
runs/*/workspace/deckbuild/
|
||||
|
||||
|
||||
# Official-run decks are deliberate evidence artifacts; re-include them.
|
||||
!runs/*/workspace/output/
|
||||
!runs/*/workspace/output/**
|
||||
@@ -0,0 +1,410 @@
|
||||
# Agent Skills PPT Demo / 使用 Agent Skills 从论文生成演示文稿
|
||||
|
||||
> Companion material for *AI Agents in Depth*, Chapter 2 — **Experiment 2-6 ★★: Generate a presentation from a paper using Agent Skills**.
|
||||
> 配套《深入理解 AI Agent》第 2 章 **实验 2-6 ★★:使用 Agent Skills 从论文生成演示文稿**。
|
||||
|
||||
← [Chapter 2 index / 返回第 2 章目录](../README.md)
|
||||
|
||||
---
|
||||
|
||||
## Canonical manuscript reproduction / 正式复现实验
|
||||
|
||||
Experiment 2-6 is **the pinned official Anthropic PPTX Skill + a real academic
|
||||
PDF**, executed by a skills-capable agent runtime. Under the author's
|
||||
runtime-agnostic acceptance policy (2026-07-31), acceptance is NOT gated on
|
||||
Anthropic credentials: the runtime may be **Claude Code** or an equivalent
|
||||
runtime that supports SKILL.md-style progressive disclosure, such as **Kimi
|
||||
Code CLI**. The pinned Skill content, the real paper, and every artifact gate
|
||||
are identical for either runtime.
|
||||
|
||||
The runner pins the official repository to revision
|
||||
`69c0b1a0674149f27b61b2635f935524b6add202`, the revision containing the
|
||||
`html2pptx.md` flow named in the manuscript, and uses Vaswani et al.'s real
|
||||
*Attention Is All You Need* PDF (arXiv:1706.03762, SHA-256
|
||||
`bdfaa68d...82df697`).
|
||||
|
||||
Run with Kimi Code CLI (`KIMI_API_KEY` / `MOONSHOT_API_KEY`, model
|
||||
`kimi-code/k3`):
|
||||
|
||||
```bash
|
||||
cd chapter2/agent-skills-ppt
|
||||
python run_official_experiment.py --runtime kimi \
|
||||
--output runs/exp2-6-kimi-pptx-$(date +%Y%m%d-%H%M%S)
|
||||
```
|
||||
|
||||
Run with Claude Code (valid `ANTHROPIC_API_KEY`, or `--auth-source
|
||||
claude-login` for an enabled Claude Code login):
|
||||
|
||||
```bash
|
||||
cd chapter2/agent-skills-ppt
|
||||
python run_official_experiment.py --runtime claude \
|
||||
--output runs/exp2-6-claude-pptx-$(date +%Y%m%d-%H%M%S)
|
||||
```
|
||||
|
||||
Both paths fetch and verify the pinned external Skill (never copied or
|
||||
reimplemented), install it as the runtime's only Skill (Claude:
|
||||
`.claude/skills/pptx` symlink; Kimi: `--skills-dir`, which replaces the
|
||||
auto-discovered skill directories for that launch), and capture the raw
|
||||
stream-json event stream as the receipt. Raw events prove Skill selection,
|
||||
full `SKILL.md`/`html2pptx.md` disclosure, official script use, thumbnail
|
||||
inspection, and artifact creation. The fail-closed validator requires 10–15
|
||||
slides, all manuscript sections, three PDF-extracted visuals byte-identical to
|
||||
media embedded in the deck, a full-deck thumbnail grid, and a credential scan
|
||||
of the stream. See `experiment_protocol.json` for all frozen gates.
|
||||
|
||||
### Canonical evidence status (2026-07-31): PASSED with Kimi Code CLI
|
||||
|
||||
`runs/exp2-6-kimi-pptx-20260731-v1/manifest.json` passes all 15 gates:
|
||||
|
||||
- Runtime: Kimi Code CLI 0.31.0, model `kimi-code/k3`, 114 tool calls over 25
|
||||
assistant turns; the raw stream (`kimi_stream.jsonl`) contains no credential
|
||||
material.
|
||||
- Progressive disclosure is genuine: the model invoked the `pptx` Skill
|
||||
(metadata → full `SKILL.md`), then read `html2pptx.md`, used the official
|
||||
`scripts/html2pptx.js` workflow, ran the official `scripts/thumbnail.py`,
|
||||
and iterated on visually inspected thumbnails (overlap/cutoff fixes) before
|
||||
finishing.
|
||||
- Deck: 13 slides covering title, background, method/architecture, training,
|
||||
key results, generalization, interpretability, and conclusion; valid
|
||||
OOXML ZIP, reopened by python-pptx and rendered to 13 pages by LibreOffice.
|
||||
- Four visuals (Figure 1, Figure 2, Table 2, Figure 3) were cropped from the
|
||||
source PDF with `pdftoppm`, documented in `source_visuals/manifest.json`
|
||||
with page/label/caption, and are byte-identical to media embedded in the
|
||||
PPTX.
|
||||
|
||||
Earlier Claude Code attempts (`runs/exp2-6-claude-pptx-20260730-v2`–`v4`) were
|
||||
externally blocked before inference by invalid/disabled Anthropic credentials;
|
||||
their fail-closed manifests and credential-free streams are retained as
|
||||
evidence of the old gate. The Claude path above remains fully supported for
|
||||
readers who have Anthropic credentials. The existing
|
||||
`output/presentation.pptx` belongs to the legacy demo (nine slides and no
|
||||
embedded media) and is not acceptance evidence.
|
||||
|
||||
正式复现使用固定的 Anthropic 官方 PPTX Skill 与真实论文 PDF,运行时可以是
|
||||
Claude Code 或支持 SKILL.md 渐进式披露的等价运行时(如 Kimi Code CLI)——实验
|
||||
对象是 Skill 内容,运行时可替换。两条路径都会固定外部仓库版本、保存完整的渐进式
|
||||
披露轨迹,并对页数、章节、论文原图、PPTX 有效性、缩略图和凭证泄漏逐项验收。
|
||||
|
||||
## Legacy mechanism illustration (not acceptance evidence)
|
||||
|
||||
The older `demo.py` and bundled `skills/pptx` tree below are retained as an
|
||||
offline teaching aid. They use a local isomorphic loader and a prewritten short
|
||||
outline, so neither online nor offline mode counts as fulfillment of the
|
||||
manuscript experiment.
|
||||
|
||||
以下旧 demo 仅用于离线讲解机制,不属于实验 2-6 的正式验收证据。
|
||||
|
||||
---
|
||||
|
||||
## English
|
||||
|
||||
### Legacy demo purpose
|
||||
|
||||
Validates a core claim from the book: **an Agent can complete complex work by loading domain Skills on demand via progressive disclosure**, without stuffing all knowledge into the system prompt at once.
|
||||
|
||||
This demo lets an Agent turn a (bundled) short paper into an 8–12 page PowerPoint. At startup the Agent sees only a **thin Skill catalog**; when it decides the task needs the `pptx` Skill, it loads the full workflow, sub-docs, and bundled scripts layer by layer, then generates a real `.pptx` with **python-pptx**.
|
||||
|
||||
### Relation to Anthropic’s PPTX Skill
|
||||
|
||||
The original book experiment ran on **Claude Code + Anthropic’s official PPTX Skill**. Because Anthropic access is not always available, this project **implements an isomorphic Skills mechanism** (not Anthropic’s runtime):
|
||||
|
||||
| Dimension | Anthropic PPTX Skill (book) | This project (isomorphic) |
|
||||
|-----------|-----------------------------|---------------------------|
|
||||
| Runtime | Claude Code | Python + OpenAI SDK (`gpt-5.6-luna`) |
|
||||
| Layer 1 · metadata | Inject name+description of all Skills at start | `scan_skill_catalog()` reads frontmatter into the system prompt |
|
||||
| Layer 2 · core flow | Skill tool loads full `SKILL.md` | `read_skill` loads `skills/pptx/SKILL.md` |
|
||||
| Layer 3 · details | Refs like `html2pptx.md` / `reference.md` | `read_skill_file` reads `reference.md` / script sources |
|
||||
| Bundled scripts | e.g. `scripts/thumbnail.py` | `scripts/generate_pptx.py` (python-pptx generator) |
|
||||
|
||||
The mechanism maps one-to-one; the built-in Skill loader is replaced by explicit read/execute tools so progressive disclosure still works without Anthropic access.
|
||||
|
||||
> **OpenRouter fallback:** Primary path is OpenAI (default model `gpt-5.6-luna`). If `OPENAI_API_KEY` is unset but `OPENROUTER_API_KEY` is set, requests go through OpenRouter (`gpt-*` → `openai/…`). With `OPENAI_API_KEY` set, behavior is unchanged.
|
||||
|
||||
### Three-layer progressive disclosure
|
||||
|
||||
```
|
||||
skills/
|
||||
└── pptx/
|
||||
├── SKILL.md # L1: YAML frontmatter (name+description) only in system prompt
|
||||
│ # L2: body core flow — loaded via read_skill
|
||||
├── reference.md # L3: layout/color/tech details — via read_skill_file
|
||||
└── scripts/
|
||||
└── generate_pptx.py # Bundled script — via run_skill_script
|
||||
```
|
||||
|
||||
- **Layer 1 (metadata):** At startup the system prompt only has each Skill’s `name + description` (~hundreds of tokens). The Agent does not yet know how to build a PPT.
|
||||
- **Layer 2 (core flow):** When the task needs `pptx`, it calls `read_skill("pptx")` and loads full `SKILL.md` as a tool result (page plan + script conventions).
|
||||
- **Layer 3 (details):** For implementation/style detail, call `read_skill_file("pptx", "reference.md")` or read script sources.
|
||||
- **Execute:** Build a slide-outline JSON, call `run_skill_script` → `generate_pptx.py` → `output/presentation.pptx`.
|
||||
|
||||
### Run
|
||||
|
||||
```bash
|
||||
# From the repository root: use the shared Chapter 2 environment
|
||||
uv sync --locked --python 3.12 --extra ch2
|
||||
|
||||
# Activate it before changing directories:
|
||||
# macOS/Linux:
|
||||
source .venv/bin/activate
|
||||
# Windows PowerShell: .\.venv\Scripts\Activate.ps1
|
||||
# Windows cmd: .venv\Scripts\activate.bat
|
||||
|
||||
# pip fallback when uv is not installed:
|
||||
# python -m pip install -e ".[ch2]"
|
||||
|
||||
cd chapter2/agent-skills-ppt
|
||||
|
||||
# Single-project compatibility path, still supported during migration:
|
||||
# python -m pip install -r requirements.txt
|
||||
|
||||
cp env.example .env # or export directly
|
||||
export OPENAI_API_KEY=your-openai-api-key # default model gpt-5.6-luna; override with OPENAI_MODEL
|
||||
python demo.py
|
||||
python demo.py --paper papers/your_paper.md # different paper/outline
|
||||
python demo.py -o output/deck.pptx --model gpt-5.6-luna # output path / model
|
||||
python demo.py --help # full flag list
|
||||
```
|
||||
|
||||
One command `python demo.py` runs the full path: real OpenAI calls, prints each progressive-disclosure step, writes `output/presentation.pptx`, and re-opens the file with python-pptx to verify page count and titles.
|
||||
|
||||
#### CLI flags
|
||||
|
||||
| Flag | Default | Description |
|
||||
|------|---------|-------------|
|
||||
| `--paper` | `papers/sample_paper.md` | Input paper/outline (markdown) path |
|
||||
| `--output` / `-o` | `output/presentation.pptx` | Output `.pptx` path |
|
||||
| `--model` | `OPENAI_MODEL` or `gpt-5.6-luna` | OpenAI model name |
|
||||
| `--max-turns` | `8` | Max agentic-loop turns |
|
||||
| `--offline` | off | Offline demo, no OpenAI (see below) |
|
||||
|
||||
#### Offline mode (no API key, reproducible)
|
||||
|
||||
Without an OpenAI key, `--offline` runs the same three-layer progressive disclosure: it reads the bundled outline `papers/sample_outline.json` and uses the **same tool path** (`read_skill` → `read_skill_file` → `run_skill_script`) to generate and verify the pptx deterministically. The only difference is that which Skill/outline to use is fixed by files, not live model decisions—good for teaching demos and smoke tests.
|
||||
|
||||
```bash
|
||||
python demo.py --offline # writes output/presentation.pptx, no network
|
||||
python demo.py --offline -o output/deck.pptx # custom output path
|
||||
```
|
||||
|
||||
#### Offline validation
|
||||
|
||||
```bash
|
||||
# From the repository root; include dev tools for pytest.
|
||||
uv sync --locked --python 3.12 --extra ch2 --extra dev
|
||||
source .venv/bin/activate
|
||||
# Windows PowerShell: .\.venv\Scripts\Activate.ps1
|
||||
|
||||
cd chapter2/agent-skills-ppt
|
||||
python -m pytest tests
|
||||
python demo.py --offline
|
||||
```
|
||||
|
||||
`tests/` contains offline regressions for malformed or unsafe tool-dispatch arguments and PPTX generator edge cases. They do not require an API key.
|
||||
|
||||
The bundled script can also run alone (no Agent):
|
||||
|
||||
```bash
|
||||
python skills/pptx/scripts/generate_pptx.py papers/sample_outline.json output/deck.pptx
|
||||
```
|
||||
|
||||
### Sample run output (excerpt)
|
||||
|
||||
```
|
||||
【第一层·元数据】Agent 启动时只看到这份薄 Skill 目录(system prompt):
|
||||
== 已安装的 Skills(薄目录,仅元数据)==
|
||||
- pptx: 从论文...生成 PowerPoint...Use when...Don't use when...
|
||||
|
||||
[Agent 第 1 轮] 调用工具 -> read_skill(name=pptx)
|
||||
>>> [渐进式披露·第二层] 加载完整 SKILL.md(1150 字符)
|
||||
[Agent 第 2 轮] 调用工具 -> read_skill_file(name=pptx, path=scripts/generate_pptx.py)
|
||||
>>> [渐进式披露·第三层] 加载子文档(4270 字符)
|
||||
[Agent 第 3 轮] 调用工具 -> run_skill_script(name=pptx, script=generate_pptx.py, ...)
|
||||
>>> 生成 presentation.pptx ...
|
||||
|
||||
【校验】用 python-pptx 重新打开生成的文件,读回页数与每页标题:
|
||||
总页数: 9
|
||||
第 1 页标题: 精简论文:渐进式披露式 Agent Skills 对上下文效率的影响
|
||||
...
|
||||
校验通过:这是一个可被 python-pptx / PowerPoint 打开的有效 .pptx(9 页)。
|
||||
```
|
||||
|
||||
(Page count/titles are planned live by the model and may vary slightly, usually within 8–12 pages.)
|
||||
|
||||
### Files
|
||||
|
||||
| File | Role |
|
||||
|------|------|
|
||||
| `demo.py` | Main: thin catalog scan → agentic loop → progressive disclosure → generate & verify pptx |
|
||||
| `skills/pptx/SKILL.md` | pptx Skill: frontmatter (metadata) + core flow |
|
||||
| `skills/pptx/reference.md` | Layer 3: layout/color/python-pptx notes |
|
||||
| `skills/pptx/scripts/generate_pptx.py` | Bundled generator: outline → `.pptx` |
|
||||
| `papers/sample_paper.md` | Bundled short paper/outline (online input) |
|
||||
| `papers/sample_outline.json` | Slide outline for offline mode (payload schema example) |
|
||||
| `tests/` | Offline regression tests for dispatch safety and generator edge cases |
|
||||
| `output/presentation.pptx` | Generated deck (created at runtime) |
|
||||
|
||||
### Use another paper
|
||||
|
||||
Replace `papers/sample_paper.md` or pass `python demo.py --paper your_paper.md`.
|
||||
|
||||
---
|
||||
|
||||
## 中文
|
||||
|
||||
### 目的
|
||||
|
||||
验证书中的核心命题:**Agent 通过「渐进式披露(Progressive Disclosure)」按需加载专业领域 Skill,即可完成复杂任务,而无需把所有知识一次性塞进系统提示词。**
|
||||
|
||||
本 demo 让一个 Agent 从一篇(自带的)精简论文生成一份 8-12 页的 PowerPoint。Agent 启动时**只看到一份薄 Skill 目录**,当它识别出任务需要 `pptx` Skill 后,才逐层加载该 Skill 的完整流程、子文档与捆绑脚本,最后用 **python-pptx** 生成真实的 `.pptx` 文件。
|
||||
|
||||
### 与 Anthropic PPTX Skill 的关系
|
||||
|
||||
书中原实验跑在 **Claude Code + Anthropic 官方 PPTX Skill** 上。由于当前环境的 Anthropic key 未必可用,本项目**自建了一套同构的 Skills 机制**来复现同样的思想,而非调用 Anthropic:
|
||||
|
||||
| 维度 | Anthropic PPTX Skill(书中) | 本项目(自建同构版) |
|
||||
|------|------------------------------|----------------------|
|
||||
| 运行时 | Claude Code | Python + OpenAI SDK(`gpt-5.6-luna`) |
|
||||
| 第一层·元数据 | 启动注入所有 Skill 的 name+description | `scan_skill_catalog()` 只读 frontmatter 拼进 system prompt |
|
||||
| 第二层·核心流程 | Skill 工具加载完整 `SKILL.md` | `read_skill` 工具加载 `skills/pptx/SKILL.md` |
|
||||
| 第三层·细则 | 引用 `html2pptx.md` / `reference.md` | `read_skill_file` 读 `reference.md` / 脚本源码 |
|
||||
| 捆绑脚本 | `scripts/thumbnail.py` 等 | `scripts/generate_pptx.py`(python-pptx 生成器) |
|
||||
|
||||
机制一一对应,只是把「Claude 内置的 Skill 加载器」换成了几个显式的读取/执行工具,从而在没有 Anthropic 访问权限时,依然能真实演示渐进式披露的三层加载过程。
|
||||
|
||||
> 说明:本项目主用 OpenAI(默认模型 gpt-5.6-luna)。**通用回退**:未设置 `OPENAI_API_KEY` 时,只要配置了 `OPENROUTER_API_KEY`,会自动改走 OpenRouter(`gpt-*` 映射为 `openai/…`)。设置了 `OPENAI_API_KEY` 时行为完全不变。
|
||||
|
||||
### 渐进式披露的三层结构
|
||||
|
||||
```
|
||||
skills/
|
||||
└── pptx/
|
||||
├── SKILL.md # 第一层:顶部 YAML frontmatter(name+description) —— 只有它进 system prompt
|
||||
│ # 第二层:正文核心流程 —— read_skill 时才加载
|
||||
├── reference.md # 第三层:版式/配色/技术细则 —— read_skill_file 时才加载
|
||||
└── scripts/
|
||||
└── generate_pptx.py # 捆绑可执行脚本 —— run_skill_script 时才执行
|
||||
```
|
||||
|
||||
- **第一层(元数据)**:Agent 启动时,`system prompt` 里只有各 Skill 的 `name + description`(约数百 token)。此刻它并不知道怎么做 PPT。
|
||||
- **第二层(核心流程)**:Agent 判断任务需要 `pptx`,调用 `read_skill("pptx")` 把完整 `SKILL.md` 作为 tool result 载入上下文,得到页序规划与脚本调用约定。
|
||||
- **第三层(细则)**:如需实现/样式细节,Agent 再用 `read_skill_file("pptx", "reference.md")` 或读取脚本源码。
|
||||
- **执行**:Agent 组织好幻灯片大纲 JSON,通过 `run_skill_script` 调用捆绑的 `generate_pptx.py`,用 python-pptx 落地为 `output/presentation.pptx`。
|
||||
|
||||
### 运行
|
||||
|
||||
```bash
|
||||
# 在仓库根目录使用统一的第 2 章环境
|
||||
uv sync --locked --python 3.12 --extra ch2
|
||||
|
||||
# 切换目录前先激活环境:
|
||||
# macOS/Linux:
|
||||
source .venv/bin/activate
|
||||
# Windows PowerShell:.\.venv\Scripts\Activate.ps1
|
||||
# Windows cmd:.venv\Scripts\activate.bat
|
||||
|
||||
# 未安装 uv 时可用 pip 兜底:
|
||||
# python -m pip install -e ".[ch2]"
|
||||
|
||||
cd chapter2/agent-skills-ppt
|
||||
|
||||
# 迁移期间仍支持单项目兼容路径:
|
||||
# python -m pip install -r requirements.txt
|
||||
|
||||
cp env.example .env # 或直接 export
|
||||
export OPENAI_API_KEY=your-openai-api-key # 默认模型 gpt-5.6-luna,可用 OPENAI_MODEL 覆盖
|
||||
python demo.py
|
||||
python demo.py --paper papers/your_paper.md # 换一篇论文/大纲
|
||||
python demo.py -o output/deck.pptx --model gpt-5.6-luna # 指定输出路径 / 模型
|
||||
python demo.py --help # 查看全部参数
|
||||
```
|
||||
|
||||
一条命令 `python demo.py` 即可跑通:真实调用 OpenAI,打印渐进式披露的每一步,生成 `output/presentation.pptx`,并用 python-pptx 重新打开该文件读回页数与每页标题作为校验。
|
||||
|
||||
#### 命令行参数
|
||||
|
||||
| 参数 | 默认值 | 说明 |
|
||||
|------|--------|------|
|
||||
| `--paper` | `papers/sample_paper.md` | 输入论文/大纲(markdown)路径 |
|
||||
| `--output` / `-o` | `output/presentation.pptx` | 输出 `.pptx` 路径 |
|
||||
| `--model` | `OPENAI_MODEL` 或 `gpt-5.6-luna` | OpenAI 模型名 |
|
||||
| `--max-turns` | `8` | agentic loop 的最大轮数 |
|
||||
| `--offline` | 关 | 离线演示,不调用 OpenAI(见下) |
|
||||
|
||||
#### 离线模式(无需 API key,可复现)
|
||||
|
||||
没有 OpenAI key 时,用 `--offline` 即可跑通同一套三层渐进式披露:它读取内置大纲 `papers/sample_outline.json`,走**与在线完全相同**的工具通道(`read_skill` → `read_skill_file` → `run_skill_script`)确定性地生成并校验 pptx。唯一区别是「用哪个 Skill、大纲写什么」由预置文件给定,而非模型即时决策——因此它适合作为可复现的教学演示与冒烟测试。
|
||||
|
||||
```bash
|
||||
python demo.py --offline # 生成 output/presentation.pptx,全程无网络
|
||||
python demo.py --offline -o output/deck.pptx # 指定输出路径
|
||||
```
|
||||
|
||||
#### 离线验证
|
||||
|
||||
```bash
|
||||
# 从仓库根目录开始;pytest 需要 dev 依赖。
|
||||
uv sync --locked --python 3.12 --extra ch2 --extra dev
|
||||
source .venv/bin/activate
|
||||
# Windows PowerShell: .\.venv\Scripts\Activate.ps1
|
||||
|
||||
cd chapter2/agent-skills-ppt
|
||||
python -m pytest tests
|
||||
python demo.py --offline
|
||||
```
|
||||
|
||||
`tests/` 包含工具分发参数缺失、非法路径和 PPTX 生成器边界情况的离线回归测试,无需 API Key。
|
||||
|
||||
捆绑脚本本身也可脱离 Agent 单独运行,直接把大纲 JSON 落地为 pptx:
|
||||
|
||||
```bash
|
||||
python skills/pptx/scripts/generate_pptx.py papers/sample_outline.json output/deck.pptx
|
||||
```
|
||||
|
||||
### 真实运行输出(节选)
|
||||
|
||||
```
|
||||
【第一层·元数据】Agent 启动时只看到这份薄 Skill 目录(system prompt):
|
||||
== 已安装的 Skills(薄目录,仅元数据)==
|
||||
- pptx: 从论文...生成 PowerPoint...Use when...Don't use when...
|
||||
|
||||
[Agent 第 1 轮] 调用工具 -> read_skill(name=pptx)
|
||||
>>> [渐进式披露·第二层] 加载完整 SKILL.md(1150 字符)
|
||||
[Agent 第 2 轮] 调用工具 -> read_skill_file(name=pptx, path=scripts/generate_pptx.py)
|
||||
>>> [渐进式披露·第三层] 加载子文档(4270 字符)
|
||||
[Agent 第 3 轮] 调用工具 -> run_skill_script(name=pptx, script=generate_pptx.py, ...)
|
||||
>>> 生成 presentation.pptx ...
|
||||
|
||||
【校验】用 python-pptx 重新打开生成的文件,读回页数与每页标题:
|
||||
总页数: 9
|
||||
第 1 页标题: 精简论文:渐进式披露式 Agent Skills 对上下文效率的影响
|
||||
第 2 页标题: 目录
|
||||
...
|
||||
第 9 页标题: 小结
|
||||
校验通过:这是一个可被 python-pptx / PowerPoint 打开的有效 .pptx(9 页)。
|
||||
```
|
||||
|
||||
(页数/标题由模型即时规划,每次运行可能略有差异,但均落在 8-12 页区间。)
|
||||
|
||||
### 文件说明
|
||||
|
||||
| 文件 | 作用 |
|
||||
|------|------|
|
||||
| `demo.py` | 主程序:扫描薄目录 → agentic loop → 渐进式披露 → 生成并校验 pptx |
|
||||
| `skills/pptx/SKILL.md` | pptx Skill:frontmatter(元数据)+ 核心流程 |
|
||||
| `skills/pptx/reference.md` | 第三层细则:版式/配色/python-pptx 技术点 |
|
||||
| `skills/pptx/scripts/generate_pptx.py` | 捆绑生成器,用 python-pptx 从大纲生成 .pptx |
|
||||
| `papers/sample_paper.md` | 自带的精简论文/大纲(在线模式输入) |
|
||||
| `papers/sample_outline.json` | 内置幻灯片大纲(离线模式输入,同时是 payload schema 的范例) |
|
||||
| `tests/` | 工具分发安全性与生成器边界情况的离线回归测试 |
|
||||
| `output/presentation.pptx` | 生成的演示文稿(输出,运行后产生) |
|
||||
|
||||
### 换一篇论文
|
||||
|
||||
把 `papers/sample_paper.md` 替换为你自己的论文/大纲(markdown),或直接 `python demo.py --paper 你的论文.md` 指定路径即可。
|
||||
|
||||
---
|
||||
|
||||
## Notes / 说明
|
||||
|
||||
- Commands, paths, env vars, and model names are identical in both language sections.
|
||||
- 命令、路径、环境变量与模型名在中英文两节中保持一致。
|
||||
@@ -0,0 +1,430 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
实验 2-6:使用 Agent Skills 从论文生成演示文稿(自建同构 Skills 机制)
|
||||
|
||||
本 demo 复现《深入理解 AI Agent》第二章「Agent Skills / 渐进式披露」一节的思想。
|
||||
由于 Anthropic key 无效,这里用 OpenAI(gpt-5.6-luna)+ 一套自建的、与 Anthropic
|
||||
Skills 同构的机制来演示,核心是「渐进式披露(Progressive Disclosure)」:
|
||||
|
||||
第一层(元数据):Agent 启动时的 system prompt 里只放各 Skill 的 name +
|
||||
description(薄目录,数百 token),并不含具体流程。
|
||||
第二层(核心流程):当任务需要时,Agent 主动用 read_skill 工具加载完整 SKILL.md。
|
||||
第三层(细则):Agent 可再用 read_skill_file 读取 reference.md / 脚本源码。
|
||||
|
||||
然后 Agent 用捆绑脚本 scripts/generate_pptx.py(经 run_skill_script 工具)用
|
||||
python-pptx 生成真实的 .pptx,并读回校验页数与每页标题。
|
||||
|
||||
运行:
|
||||
export OPENAI_API_KEY=your-openai-api-key
|
||||
python demo.py
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
from openai import OpenAI
|
||||
from pptx import Presentation
|
||||
|
||||
# 从同目录 .env 读取 OPENAI_API_KEY(若安装了 python-dotenv)
|
||||
try:
|
||||
from dotenv import load_dotenv
|
||||
|
||||
load_dotenv(Path(__file__).resolve().parent / ".env")
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# 路径与配置
|
||||
# ---------------------------------------------------------------------------
|
||||
ROOT = Path(__file__).resolve().parent
|
||||
SKILLS_DIR = ROOT / "skills"
|
||||
PAPER_PATH = ROOT / "papers" / "sample_paper.md"
|
||||
OUTPUT_DIR = ROOT / "output"
|
||||
MODEL = os.environ.get("OPENAI_MODEL", "gpt-5.6-luna")
|
||||
|
||||
|
||||
def log(msg: str) -> None:
|
||||
print(msg, flush=True)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# 第一层:启动时扫描 skills/ 目录,只读取每个 SKILL.md 的 frontmatter
|
||||
# (name + description),拼成薄目录注入 system prompt。这一步刻意「只看目录」。
|
||||
# ---------------------------------------------------------------------------
|
||||
def parse_frontmatter(skill_md: str) -> dict:
|
||||
"""从 SKILL.md 顶部的 --- YAML frontmatter --- 中解析 name / description。"""
|
||||
meta = {}
|
||||
if not skill_md.startswith("---"):
|
||||
return meta
|
||||
end = skill_md.find("---", 3)
|
||||
if end == -1:
|
||||
return meta
|
||||
for line in skill_md[3:end].splitlines():
|
||||
if ":" in line:
|
||||
k, v = line.split(":", 1)
|
||||
meta[k.strip()] = v.strip()
|
||||
return meta
|
||||
|
||||
|
||||
def scan_skill_catalog() -> dict:
|
||||
"""返回 {skill_name: {"description":..., "dir": Path}},只含元数据。"""
|
||||
catalog = {}
|
||||
for skill_md in sorted(SKILLS_DIR.glob("*/SKILL.md")):
|
||||
meta = parse_frontmatter(skill_md.read_text(encoding="utf-8"))
|
||||
name = meta.get("name") or skill_md.parent.name
|
||||
catalog[name] = {
|
||||
"description": meta.get("description", ""),
|
||||
"dir": skill_md.parent,
|
||||
}
|
||||
return catalog
|
||||
|
||||
|
||||
def build_system_prompt(catalog: dict) -> str:
|
||||
lines = [
|
||||
"你是一个能使用 Agent Skills 的助手。你并不预先知道每个 Skill 的详细流程,",
|
||||
"只在下方看到一份「薄目录」——每个 Skill 的 name 与 description(路由条件)。",
|
||||
"",
|
||||
"当任务需要某个 Skill 时,你必须:",
|
||||
" 1) 先用 read_skill(name) 加载它的完整 SKILL.md(第二层:核心流程);",
|
||||
" 2) 如需实现/样式细节,再用 read_skill_file(name, path) 读取子文档或脚本(第三层);",
|
||||
" 3) 按 SKILL.md 的约定,用 run_skill_script 调用捆绑脚本完成任务。",
|
||||
"不要在没有 read_skill 的情况下臆测某个 Skill 的调用方式。",
|
||||
"",
|
||||
"== 已安装的 Skills(薄目录,仅元数据)==",
|
||||
]
|
||||
for name, info in catalog.items():
|
||||
lines.append(f"- {name}: {info['description']}")
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# 工具实现:read_skill / read_skill_file / run_skill_script
|
||||
# 这些是「渐进式披露」的通道——第二、三层内容只有被调用时才进入上下文。
|
||||
# ---------------------------------------------------------------------------
|
||||
def tool_read_skill(catalog: dict, name: str) -> str:
|
||||
info = catalog.get(name)
|
||||
if not info:
|
||||
return f"[error] 未找到 Skill: {name}"
|
||||
content = (info["dir"] / "SKILL.md").read_text(encoding="utf-8")
|
||||
log(f"\n >>> [渐进式披露·第二层] Agent 调用 read_skill('{name}'),"
|
||||
f"加载完整 SKILL.md({len(content)} 字符)")
|
||||
return content
|
||||
|
||||
|
||||
def tool_read_skill_file(catalog: dict, name: str, rel_path: str) -> str:
|
||||
info = catalog.get(name)
|
||||
if not info:
|
||||
return f"[error] 未找到 Skill: {name}"
|
||||
target = (info["dir"] / rel_path).resolve()
|
||||
# 防目录穿越:必须落在该 skill 目录内
|
||||
if not str(target).startswith(str(info["dir"].resolve())):
|
||||
return f"[error] 非法路径: {rel_path}"
|
||||
if not target.exists():
|
||||
return f"[error] 文件不存在: {rel_path}"
|
||||
content = target.read_text(encoding="utf-8")
|
||||
log(f" >>> [渐进式披露·第三层] Agent 调用 read_skill_file('{name}', '{rel_path}'),"
|
||||
f"加载子文档({len(content)} 字符)")
|
||||
return content
|
||||
|
||||
|
||||
def tool_run_skill_script(catalog: dict, name: str, script: str, payload: str,
|
||||
out_path: Path) -> str:
|
||||
info = catalog.get(name)
|
||||
if not info:
|
||||
return f"[error] 未找到 Skill: {name}"
|
||||
scripts_dir = (info["dir"] / "scripts").resolve()
|
||||
script_path = (scripts_dir / script).resolve()
|
||||
# 防目录穿越:脚本会被直接执行,必须落在该 skill 的 scripts 目录内
|
||||
if not script_path.is_relative_to(scripts_dir):
|
||||
return f"[error] 非法脚本路径: {script}"
|
||||
if not script_path.exists():
|
||||
return f"[error] 脚本不存在: {script}"
|
||||
|
||||
# 动态载入捆绑脚本(它就是 Skill 的一部分)
|
||||
import importlib.util
|
||||
spec = importlib.util.spec_from_file_location("bundled_generator", script_path)
|
||||
module = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(module)
|
||||
|
||||
try:
|
||||
data = json.loads(payload) if isinstance(payload, str) else payload
|
||||
except json.JSONDecodeError as e:
|
||||
return f"[error] payload 不是合法 JSON: {e}"
|
||||
|
||||
log(f" >>> [执行捆绑脚本] run_skill_script('{name}', '{script}') "
|
||||
f"生成 {out_path.name} ...")
|
||||
result = module.build_presentation(data, str(out_path))
|
||||
return json.dumps(result, ensure_ascii=False)
|
||||
|
||||
|
||||
TOOLS = [
|
||||
{
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "read_skill",
|
||||
"description": "加载指定 Skill 的完整 SKILL.md(核心流程,渐进式披露第二层)。",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {"name": {"type": "string", "description": "Skill 名称"}},
|
||||
"required": ["name"],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "read_skill_file",
|
||||
"description": "读取某 Skill 目录内的子文档或脚本源码(细则,渐进式披露第三层)。",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {"type": "string"},
|
||||
"path": {"type": "string", "description": "相对 skill 目录的路径,如 reference.md 或 scripts/generate_pptx.py"},
|
||||
},
|
||||
"required": ["name", "path"],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "run_skill_script",
|
||||
"description": "执行某 Skill 捆绑的脚本以完成实际产出(如生成 pptx)。",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {"type": "string"},
|
||||
"script": {"type": "string", "description": "脚本文件名,如 generate_pptx.py"},
|
||||
"payload": {"type": "string", "description": "传给脚本的 JSON 字符串(大纲)"},
|
||||
},
|
||||
"required": ["name", "script", "payload"],
|
||||
},
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
def dispatch(catalog: dict, name: str, args: dict, out_path: Path) -> str:
|
||||
# 模型给的 arguments 可能缺字段(或根本不是合法 JSON,被上层回退成 {})。
|
||||
# 缺参时返回 [error] 让 Agent 在下一轮自我纠正,而不是抛 KeyError 中断 loop。
|
||||
required = {
|
||||
"read_skill": ["name"],
|
||||
"read_skill_file": ["name", "path"],
|
||||
"run_skill_script": ["name", "script", "payload"],
|
||||
}
|
||||
if name not in required:
|
||||
return f"[error] 未知工具: {name}"
|
||||
missing = [k for k in required[name] if k not in args]
|
||||
if missing:
|
||||
return f"[error] 工具 {name} 缺少参数: {', '.join(missing)}"
|
||||
if name == "read_skill":
|
||||
return tool_read_skill(catalog, args["name"])
|
||||
if name == "read_skill_file":
|
||||
return tool_read_skill_file(catalog, args["name"], args["path"])
|
||||
return tool_run_skill_script(catalog, args["name"], args["script"],
|
||||
args["payload"], out_path)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# 主流程:agentic loop
|
||||
# ---------------------------------------------------------------------------
|
||||
def run_agent(paper_path: Path, model: str, out_path: Path,
|
||||
max_turns: int = 8) -> Path | None:
|
||||
# OPENAI_API_KEY 存在则官方直连;否则回退 OPENROUTER_API_KEY
|
||||
# (gpt-* 模型名会被映射为 openai/…)。两者皆无则给出清晰错误。
|
||||
from agentbook.providers import resolve_backend
|
||||
|
||||
if not os.environ.get("OPENAI_API_KEY") and not os.environ.get("OPENROUTER_API_KEY"):
|
||||
log("错误:未设置 OPENAI_API_KEY,也未设置 OPENROUTER_API_KEY(通用回退)。")
|
||||
log("请 export OPENAI_API_KEY=your-openai-api-key 或 export OPENROUTER_API_KEY=your-openrouter-api-key")
|
||||
log("(无 key 时可用 --offline 走内置大纲、确定性地复现三层渐进式披露并生成 pptx。)")
|
||||
sys.exit(1)
|
||||
|
||||
# 端点与 key 的对应关系由 agentbook 的 provider 注册表统一维护,
|
||||
# OPENAI_BASE_URL 覆盖也在其中处理。
|
||||
backend = resolve_backend("openai", model=model)
|
||||
model = backend.model
|
||||
# timeout + 自动重试:单次网络/SSL 抖动不至于让整个 agentic loop 崩溃
|
||||
client = OpenAI(
|
||||
api_key=backend.api_key, base_url=backend.base_url, timeout=60.0, max_retries=3
|
||||
)
|
||||
catalog = scan_skill_catalog()
|
||||
|
||||
system_prompt = build_system_prompt(catalog)
|
||||
log("=" * 72)
|
||||
log("【第一层·元数据】Agent 启动时只看到这份薄 Skill 目录(system prompt):")
|
||||
log("-" * 72)
|
||||
log(system_prompt)
|
||||
log("-" * 72)
|
||||
log(f"(薄目录约 {len(system_prompt)} 字符 / 数百 token;各 Skill 的详细流程此刻并不在上下文中)")
|
||||
log("=" * 72)
|
||||
|
||||
paper = paper_path.read_text(encoding="utf-8")
|
||||
user_task = (
|
||||
"请把下面这篇论文做成一份 8-12 页的演示文稿(含标题页、目录页、问题背景、"
|
||||
"方法概述、关键结果、局限性、小结页),总页数务必落在 8-12 页。"
|
||||
"先判断该用哪个 Skill,再严格按其 SKILL.md 的页序与约束操作。\n\n"
|
||||
"=== 论文全文 ===\n" + paper
|
||||
)
|
||||
|
||||
messages = [
|
||||
{"role": "system", "content": system_prompt},
|
||||
{"role": "user", "content": user_task},
|
||||
]
|
||||
|
||||
log("\n【任务下发】要求 Agent 从论文生成演示文稿。观察它如何按需渐进式披露:\n")
|
||||
|
||||
final_result = None
|
||||
for turn in range(1, max_turns + 1):
|
||||
resp = client.chat.completions.create(
|
||||
model=model,
|
||||
messages=messages,
|
||||
tools=TOOLS,
|
||||
temperature=0.2,
|
||||
)
|
||||
msg = resp.choices[0].message
|
||||
messages.append(msg.model_dump(exclude_none=True))
|
||||
|
||||
if not msg.tool_calls:
|
||||
log(f"\n【Agent 第 {turn} 轮·结束语】\n{msg.content}")
|
||||
break
|
||||
|
||||
for tc in msg.tool_calls:
|
||||
fn = tc.function.name
|
||||
try:
|
||||
args = json.loads(tc.function.arguments or "{}")
|
||||
except json.JSONDecodeError:
|
||||
args = {}
|
||||
log(f"\n[Agent 第 {turn} 轮] 调用工具 -> {fn}({', '.join(f'{k}={_short(v)}' for k, v in args.items())})")
|
||||
result = dispatch(catalog, fn, args, out_path)
|
||||
if fn == "run_skill_script" and not result.startswith("[error]"):
|
||||
final_result = json.loads(result)
|
||||
log(f" >>> 生成结果:{result}")
|
||||
messages.append({
|
||||
"role": "tool",
|
||||
"tool_call_id": tc.id,
|
||||
"content": result,
|
||||
})
|
||||
|
||||
if final_result:
|
||||
return Path(final_result["path"])
|
||||
return None
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# 离线复现:无 OpenAI key 时,用内置大纲(papers/sample_outline.json)确定性地
|
||||
# 走完与在线完全相同的三层渐进式披露与工具通道(read_skill / read_skill_file /
|
||||
# run_skill_script),从而在没有任何 API 访问权限时也能真实生成并校验 pptx。
|
||||
# 唯一区别是「用哪个 Skill、大纲写什么」由预置脚本给定,而非模型即时决策。
|
||||
# ---------------------------------------------------------------------------
|
||||
OUTLINE_PATH = ROOT / "papers" / "sample_outline.json"
|
||||
|
||||
|
||||
def run_offline(out_path: Path) -> Path | None:
|
||||
catalog = scan_skill_catalog()
|
||||
system_prompt = build_system_prompt(catalog)
|
||||
log("=" * 72)
|
||||
log("【离线模式】不调用 OpenAI,用内置大纲确定性地复现三层渐进式披露。")
|
||||
log("【第一层·元数据】启动时只看到这份薄 Skill 目录(system prompt):")
|
||||
log("-" * 72)
|
||||
log(system_prompt)
|
||||
log("-" * 72)
|
||||
log(f"(薄目录约 {len(system_prompt)} 字符;各 Skill 的详细流程此刻并不在上下文中)")
|
||||
log("=" * 72)
|
||||
|
||||
if not OUTLINE_PATH.exists():
|
||||
log(f"错误:内置大纲不存在:{OUTLINE_PATH}")
|
||||
return None
|
||||
|
||||
# 与在线 agentic loop 相同的工具通道,只是调用序列由脚本给定
|
||||
log("\n【离线回放】按 SKILL.md 约定,逐层加载并调用捆绑脚本:")
|
||||
dispatch(catalog, "read_skill", {"name": "pptx"}, out_path)
|
||||
dispatch(catalog, "read_skill_file",
|
||||
{"name": "pptx", "path": "reference.md"}, out_path)
|
||||
|
||||
payload = OUTLINE_PATH.read_text(encoding="utf-8")
|
||||
result = dispatch(catalog, "run_skill_script",
|
||||
{"name": "pptx", "script": "generate_pptx.py", "payload": payload},
|
||||
out_path)
|
||||
if result.startswith("[error]"):
|
||||
log(f" >>> 生成失败:{result}")
|
||||
return None
|
||||
log(f" >>> 生成结果:{result}")
|
||||
return Path(json.loads(result)["path"])
|
||||
|
||||
|
||||
def _short(v, n=48):
|
||||
s = str(v).replace("\n", " ")
|
||||
return s if len(s) <= n else s[:n] + "…"
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# 校验:用 python-pptx 重新打开生成的文件,读回页数与每页标题,证明是有效 pptx。
|
||||
# ---------------------------------------------------------------------------
|
||||
def verify_pptx(path: Path) -> None:
|
||||
log("\n" + "=" * 72)
|
||||
log("【校验】用 python-pptx 重新打开生成的文件,读回页数与每页标题:")
|
||||
log("-" * 72)
|
||||
prs = Presentation(str(path))
|
||||
slides = list(prs.slides)
|
||||
log(f"文件: {path}")
|
||||
log(f"总页数: {len(slides)}")
|
||||
for i, slide in enumerate(slides, 1):
|
||||
first_text = "(空)"
|
||||
for shp in slide.shapes:
|
||||
if shp.has_text_frame and shp.text_frame.text.strip():
|
||||
first_text = shp.text_frame.text.strip().splitlines()[0]
|
||||
break
|
||||
log(f" 第 {i:>2} 页标题: {first_text}")
|
||||
log("-" * 72)
|
||||
log(f"校验通过:这是一个可被 python-pptx / PowerPoint 打开的有效 .pptx({len(slides)} 页)。")
|
||||
log("=" * 72)
|
||||
|
||||
|
||||
def parse_args():
|
||||
p = argparse.ArgumentParser(
|
||||
description="实验 2-6:用 Agent Skills 的「渐进式披露」从论文生成演示文稿。"
|
||||
"Agent 启动只看到薄 Skill 目录,按需逐层加载 pptx Skill 的流程与脚本,"
|
||||
"最后用 python-pptx 生成并校验 output/presentation.pptx。",
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
)
|
||||
p.add_argument("--paper", default=str(PAPER_PATH),
|
||||
help="输入论文/大纲(markdown)路径,默认 papers/sample_paper.md。")
|
||||
p.add_argument("--output", "-o", default=str(OUTPUT_DIR / "presentation.pptx"),
|
||||
help="输出 .pptx 路径,默认 output/presentation.pptx。")
|
||||
p.add_argument("--model", default=MODEL,
|
||||
help="OpenAI 模型名,默认取环境变量 OPENAI_MODEL,否则 gpt-5.6-luna。")
|
||||
p.add_argument("--max-turns", type=int, default=8,
|
||||
help="agentic loop 的最大轮数,默认 8。")
|
||||
p.add_argument("--offline", action="store_true",
|
||||
help="离线演示:不调用 OpenAI,用内置大纲(papers/sample_outline.json)"
|
||||
"确定性地走完三层渐进式披露并生成 pptx(无需 API key,可复现)。")
|
||||
return p.parse_args()
|
||||
|
||||
|
||||
def main():
|
||||
args = parse_args()
|
||||
paper_path = Path(args.paper)
|
||||
out_path = Path(args.output)
|
||||
out_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
if args.offline:
|
||||
pptx_path = run_offline(out_path)
|
||||
else:
|
||||
if not paper_path.exists():
|
||||
log(f"错误:论文文件不存在:{paper_path}")
|
||||
sys.exit(1)
|
||||
pptx_path = run_agent(paper_path, args.model, out_path, args.max_turns)
|
||||
|
||||
if pptx_path and pptx_path.exists():
|
||||
verify_pptx(pptx_path)
|
||||
else:
|
||||
log("\n未生成 pptx。请检查上面的日志。")
|
||||
sys.exit(2)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,5 @@
|
||||
# 复制为 .env 或直接 export 到环境变量
|
||||
# 主用 OpenAI;未设置 OPENAI_API_KEY 时可回退到 OPENROUTER_API_KEY(通用回退)
|
||||
OPENAI_API_KEY=your-openai-api-key
|
||||
# 可选:覆盖默认模型(默认 gpt-5.6-luna)
|
||||
OPENAI_MODEL=gpt-5.6-luna
|
||||
@@ -0,0 +1,65 @@
|
||||
{
|
||||
"experiment_id": "2-6",
|
||||
"protocol_version": "1.1.0",
|
||||
"frozen_on": "2026-07-30",
|
||||
"revised_on": "2026-07-31",
|
||||
"authority": "book/chapter2.md:767",
|
||||
"runtime": {
|
||||
"agent": "Claude Code",
|
||||
"model_alias": "sonnet",
|
||||
"acceptance_policy": "Runtime-agnostic (author policy, 2026-07-31): acceptance is NOT gated on Anthropic/Claude Code. Any agent runtime + model that supports SKILL.md-style progressive disclosure may complete this experiment, because not every reader has an Anthropic key. The pinned official Anthropic PPTX Skill content, the real paper, and all artifact gates are unchanged; Claude Code remains the reference path for readers who have Anthropic credentials.",
|
||||
"alternate_runtimes": {
|
||||
"kimi": {
|
||||
"agent": "Kimi Code CLI",
|
||||
"binary": "kimi",
|
||||
"binary_fallback": "~/.kimi-code/bin/kimi",
|
||||
"model_alias": "kimi-code/k3",
|
||||
"auth_environment_variables": ["KIMI_API_KEY", "MOONSHOT_API_KEY"],
|
||||
"skills_flag": "--skills-dir",
|
||||
"stream_format": "stream-json"
|
||||
}
|
||||
},
|
||||
"official_skill_repository": "https://github.com/anthropics/skills.git",
|
||||
"official_skill_revision": "69c0b1a0674149f27b61b2635f935524b6add202",
|
||||
"skill_path": "skills/pptx",
|
||||
"revision_reason": "This is the official revision whose PPTX Skill contains the html2pptx.md workflow named by the manuscript; later revision 4e6907a packages that guide as html2pptx.tgz."
|
||||
},
|
||||
"paper": {
|
||||
"title": "Attention Is All You Need",
|
||||
"authors": "Ashish Vaswani et al.",
|
||||
"arxiv_id": "1706.03762",
|
||||
"pdf_url": "https://arxiv.org/pdf/1706.03762",
|
||||
"pdf_sha256": "bdfaa68d8984f0dc02beaca527b76f207d99b666d31d1da728ee0728182df697"
|
||||
},
|
||||
"output": {
|
||||
"minimum_slides": 10,
|
||||
"maximum_slides": 15,
|
||||
"required_sections": [
|
||||
"title",
|
||||
"problem/background",
|
||||
"method/Transformer architecture",
|
||||
"key results",
|
||||
"conclusion"
|
||||
],
|
||||
"minimum_paper_visuals": 3,
|
||||
"visual_policy": "At least three images must be extracted or cropped from the source PDF, embedded in the deck, and listed with PDF page and source label in source_visuals/manifest.json."
|
||||
},
|
||||
"progressive_disclosure_gates": [
|
||||
"the agent runtime discovers only PPTX Skill metadata before selection",
|
||||
"the agent invokes the official pptx Skill and loads its complete SKILL.md",
|
||||
"the agent reads the complete official html2pptx.md only after selecting the Skill",
|
||||
"the agent uses the official scripts/html2pptx.js workflow",
|
||||
"the agent invokes the official scripts/thumbnail.py preview workflow and visually inspects the result"
|
||||
],
|
||||
"artifact_gates": [
|
||||
"the source PDF hash matches the preregistered academic paper",
|
||||
"the presentation is a valid ZIP/OOXML package and python-pptx reopens it",
|
||||
"slide count is between 10 and 15 inclusive",
|
||||
"the five required content sections are present",
|
||||
"three or more source visual files are byte-identical to media embedded in the PPTX",
|
||||
"each source visual has a PDF page, paper label, and caption in the visual manifest",
|
||||
"a full-deck thumbnail grid exists",
|
||||
"raw agent-runtime stream events, actual model, usage/cost where the runtime reports it, commands, hashes, and credential scan are retained"
|
||||
],
|
||||
"claim_policy": "The bundled Python demo is a noncanonical mechanism illustration and cannot satisfy Experiment 2-6. Only a real agent-runtime run with the pinned official Skill and real paper can complete this protocol. The runtime may be Claude Code or an equivalent skills-capable runtime (for example Kimi Code CLI); the pinned official Anthropic PPTX Skill content and every artifact gate below apply identically to either runtime."
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
{
|
||||
"title": "渐进式披露式 Agent Skills 对上下文效率的影响",
|
||||
"subtitle": "示例作者团队 · 示例数据(对应 papers/sample_paper.md)",
|
||||
"slides": [
|
||||
{
|
||||
"title": "目录",
|
||||
"bullets": [
|
||||
"研究背景与问题",
|
||||
"方法概述:三层渐进式披露",
|
||||
"关键结果:上下文与缓存",
|
||||
"局限性与讨论",
|
||||
"小结"
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "研究背景与问题",
|
||||
"bullets": [
|
||||
"Agent 支持的任务越多,单一系统提示词越线性膨胀",
|
||||
"长提示词带来 token 成本、注意力稀释、缓存前缀失效三重代价",
|
||||
"核心矛盾:让 Agent「知道自己有哪些能力」又不长期占用上下文"
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "方法概述(总体思路)",
|
||||
"bullets": [
|
||||
"先给 Agent 一份薄目录,需要时再加载完整 Skill",
|
||||
"第一层:启动只注入各 Skill 的 name + description(数百 token)",
|
||||
"第二层:任务触发时加载完整 SKILL.md 作为 tool result"
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "方法概述(关键机制)",
|
||||
"bullets": [
|
||||
"第三层:按需读取 reference.md、脚本源码等子文档",
|
||||
"description 应写成「路由条件」而非「功能介绍」",
|
||||
"捆绑可执行脚本,把知识升级为可落地的能力"
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "关键结果(效率指标)",
|
||||
"bullets": [
|
||||
"常驻上下文从数千 token 降到目录级的数百 token",
|
||||
"工具数量恒定、前缀稳定,KV Cache 命中率显著提升"
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "关键结果(效果对比)",
|
||||
"bullets": [
|
||||
"需要专业 Skill 的任务上,成功率与「全量注入」基线持平",
|
||||
"加入反例(Don't use when)明显提升路由准确率",
|
||||
"减少不相关任务上的误触发"
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "局限性与讨论",
|
||||
"bullets": [
|
||||
"触发依赖模型的「元认知」,判断失误会漏加载 Skill",
|
||||
"第三方 Skill 是新的提示注入面,加载前需审查其内容"
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "小结",
|
||||
"bullets": [
|
||||
"渐进式披露把「一次性塞满」变为「按需加载」",
|
||||
"几乎不损失任务成功率,同时大幅降低常驻上下文",
|
||||
"是构建可扩展 Agent 能力体系的实用范式"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
# 精简论文:渐进式披露式 Agent Skills 对上下文效率的影响
|
||||
|
||||
作者:示例作者团队(Anthropic 风格 Agent 研究,示例数据)
|
||||
|
||||
## 摘要
|
||||
|
||||
现代 LLM Agent 需要覆盖越来越多的专业任务,传统做法是把所有指令塞进单一
|
||||
系统提示词,导致 token 消耗膨胀、注意力被稀释、KV Cache 前缀频繁失效。
|
||||
本文提出并评估一种「渐进式披露(Progressive Disclosure)」的 Agent Skills
|
||||
机制:先向 Agent 注入各 Skill 的薄目录(仅 name + description),当任务确实
|
||||
需要时再按需加载完整的 SKILL.md 与子文档。实验表明,该机制在保持任务成功率的
|
||||
同时显著降低常驻上下文长度。
|
||||
|
||||
## 1. 研究背景与问题
|
||||
|
||||
- 随着 Agent 支持的任务种类增长,单一系统提示词呈线性膨胀。
|
||||
- 长提示词带来三重代价:token 成本、注意力稀释、缓存前缀失效。
|
||||
- 核心问题:能否在「Agent 知道自己有哪些能力」与「不为此长期占用上下文」之间取得平衡?
|
||||
|
||||
## 2. 方法概述
|
||||
|
||||
- **三层渐进式披露**:
|
||||
- 第一层(元数据):启动时只注入每个 Skill 的 name + description(数百 token)。
|
||||
- 第二层(核心流程):任务触发时加载完整 SKILL.md 作为 tool result。
|
||||
- 第三层(细则):按需读取 reference.md、脚本源码等子文档。
|
||||
- **路由决策依赖 description**:描述应写成「路由条件」而非「功能介绍」,
|
||||
并给出反例(Don't use when),以降低误触发。
|
||||
- **捆绑可执行脚本**:Skill 不止是文档,还可附带脚本与模板,把知识升级为能力。
|
||||
|
||||
## 3. 关键结果
|
||||
|
||||
- 常驻上下文从「全量塞入」的数千 token 降到目录级的数百 token。
|
||||
- 因为工具数量恒定、前缀稳定,KV Cache 命中率显著提升。
|
||||
- 在需要专业 Skill 的任务上,成功率与「全量注入」基线持平(无明显下降)。
|
||||
- 反例(Don't use when)能明显提升路由准确率,减少不相关任务上的误触发。
|
||||
|
||||
## 4. 局限性与讨论
|
||||
|
||||
- 触发依赖模型的「元认知」:模型需判断自己何时需要某个 Skill,判断失误会漏加载。
|
||||
- 第三方 Skill 是新的提示注入面,加载前需审查其内容。
|
||||
|
||||
## 5. 结论
|
||||
|
||||
渐进式披露把「一次性塞满」变为「按需加载」,在几乎不损失任务成功率的前提下,
|
||||
大幅降低常驻上下文并改善缓存友好度,是构建可扩展 Agent 能力体系的实用范式。
|
||||
@@ -0,0 +1,75 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Fetch and verify the pinned official Anthropic PPTX Skill (no reimplementation)."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import hashlib
|
||||
import json
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parent
|
||||
PROTOCOL = json.loads((ROOT / "experiment_protocol.json").read_text(encoding="utf-8"))
|
||||
|
||||
|
||||
def run(command: list[str], cwd: Path | None = None) -> str:
|
||||
result = subprocess.run(command, cwd=cwd, check=True, text=True, capture_output=True)
|
||||
return result.stdout.strip()
|
||||
|
||||
|
||||
def sha256(path: Path) -> str:
|
||||
return hashlib.sha256(path.read_bytes()).hexdigest()
|
||||
|
||||
|
||||
def prepare(destination: Path) -> dict:
|
||||
destination = destination.resolve()
|
||||
repository = PROTOCOL["runtime"]["official_skill_repository"]
|
||||
revision = PROTOCOL["runtime"]["official_skill_revision"]
|
||||
if not (destination / ".git").exists():
|
||||
destination.parent.mkdir(parents=True, exist_ok=True)
|
||||
run(["git", "clone", "--filter=blob:none", "--no-checkout", repository, str(destination)])
|
||||
run(["git", "fetch", "origin", revision], cwd=destination)
|
||||
run(["git", "checkout", "--detach", revision], cwd=destination)
|
||||
head = run(["git", "rev-parse", "HEAD"], cwd=destination)
|
||||
if head != revision:
|
||||
raise RuntimeError(f"official Skill revision mismatch: {head} != {revision}")
|
||||
required = [
|
||||
destination / "skills/pptx/SKILL.md",
|
||||
destination / "skills/pptx/html2pptx.md",
|
||||
destination / "skills/pptx/scripts/html2pptx.js",
|
||||
destination / "skills/pptx/scripts/thumbnail.py",
|
||||
]
|
||||
missing = [str(path) for path in required if not path.is_file()]
|
||||
if missing:
|
||||
raise RuntimeError("pinned official Skill is missing required files: " + ", ".join(missing))
|
||||
return {
|
||||
"repository": repository,
|
||||
"revision": head,
|
||||
"skill_path": str((destination / "skills/pptx").resolve()),
|
||||
"required_file_hashes": {
|
||||
str(path.relative_to(destination)): sha256(path) for path in required
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument(
|
||||
"--destination",
|
||||
type=Path,
|
||||
default=ROOT / "external" / "anthropics-skills",
|
||||
)
|
||||
parser.add_argument("--receipt", type=Path)
|
||||
args = parser.parse_args()
|
||||
receipt = prepare(args.destination)
|
||||
if args.receipt:
|
||||
args.receipt.parent.mkdir(parents=True, exist_ok=True)
|
||||
args.receipt.write_text(json.dumps(receipt, indent=2), encoding="utf-8")
|
||||
print(json.dumps(receipt, indent=2))
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
@@ -0,0 +1,7 @@
|
||||
# Shared provider resolver from the repository root. Run this requirements file
|
||||
# from the experiment directory, as shown in the README.
|
||||
-e ../..
|
||||
|
||||
openai>=1.30.0
|
||||
python-pptx>=0.6.23
|
||||
python-dotenv>=1.0.0
|
||||
@@ -0,0 +1,271 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Run Experiment 2-6 with a real skills-capable agent runtime and Anthropic's pinned PPTX Skill.
|
||||
|
||||
Two runtimes are supported under the author-mandated runtime-agnostic
|
||||
acceptance policy (see experiment_protocol.json):
|
||||
|
||||
- ``--runtime claude`` (default): Claude Code, for readers with Anthropic
|
||||
credentials.
|
||||
- ``--runtime kimi``: Kimi Code CLI (or an equivalent runtime), authenticated
|
||||
with KIMI_API_KEY / MOONSHOT_API_KEY.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
import requests
|
||||
|
||||
from prepare_official_skill import prepare
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parent
|
||||
PROTOCOL_PATH = ROOT / "experiment_protocol.json"
|
||||
|
||||
CLAUDE_PROMPT = """/pptx
|
||||
|
||||
Create a polished 10–15 slide presentation from the real academic paper at
|
||||
`attention-is-all-you-need.pdf`. Write the final deck to
|
||||
`output/attention-is-all-you-need.pptx`.
|
||||
|
||||
This is an audited Agent Skills experiment. Follow the official PPTX Skill by
|
||||
progressive disclosure: invoke the pptx Skill, read its complete SKILL.md, then
|
||||
read its complete html2pptx.md only after selection. Use the pinned official
|
||||
`scripts/html2pptx.js` workflow. Use the official `scripts/thumbnail.py` to
|
||||
make `output/full-deck-thumbnail.jpg`, inspect the full grid, and fix visible
|
||||
overlap, cutoff, contrast, or alignment defects before finishing.
|
||||
|
||||
Content gates:
|
||||
- cover title, problem/background, Transformer method/architecture, key
|
||||
experimental results, and conclusion;
|
||||
- extract or crop at least three visuals directly from the source PDF (not
|
||||
invented replacements), place the files under `source_visuals/`, and embed
|
||||
all of them in the deck;
|
||||
- create `source_visuals/manifest.json` as a JSON list. Each item must contain
|
||||
`file`, one-based PDF `page`, the paper's `label` (for example Figure 1 or
|
||||
Table 2), and a faithful `caption`;
|
||||
- make every visual consistent with the surrounding slide explanation and
|
||||
cite its source page/label on-slide.
|
||||
|
||||
You may install the Node packages required by the official Skill inside this
|
||||
workspace. Do not use the repository's bundled `demo.py`, local proxy Skill,
|
||||
or prewritten sample outline. The final response must name the deck,
|
||||
thumbnail, visual manifest, slide count, validation performed, and any
|
||||
remaining limitation.
|
||||
"""
|
||||
|
||||
KIMI_PROMPT = """Create a polished 10–15 slide presentation from the real academic paper at
|
||||
`attention-is-all-you-need.pdf` using your installed `pptx` Skill. Write the
|
||||
final deck to `output/attention-is-all-you-need.pptx`.
|
||||
|
||||
This is an audited Agent Skills experiment. Follow the official PPTX Skill by
|
||||
progressive disclosure: invoke the pptx Skill through the Skill tool (this
|
||||
loads its complete SKILL.md), then read its complete html2pptx.md only after
|
||||
selection. Use the pinned official `scripts/html2pptx.js` workflow. Use the
|
||||
official `scripts/thumbnail.py` to make `output/full-deck-thumbnail.jpg`,
|
||||
inspect the full grid, and fix visible overlap, cutoff, contrast, or alignment
|
||||
defects before finishing.
|
||||
|
||||
Content gates:
|
||||
- cover title, problem/background, Transformer method/architecture, key
|
||||
experimental results, and conclusion;
|
||||
- extract or crop at least three visuals directly from the source PDF (not
|
||||
invented replacements), place the files under `source_visuals/`, and embed
|
||||
all of them in the deck;
|
||||
- create `source_visuals/manifest.json` as a JSON list. Each item must contain
|
||||
`file`, one-based PDF `page`, the paper's `label` (for example Figure 1 or
|
||||
Table 2), and a faithful `caption`;
|
||||
- make every visual consistent with the surrounding slide explanation and
|
||||
cite its source page/label on-slide.
|
||||
|
||||
You may install the Node packages required by the official Skill inside this
|
||||
workspace. Do not use the repository's bundled `demo.py`, local proxy Skill,
|
||||
or prewritten sample outline. The final response must name the deck,
|
||||
thumbnail, visual manifest, slide count, validation performed, and any
|
||||
remaining limitation.
|
||||
"""
|
||||
|
||||
|
||||
def resolve_kimi_binary() -> str:
|
||||
binary = shutil.which("kimi")
|
||||
if binary:
|
||||
return binary
|
||||
fallback = Path.home() / ".kimi-code" / "bin" / "kimi"
|
||||
if fallback.is_file():
|
||||
return str(fallback)
|
||||
raise RuntimeError("Kimi Code CLI not found on PATH or at ~/.kimi-code/bin/kimi")
|
||||
|
||||
|
||||
def stream_process(command: list[str], workspace: Path, env: dict, stream_path: Path,
|
||||
stderr_path: Path, tag: str) -> int:
|
||||
with stream_path.open("w", encoding="utf-8") as stdout_file, stderr_path.open(
|
||||
"w", encoding="utf-8"
|
||||
) as stderr_file:
|
||||
process = subprocess.Popen(
|
||||
command,
|
||||
cwd=workspace,
|
||||
env=env,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=stderr_file,
|
||||
text=True,
|
||||
bufsize=1,
|
||||
)
|
||||
assert process.stdout is not None
|
||||
for line in process.stdout:
|
||||
stdout_file.write(line)
|
||||
stdout_file.flush()
|
||||
try:
|
||||
event = json.loads(line)
|
||||
event_type = event.get("type") or event.get("role")
|
||||
if event_type in {"assistant", "result", "system", "tool", "meta"}:
|
||||
print(f"[{tag}] {event_type}", flush=True)
|
||||
except json.JSONDecodeError:
|
||||
pass
|
||||
return process.wait()
|
||||
|
||||
|
||||
def run_claude(args, run_dir: Path, workspace: Path, official_skill: Path, protocol: dict) -> None:
|
||||
(workspace / ".claude" / "skills").mkdir(parents=True)
|
||||
(workspace / ".claude" / "skills" / "pptx").symlink_to(
|
||||
official_skill, target_is_directory=True
|
||||
)
|
||||
prompt = CLAUDE_PROMPT
|
||||
(run_dir / "prompt.txt").write_text(prompt, encoding="utf-8")
|
||||
command = [
|
||||
# Put the positional prompt before --add-dir. The current Claude Code
|
||||
# CLI declares --add-dir as variadic, so a trailing prompt is otherwise
|
||||
# consumed as another directory and --print reports that no input was
|
||||
# provided.
|
||||
"claude", prompt, "--print", "--output-format", "stream-json", "--verbose",
|
||||
"--model", protocol["runtime"]["model_alias"], "--effort", "high",
|
||||
"--max-budget-usd", "8", "--no-session-persistence",
|
||||
"--dangerously-skip-permissions", "--add-dir", str(official_skill),
|
||||
]
|
||||
(run_dir / "command.json").write_text(json.dumps(command, indent=2), encoding="utf-8")
|
||||
env = os.environ.copy()
|
||||
env["CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC"] = "1"
|
||||
if args.auth_source == "claude-login":
|
||||
# An invalid environment key takes precedence over an otherwise valid
|
||||
# Claude Code OAuth login. Make this explicit and record it without
|
||||
# ever serializing credential values.
|
||||
env.pop("ANTHROPIC_API_KEY", None)
|
||||
(run_dir / "auth_source.json").write_text(
|
||||
json.dumps({"auth_source": args.auth_source}, indent=2), encoding="utf-8"
|
||||
)
|
||||
return_code = stream_process(
|
||||
command, workspace, env, run_dir / "claude_stream.jsonl",
|
||||
run_dir / "claude_stderr.log", "claude",
|
||||
)
|
||||
(run_dir / "claude_exit.json").write_text(
|
||||
json.dumps({"return_code": return_code}, indent=2), encoding="utf-8"
|
||||
)
|
||||
|
||||
|
||||
def run_kimi(args, run_dir: Path, workspace: Path, official_skill: Path, protocol: dict) -> None:
|
||||
kimi = protocol["runtime"]["alternate_runtimes"]["kimi"]
|
||||
binary = resolve_kimi_binary()
|
||||
# --skills-dir replaces the auto-discovered user/project skill directories
|
||||
# for this launch, so the runtime genuinely starts with only the pinned
|
||||
# official Skill's metadata in its catalog.
|
||||
skills_dir = workspace / "kimi-skills"
|
||||
skills_dir.mkdir(parents=True)
|
||||
(skills_dir / "pptx").symlink_to(official_skill, target_is_directory=True)
|
||||
prompt = KIMI_PROMPT
|
||||
(run_dir / "prompt.txt").write_text(prompt, encoding="utf-8")
|
||||
command = [
|
||||
binary, "--prompt", prompt, "--output-format", "stream-json",
|
||||
"--model", kimi["model_alias"],
|
||||
"--skills-dir", str(skills_dir), "--add-dir", str(official_skill),
|
||||
]
|
||||
(run_dir / "command.json").write_text(json.dumps(command, indent=2), encoding="utf-8")
|
||||
env = os.environ.copy()
|
||||
(run_dir / "runtime.json").write_text(
|
||||
json.dumps(
|
||||
{
|
||||
"runtime": "kimi",
|
||||
"binary": binary,
|
||||
"model_alias": kimi["model_alias"],
|
||||
"skills_dir": str(skills_dir),
|
||||
"auth_environment_variables_present": [
|
||||
name for name in kimi["auth_environment_variables"] if os.getenv(name)
|
||||
],
|
||||
},
|
||||
indent=2,
|
||||
),
|
||||
encoding="utf-8",
|
||||
)
|
||||
return_code = stream_process(
|
||||
command, workspace, env, run_dir / "kimi_stream.jsonl",
|
||||
run_dir / "kimi_stderr.log", "kimi",
|
||||
)
|
||||
(run_dir / "kimi_exit.json").write_text(
|
||||
json.dumps({"return_code": return_code}, indent=2), encoding="utf-8"
|
||||
)
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument("--output", required=True, type=Path)
|
||||
parser.add_argument(
|
||||
"--runtime",
|
||||
choices=("claude", "kimi"),
|
||||
default="claude",
|
||||
help="Agent runtime that executes the pinned official Skill.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--official-repo",
|
||||
type=Path,
|
||||
default=ROOT / "external" / "anthropics-skills",
|
||||
)
|
||||
parser.add_argument("--resume-validation", action="store_true")
|
||||
parser.add_argument(
|
||||
"--auth-source",
|
||||
choices=("environment", "claude-login"),
|
||||
default="environment",
|
||||
help="Claude runtime only: use ANTHROPIC_API_KEY or explicitly use Claude Code's authenticated login.",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
run_dir = args.output.resolve()
|
||||
if args.resume_validation:
|
||||
return subprocess.run(
|
||||
[sys.executable, str(ROOT / "validate_official_run.py"), str(run_dir)]
|
||||
).returncode
|
||||
run_dir.mkdir(parents=True, exist_ok=False)
|
||||
protocol_bytes = PROTOCOL_PATH.read_bytes()
|
||||
protocol = json.loads(protocol_bytes)
|
||||
(run_dir / "experiment_protocol.json").write_bytes(protocol_bytes)
|
||||
skill_receipt = prepare(args.official_repo)
|
||||
(run_dir / "official_skill_receipt.json").write_text(
|
||||
json.dumps(skill_receipt, indent=2), encoding="utf-8"
|
||||
)
|
||||
|
||||
workspace = run_dir / "workspace"
|
||||
(workspace / "output").mkdir(parents=True)
|
||||
official_skill = Path(skill_receipt["skill_path"])
|
||||
response = requests.get(protocol["paper"]["pdf_url"], timeout=180)
|
||||
response.raise_for_status()
|
||||
digest = hashlib.sha256(response.content).hexdigest()
|
||||
if digest != protocol["paper"]["pdf_sha256"]:
|
||||
raise RuntimeError(f"paper hash mismatch: {digest}")
|
||||
paper_path = workspace / "attention-is-all-you-need.pdf"
|
||||
paper_path.write_bytes(response.content)
|
||||
|
||||
if args.runtime == "kimi":
|
||||
run_kimi(args, run_dir, workspace, official_skill, protocol)
|
||||
else:
|
||||
run_claude(args, run_dir, workspace, official_skill, protocol)
|
||||
validator = subprocess.run(
|
||||
[sys.executable, str(ROOT / "validate_official_run.py"), str(run_dir)]
|
||||
)
|
||||
return validator.returncode
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"return_code": 1
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
[
|
||||
"claude",
|
||||
"--print",
|
||||
"--output-format",
|
||||
"stream-json",
|
||||
"--verbose",
|
||||
"--model",
|
||||
"sonnet",
|
||||
"--effort",
|
||||
"high",
|
||||
"--max-budget-usd",
|
||||
"8",
|
||||
"--no-session-persistence",
|
||||
"--dangerously-skip-permissions",
|
||||
"--add-dir",
|
||||
"/Users/boj/book/ai-agent-book/chapter2/agent-skills-ppt/external/anthropics-skills/skills/pptx",
|
||||
"/pptx\n\nCreate a polished 10\u201315 slide presentation from the real academic paper at\n`attention-is-all-you-need.pdf`. Write the final deck to\n`output/attention-is-all-you-need.pptx`.\n\nThis is an audited Agent Skills experiment. Follow the official PPTX Skill by\nprogressive disclosure: invoke the pptx Skill, read its complete SKILL.md, then\nread its complete html2pptx.md only after selection. Use the pinned official\n`scripts/html2pptx.js` workflow. Use the official `scripts/thumbnail.py` to\nmake `output/full-deck-thumbnail.jpg`, inspect the full grid, and fix visible\noverlap, cutoff, contrast, or alignment defects before finishing.\n\nContent gates:\n- cover title, problem/background, Transformer method/architecture, key\n experimental results, and conclusion;\n- extract or crop at least three visuals directly from the source PDF (not\n invented replacements), place the files under `source_visuals/`, and embed\n all of them in the deck;\n- create `source_visuals/manifest.json` as a JSON list. Each item must contain\n `file`, one-based PDF `page`, the paper's `label` (for example Figure 1 or\n Table 2), and a faithful `caption`;\n- make every visual consistent with the surrounding slide explanation and\n cite its source page/label on-slide.\n\nYou may install the Node packages required by the official Skill inside this\nworkspace. Do not use the repository's bundled `demo.py`, local proxy Skill,\nor prewritten sample outline. The final response must name the deck,\nthumbnail, visual manifest, slide count, validation performed, and any\nremaining limitation.\n"
|
||||
]
|
||||
@@ -0,0 +1,59 @@
|
||||
{
|
||||
"experiment_id": "2-6",
|
||||
"protocol_sha256": "2990c8ef624edc12a06fb1b622de33b0fe8842cc5b42faf85788850111265eba",
|
||||
"official_skill_receipt": {
|
||||
"repository": "https://github.com/anthropics/skills.git",
|
||||
"revision": "69c0b1a0674149f27b61b2635f935524b6add202",
|
||||
"skill_path": "/Users/boj/book/ai-agent-book/chapter2/agent-skills-ppt/external/anthropics-skills/skills/pptx",
|
||||
"required_file_hashes": {
|
||||
"skills/pptx/SKILL.md": "b6f25545bfb358739f1532f793458b5dbc87ee009933cb7c306b2d951ab6617f",
|
||||
"skills/pptx/html2pptx.md": "f08ed7580969b796d9cd5ade93e2cdee981dcaf13cc5eb12e8d4a3700c2d6047",
|
||||
"skills/pptx/scripts/html2pptx.js": "c675d09a54d6a002e8ca5917b9d24a6568aa8d455bb7abeb212d4f564dd07a34",
|
||||
"skills/pptx/scripts/thumbnail.py": "c21fd950b6ada7bd2f029885d3e56bc66b7ff061cc8404c492eb301664aa9e5d"
|
||||
}
|
||||
},
|
||||
"claude_result": {},
|
||||
"slide_count": 0,
|
||||
"section_checks": {
|
||||
"title": false,
|
||||
"background": false,
|
||||
"method": false,
|
||||
"results": false,
|
||||
"conclusion": false
|
||||
},
|
||||
"source_visuals": [],
|
||||
"embedded_media": {},
|
||||
"thumbnail_files": [],
|
||||
"gates": {
|
||||
"source_pdf_hash_matches": true,
|
||||
"claude_run_succeeded": false,
|
||||
"pptx_skill_invoked": false,
|
||||
"skill_md_loaded": false,
|
||||
"html2pptx_guide_loaded": false,
|
||||
"official_html2pptx_used": false,
|
||||
"official_thumbnail_used": false,
|
||||
"thumbnail_visually_inspected": false,
|
||||
"pptx_zip_valid": false,
|
||||
"pptx_reopens": false,
|
||||
"slide_count_in_range": false,
|
||||
"required_sections_present": false,
|
||||
"three_source_visuals_embedded_and_documented": false,
|
||||
"thumbnail_grid_present": false,
|
||||
"credential_scan_passed": true
|
||||
},
|
||||
"official_complete": false,
|
||||
"artifacts": {
|
||||
"experiment_protocol.json": {
|
||||
"sha256": "2990c8ef624edc12a06fb1b622de33b0fe8842cc5b42faf85788850111265eba",
|
||||
"bytes": 2582
|
||||
},
|
||||
"claude_stream.jsonl": {
|
||||
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
||||
"bytes": 0
|
||||
},
|
||||
"workspace/attention-is-all-you-need.pdf": {
|
||||
"sha256": "bdfaa68d8984f0dc02beaca527b76f207d99b666d31d1da728ee0728182df697",
|
||||
"bytes": 2215244
|
||||
}
|
||||
}
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"experiment_id": "2-6",
|
||||
"protocol_version": "1.0.0",
|
||||
"frozen_on": "2026-07-30",
|
||||
"authority": "book/chapter2.md:767",
|
||||
"runtime": {
|
||||
"agent": "Claude Code",
|
||||
"model_alias": "sonnet",
|
||||
"official_skill_repository": "https://github.com/anthropics/skills.git",
|
||||
"official_skill_revision": "69c0b1a0674149f27b61b2635f935524b6add202",
|
||||
"skill_path": "skills/pptx",
|
||||
"revision_reason": "This is the official revision whose PPTX Skill contains the html2pptx.md workflow named by the manuscript; later revision 4e6907a packages that guide as html2pptx.tgz."
|
||||
},
|
||||
"paper": {
|
||||
"title": "Attention Is All You Need",
|
||||
"authors": "Ashish Vaswani et al.",
|
||||
"arxiv_id": "1706.03762",
|
||||
"pdf_url": "https://arxiv.org/pdf/1706.03762",
|
||||
"pdf_sha256": "bdfaa68d8984f0dc02beaca527b76f207d99b666d31d1da728ee0728182df697"
|
||||
},
|
||||
"output": {
|
||||
"minimum_slides": 10,
|
||||
"maximum_slides": 15,
|
||||
"required_sections": [
|
||||
"title",
|
||||
"problem/background",
|
||||
"method/Transformer architecture",
|
||||
"key results",
|
||||
"conclusion"
|
||||
],
|
||||
"minimum_paper_visuals": 3,
|
||||
"visual_policy": "At least three images must be extracted or cropped from the source PDF, embedded in the deck, and listed with PDF page and source label in source_visuals/manifest.json."
|
||||
},
|
||||
"progressive_disclosure_gates": [
|
||||
"Claude Code discovers only PPTX Skill metadata before selection",
|
||||
"Claude invokes the official pptx Skill and loads its complete SKILL.md",
|
||||
"Claude reads the complete official html2pptx.md only after selecting the Skill",
|
||||
"Claude uses the official scripts/html2pptx.js workflow",
|
||||
"Claude invokes the official scripts/thumbnail.py preview workflow and visually inspects the result"
|
||||
],
|
||||
"artifact_gates": [
|
||||
"the source PDF hash matches the preregistered academic paper",
|
||||
"the presentation is a valid ZIP/OOXML package and python-pptx reopens it",
|
||||
"slide count is between 10 and 15 inclusive",
|
||||
"the five required content sections are present",
|
||||
"three or more source visual files are byte-identical to media embedded in the PPTX",
|
||||
"each source visual has a PDF page, paper label, and caption in the visual manifest",
|
||||
"a full-deck thumbnail grid exists",
|
||||
"raw Claude Code stream events, actual model, usage/cost, commands, hashes, and credential scan are retained"
|
||||
],
|
||||
"claim_policy": "The bundled Python demo is a noncanonical mechanism illustration and cannot satisfy Experiment 2-6. Only a real Claude Code run with the pinned official Skill and real paper can complete this protocol."
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"experiment_id": "2-6",
|
||||
"official_complete": false,
|
||||
"protocol_sha256": "2990c8ef624edc12a06fb1b622de33b0fe8842cc5b42faf85788850111265eba",
|
||||
"comparison_sha256": "688774e2a47eabef59f7dba27f999aeb0a3936472db1bb4584078f317c518f58",
|
||||
"pptx_sha256": null
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"repository": "https://github.com/anthropics/skills.git",
|
||||
"revision": "69c0b1a0674149f27b61b2635f935524b6add202",
|
||||
"skill_path": "/Users/boj/book/ai-agent-book/chapter2/agent-skills-ppt/external/anthropics-skills/skills/pptx",
|
||||
"required_file_hashes": {
|
||||
"skills/pptx/SKILL.md": "b6f25545bfb358739f1532f793458b5dbc87ee009933cb7c306b2d951ab6617f",
|
||||
"skills/pptx/html2pptx.md": "f08ed7580969b796d9cd5ade93e2cdee981dcaf13cc5eb12e8d4a3700c2d6047",
|
||||
"skills/pptx/scripts/html2pptx.js": "c675d09a54d6a002e8ca5917b9d24a6568aa8d455bb7abeb212d4f564dd07a34",
|
||||
"skills/pptx/scripts/thumbnail.py": "c21fd950b6ada7bd2f029885d3e56bc66b7ff061cc8404c492eb301664aa9e5d"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/pptx
|
||||
|
||||
Create a polished 10–15 slide presentation from the real academic paper at
|
||||
`attention-is-all-you-need.pdf`. Write the final deck to
|
||||
`output/attention-is-all-you-need.pptx`.
|
||||
|
||||
This is an audited Agent Skills experiment. Follow the official PPTX Skill by
|
||||
progressive disclosure: invoke the pptx Skill, read its complete SKILL.md, then
|
||||
read its complete html2pptx.md only after selection. Use the pinned official
|
||||
`scripts/html2pptx.js` workflow. Use the official `scripts/thumbnail.py` to
|
||||
make `output/full-deck-thumbnail.jpg`, inspect the full grid, and fix visible
|
||||
overlap, cutoff, contrast, or alignment defects before finishing.
|
||||
|
||||
Content gates:
|
||||
- cover title, problem/background, Transformer method/architecture, key
|
||||
experimental results, and conclusion;
|
||||
- extract or crop at least three visuals directly from the source PDF (not
|
||||
invented replacements), place the files under `source_visuals/`, and embed
|
||||
all of them in the deck;
|
||||
- create `source_visuals/manifest.json` as a JSON list. Each item must contain
|
||||
`file`, one-based PDF `page`, the paper's `label` (for example Figure 1 or
|
||||
Table 2), and a faithful `caption`;
|
||||
- make every visual consistent with the surrounding slide explanation and
|
||||
cite its source page/label on-slide.
|
||||
|
||||
You may install the Node packages required by the official Skill inside this
|
||||
workspace. Do not use the repository's bundled `demo.py`, local proxy Skill,
|
||||
or prewritten sample outline. The final response must name the deck,
|
||||
thumbnail, visual manifest, slide count, validation performed, and any
|
||||
remaining limitation.
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"return_code": 1
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
{"type":"system","subtype":"init","cwd":"/Users/boj/book/ai-agent-book/chapter2/agent-skills-ppt/runs/exp2-6-claude-pptx-20260730-v2/workspace","session_id":"b7b08ae5-01d0-46f5-b0e0-2e319fa9ab18","tools":["Task","Bash","CronCreate","CronDelete","CronList","Edit","EnterWorktree","ExitWorktree","NotebookEdit","Read","ReportFindings","ScheduleWakeup","SendMessage","Skill","TaskCreate","TaskGet","TaskList","TaskOutput","TaskStop","TaskUpdate","ToolSearch","WebFetch","WebSearch","Workflow","Write"],"mcp_servers":[],"model":"claude-sonnet-5","permissionMode":"bypassPermissions","slash_commands":["pptx","deep-research","dataviz","update-config","verify","debug","code-review","simplify","batch","fewer-permission-prompts","doctor","loop","claude-api","run","run-skill-generator","agents","clear","color","compact","config","context","effort","fast","heapdump","init","mcp","model","__remote-workflow","workflow-launch-exec","reload-skills","rename","review","security-review","usage","insights","recap","goal","team-onboarding"],"apiKeySource":"ANTHROPIC_API_KEY","claude_code_version":"2.1.218","output_style":"default","agents":["claude","Explore","general-purpose","Plan","statusline-setup"],"skills":["pptx","deep-research","dataviz","update-config","verify","debug","code-review","simplify","batch","fewer-permission-prompts","doctor","loop","claude-api","run","run-skill-generator"],"plugins":[],"capabilities":["interrupt_receipt_v1","msg_lifecycle_v1"],"analytics_disabled":true,"product_feedback_disabled":false,"uuid":"ae3f0aa9-a87b-4693-a2d7-d7408763316b","memory_paths":{"auto":"/Users/boj/.claude/projects/-Users-boj-book-ai-agent-book/memory/"},"fast_mode_state":"off"}
|
||||
{"type":"system","subtype":"api_retry","attempt":1,"max_retries":10,"retry_delay_ms":547,"error_status":401,"error":"authentication_failed","session_id":"b7b08ae5-01d0-46f5-b0e0-2e319fa9ab18","uuid":"a9c5efdb-903a-4d39-9181-a5a27e9620dd"}
|
||||
{"type":"system","subtype":"api_retry","attempt":2,"max_retries":10,"retry_delay_ms":1110,"error_status":401,"error":"authentication_failed","session_id":"b7b08ae5-01d0-46f5-b0e0-2e319fa9ab18","uuid":"6be5a82f-4a4f-45e6-936c-beb3edcff939"}
|
||||
{"type":"system","subtype":"api_retry","attempt":3,"max_retries":10,"retry_delay_ms":2014,"error_status":401,"error":"authentication_failed","session_id":"b7b08ae5-01d0-46f5-b0e0-2e319fa9ab18","uuid":"40c5357e-5dae-4f62-b58e-1c6525ef2fa3"}
|
||||
{"type":"system","subtype":"api_retry","attempt":4,"max_retries":10,"retry_delay_ms":4650,"error_status":401,"error":"authentication_failed","session_id":"b7b08ae5-01d0-46f5-b0e0-2e319fa9ab18","uuid":"830d6982-79aa-4daa-a2fd-a6d2944c2559"}
|
||||
{"type":"system","subtype":"api_retry","attempt":5,"max_retries":10,"retry_delay_ms":9091,"error_status":401,"error":"authentication_failed","session_id":"b7b08ae5-01d0-46f5-b0e0-2e319fa9ab18","uuid":"22c49e8a-c0cf-4bc8-b04d-df019f57205f"}
|
||||
{"type":"system","subtype":"api_retry","attempt":6,"max_retries":10,"retry_delay_ms":19672,"error_status":401,"error":"authentication_failed","session_id":"b7b08ae5-01d0-46f5-b0e0-2e319fa9ab18","uuid":"517f55b5-92ec-460e-93f5-a20eab1a78f8"}
|
||||
{"type":"system","subtype":"api_retry","attempt":7,"max_retries":10,"retry_delay_ms":34637,"error_status":401,"error":"authentication_failed","session_id":"b7b08ae5-01d0-46f5-b0e0-2e319fa9ab18","uuid":"11241223-2cc9-4769-9800-3551fcea8305"}
|
||||
{"type":"system","subtype":"api_retry","attempt":8,"max_retries":10,"retry_delay_ms":32868,"error_status":401,"error":"authentication_failed","session_id":"b7b08ae5-01d0-46f5-b0e0-2e319fa9ab18","uuid":"42e5b7fc-5c60-4a2e-905b-1d15d5d8179b"}
|
||||
{"type":"system","subtype":"api_retry","attempt":9,"max_retries":10,"retry_delay_ms":36134,"error_status":401,"error":"authentication_failed","session_id":"b7b08ae5-01d0-46f5-b0e0-2e319fa9ab18","uuid":"9a5e6a0c-eb29-4050-b3db-75fd56179da6"}
|
||||
{"type":"system","subtype":"api_retry","attempt":10,"max_retries":10,"retry_delay_ms":34271,"error_status":401,"error":"authentication_failed","session_id":"b7b08ae5-01d0-46f5-b0e0-2e319fa9ab18","uuid":"34390b97-f09f-4081-9b46-fe98604b04fc"}
|
||||
{"type":"assistant","message":{"id":"ebd5c598-7796-4581-9513-0d0dccb49362","container":null,"model":"<synthetic>","role":"assistant","stop_details":null,"stop_reason":"stop_sequence","stop_sequence":"","type":"message","usage":{"input_tokens":0,"output_tokens":0,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"server_tool_use":{"web_search_requests":0,"web_fetch_requests":0},"service_tier":null,"cache_creation":{"ephemeral_1h_input_tokens":0,"ephemeral_5m_input_tokens":0},"inference_geo":null,"iterations":null,"speed":null},"content":[{"type":"text","text":"Failed to authenticate. API Error: 401 API key is invalid."}],"context_management":null},"parent_tool_use_id":null,"session_id":"b7b08ae5-01d0-46f5-b0e0-2e319fa9ab18","uuid":"971c3df7-a74b-489d-b32b-d20624b78096","timestamp":"2026-07-29T19:41:56.444Z","error":"authentication_failed"}
|
||||
{"is_error":true,"duration_api_ms":0,"num_turns":1,"stop_reason":"stop_sequence","session_id":"b7b08ae5-01d0-46f5-b0e0-2e319fa9ab18","total_cost_usd":0,"usage":{"input_tokens":0,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":0,"server_tool_use":{"web_search_requests":0,"web_fetch_requests":0},"service_tier":"standard","cache_creation":{"ephemeral_1h_input_tokens":0,"ephemeral_5m_input_tokens":0},"inference_geo":"","iterations":[],"speed":"standard"},"modelUsage":{},"permission_denials":[],"terminal_reason":"api_error","fast_mode_state":"off","subtype":"success","api_error_status":401,"result":"Failed to authenticate. API Error: 401 API key is invalid.","type":"result","duration_ms":182912,"uuid":"8a488e57-1f7a-4998-aa57-5800b261e318"}
|
||||
@@ -0,0 +1,18 @@
|
||||
[
|
||||
"claude",
|
||||
"/pptx\n\nCreate a polished 10\u201315 slide presentation from the real academic paper at\n`attention-is-all-you-need.pdf`. Write the final deck to\n`output/attention-is-all-you-need.pptx`.\n\nThis is an audited Agent Skills experiment. Follow the official PPTX Skill by\nprogressive disclosure: invoke the pptx Skill, read its complete SKILL.md, then\nread its complete html2pptx.md only after selection. Use the pinned official\n`scripts/html2pptx.js` workflow. Use the official `scripts/thumbnail.py` to\nmake `output/full-deck-thumbnail.jpg`, inspect the full grid, and fix visible\noverlap, cutoff, contrast, or alignment defects before finishing.\n\nContent gates:\n- cover title, problem/background, Transformer method/architecture, key\n experimental results, and conclusion;\n- extract or crop at least three visuals directly from the source PDF (not\n invented replacements), place the files under `source_visuals/`, and embed\n all of them in the deck;\n- create `source_visuals/manifest.json` as a JSON list. Each item must contain\n `file`, one-based PDF `page`, the paper's `label` (for example Figure 1 or\n Table 2), and a faithful `caption`;\n- make every visual consistent with the surrounding slide explanation and\n cite its source page/label on-slide.\n\nYou may install the Node packages required by the official Skill inside this\nworkspace. Do not use the repository's bundled `demo.py`, local proxy Skill,\nor prewritten sample outline. The final response must name the deck,\nthumbnail, visual manifest, slide count, validation performed, and any\nremaining limitation.\n",
|
||||
"--print",
|
||||
"--output-format",
|
||||
"stream-json",
|
||||
"--verbose",
|
||||
"--model",
|
||||
"sonnet",
|
||||
"--effort",
|
||||
"high",
|
||||
"--max-budget-usd",
|
||||
"8",
|
||||
"--no-session-persistence",
|
||||
"--dangerously-skip-permissions",
|
||||
"--add-dir",
|
||||
"/Users/boj/book/ai-agent-book/chapter2/agent-skills-ppt/external/anthropics-skills/skills/pptx"
|
||||
]
|
||||
@@ -0,0 +1,87 @@
|
||||
{
|
||||
"experiment_id": "2-6",
|
||||
"protocol_sha256": "2990c8ef624edc12a06fb1b622de33b0fe8842cc5b42faf85788850111265eba",
|
||||
"official_skill_receipt": {
|
||||
"repository": "https://github.com/anthropics/skills.git",
|
||||
"revision": "69c0b1a0674149f27b61b2635f935524b6add202",
|
||||
"skill_path": "/Users/boj/book/ai-agent-book/chapter2/agent-skills-ppt/external/anthropics-skills/skills/pptx",
|
||||
"required_file_hashes": {
|
||||
"skills/pptx/SKILL.md": "b6f25545bfb358739f1532f793458b5dbc87ee009933cb7c306b2d951ab6617f",
|
||||
"skills/pptx/html2pptx.md": "f08ed7580969b796d9cd5ade93e2cdee981dcaf13cc5eb12e8d4a3700c2d6047",
|
||||
"skills/pptx/scripts/html2pptx.js": "c675d09a54d6a002e8ca5917b9d24a6568aa8d455bb7abeb212d4f564dd07a34",
|
||||
"skills/pptx/scripts/thumbnail.py": "c21fd950b6ada7bd2f029885d3e56bc66b7ff061cc8404c492eb301664aa9e5d"
|
||||
}
|
||||
},
|
||||
"claude_result": {
|
||||
"subtype": "success",
|
||||
"is_error": true,
|
||||
"duration_ms": 182912,
|
||||
"duration_api_ms": 0,
|
||||
"num_turns": 1,
|
||||
"result": "Failed to authenticate. API Error: 401 API key is invalid.",
|
||||
"total_cost_usd": 0,
|
||||
"usage": {
|
||||
"input_tokens": 0,
|
||||
"cache_creation_input_tokens": 0,
|
||||
"cache_read_input_tokens": 0,
|
||||
"output_tokens": 0,
|
||||
"server_tool_use": {
|
||||
"web_search_requests": 0,
|
||||
"web_fetch_requests": 0
|
||||
},
|
||||
"service_tier": "standard",
|
||||
"cache_creation": {
|
||||
"ephemeral_1h_input_tokens": 0,
|
||||
"ephemeral_5m_input_tokens": 0
|
||||
},
|
||||
"inference_geo": "",
|
||||
"iterations": [],
|
||||
"speed": "standard"
|
||||
},
|
||||
"modelUsage": {},
|
||||
"session_id": "b7b08ae5-01d0-46f5-b0e0-2e319fa9ab18"
|
||||
},
|
||||
"slide_count": 0,
|
||||
"section_checks": {
|
||||
"title": false,
|
||||
"background": false,
|
||||
"method": false,
|
||||
"results": false,
|
||||
"conclusion": false
|
||||
},
|
||||
"source_visuals": [],
|
||||
"embedded_media": {},
|
||||
"thumbnail_files": [],
|
||||
"gates": {
|
||||
"source_pdf_hash_matches": true,
|
||||
"claude_run_succeeded": false,
|
||||
"pptx_skill_invoked": false,
|
||||
"skill_md_loaded": false,
|
||||
"html2pptx_guide_loaded": false,
|
||||
"official_html2pptx_used": false,
|
||||
"official_thumbnail_used": false,
|
||||
"thumbnail_visually_inspected": false,
|
||||
"pptx_zip_valid": false,
|
||||
"pptx_reopens": false,
|
||||
"slide_count_in_range": false,
|
||||
"required_sections_present": false,
|
||||
"three_source_visuals_embedded_and_documented": false,
|
||||
"thumbnail_grid_present": false,
|
||||
"credential_scan_passed": true
|
||||
},
|
||||
"official_complete": false,
|
||||
"artifacts": {
|
||||
"experiment_protocol.json": {
|
||||
"sha256": "2990c8ef624edc12a06fb1b622de33b0fe8842cc5b42faf85788850111265eba",
|
||||
"bytes": 2582
|
||||
},
|
||||
"claude_stream.jsonl": {
|
||||
"sha256": "40004d1a5ed3c5f9dd4f8526b438bef025149feada0edd226f8e956d83874cdc",
|
||||
"bytes": 5725
|
||||
},
|
||||
"workspace/attention-is-all-you-need.pdf": {
|
||||
"sha256": "bdfaa68d8984f0dc02beaca527b76f207d99b666d31d1da728ee0728182df697",
|
||||
"bytes": 2215244
|
||||
}
|
||||
}
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"experiment_id": "2-6",
|
||||
"protocol_version": "1.0.0",
|
||||
"frozen_on": "2026-07-30",
|
||||
"authority": "book/chapter2.md:767",
|
||||
"runtime": {
|
||||
"agent": "Claude Code",
|
||||
"model_alias": "sonnet",
|
||||
"official_skill_repository": "https://github.com/anthropics/skills.git",
|
||||
"official_skill_revision": "69c0b1a0674149f27b61b2635f935524b6add202",
|
||||
"skill_path": "skills/pptx",
|
||||
"revision_reason": "This is the official revision whose PPTX Skill contains the html2pptx.md workflow named by the manuscript; later revision 4e6907a packages that guide as html2pptx.tgz."
|
||||
},
|
||||
"paper": {
|
||||
"title": "Attention Is All You Need",
|
||||
"authors": "Ashish Vaswani et al.",
|
||||
"arxiv_id": "1706.03762",
|
||||
"pdf_url": "https://arxiv.org/pdf/1706.03762",
|
||||
"pdf_sha256": "bdfaa68d8984f0dc02beaca527b76f207d99b666d31d1da728ee0728182df697"
|
||||
},
|
||||
"output": {
|
||||
"minimum_slides": 10,
|
||||
"maximum_slides": 15,
|
||||
"required_sections": [
|
||||
"title",
|
||||
"problem/background",
|
||||
"method/Transformer architecture",
|
||||
"key results",
|
||||
"conclusion"
|
||||
],
|
||||
"minimum_paper_visuals": 3,
|
||||
"visual_policy": "At least three images must be extracted or cropped from the source PDF, embedded in the deck, and listed with PDF page and source label in source_visuals/manifest.json."
|
||||
},
|
||||
"progressive_disclosure_gates": [
|
||||
"Claude Code discovers only PPTX Skill metadata before selection",
|
||||
"Claude invokes the official pptx Skill and loads its complete SKILL.md",
|
||||
"Claude reads the complete official html2pptx.md only after selecting the Skill",
|
||||
"Claude uses the official scripts/html2pptx.js workflow",
|
||||
"Claude invokes the official scripts/thumbnail.py preview workflow and visually inspects the result"
|
||||
],
|
||||
"artifact_gates": [
|
||||
"the source PDF hash matches the preregistered academic paper",
|
||||
"the presentation is a valid ZIP/OOXML package and python-pptx reopens it",
|
||||
"slide count is between 10 and 15 inclusive",
|
||||
"the five required content sections are present",
|
||||
"three or more source visual files are byte-identical to media embedded in the PPTX",
|
||||
"each source visual has a PDF page, paper label, and caption in the visual manifest",
|
||||
"a full-deck thumbnail grid exists",
|
||||
"raw Claude Code stream events, actual model, usage/cost, commands, hashes, and credential scan are retained"
|
||||
],
|
||||
"claim_policy": "The bundled Python demo is a noncanonical mechanism illustration and cannot satisfy Experiment 2-6. Only a real Claude Code run with the pinned official Skill and real paper can complete this protocol."
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"experiment_id": "2-6",
|
||||
"official_complete": false,
|
||||
"protocol_sha256": "2990c8ef624edc12a06fb1b622de33b0fe8842cc5b42faf85788850111265eba",
|
||||
"comparison_sha256": "c3656f5fb04adf733f90731b2be71791a69a54d2ad91b633b58adc1262a3c9ec",
|
||||
"pptx_sha256": null
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"repository": "https://github.com/anthropics/skills.git",
|
||||
"revision": "69c0b1a0674149f27b61b2635f935524b6add202",
|
||||
"skill_path": "/Users/boj/book/ai-agent-book/chapter2/agent-skills-ppt/external/anthropics-skills/skills/pptx",
|
||||
"required_file_hashes": {
|
||||
"skills/pptx/SKILL.md": "b6f25545bfb358739f1532f793458b5dbc87ee009933cb7c306b2d951ab6617f",
|
||||
"skills/pptx/html2pptx.md": "f08ed7580969b796d9cd5ade93e2cdee981dcaf13cc5eb12e8d4a3700c2d6047",
|
||||
"skills/pptx/scripts/html2pptx.js": "c675d09a54d6a002e8ca5917b9d24a6568aa8d455bb7abeb212d4f564dd07a34",
|
||||
"skills/pptx/scripts/thumbnail.py": "c21fd950b6ada7bd2f029885d3e56bc66b7ff061cc8404c492eb301664aa9e5d"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/pptx
|
||||
|
||||
Create a polished 10–15 slide presentation from the real academic paper at
|
||||
`attention-is-all-you-need.pdf`. Write the final deck to
|
||||
`output/attention-is-all-you-need.pptx`.
|
||||
|
||||
This is an audited Agent Skills experiment. Follow the official PPTX Skill by
|
||||
progressive disclosure: invoke the pptx Skill, read its complete SKILL.md, then
|
||||
read its complete html2pptx.md only after selection. Use the pinned official
|
||||
`scripts/html2pptx.js` workflow. Use the official `scripts/thumbnail.py` to
|
||||
make `output/full-deck-thumbnail.jpg`, inspect the full grid, and fix visible
|
||||
overlap, cutoff, contrast, or alignment defects before finishing.
|
||||
|
||||
Content gates:
|
||||
- cover title, problem/background, Transformer method/architecture, key
|
||||
experimental results, and conclusion;
|
||||
- extract or crop at least three visuals directly from the source PDF (not
|
||||
invented replacements), place the files under `source_visuals/`, and embed
|
||||
all of them in the deck;
|
||||
- create `source_visuals/manifest.json` as a JSON list. Each item must contain
|
||||
`file`, one-based PDF `page`, the paper's `label` (for example Figure 1 or
|
||||
Table 2), and a faithful `caption`;
|
||||
- make every visual consistent with the surrounding slide explanation and
|
||||
cite its source page/label on-slide.
|
||||
|
||||
You may install the Node packages required by the official Skill inside this
|
||||
workspace. Do not use the repository's bundled `demo.py`, local proxy Skill,
|
||||
or prewritten sample outline. The final response must name the deck,
|
||||
thumbnail, visual manifest, slide count, validation performed, and any
|
||||
remaining limitation.
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"auth_source": "claude-login"
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"return_code": 1
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{"type":"system","subtype":"init","cwd":"/Users/boj/book/ai-agent-book/chapter2/agent-skills-ppt/runs/exp2-6-claude-pptx-20260730-v3/workspace","session_id":"2585a5cf-5b06-4497-9d62-bceddbf00eac","tools":["Task","Bash","CronCreate","CronDelete","CronList","Edit","EnterWorktree","ExitWorktree","NotebookEdit","Read","ReportFindings","ScheduleWakeup","SendMessage","Skill","TaskCreate","TaskGet","TaskList","TaskOutput","TaskStop","TaskUpdate","ToolSearch","WebFetch","WebSearch","Workflow","Write"],"mcp_servers":[],"model":"claude-sonnet-5","permissionMode":"bypassPermissions","slash_commands":["pptx","deep-research","dataviz","update-config","verify","debug","code-review","simplify","batch","fewer-permission-prompts","doctor","loop","claude-api","run","run-skill-generator","agents","clear","color","compact","config","context","effort","fast","heapdump","init","mcp","model","__remote-workflow","workflow-launch-exec","reload-skills","rename","review","security-review","usage","insights","recap","goal","team-onboarding"],"apiKeySource":"none","claude_code_version":"2.1.218","output_style":"default","agents":["claude","Explore","general-purpose","Plan","statusline-setup"],"skills":["pptx","deep-research","dataviz","update-config","verify","debug","code-review","simplify","batch","fewer-permission-prompts","doctor","loop","claude-api","run","run-skill-generator"],"plugins":[],"capabilities":["interrupt_receipt_v1","msg_lifecycle_v1"],"analytics_disabled":true,"product_feedback_disabled":false,"uuid":"237fe704-5eb6-4ee4-9387-ec286a938081","memory_paths":{"auto":"/Users/boj/.claude/projects/-Users-boj-book-ai-agent-book/memory/"},"fast_mode_state":"off"}
|
||||
{"type":"assistant","message":{"id":"e8088492-91cb-4525-b2e2-d7722ea70525","container":null,"model":"<synthetic>","role":"assistant","stop_details":null,"stop_reason":"stop_sequence","stop_sequence":"","type":"message","usage":{"input_tokens":0,"output_tokens":0,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"server_tool_use":{"web_search_requests":0,"web_fetch_requests":0},"service_tier":null,"cache_creation":{"ephemeral_1h_input_tokens":0,"ephemeral_5m_input_tokens":0},"inference_geo":null,"iterations":null,"speed":null},"content":[{"type":"text","text":"Your organization has disabled Claude subscription access for Claude Code · Use an Anthropic API key instead, or ask your admin to enable access"}],"context_management":null},"parent_tool_use_id":null,"session_id":"2585a5cf-5b06-4497-9d62-bceddbf00eac","uuid":"bbe9a176-cd1f-4bcc-b388-760c2cf809a9","timestamp":"2026-07-29T19:43:40.971Z","error":"oauth_org_not_allowed","request_id":"req_011CdWvNmicoehed6MsdjMFA"}
|
||||
{"is_error":true,"duration_api_ms":0,"num_turns":1,"stop_reason":"stop_sequence","session_id":"2585a5cf-5b06-4497-9d62-bceddbf00eac","total_cost_usd":0,"usage":{"input_tokens":0,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":0,"server_tool_use":{"web_search_requests":0,"web_fetch_requests":0},"service_tier":"standard","cache_creation":{"ephemeral_1h_input_tokens":0,"ephemeral_5m_input_tokens":0},"inference_geo":"","iterations":[],"speed":"standard"},"modelUsage":{},"permission_denials":[],"terminal_reason":"api_error","fast_mode_state":"off","subtype":"success","api_error_status":403,"result":"Your organization has disabled Claude subscription access for Claude Code · Use an Anthropic API key instead, or ask your admin to enable access","type":"result","duration_ms":2531,"uuid":"995b0e91-7a44-4ea5-9023-fe94311c0e69"}
|
||||
@@ -0,0 +1,18 @@
|
||||
[
|
||||
"claude",
|
||||
"/pptx\n\nCreate a polished 10\u201315 slide presentation from the real academic paper at\n`attention-is-all-you-need.pdf`. Write the final deck to\n`output/attention-is-all-you-need.pptx`.\n\nThis is an audited Agent Skills experiment. Follow the official PPTX Skill by\nprogressive disclosure: invoke the pptx Skill, read its complete SKILL.md, then\nread its complete html2pptx.md only after selection. Use the pinned official\n`scripts/html2pptx.js` workflow. Use the official `scripts/thumbnail.py` to\nmake `output/full-deck-thumbnail.jpg`, inspect the full grid, and fix visible\noverlap, cutoff, contrast, or alignment defects before finishing.\n\nContent gates:\n- cover title, problem/background, Transformer method/architecture, key\n experimental results, and conclusion;\n- extract or crop at least three visuals directly from the source PDF (not\n invented replacements), place the files under `source_visuals/`, and embed\n all of them in the deck;\n- create `source_visuals/manifest.json` as a JSON list. Each item must contain\n `file`, one-based PDF `page`, the paper's `label` (for example Figure 1 or\n Table 2), and a faithful `caption`;\n- make every visual consistent with the surrounding slide explanation and\n cite its source page/label on-slide.\n\nYou may install the Node packages required by the official Skill inside this\nworkspace. Do not use the repository's bundled `demo.py`, local proxy Skill,\nor prewritten sample outline. The final response must name the deck,\nthumbnail, visual manifest, slide count, validation performed, and any\nremaining limitation.\n",
|
||||
"--print",
|
||||
"--output-format",
|
||||
"stream-json",
|
||||
"--verbose",
|
||||
"--model",
|
||||
"sonnet",
|
||||
"--effort",
|
||||
"high",
|
||||
"--max-budget-usd",
|
||||
"8",
|
||||
"--no-session-persistence",
|
||||
"--dangerously-skip-permissions",
|
||||
"--add-dir",
|
||||
"/Users/boj/book/ai-agent-book/chapter2/agent-skills-ppt/external/anthropics-skills/skills/pptx"
|
||||
]
|
||||
@@ -0,0 +1,87 @@
|
||||
{
|
||||
"experiment_id": "2-6",
|
||||
"protocol_sha256": "2990c8ef624edc12a06fb1b622de33b0fe8842cc5b42faf85788850111265eba",
|
||||
"official_skill_receipt": {
|
||||
"repository": "https://github.com/anthropics/skills.git",
|
||||
"revision": "69c0b1a0674149f27b61b2635f935524b6add202",
|
||||
"skill_path": "/Users/boj/book/ai-agent-book/chapter2/agent-skills-ppt/external/anthropics-skills/skills/pptx",
|
||||
"required_file_hashes": {
|
||||
"skills/pptx/SKILL.md": "b6f25545bfb358739f1532f793458b5dbc87ee009933cb7c306b2d951ab6617f",
|
||||
"skills/pptx/html2pptx.md": "f08ed7580969b796d9cd5ade93e2cdee981dcaf13cc5eb12e8d4a3700c2d6047",
|
||||
"skills/pptx/scripts/html2pptx.js": "c675d09a54d6a002e8ca5917b9d24a6568aa8d455bb7abeb212d4f564dd07a34",
|
||||
"skills/pptx/scripts/thumbnail.py": "c21fd950b6ada7bd2f029885d3e56bc66b7ff061cc8404c492eb301664aa9e5d"
|
||||
}
|
||||
},
|
||||
"claude_result": {
|
||||
"subtype": "success",
|
||||
"is_error": true,
|
||||
"duration_ms": 2531,
|
||||
"duration_api_ms": 0,
|
||||
"num_turns": 1,
|
||||
"result": "Your organization has disabled Claude subscription access for Claude Code · Use an Anthropic API key instead, or ask your admin to enable access",
|
||||
"total_cost_usd": 0,
|
||||
"usage": {
|
||||
"input_tokens": 0,
|
||||
"cache_creation_input_tokens": 0,
|
||||
"cache_read_input_tokens": 0,
|
||||
"output_tokens": 0,
|
||||
"server_tool_use": {
|
||||
"web_search_requests": 0,
|
||||
"web_fetch_requests": 0
|
||||
},
|
||||
"service_tier": "standard",
|
||||
"cache_creation": {
|
||||
"ephemeral_1h_input_tokens": 0,
|
||||
"ephemeral_5m_input_tokens": 0
|
||||
},
|
||||
"inference_geo": "",
|
||||
"iterations": [],
|
||||
"speed": "standard"
|
||||
},
|
||||
"modelUsage": {},
|
||||
"session_id": "2585a5cf-5b06-4497-9d62-bceddbf00eac"
|
||||
},
|
||||
"slide_count": 0,
|
||||
"section_checks": {
|
||||
"title": false,
|
||||
"background": false,
|
||||
"method": false,
|
||||
"results": false,
|
||||
"conclusion": false
|
||||
},
|
||||
"source_visuals": [],
|
||||
"embedded_media": {},
|
||||
"thumbnail_files": [],
|
||||
"gates": {
|
||||
"source_pdf_hash_matches": true,
|
||||
"claude_run_succeeded": false,
|
||||
"pptx_skill_invoked": false,
|
||||
"skill_md_loaded": false,
|
||||
"html2pptx_guide_loaded": false,
|
||||
"official_html2pptx_used": false,
|
||||
"official_thumbnail_used": false,
|
||||
"thumbnail_visually_inspected": false,
|
||||
"pptx_zip_valid": false,
|
||||
"pptx_reopens": false,
|
||||
"slide_count_in_range": false,
|
||||
"required_sections_present": false,
|
||||
"three_source_visuals_embedded_and_documented": false,
|
||||
"thumbnail_grid_present": false,
|
||||
"credential_scan_passed": true
|
||||
},
|
||||
"official_complete": false,
|
||||
"artifacts": {
|
||||
"experiment_protocol.json": {
|
||||
"sha256": "2990c8ef624edc12a06fb1b622de33b0fe8842cc5b42faf85788850111265eba",
|
||||
"bytes": 2582
|
||||
},
|
||||
"claude_stream.jsonl": {
|
||||
"sha256": "7839179c7f92364b1fe8cbb183c9277040b1213237f0b208022bac82bbf4d6db",
|
||||
"bytes": 3523
|
||||
},
|
||||
"workspace/attention-is-all-you-need.pdf": {
|
||||
"sha256": "bdfaa68d8984f0dc02beaca527b76f207d99b666d31d1da728ee0728182df697",
|
||||
"bytes": 2215244
|
||||
}
|
||||
}
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"experiment_id": "2-6",
|
||||
"protocol_version": "1.0.0",
|
||||
"frozen_on": "2026-07-30",
|
||||
"authority": "book/chapter2.md:767",
|
||||
"runtime": {
|
||||
"agent": "Claude Code",
|
||||
"model_alias": "sonnet",
|
||||
"official_skill_repository": "https://github.com/anthropics/skills.git",
|
||||
"official_skill_revision": "69c0b1a0674149f27b61b2635f935524b6add202",
|
||||
"skill_path": "skills/pptx",
|
||||
"revision_reason": "This is the official revision whose PPTX Skill contains the html2pptx.md workflow named by the manuscript; later revision 4e6907a packages that guide as html2pptx.tgz."
|
||||
},
|
||||
"paper": {
|
||||
"title": "Attention Is All You Need",
|
||||
"authors": "Ashish Vaswani et al.",
|
||||
"arxiv_id": "1706.03762",
|
||||
"pdf_url": "https://arxiv.org/pdf/1706.03762",
|
||||
"pdf_sha256": "bdfaa68d8984f0dc02beaca527b76f207d99b666d31d1da728ee0728182df697"
|
||||
},
|
||||
"output": {
|
||||
"minimum_slides": 10,
|
||||
"maximum_slides": 15,
|
||||
"required_sections": [
|
||||
"title",
|
||||
"problem/background",
|
||||
"method/Transformer architecture",
|
||||
"key results",
|
||||
"conclusion"
|
||||
],
|
||||
"minimum_paper_visuals": 3,
|
||||
"visual_policy": "At least three images must be extracted or cropped from the source PDF, embedded in the deck, and listed with PDF page and source label in source_visuals/manifest.json."
|
||||
},
|
||||
"progressive_disclosure_gates": [
|
||||
"Claude Code discovers only PPTX Skill metadata before selection",
|
||||
"Claude invokes the official pptx Skill and loads its complete SKILL.md",
|
||||
"Claude reads the complete official html2pptx.md only after selecting the Skill",
|
||||
"Claude uses the official scripts/html2pptx.js workflow",
|
||||
"Claude invokes the official scripts/thumbnail.py preview workflow and visually inspects the result"
|
||||
],
|
||||
"artifact_gates": [
|
||||
"the source PDF hash matches the preregistered academic paper",
|
||||
"the presentation is a valid ZIP/OOXML package and python-pptx reopens it",
|
||||
"slide count is between 10 and 15 inclusive",
|
||||
"the five required content sections are present",
|
||||
"three or more source visual files are byte-identical to media embedded in the PPTX",
|
||||
"each source visual has a PDF page, paper label, and caption in the visual manifest",
|
||||
"a full-deck thumbnail grid exists",
|
||||
"raw Claude Code stream events, actual model, usage/cost, commands, hashes, and credential scan are retained"
|
||||
],
|
||||
"claim_policy": "The bundled Python demo is a noncanonical mechanism illustration and cannot satisfy Experiment 2-6. Only a real Claude Code run with the pinned official Skill and real paper can complete this protocol."
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"experiment_id": "2-6",
|
||||
"official_complete": false,
|
||||
"protocol_sha256": "2990c8ef624edc12a06fb1b622de33b0fe8842cc5b42faf85788850111265eba",
|
||||
"comparison_sha256": "9fd8320f12627a8fc9d20904c0776e70895d6903704b23b5215d154a9d165735",
|
||||
"pptx_sha256": null
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"repository": "https://github.com/anthropics/skills.git",
|
||||
"revision": "69c0b1a0674149f27b61b2635f935524b6add202",
|
||||
"skill_path": "/Users/boj/book/ai-agent-book/chapter2/agent-skills-ppt/external/anthropics-skills/skills/pptx",
|
||||
"required_file_hashes": {
|
||||
"skills/pptx/SKILL.md": "b6f25545bfb358739f1532f793458b5dbc87ee009933cb7c306b2d951ab6617f",
|
||||
"skills/pptx/html2pptx.md": "f08ed7580969b796d9cd5ade93e2cdee981dcaf13cc5eb12e8d4a3700c2d6047",
|
||||
"skills/pptx/scripts/html2pptx.js": "c675d09a54d6a002e8ca5917b9d24a6568aa8d455bb7abeb212d4f564dd07a34",
|
||||
"skills/pptx/scripts/thumbnail.py": "c21fd950b6ada7bd2f029885d3e56bc66b7ff061cc8404c492eb301664aa9e5d"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/pptx
|
||||
|
||||
Create a polished 10–15 slide presentation from the real academic paper at
|
||||
`attention-is-all-you-need.pdf`. Write the final deck to
|
||||
`output/attention-is-all-you-need.pptx`.
|
||||
|
||||
This is an audited Agent Skills experiment. Follow the official PPTX Skill by
|
||||
progressive disclosure: invoke the pptx Skill, read its complete SKILL.md, then
|
||||
read its complete html2pptx.md only after selection. Use the pinned official
|
||||
`scripts/html2pptx.js` workflow. Use the official `scripts/thumbnail.py` to
|
||||
make `output/full-deck-thumbnail.jpg`, inspect the full grid, and fix visible
|
||||
overlap, cutoff, contrast, or alignment defects before finishing.
|
||||
|
||||
Content gates:
|
||||
- cover title, problem/background, Transformer method/architecture, key
|
||||
experimental results, and conclusion;
|
||||
- extract or crop at least three visuals directly from the source PDF (not
|
||||
invented replacements), place the files under `source_visuals/`, and embed
|
||||
all of them in the deck;
|
||||
- create `source_visuals/manifest.json` as a JSON list. Each item must contain
|
||||
`file`, one-based PDF `page`, the paper's `label` (for example Figure 1 or
|
||||
Table 2), and a faithful `caption`;
|
||||
- make every visual consistent with the surrounding slide explanation and
|
||||
cite its source page/label on-slide.
|
||||
|
||||
You may install the Node packages required by the official Skill inside this
|
||||
workspace. Do not use the repository's bundled `demo.py`, local proxy Skill,
|
||||
or prewritten sample outline. The final response must name the deck,
|
||||
thumbnail, visual manifest, slide count, validation performed, and any
|
||||
remaining limitation.
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"auth_source": "environment"
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"return_code": 1
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
{"type":"system","subtype":"init","cwd":"/Users/boj/book/ai-agent-book/chapter2/agent-skills-ppt/runs/exp2-6-claude-pptx-20260730-v4/workspace","session_id":"8ab46948-d96e-4312-ad33-4c572984fe68","tools":["Task","Bash","CronCreate","CronDelete","CronList","Edit","EnterWorktree","ExitWorktree","NotebookEdit","Read","ReportFindings","ScheduleWakeup","SendMessage","Skill","TaskCreate","TaskGet","TaskList","TaskOutput","TaskStop","TaskUpdate","ToolSearch","WebFetch","WebSearch","Workflow","Write"],"mcp_servers":[],"model":"claude-sonnet-5","permissionMode":"bypassPermissions","slash_commands":["pptx","deep-research","dataviz","update-config","verify","debug","code-review","simplify","batch","fewer-permission-prompts","doctor","loop","claude-api","run","run-skill-generator","agents","clear","color","compact","config","context","effort","fast","heapdump","init","mcp","model","__remote-workflow","workflow-launch-exec","reload-skills","rename","review","security-review","usage","insights","recap","goal","team-onboarding"],"apiKeySource":"ANTHROPIC_API_KEY","claude_code_version":"2.1.218","output_style":"default","agents":["claude","Explore","general-purpose","Plan","statusline-setup"],"skills":["pptx","deep-research","dataviz","update-config","verify","debug","code-review","simplify","batch","fewer-permission-prompts","doctor","loop","claude-api","run","run-skill-generator"],"plugins":[],"capabilities":["interrupt_receipt_v1","msg_lifecycle_v1"],"analytics_disabled":true,"product_feedback_disabled":false,"uuid":"6e950b22-b7c4-4d6c-8b8b-8e446b938f81","memory_paths":{"auto":"/Users/boj/.claude/projects/-Users-boj-book-ai-agent-book/memory/"},"fast_mode_state":"off"}
|
||||
{"type":"system","subtype":"api_retry","attempt":1,"max_retries":10,"retry_delay_ms":565,"error_status":401,"error":"authentication_failed","session_id":"8ab46948-d96e-4312-ad33-4c572984fe68","uuid":"3882d3fc-b03c-4dde-87fe-e7149c9e24eb"}
|
||||
{"type":"system","subtype":"api_retry","attempt":2,"max_retries":10,"retry_delay_ms":1036,"error_status":401,"error":"authentication_failed","session_id":"8ab46948-d96e-4312-ad33-4c572984fe68","uuid":"08634263-cd94-4d42-98af-a71268b117f7"}
|
||||
{"type":"system","subtype":"api_retry","attempt":3,"max_retries":10,"retry_delay_ms":2214,"error_status":401,"error":"authentication_failed","session_id":"8ab46948-d96e-4312-ad33-4c572984fe68","uuid":"095c96a0-0012-407d-9c26-02dea507fce6"}
|
||||
{"type":"system","subtype":"api_retry","attempt":4,"max_retries":10,"retry_delay_ms":4069,"error_status":401,"error":"authentication_failed","session_id":"8ab46948-d96e-4312-ad33-4c572984fe68","uuid":"4ca5d3ea-a79a-48c2-b62b-e5276d172e32"}
|
||||
{"type":"system","subtype":"api_retry","attempt":5,"max_retries":10,"retry_delay_ms":9296,"error_status":401,"error":"authentication_failed","session_id":"8ab46948-d96e-4312-ad33-4c572984fe68","uuid":"2d2fa67a-832a-4446-a7d8-9ce05e25af33"}
|
||||
{"type":"system","subtype":"api_retry","attempt":6,"max_retries":10,"retry_delay_ms":16597,"error_status":401,"error":"authentication_failed","session_id":"8ab46948-d96e-4312-ad33-4c572984fe68","uuid":"29753ccb-3721-4f02-b1a0-9b9c350a67a4"}
|
||||
{"type":"system","subtype":"api_retry","attempt":7,"max_retries":10,"retry_delay_ms":35804,"error_status":401,"error":"authentication_failed","session_id":"8ab46948-d96e-4312-ad33-4c572984fe68","uuid":"032622d8-bdd9-408d-9f3f-faff25d6184d"}
|
||||
{"type":"system","subtype":"api_retry","attempt":8,"max_retries":10,"retry_delay_ms":32162,"error_status":401,"error":"authentication_failed","session_id":"8ab46948-d96e-4312-ad33-4c572984fe68","uuid":"1c7b69c0-bc76-4e54-b4cf-12d051b82829"}
|
||||
{"type":"system","subtype":"api_retry","attempt":9,"max_retries":10,"retry_delay_ms":38480,"error_status":401,"error":"authentication_failed","session_id":"8ab46948-d96e-4312-ad33-4c572984fe68","uuid":"b1975489-854b-46ef-8fc6-ee25f180ba14"}
|
||||
{"type":"system","subtype":"api_retry","attempt":10,"max_retries":10,"retry_delay_ms":38395,"error_status":401,"error":"authentication_failed","session_id":"8ab46948-d96e-4312-ad33-4c572984fe68","uuid":"d5de9ee1-cfa6-474c-9501-7d4f37514d14"}
|
||||
{"type":"assistant","message":{"id":"a14dc2e5-e5e8-4327-9453-80b611bb36c6","container":null,"model":"<synthetic>","role":"assistant","stop_details":null,"stop_reason":"stop_sequence","stop_sequence":"","type":"message","usage":{"input_tokens":0,"output_tokens":0,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"server_tool_use":{"web_search_requests":0,"web_fetch_requests":0},"service_tier":null,"cache_creation":{"ephemeral_1h_input_tokens":0,"ephemeral_5m_input_tokens":0},"inference_geo":null,"iterations":null,"speed":null},"content":[{"type":"text","text":"Failed to authenticate. API Error: 401 API key is invalid."}],"context_management":null},"parent_tool_use_id":null,"session_id":"8ab46948-d96e-4312-ad33-4c572984fe68","uuid":"1360d6a4-bd75-4190-a726-4267bd86c782","timestamp":"2026-07-30T04:13:19.758Z","error":"authentication_failed"}
|
||||
{"is_error":true,"duration_api_ms":0,"num_turns":1,"stop_reason":"stop_sequence","session_id":"8ab46948-d96e-4312-ad33-4c572984fe68","total_cost_usd":0,"usage":{"input_tokens":0,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":0,"server_tool_use":{"web_search_requests":0,"web_fetch_requests":0},"service_tier":"standard","cache_creation":{"ephemeral_1h_input_tokens":0,"ephemeral_5m_input_tokens":0},"inference_geo":"","iterations":[],"speed":"standard"},"modelUsage":{},"permission_denials":[],"terminal_reason":"api_error","fast_mode_state":"off","subtype":"success","api_error_status":401,"result":"Failed to authenticate. API Error: 401 API key is invalid.","type":"result","duration_ms":186850,"uuid":"f27534f9-e2af-4e21-a4da-95ede789ca38"}
|
||||
@@ -0,0 +1,18 @@
|
||||
[
|
||||
"claude",
|
||||
"/pptx\n\nCreate a polished 10\u201315 slide presentation from the real academic paper at\n`attention-is-all-you-need.pdf`. Write the final deck to\n`output/attention-is-all-you-need.pptx`.\n\nThis is an audited Agent Skills experiment. Follow the official PPTX Skill by\nprogressive disclosure: invoke the pptx Skill, read its complete SKILL.md, then\nread its complete html2pptx.md only after selection. Use the pinned official\n`scripts/html2pptx.js` workflow. Use the official `scripts/thumbnail.py` to\nmake `output/full-deck-thumbnail.jpg`, inspect the full grid, and fix visible\noverlap, cutoff, contrast, or alignment defects before finishing.\n\nContent gates:\n- cover title, problem/background, Transformer method/architecture, key\n experimental results, and conclusion;\n- extract or crop at least three visuals directly from the source PDF (not\n invented replacements), place the files under `source_visuals/`, and embed\n all of them in the deck;\n- create `source_visuals/manifest.json` as a JSON list. Each item must contain\n `file`, one-based PDF `page`, the paper's `label` (for example Figure 1 or\n Table 2), and a faithful `caption`;\n- make every visual consistent with the surrounding slide explanation and\n cite its source page/label on-slide.\n\nYou may install the Node packages required by the official Skill inside this\nworkspace. Do not use the repository's bundled `demo.py`, local proxy Skill,\nor prewritten sample outline. The final response must name the deck,\nthumbnail, visual manifest, slide count, validation performed, and any\nremaining limitation.\n",
|
||||
"--print",
|
||||
"--output-format",
|
||||
"stream-json",
|
||||
"--verbose",
|
||||
"--model",
|
||||
"sonnet",
|
||||
"--effort",
|
||||
"high",
|
||||
"--max-budget-usd",
|
||||
"8",
|
||||
"--no-session-persistence",
|
||||
"--dangerously-skip-permissions",
|
||||
"--add-dir",
|
||||
"/Users/boj/book/ai-agent-book/chapter2/agent-skills-ppt/external/anthropics-skills/skills/pptx"
|
||||
]
|
||||
@@ -0,0 +1,87 @@
|
||||
{
|
||||
"experiment_id": "2-6",
|
||||
"protocol_sha256": "2990c8ef624edc12a06fb1b622de33b0fe8842cc5b42faf85788850111265eba",
|
||||
"official_skill_receipt": {
|
||||
"repository": "https://github.com/anthropics/skills.git",
|
||||
"revision": "69c0b1a0674149f27b61b2635f935524b6add202",
|
||||
"skill_path": "/Users/boj/book/ai-agent-book/chapter2/agent-skills-ppt/external/anthropics-skills/skills/pptx",
|
||||
"required_file_hashes": {
|
||||
"skills/pptx/SKILL.md": "b6f25545bfb358739f1532f793458b5dbc87ee009933cb7c306b2d951ab6617f",
|
||||
"skills/pptx/html2pptx.md": "f08ed7580969b796d9cd5ade93e2cdee981dcaf13cc5eb12e8d4a3700c2d6047",
|
||||
"skills/pptx/scripts/html2pptx.js": "c675d09a54d6a002e8ca5917b9d24a6568aa8d455bb7abeb212d4f564dd07a34",
|
||||
"skills/pptx/scripts/thumbnail.py": "c21fd950b6ada7bd2f029885d3e56bc66b7ff061cc8404c492eb301664aa9e5d"
|
||||
}
|
||||
},
|
||||
"claude_result": {
|
||||
"subtype": "success",
|
||||
"is_error": true,
|
||||
"duration_ms": 186850,
|
||||
"duration_api_ms": 0,
|
||||
"num_turns": 1,
|
||||
"result": "Failed to authenticate. API Error: 401 API key is invalid.",
|
||||
"total_cost_usd": 0,
|
||||
"usage": {
|
||||
"input_tokens": 0,
|
||||
"cache_creation_input_tokens": 0,
|
||||
"cache_read_input_tokens": 0,
|
||||
"output_tokens": 0,
|
||||
"server_tool_use": {
|
||||
"web_search_requests": 0,
|
||||
"web_fetch_requests": 0
|
||||
},
|
||||
"service_tier": "standard",
|
||||
"cache_creation": {
|
||||
"ephemeral_1h_input_tokens": 0,
|
||||
"ephemeral_5m_input_tokens": 0
|
||||
},
|
||||
"inference_geo": "",
|
||||
"iterations": [],
|
||||
"speed": "standard"
|
||||
},
|
||||
"modelUsage": {},
|
||||
"session_id": "8ab46948-d96e-4312-ad33-4c572984fe68"
|
||||
},
|
||||
"slide_count": 0,
|
||||
"section_checks": {
|
||||
"title": false,
|
||||
"background": false,
|
||||
"method": false,
|
||||
"results": false,
|
||||
"conclusion": false
|
||||
},
|
||||
"source_visuals": [],
|
||||
"embedded_media": {},
|
||||
"thumbnail_files": [],
|
||||
"gates": {
|
||||
"source_pdf_hash_matches": true,
|
||||
"claude_run_succeeded": false,
|
||||
"pptx_skill_invoked": false,
|
||||
"skill_md_loaded": false,
|
||||
"html2pptx_guide_loaded": false,
|
||||
"official_html2pptx_used": false,
|
||||
"official_thumbnail_used": false,
|
||||
"thumbnail_visually_inspected": false,
|
||||
"pptx_zip_valid": false,
|
||||
"pptx_reopens": false,
|
||||
"slide_count_in_range": false,
|
||||
"required_sections_present": false,
|
||||
"three_source_visuals_embedded_and_documented": false,
|
||||
"thumbnail_grid_present": false,
|
||||
"credential_scan_passed": true
|
||||
},
|
||||
"official_complete": false,
|
||||
"artifacts": {
|
||||
"experiment_protocol.json": {
|
||||
"sha256": "2990c8ef624edc12a06fb1b622de33b0fe8842cc5b42faf85788850111265eba",
|
||||
"bytes": 2582
|
||||
},
|
||||
"claude_stream.jsonl": {
|
||||
"sha256": "531ee0e7a5ffcdbd4060108ed809e8576b13604f29a3cc3fbd259afac3cf9afb",
|
||||
"bytes": 5725
|
||||
},
|
||||
"workspace/attention-is-all-you-need.pdf": {
|
||||
"sha256": "bdfaa68d8984f0dc02beaca527b76f207d99b666d31d1da728ee0728182df697",
|
||||
"bytes": 2215244
|
||||
}
|
||||
}
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"experiment_id": "2-6",
|
||||
"protocol_version": "1.0.0",
|
||||
"frozen_on": "2026-07-30",
|
||||
"authority": "book/chapter2.md:767",
|
||||
"runtime": {
|
||||
"agent": "Claude Code",
|
||||
"model_alias": "sonnet",
|
||||
"official_skill_repository": "https://github.com/anthropics/skills.git",
|
||||
"official_skill_revision": "69c0b1a0674149f27b61b2635f935524b6add202",
|
||||
"skill_path": "skills/pptx",
|
||||
"revision_reason": "This is the official revision whose PPTX Skill contains the html2pptx.md workflow named by the manuscript; later revision 4e6907a packages that guide as html2pptx.tgz."
|
||||
},
|
||||
"paper": {
|
||||
"title": "Attention Is All You Need",
|
||||
"authors": "Ashish Vaswani et al.",
|
||||
"arxiv_id": "1706.03762",
|
||||
"pdf_url": "https://arxiv.org/pdf/1706.03762",
|
||||
"pdf_sha256": "bdfaa68d8984f0dc02beaca527b76f207d99b666d31d1da728ee0728182df697"
|
||||
},
|
||||
"output": {
|
||||
"minimum_slides": 10,
|
||||
"maximum_slides": 15,
|
||||
"required_sections": [
|
||||
"title",
|
||||
"problem/background",
|
||||
"method/Transformer architecture",
|
||||
"key results",
|
||||
"conclusion"
|
||||
],
|
||||
"minimum_paper_visuals": 3,
|
||||
"visual_policy": "At least three images must be extracted or cropped from the source PDF, embedded in the deck, and listed with PDF page and source label in source_visuals/manifest.json."
|
||||
},
|
||||
"progressive_disclosure_gates": [
|
||||
"Claude Code discovers only PPTX Skill metadata before selection",
|
||||
"Claude invokes the official pptx Skill and loads its complete SKILL.md",
|
||||
"Claude reads the complete official html2pptx.md only after selecting the Skill",
|
||||
"Claude uses the official scripts/html2pptx.js workflow",
|
||||
"Claude invokes the official scripts/thumbnail.py preview workflow and visually inspects the result"
|
||||
],
|
||||
"artifact_gates": [
|
||||
"the source PDF hash matches the preregistered academic paper",
|
||||
"the presentation is a valid ZIP/OOXML package and python-pptx reopens it",
|
||||
"slide count is between 10 and 15 inclusive",
|
||||
"the five required content sections are present",
|
||||
"three or more source visual files are byte-identical to media embedded in the PPTX",
|
||||
"each source visual has a PDF page, paper label, and caption in the visual manifest",
|
||||
"a full-deck thumbnail grid exists",
|
||||
"raw Claude Code stream events, actual model, usage/cost, commands, hashes, and credential scan are retained"
|
||||
],
|
||||
"claim_policy": "The bundled Python demo is a noncanonical mechanism illustration and cannot satisfy Experiment 2-6. Only a real Claude Code run with the pinned official Skill and real paper can complete this protocol."
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"experiment_id": "2-6",
|
||||
"official_complete": false,
|
||||
"protocol_sha256": "2990c8ef624edc12a06fb1b622de33b0fe8842cc5b42faf85788850111265eba",
|
||||
"comparison_sha256": "4779c6ed74afbe704287db61f707043ca4aa2de274cb3b74364733f4a79d3a48",
|
||||
"pptx_sha256": null
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"repository": "https://github.com/anthropics/skills.git",
|
||||
"revision": "69c0b1a0674149f27b61b2635f935524b6add202",
|
||||
"skill_path": "/Users/boj/book/ai-agent-book/chapter2/agent-skills-ppt/external/anthropics-skills/skills/pptx",
|
||||
"required_file_hashes": {
|
||||
"skills/pptx/SKILL.md": "b6f25545bfb358739f1532f793458b5dbc87ee009933cb7c306b2d951ab6617f",
|
||||
"skills/pptx/html2pptx.md": "f08ed7580969b796d9cd5ade93e2cdee981dcaf13cc5eb12e8d4a3700c2d6047",
|
||||
"skills/pptx/scripts/html2pptx.js": "c675d09a54d6a002e8ca5917b9d24a6568aa8d455bb7abeb212d4f564dd07a34",
|
||||
"skills/pptx/scripts/thumbnail.py": "c21fd950b6ada7bd2f029885d3e56bc66b7ff061cc8404c492eb301664aa9e5d"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/pptx
|
||||
|
||||
Create a polished 10–15 slide presentation from the real academic paper at
|
||||
`attention-is-all-you-need.pdf`. Write the final deck to
|
||||
`output/attention-is-all-you-need.pptx`.
|
||||
|
||||
This is an audited Agent Skills experiment. Follow the official PPTX Skill by
|
||||
progressive disclosure: invoke the pptx Skill, read its complete SKILL.md, then
|
||||
read its complete html2pptx.md only after selection. Use the pinned official
|
||||
`scripts/html2pptx.js` workflow. Use the official `scripts/thumbnail.py` to
|
||||
make `output/full-deck-thumbnail.jpg`, inspect the full grid, and fix visible
|
||||
overlap, cutoff, contrast, or alignment defects before finishing.
|
||||
|
||||
Content gates:
|
||||
- cover title, problem/background, Transformer method/architecture, key
|
||||
experimental results, and conclusion;
|
||||
- extract or crop at least three visuals directly from the source PDF (not
|
||||
invented replacements), place the files under `source_visuals/`, and embed
|
||||
all of them in the deck;
|
||||
- create `source_visuals/manifest.json` as a JSON list. Each item must contain
|
||||
`file`, one-based PDF `page`, the paper's `label` (for example Figure 1 or
|
||||
Table 2), and a faithful `caption`;
|
||||
- make every visual consistent with the surrounding slide explanation and
|
||||
cite its source page/label on-slide.
|
||||
|
||||
You may install the Node packages required by the official Skill inside this
|
||||
workspace. Do not use the repository's bundled `demo.py`, local proxy Skill,
|
||||
or prewritten sample outline. The final response must name the deck,
|
||||
thumbnail, visual manifest, slide count, validation performed, and any
|
||||
remaining limitation.
|
||||
@@ -0,0 +1,13 @@
|
||||
[
|
||||
"/Users/boj/.kimi-code/bin/kimi",
|
||||
"--prompt",
|
||||
"Create a polished 10\u201315 slide presentation from the real academic paper at\n`attention-is-all-you-need.pdf` using your installed `pptx` Skill. Write the\nfinal deck to `output/attention-is-all-you-need.pptx`.\n\nThis is an audited Agent Skills experiment. Follow the official PPTX Skill by\nprogressive disclosure: invoke the pptx Skill through the Skill tool (this\nloads its complete SKILL.md), then read its complete html2pptx.md only after\nselection. Use the pinned official `scripts/html2pptx.js` workflow. Use the\nofficial `scripts/thumbnail.py` to make `output/full-deck-thumbnail.jpg`,\ninspect the full grid, and fix visible overlap, cutoff, contrast, or alignment\ndefects before finishing.\n\nContent gates:\n- cover title, problem/background, Transformer method/architecture, key\n experimental results, and conclusion;\n- extract or crop at least three visuals directly from the source PDF (not\n invented replacements), place the files under `source_visuals/`, and embed\n all of them in the deck;\n- create `source_visuals/manifest.json` as a JSON list. Each item must contain\n `file`, one-based PDF `page`, the paper's `label` (for example Figure 1 or\n Table 2), and a faithful `caption`;\n- make every visual consistent with the surrounding slide explanation and\n cite its source page/label on-slide.\n\nYou may install the Node packages required by the official Skill inside this\nworkspace. Do not use the repository's bundled `demo.py`, local proxy Skill,\nor prewritten sample outline. The final response must name the deck,\nthumbnail, visual manifest, slide count, validation performed, and any\nremaining limitation.\n",
|
||||
"--output-format",
|
||||
"stream-json",
|
||||
"--model",
|
||||
"kimi-code/k3",
|
||||
"--skills-dir",
|
||||
"/Users/boj/book/ai-agent-book-exp2-6-mp/chapter2/agent-skills-ppt/runs/exp2-6-kimi-pptx-20260731-v1/workspace/kimi-skills",
|
||||
"--add-dir",
|
||||
"/Users/boj/book/ai-agent-book-exp2-6-mp/chapter2/agent-skills-ppt/external/anthropics-skills/skills/pptx"
|
||||
]
|
||||
@@ -0,0 +1,132 @@
|
||||
{
|
||||
"experiment_id": "2-6",
|
||||
"runtime": "kimi",
|
||||
"protocol_sha256": "1316b6c5bca03b76b7fda2c1fc31b9076394bf996cacb4f52add2db98dbae84e",
|
||||
"official_skill_receipt": {
|
||||
"repository": "https://github.com/anthropics/skills.git",
|
||||
"revision": "69c0b1a0674149f27b61b2635f935524b6add202",
|
||||
"skill_path": "/Users/boj/book/ai-agent-book-exp2-6-mp/chapter2/agent-skills-ppt/external/anthropics-skills/skills/pptx",
|
||||
"required_file_hashes": {
|
||||
"skills/pptx/SKILL.md": "b6f25545bfb358739f1532f793458b5dbc87ee009933cb7c306b2d951ab6617f",
|
||||
"skills/pptx/html2pptx.md": "f08ed7580969b796d9cd5ade93e2cdee981dcaf13cc5eb12e8d4a3700c2d6047",
|
||||
"skills/pptx/scripts/html2pptx.js": "c675d09a54d6a002e8ca5917b9d24a6568aa8d455bb7abeb212d4f564dd07a34",
|
||||
"skills/pptx/scripts/thumbnail.py": "c21fd950b6ada7bd2f029885d3e56bc66b7ff061cc8404c492eb301664aa9e5d"
|
||||
}
|
||||
},
|
||||
"agent_result": {
|
||||
"return_code": 0,
|
||||
"model_alias": "kimi-code/k3",
|
||||
"num_assistant_messages": 25,
|
||||
"num_tool_calls": 114,
|
||||
"tool_names": [
|
||||
"Bash",
|
||||
"Edit",
|
||||
"Grep",
|
||||
"Read",
|
||||
"ReadMediaFile",
|
||||
"Skill",
|
||||
"TodoList",
|
||||
"Write"
|
||||
],
|
||||
"session_id": "session_605154fa-66bf-4bb2-89f4-86a48d3dcd8f",
|
||||
"final_response": "Done. The presentation was built with the official PPTX Skill workflow (SKILL.md → html2pptx.md → pinned `scripts/html2pptx.js` → `scripts/thumbnail.py` visual check).\n\n**Deliverables**\n- Deck: `output/attention-is-all-you-need.pptx` — 13 slides, 16:9\n- Thumbnail grid: `output/full-deck-thumbnail.jpg` (official `thumbnail.py`, 4 cols)\n- Visual manifest: `source_visuals/manifest.json` — 4 entries with `file`, one-based PDF `page`, `label`, faithful `caption`\n- Cropped-from-PDF visuals (all embedded in the deck, each cited on-slide with label + page):\n - `fig1-03.png` — Figure 1, p. 3 (architecture) → cover + slide 4\n - `fig2-04.png` — Figure 2, p. 4 (scaled dot-product / multi-head attention) → slide 5\n - `table2-08.png` — Table 2, p. 8 (BLEU results) → slide 9\n - `fig3-13.png` — Figure 3, p. 13 (attention visualization) → slide 12\n\n**Content coverage** — cover title/authors/venue (1), problem/background (2), key idea (3), Transformer method/architecture (4–6), why self-attention with Table 1 adapted as a native table (7), training setup (8), key experimental results incl. Table 2 image and a BLEU bar chart (9–10), generalization to constituency parsing (11), interpretability (12), conclusion (13).\n\n**Validation performed**\n- `html2pptx.js` dimension/overflow validation passed for every HTML slide\n- Full-deck thumbnail grid inspected; every slide also re-rendered at 120–220 DPI via LibreOffice/pdftoppm and individually inspected\n- Defects found and fixed: dropped `<sub>` subscript content (rewritten as `d_k`/`d_model` style), inconsistent bullet glyphs (root-caused to duplicate mid-paragraph `<a:pPr>` emitted by pptxgenjs; 75 removed via OOXML post-processing), a broken chart relationship path (normalized to relative), and rounded chart data labels (set to exact `0.00` format)\n- `ooxml/scripts/validate.py` passes on the final packed file; manifest JSON parses and matches the cropped files\n\n**Remaining limitations**\n- Slides were visually verified through LibreOffice rendering, not Microsoft PowerPoint itself; minor font-metric differences are possible there\n- The complexity table on slide 7 is a faithful adaptation of Table 1 (native table, cited as \"Adapted from Table 1, p. 6\") rather than a PDF crop — the four required direct crops are Figures 1, 2, 3 and Table 2"
|
||||
},
|
||||
"slide_count": 13,
|
||||
"section_checks": {
|
||||
"title": true,
|
||||
"background": true,
|
||||
"method": true,
|
||||
"results": true,
|
||||
"conclusion": true
|
||||
},
|
||||
"source_visuals": [
|
||||
{
|
||||
"file": "fig1-03.png",
|
||||
"sha256": "eac33d539b220d8f092233f0ae589302365890b85444a1fdbfb88597e1eebdce",
|
||||
"embedded": true,
|
||||
"page": 3,
|
||||
"label": "Figure 1",
|
||||
"caption": "The Transformer - model architecture."
|
||||
},
|
||||
{
|
||||
"file": "fig2-04.png",
|
||||
"sha256": "66eb2559c7e7483a15a1f13b95babec32b4529b216664a150d974213ac5a8edc",
|
||||
"embedded": true,
|
||||
"page": 4,
|
||||
"label": "Figure 2",
|
||||
"caption": "(left) Scaled Dot-Product Attention. (right) Multi-Head Attention consists of several attention layers running in parallel."
|
||||
},
|
||||
{
|
||||
"file": "table2-08.png",
|
||||
"sha256": "8b2ead56595513b994224b6f1be49d6751fa8633b706638092670478b7ddb3c1",
|
||||
"embedded": true,
|
||||
"page": 8,
|
||||
"label": "Table 2",
|
||||
"caption": "The Transformer achieves better BLEU scores than previous state-of-the-art models on the English-to-German and English-to-French newstest2014 tests at a fraction of the training cost."
|
||||
},
|
||||
{
|
||||
"file": "fig3-13.png",
|
||||
"sha256": "47e9df791c547feee32f1f88649a70a256ce4552e55fb4ff258a40fd5998ccd6",
|
||||
"embedded": true,
|
||||
"page": 13,
|
||||
"label": "Figure 3",
|
||||
"caption": "An example of the attention mechanism following long-distance dependencies in the encoder self-attention in layer 5 of 6. Many of the attention heads attend to a distant dependency of the verb 'making', completing the phrase 'making...more difficult'. Attentions here shown only for the word 'making'. Different colors represent different heads. Best viewed in color."
|
||||
}
|
||||
],
|
||||
"embedded_media": {
|
||||
"ppt/media/image-4-1.png": "eac33d539b220d8f092233f0ae589302365890b85444a1fdbfb88597e1eebdce",
|
||||
"ppt/media/image-1-2.png": "eac33d539b220d8f092233f0ae589302365890b85444a1fdbfb88597e1eebdce",
|
||||
"ppt/media/image-5-1.png": "66eb2559c7e7483a15a1f13b95babec32b4529b216664a150d974213ac5a8edc",
|
||||
"ppt/media/image-12-1.png": "47e9df791c547feee32f1f88649a70a256ce4552e55fb4ff258a40fd5998ccd6",
|
||||
"ppt/media/image-9-1.png": "8b2ead56595513b994224b6f1be49d6751fa8633b706638092670478b7ddb3c1",
|
||||
"ppt/media/Slide-13-image-1.png": "629d702b5ca51d6380ada24547bd77941b262b3434e394996946cb7b0bfc8398",
|
||||
"ppt/media/Slide-1-image-1.png": "629d702b5ca51d6380ada24547bd77941b262b3434e394996946cb7b0bfc8398"
|
||||
},
|
||||
"thumbnail_files": [
|
||||
"workspace/output/full-deck-thumbnail.jpg"
|
||||
],
|
||||
"gates": {
|
||||
"source_pdf_hash_matches": true,
|
||||
"kimi_run_succeeded": true,
|
||||
"pptx_skill_invoked": true,
|
||||
"skill_md_loaded": true,
|
||||
"html2pptx_guide_loaded": true,
|
||||
"official_html2pptx_used": true,
|
||||
"official_thumbnail_used": true,
|
||||
"thumbnail_visually_inspected": true,
|
||||
"pptx_zip_valid": true,
|
||||
"pptx_reopens": true,
|
||||
"slide_count_in_range": true,
|
||||
"required_sections_present": true,
|
||||
"three_source_visuals_embedded_and_documented": true,
|
||||
"thumbnail_grid_present": true,
|
||||
"credential_scan_passed": true
|
||||
},
|
||||
"official_complete": true,
|
||||
"artifacts": {
|
||||
"experiment_protocol.json": {
|
||||
"sha256": "1316b6c5bca03b76b7fda2c1fc31b9076394bf996cacb4f52add2db98dbae84e",
|
||||
"bytes": 3709
|
||||
},
|
||||
"kimi_stream.jsonl": {
|
||||
"sha256": "00eaaa3a884c35a203ffbacd65d146b44abf4a5f3a28e9e979a2f83e701541a1",
|
||||
"bytes": 5595585
|
||||
},
|
||||
"workspace/attention-is-all-you-need.pdf": {
|
||||
"sha256": "bdfaa68d8984f0dc02beaca527b76f207d99b666d31d1da728ee0728182df697",
|
||||
"bytes": 2215244
|
||||
},
|
||||
"workspace/output/attention-is-all-you-need.pptx": {
|
||||
"sha256": "be890e73d6b4bf91d888079ffb4cd7f63435bfcadd7046b580d64627907de41d",
|
||||
"bytes": 605203
|
||||
},
|
||||
"workspace/source_visuals/manifest.json": {
|
||||
"sha256": "be3b44999ae79695ac42f3fb7a538fdfc6ce84a53f6173d1547df1f201a0c350",
|
||||
"bytes": 1091
|
||||
},
|
||||
"workspace/output/full-deck-thumbnail.jpg": {
|
||||
"sha256": "7f7eae7496b8748d3bc1f179b8e3542f5fc05c9e13dac46f4125bf0d782aeabf",
|
||||
"bytes": 255718
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
{
|
||||
"experiment_id": "2-6",
|
||||
"protocol_version": "1.1.0",
|
||||
"frozen_on": "2026-07-30",
|
||||
"revised_on": "2026-07-31",
|
||||
"authority": "book/chapter2.md:767",
|
||||
"runtime": {
|
||||
"agent": "Claude Code",
|
||||
"model_alias": "sonnet",
|
||||
"acceptance_policy": "Runtime-agnostic (author policy, 2026-07-31): acceptance is NOT gated on Anthropic/Claude Code. Any agent runtime + model that supports SKILL.md-style progressive disclosure may complete this experiment, because not every reader has an Anthropic key. The pinned official Anthropic PPTX Skill content, the real paper, and all artifact gates are unchanged; Claude Code remains the reference path for readers who have Anthropic credentials.",
|
||||
"alternate_runtimes": {
|
||||
"kimi": {
|
||||
"agent": "Kimi Code CLI",
|
||||
"binary": "kimi",
|
||||
"binary_fallback": "~/.kimi-code/bin/kimi",
|
||||
"model_alias": "kimi-code/k3",
|
||||
"auth_environment_variables": ["KIMI_API_KEY", "MOONSHOT_API_KEY"],
|
||||
"skills_flag": "--skills-dir",
|
||||
"stream_format": "stream-json"
|
||||
}
|
||||
},
|
||||
"official_skill_repository": "https://github.com/anthropics/skills.git",
|
||||
"official_skill_revision": "69c0b1a0674149f27b61b2635f935524b6add202",
|
||||
"skill_path": "skills/pptx",
|
||||
"revision_reason": "This is the official revision whose PPTX Skill contains the html2pptx.md workflow named by the manuscript; later revision 4e6907a packages that guide as html2pptx.tgz."
|
||||
},
|
||||
"paper": {
|
||||
"title": "Attention Is All You Need",
|
||||
"authors": "Ashish Vaswani et al.",
|
||||
"arxiv_id": "1706.03762",
|
||||
"pdf_url": "https://arxiv.org/pdf/1706.03762",
|
||||
"pdf_sha256": "bdfaa68d8984f0dc02beaca527b76f207d99b666d31d1da728ee0728182df697"
|
||||
},
|
||||
"output": {
|
||||
"minimum_slides": 10,
|
||||
"maximum_slides": 15,
|
||||
"required_sections": [
|
||||
"title",
|
||||
"problem/background",
|
||||
"method/Transformer architecture",
|
||||
"key results",
|
||||
"conclusion"
|
||||
],
|
||||
"minimum_paper_visuals": 3,
|
||||
"visual_policy": "At least three images must be extracted or cropped from the source PDF, embedded in the deck, and listed with PDF page and source label in source_visuals/manifest.json."
|
||||
},
|
||||
"progressive_disclosure_gates": [
|
||||
"the agent runtime discovers only PPTX Skill metadata before selection",
|
||||
"the agent invokes the official pptx Skill and loads its complete SKILL.md",
|
||||
"the agent reads the complete official html2pptx.md only after selecting the Skill",
|
||||
"the agent uses the official scripts/html2pptx.js workflow",
|
||||
"the agent invokes the official scripts/thumbnail.py preview workflow and visually inspects the result"
|
||||
],
|
||||
"artifact_gates": [
|
||||
"the source PDF hash matches the preregistered academic paper",
|
||||
"the presentation is a valid ZIP/OOXML package and python-pptx reopens it",
|
||||
"slide count is between 10 and 15 inclusive",
|
||||
"the five required content sections are present",
|
||||
"three or more source visual files are byte-identical to media embedded in the PPTX",
|
||||
"each source visual has a PDF page, paper label, and caption in the visual manifest",
|
||||
"a full-deck thumbnail grid exists",
|
||||
"raw agent-runtime stream events, actual model, usage/cost where the runtime reports it, commands, hashes, and credential scan are retained"
|
||||
],
|
||||
"claim_policy": "The bundled Python demo is a noncanonical mechanism illustration and cannot satisfy Experiment 2-6. Only a real agent-runtime run with the pinned official Skill and real paper can complete this protocol. The runtime may be Claude Code or an equivalent skills-capable runtime (for example Kimi Code CLI); the pinned official Anthropic PPTX Skill content and every artifact gate below apply identically to either runtime."
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"return_code": 0
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"experiment_id": "2-6",
|
||||
"runtime": "kimi",
|
||||
"official_complete": true,
|
||||
"protocol_sha256": "1316b6c5bca03b76b7fda2c1fc31b9076394bf996cacb4f52add2db98dbae84e",
|
||||
"comparison_sha256": "52f7e327fcf71f2038f0449c70f19f9e7753406511c6bd93660e33a2967bb098",
|
||||
"pptx_sha256": "be890e73d6b4bf91d888079ffb4cd7f63435bfcadd7046b580d64627907de41d"
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"repository": "https://github.com/anthropics/skills.git",
|
||||
"revision": "69c0b1a0674149f27b61b2635f935524b6add202",
|
||||
"skill_path": "/Users/boj/book/ai-agent-book-exp2-6-mp/chapter2/agent-skills-ppt/external/anthropics-skills/skills/pptx",
|
||||
"required_file_hashes": {
|
||||
"skills/pptx/SKILL.md": "b6f25545bfb358739f1532f793458b5dbc87ee009933cb7c306b2d951ab6617f",
|
||||
"skills/pptx/html2pptx.md": "f08ed7580969b796d9cd5ade93e2cdee981dcaf13cc5eb12e8d4a3700c2d6047",
|
||||
"skills/pptx/scripts/html2pptx.js": "c675d09a54d6a002e8ca5917b9d24a6568aa8d455bb7abeb212d4f564dd07a34",
|
||||
"skills/pptx/scripts/thumbnail.py": "c21fd950b6ada7bd2f029885d3e56bc66b7ff061cc8404c492eb301664aa9e5d"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
Create a polished 10–15 slide presentation from the real academic paper at
|
||||
`attention-is-all-you-need.pdf` using your installed `pptx` Skill. Write the
|
||||
final deck to `output/attention-is-all-you-need.pptx`.
|
||||
|
||||
This is an audited Agent Skills experiment. Follow the official PPTX Skill by
|
||||
progressive disclosure: invoke the pptx Skill through the Skill tool (this
|
||||
loads its complete SKILL.md), then read its complete html2pptx.md only after
|
||||
selection. Use the pinned official `scripts/html2pptx.js` workflow. Use the
|
||||
official `scripts/thumbnail.py` to make `output/full-deck-thumbnail.jpg`,
|
||||
inspect the full grid, and fix visible overlap, cutoff, contrast, or alignment
|
||||
defects before finishing.
|
||||
|
||||
Content gates:
|
||||
- cover title, problem/background, Transformer method/architecture, key
|
||||
experimental results, and conclusion;
|
||||
- extract or crop at least three visuals directly from the source PDF (not
|
||||
invented replacements), place the files under `source_visuals/`, and embed
|
||||
all of them in the deck;
|
||||
- create `source_visuals/manifest.json` as a JSON list. Each item must contain
|
||||
`file`, one-based PDF `page`, the paper's `label` (for example Figure 1 or
|
||||
Table 2), and a faithful `caption`;
|
||||
- make every visual consistent with the surrounding slide explanation and
|
||||
cite its source page/label on-slide.
|
||||
|
||||
You may install the Node packages required by the official Skill inside this
|
||||
workspace. Do not use the repository's bundled `demo.py`, local proxy Skill,
|
||||
or prewritten sample outline. The final response must name the deck,
|
||||
thumbnail, visual manifest, slide count, validation performed, and any
|
||||
remaining limitation.
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"runtime": "kimi",
|
||||
"binary": "/Users/boj/.kimi-code/bin/kimi",
|
||||
"model_alias": "kimi-code/k3",
|
||||
"skills_dir": "/Users/boj/book/ai-agent-book-exp2-6-mp/chapter2/agent-skills-ppt/runs/exp2-6-kimi-pptx-20260731-v1/workspace/kimi-skills",
|
||||
"auth_environment_variables_present": [
|
||||
"KIMI_API_KEY",
|
||||
"MOONSHOT_API_KEY"
|
||||
]
|
||||
}
|
||||
BIN
Binary file not shown.
|
After Width: | Height: | Size: 120 KiB |
@@ -0,0 +1,85 @@
|
||||
const pptxgen = require('pptxgenjs');
|
||||
const html2pptx = require('./kimi-skills/pptx/scripts/html2pptx.js');
|
||||
|
||||
async function build() {
|
||||
const pptx = new pptxgen();
|
||||
pptx.layout = 'LAYOUT_16x9';
|
||||
pptx.author = 'Kimi';
|
||||
pptx.title = 'Attention Is All You Need';
|
||||
|
||||
// Slides 1-6
|
||||
await html2pptx('slides/01-cover.html', pptx);
|
||||
await html2pptx('slides/02-problem.html', pptx);
|
||||
await html2pptx('slides/03-keyidea.html', pptx);
|
||||
await html2pptx('slides/04-architecture.html', pptx);
|
||||
await html2pptx('slides/05-attention.html', pptx);
|
||||
await html2pptx('slides/06-building-blocks.html', pptx);
|
||||
|
||||
// Slide 7: complexity table (adapted from Table 1, p. 6)
|
||||
const { slide: s7, placeholders: p7 } = await html2pptx('slides/07-why-self-attention.html', pptx);
|
||||
const hdr = { fill: { color: '4338CA' }, color: 'FFFFFF', bold: true, fontSize: 10 };
|
||||
const rows = [
|
||||
[
|
||||
{ text: 'Layer Type', options: hdr }, { text: 'Complexity per Layer', options: hdr },
|
||||
{ text: 'Sequential Ops', options: hdr }, { text: 'Max Path Length', options: hdr }
|
||||
],
|
||||
['Self-Attention', 'O(n²·d)', 'O(1)', 'O(1)'],
|
||||
['Recurrent', 'O(n·d²)', 'O(n)', 'O(n)'],
|
||||
['Convolutional', 'O(k·n·d²)', 'O(1)', 'O(log_k n)'],
|
||||
['Self-Attention (restricted)', 'O(r·n·d)', 'O(1)', 'O(n/r)']
|
||||
];
|
||||
s7.addTable(rows, {
|
||||
...p7[0],
|
||||
colW: [1.55, 1.15, 1.0, 1.1],
|
||||
fontSize: 9.5,
|
||||
fontFace: 'Arial',
|
||||
border: { pt: 0.75, color: 'C9C6E8' },
|
||||
align: 'center',
|
||||
valign: 'middle',
|
||||
fill: { color: 'FFFFFF' }
|
||||
});
|
||||
|
||||
// Slides 8-9
|
||||
await html2pptx('slides/08-training.html', pptx);
|
||||
await html2pptx('slides/09-results.html', pptx);
|
||||
|
||||
// Slide 10: EN-DE BLEU bar chart (values from Table 2, p. 8)
|
||||
const { slide: s10, placeholders: p10 } = await html2pptx('slides/10-chart.html', pptx);
|
||||
s10.addChart(pptx.charts.BAR, [{
|
||||
name: 'BLEU',
|
||||
labels: ['ByteNet', 'GNMT+RL', 'ConvS2S', 'MoE', 'ConvS2S Ens.', 'TF (base)', 'TF (big)'],
|
||||
values: [23.75, 24.6, 25.16, 26.03, 26.36, 27.3, 28.4]
|
||||
}], {
|
||||
...p10[0],
|
||||
barDir: 'col',
|
||||
showLegend: false,
|
||||
showValue: true,
|
||||
dataLabelPosition: 'outEnd',
|
||||
dataLabelFontSize: 9,
|
||||
dataLabelColor: '1A1633',
|
||||
dataLabelFormatCode: '0.00',
|
||||
showCatAxisTitle: false,
|
||||
catAxisLabelFontSize: 9,
|
||||
valAxisMinVal: 20,
|
||||
valAxisMaxVal: 30,
|
||||
valAxisMajorUnit: 2,
|
||||
showValAxisTitle: true,
|
||||
valAxisTitle: 'BLEU (newstest2014)',
|
||||
valAxisLabelFontSize: 8,
|
||||
valAxisTitleFontSize: 9,
|
||||
chartColors: ['9B97B8', '9B97B8', '9B97B8', '9B97B8', '7C3AED', '4338CA', 'F59E0B'],
|
||||
valAxisLineShow: false,
|
||||
serAxisLineShow: false,
|
||||
showCatName: true
|
||||
});
|
||||
|
||||
// Slides 11-13
|
||||
await html2pptx('slides/11-generalization.html', pptx);
|
||||
await html2pptx('slides/12-interpretability.html', pptx);
|
||||
await html2pptx('slides/13-conclusion.html', pptx);
|
||||
|
||||
await pptx.writeFile({ fileName: 'output/attention-is-all-you-need.pptx' });
|
||||
console.log('Saved output/attention-is-all-you-need.pptx');
|
||||
}
|
||||
|
||||
build().catch(e => { console.error(e); process.exit(1); });
|
||||
@@ -0,0 +1,17 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Post-process deck: remove duplicate mid-paragraph <a:pPr> elements that
|
||||
pptxgenjs emits when list items contain multiple inline-formatting runs.
|
||||
The duplicate (later) pPr carries buNone, which makes LibreOffice drop the
|
||||
bullet glyph. Keeping only the first pPr per <a:p> restores uniform bullets."""
|
||||
import re, glob, sys
|
||||
|
||||
pattern = re.compile(r'(</a:r>)\s*<a:pPr\b.*?</a:pPr>', re.S)
|
||||
total = 0
|
||||
for path in glob.glob('deckbuild/ppt/slides/slide*.xml'):
|
||||
xml = open(path, encoding='utf-8').read()
|
||||
fixed, n = pattern.subn(r'\1', xml)
|
||||
if n:
|
||||
open(path, 'w', encoding='utf-8').write(fixed)
|
||||
total += n
|
||||
print(f'{path}: removed {n} duplicate pPr')
|
||||
print(f'total removed: {total}')
|
||||
@@ -0,0 +1,15 @@
|
||||
const sharp = require('sharp');
|
||||
|
||||
// Cover background: deep indigo -> violet diagonal gradient, rasterized (CSS gradients not supported)
|
||||
const cover = `<svg xmlns="http://www.w3.org/2000/svg" width="1920" height="1080">
|
||||
<defs>
|
||||
<linearGradient id="g" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" style="stop-color:#14102E"/>
|
||||
<stop offset="55%" style="stop-color:#2A1668"/>
|
||||
<stop offset="100%" style="stop-color:#5B21B6"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect width="100%" height="100%" fill="url(#g)"/>
|
||||
</svg>`;
|
||||
|
||||
sharp(Buffer.from(cover)).png().toFile('assets/cover-bg.png').then(() => console.log('assets ok'));
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
|
After Width: | Height: | Size: 250 KiB |
+805
@@ -0,0 +1,805 @@
|
||||
{
|
||||
"name": "workspace",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "workspace",
|
||||
"version": "1.0.0",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"playwright": "^1.62.1",
|
||||
"pptxgenjs": "^4.0.1",
|
||||
"sharp": "^0.35.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@emnapi/runtime": {
|
||||
"version": "1.11.3",
|
||||
"resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.3.tgz",
|
||||
"integrity": "sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/colour": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz",
|
||||
"integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-darwin-arm64": {
|
||||
"version": "0.35.3",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.35.3.tgz",
|
||||
"integrity": "sha512-RMnFX7YQsMoh7lWfcM4NEHHymBX/rLuKNPVM84XE9ONPcaSCDgE7CHIHpSgPcO2xcRthgBy1HfNO319mwhIAkg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=20.9.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-libvips-darwin-arm64": "1.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-darwin-x64": {
|
||||
"version": "0.35.3",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.35.3.tgz",
|
||||
"integrity": "sha512-Xo+5uFBtLN0BKqieTxiFzFPQAUlBbbH5iBKyRX/z1JrbnYsHTfKJnUfL8+p2TPXr1pXqao4eeL4Rl144uDpK9w==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=20.9.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-libvips-darwin-x64": "1.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-freebsd-wasm32": {
|
||||
"version": "0.35.3",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-freebsd-wasm32/-/sharp-freebsd-wasm32-0.35.3.tgz",
|
||||
"integrity": "sha512-lUxcqWIj2wMQ9BrwNjngcr1gWUr5xgaGThBRqPPalIC2n67Cqj1uPh8NnA/ZhAg8hUbKl+kVHKwgUIwe6ZYPrg==",
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"dependencies": {
|
||||
"@img/sharp-wasm32": "0.35.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.9.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-libvips-darwin-arm64": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.3.2.tgz",
|
||||
"integrity": "sha512-9J6ypZFpQBj4YnePGoq/S38w6nz+vqg5WZLrLGY4YuSemdMq47GMLBPO42MzwdGwpg/agZ7xzZcFHa48xlywfg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-libvips-darwin-x64": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.3.2.tgz",
|
||||
"integrity": "sha512-m2pW1n6cns9VaubNwsZ+c3CRYjxNQWgJ5gPlnL1nbBcpkBvFm6SCFN5o0psFHI8w9n11NKhFkeEDns98tiqbEw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-libvips-linux-arm": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.3.2.tgz",
|
||||
"integrity": "sha512-1eMLzy92I4J6rmi4mAT8yC3HxOtniyGELlzGbNMLLeqe052ahFQ0h6LFq+lh5DsDIdYViIDst08abvSbcEdLXQ==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"license": "LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-libvips-linux-arm64": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.3.2.tgz",
|
||||
"integrity": "sha512-dqVSFynCox4C/J8kT16V7SIFAns0IjgLwkvYT7p8LQVmJ5OS5b6tI9IGflxTeuBS//zXeFIUbwt5dwxyZ17cnA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-libvips-linux-ppc64": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.3.2.tgz",
|
||||
"integrity": "sha512-3z0NHDxD6n5I9gc05U1eW1AyRm+Gznzq3naMrthPNqE6oYykcogW0l/jfpJdjYnuNl8R7yI9pNbE1XiUeyq0Aw==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"license": "LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-libvips-linux-riscv64": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.3.2.tgz",
|
||||
"integrity": "sha512-bsb4rI+NldGOsXuej2r8OdSS8+zXDVaCWxyWrcv6kneTOlgAHtZABRzBBCwdsPiD90J4myNJuHpg6kA20ImW/w==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
"license": "LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-libvips-linux-s390x": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.3.2.tgz",
|
||||
"integrity": "sha512-/ABshyj8gCpyIrNXnHn4LorDJ0HHm1VhXPBlxZ8zAtfVPAaSafXPGn+sUSIRiwaSBy0mmFjSjiXI5mkcwdChKQ==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
"license": "LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-libvips-linux-x64": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.3.2.tgz",
|
||||
"integrity": "sha512-ITPEtgffGJ0S6G9dRyw/366tJQqFRcHWPHhC+Stpg3Z8AEMrDrTr2lhdz4f/Y/HMbRh//7Z5mBzEpVdi62Oc3w==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-libvips-linuxmusl-arm64": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.3.2.tgz",
|
||||
"integrity": "sha512-zE9EdiUzUmg5mDT5a1rk5fYJ6GWPloTwWBYDS14naqHsL+EaMpDj1AWnpLgh3u0YCORv2Tt50wrcrpYqkP97Kw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-libvips-linuxmusl-x64": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.3.2.tgz",
|
||||
"integrity": "sha512-m0lrLiUt+lBYnCFr8qV/65yMR4E/c7/wf78I5eKTdkEakFAlZ9QlzEM3QIhhAwVeUhLAHLcCq7a7Vszq/oFNZQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-linux-arm": {
|
||||
"version": "0.35.3",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.35.3.tgz",
|
||||
"integrity": "sha512-affVWCTLooy8TSxbDx2qkzuDeaWLNVBA+P//FNBirHsXpP2fuBhk5AuboYUnrDnzoXes8GFjpTx0SBFOCRg+FA==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=20.9.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-libvips-linux-arm": "1.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-linux-arm64": {
|
||||
"version": "0.35.3",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.35.3.tgz",
|
||||
"integrity": "sha512-QgKDspHPnrU+GQ55XPhGwyhC8acLVOOSyAvo1oVfFmrIXLkDNmGWzAfDZ4xK8oSA1qBQrALcHX0G5UZni/SuFQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=20.9.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-libvips-linux-arm64": "1.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-linux-ppc64": {
|
||||
"version": "0.35.3",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.35.3.tgz",
|
||||
"integrity": "sha512-sMd8rDxmpLOwv/7N44klFjOD5DUO7FLdjiXDI0hoxYaf7Ar262dQIEkosE98bps+5HPLtp/EvNqeqQtOycP/IA==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=20.9.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-libvips-linux-ppc64": "1.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-linux-riscv64": {
|
||||
"version": "0.35.3",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.35.3.tgz",
|
||||
"integrity": "sha512-0Eob78yjlYPfL5vMNWAW55l3R9Y6BQS/gOfe0ZcP9mEz9ohhKSt4im1hayiknXgf8AWrFqMvJcKIdmLmEe7yeQ==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=20.9.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-libvips-linux-riscv64": "1.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-linux-s390x": {
|
||||
"version": "0.35.3",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.35.3.tgz",
|
||||
"integrity": "sha512-KgAxQ0DxpNOq1rG2t5cgTgShJFGSuU7XO45cqC+1NVOuZnP6tlgZRuSYOfNupGkHID0o3cJOsw4DVeJpMovcGw==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=20.9.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-libvips-linux-s390x": "1.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-linux-x64": {
|
||||
"version": "0.35.3",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.35.3.tgz",
|
||||
"integrity": "sha512-8pqvxubL2PGdhlPy6GLqzDYMUjyRmKAwKHYKixpdJYBUK7PJ0C029XdsnpFIdgRZG68fZiGdHVWcKPvtiPB4cA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=20.9.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-libvips-linux-x64": "1.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-linuxmusl-arm64": {
|
||||
"version": "0.35.3",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.35.3.tgz",
|
||||
"integrity": "sha512-Vz0iQjzzcSX3HCbfwFfCSG/9SCIqyO0mH2sXyiHaAYfBk0cRsCWXRyQYX0ovCK/PAQBbTzQ0dsPQHh5MAFL59w==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=20.9.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-libvips-linuxmusl-arm64": "1.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-linuxmusl-x64": {
|
||||
"version": "0.35.3",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.35.3.tgz",
|
||||
"integrity": "sha512-6O1NPKcDVj9QEdg7Hx549EX8U0rp6yXQERqru6yRN7fGBn32UvIRJUlWnk+8xDCiG76hXVBbX82NZ/ZKr0euIg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=20.9.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-libvips-linuxmusl-x64": "1.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-wasm32": {
|
||||
"version": "0.35.3",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.35.3.tgz",
|
||||
"integrity": "sha512-cZ0XkcYGpHZkqW6iCkqTcmUC0CD9DhD5d/qeZlZkfRBn6GnHniZXLUo5+9xw8Iv76YE6LQFN9YNBlKREcCG76w==",
|
||||
"license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@emnapi/runtime": "^1.11.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.9.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-webcontainers-wasm32": {
|
||||
"version": "0.35.3",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-webcontainers-wasm32/-/sharp-webcontainers-wasm32-0.35.3.tgz",
|
||||
"integrity": "sha512-2rnq7bX3NzeR2T4YWgz8qiG4h3TSdMe+vN1iQXpJleSJ3SM5zQ8Fy2SyyXAWlbxpEZ2Y+Z4u1BePgJEYbSy80Q==",
|
||||
"cpu": [
|
||||
"wasm32"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@img/sharp-wasm32": "0.35.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.9.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-win32-arm64": {
|
||||
"version": "0.35.3",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.35.3.tgz",
|
||||
"integrity": "sha512-4bPwFdMbeC4JQ8L8LOyWp6nsHcboP5fxkp6iPOXz2Vg49R42TuMs2whkJ5OAP4/Ul035qOzy0AecOF9VOscn4w==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "Apache-2.0 AND LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=20.9.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-win32-ia32": {
|
||||
"version": "0.35.3",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.35.3.tgz",
|
||||
"integrity": "sha512-r53mXsBN6lFUDiST764SvgwUdHAqM4rPAiDzAmf4fLoB6X/rkfyTrLCg6+g17wJJiCmB3JYgHuUldCWUIRFSXw==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"license": "Apache-2.0 AND LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^20.9.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-win32-x64": {
|
||||
"version": "0.35.3",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.35.3.tgz",
|
||||
"integrity": "sha512-D4y1vNeZrIIJCN+uHaWVtH86B+aCrdMYYjicy9pXHvbGZeGYLLSd3wdVuC37FxVXlU1ARsk84eKWfWMXGYEqvA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "Apache-2.0 AND LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=20.9.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "22.20.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.20.1.tgz",
|
||||
"integrity": "sha512-EANqOCF9QFyra+4pfxUcX9STKJpCLjMbObVzljIJomAWSnuSIEAvyzEU53GaajbXJEgdh0iEcPL+DGvpUd4k1Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"undici-types": "~6.21.0"
|
||||
}
|
||||
},
|
||||
"node_modules/core-util-is": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
|
||||
"integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/detect-libc": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
|
||||
"integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/fsevents": {
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
|
||||
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/https": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/https/-/https-1.0.0.tgz",
|
||||
"integrity": "sha512-4EC57ddXrkaF0x83Oj8sM6SLQHAWXw90Skqu2M4AEWENZ3F02dFJE/GARA8igO79tcgYqGrD7ae4f5L3um2lgg==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/image-size": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/image-size/-/image-size-1.2.1.tgz",
|
||||
"integrity": "sha512-rH+46sQJ2dlwfjfhCyNx5thzrv+dtmBIhPHk0zgRUukHzZ/kRueTJXoYYsclBaKcSMBWuGbOFXtioLpzTb5euw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"queue": "6.0.2"
|
||||
},
|
||||
"bin": {
|
||||
"image-size": "bin/image-size.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.x"
|
||||
}
|
||||
},
|
||||
"node_modules/immediate": {
|
||||
"version": "3.0.6",
|
||||
"resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
|
||||
"integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/inherits": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/isarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||
"integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/jszip": {
|
||||
"version": "3.10.1",
|
||||
"resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz",
|
||||
"integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==",
|
||||
"license": "(MIT OR GPL-3.0-or-later)",
|
||||
"dependencies": {
|
||||
"lie": "~3.3.0",
|
||||
"pako": "~1.0.2",
|
||||
"readable-stream": "~2.3.6",
|
||||
"setimmediate": "^1.0.5"
|
||||
}
|
||||
},
|
||||
"node_modules/lie": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz",
|
||||
"integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"immediate": "~3.0.5"
|
||||
}
|
||||
},
|
||||
"node_modules/pako": {
|
||||
"version": "1.0.11",
|
||||
"resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
|
||||
"integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==",
|
||||
"license": "(MIT AND Zlib)"
|
||||
},
|
||||
"node_modules/playwright": {
|
||||
"version": "1.62.1",
|
||||
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.62.1.tgz",
|
||||
"integrity": "sha512-0M+L3LAD8/nm554LOla9Ayx0j0tmFZ0FBcoQ7F1VuVHpM/XpiC8RcDzBQB8W5+hA8L22THxELzeF+2WcUzvcLg==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"playwright-core": "1.62.1"
|
||||
},
|
||||
"bin": {
|
||||
"playwright": "cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"fsevents": "2.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/playwright-core": {
|
||||
"version": "1.62.1",
|
||||
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.62.1.tgz",
|
||||
"integrity": "sha512-wPYSwEBJY9GHraISXqyqtx0na0LpO3XEX7jNDhntbex7tzUS7kLnZsOlFruFJB4Hi/rhDMjXGqHewDZ68nYZVw==",
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
"playwright-core": "cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20"
|
||||
}
|
||||
},
|
||||
"node_modules/pptxgenjs": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/pptxgenjs/-/pptxgenjs-4.0.1.tgz",
|
||||
"integrity": "sha512-TeJISr8wouAuXw4C1F/mC33xbZs/FuEG6nH9FG1Zj+nuPcGMP5YRHl6X+j3HSUnS1f3at6k75ZZXPMZlA5Lj9A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/node": "^22.8.1",
|
||||
"https": "^1.0.0",
|
||||
"image-size": "^1.2.1",
|
||||
"jszip": "^3.10.1"
|
||||
}
|
||||
},
|
||||
"node_modules/process-nextick-args": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
|
||||
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/queue": {
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz",
|
||||
"integrity": "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"inherits": "~2.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/readable-stream": {
|
||||
"version": "2.3.8",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
|
||||
"integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"core-util-is": "~1.0.0",
|
||||
"inherits": "~2.0.3",
|
||||
"isarray": "~1.0.0",
|
||||
"process-nextick-args": "~2.0.0",
|
||||
"safe-buffer": "~5.1.1",
|
||||
"string_decoder": "~1.1.1",
|
||||
"util-deprecate": "~1.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/safe-buffer": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/semver": {
|
||||
"version": "7.8.5",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz",
|
||||
"integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==",
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/setimmediate": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
|
||||
"integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/sharp": {
|
||||
"version": "0.35.3",
|
||||
"resolved": "https://registry.npmjs.org/sharp/-/sharp-0.35.3.tgz",
|
||||
"integrity": "sha512-ej0zVHuZGHCiABXcNxeYhpRnPNPAcvbG8RMdBAhDAxLKkCRVSpK3Iyu7qbqw3JMzoj0REeM6f3tJLtVwl0023Q==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@img/colour": "^1.1.0",
|
||||
"detect-libc": "^2.1.2",
|
||||
"semver": "^7.8.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.9.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-darwin-arm64": "0.35.3",
|
||||
"@img/sharp-darwin-x64": "0.35.3",
|
||||
"@img/sharp-freebsd-wasm32": "0.35.3",
|
||||
"@img/sharp-libvips-darwin-arm64": "1.3.2",
|
||||
"@img/sharp-libvips-darwin-x64": "1.3.2",
|
||||
"@img/sharp-libvips-linux-arm": "1.3.2",
|
||||
"@img/sharp-libvips-linux-arm64": "1.3.2",
|
||||
"@img/sharp-libvips-linux-ppc64": "1.3.2",
|
||||
"@img/sharp-libvips-linux-riscv64": "1.3.2",
|
||||
"@img/sharp-libvips-linux-s390x": "1.3.2",
|
||||
"@img/sharp-libvips-linux-x64": "1.3.2",
|
||||
"@img/sharp-libvips-linuxmusl-arm64": "1.3.2",
|
||||
"@img/sharp-libvips-linuxmusl-x64": "1.3.2",
|
||||
"@img/sharp-linux-arm": "0.35.3",
|
||||
"@img/sharp-linux-arm64": "0.35.3",
|
||||
"@img/sharp-linux-ppc64": "0.35.3",
|
||||
"@img/sharp-linux-riscv64": "0.35.3",
|
||||
"@img/sharp-linux-s390x": "0.35.3",
|
||||
"@img/sharp-linux-x64": "0.35.3",
|
||||
"@img/sharp-linuxmusl-arm64": "0.35.3",
|
||||
"@img/sharp-linuxmusl-x64": "0.35.3",
|
||||
"@img/sharp-webcontainers-wasm32": "0.35.3",
|
||||
"@img/sharp-win32-arm64": "0.35.3",
|
||||
"@img/sharp-win32-ia32": "0.35.3",
|
||||
"@img/sharp-win32-x64": "0.35.3"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/node": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"safe-buffer": "~5.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/tslib": {
|
||||
"version": "2.8.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
||||
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
|
||||
"license": "0BSD",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/undici-types": {
|
||||
"version": "6.21.0",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
|
||||
"integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
|
||||
"license": "MIT"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "workspace",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"type": "commonjs",
|
||||
"dependencies": {
|
||||
"playwright": "^1.62.1",
|
||||
"pptxgenjs": "^4.0.1",
|
||||
"sharp": "^0.35.3"
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
+31
@@ -0,0 +1,31 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head><style>
|
||||
html { background: #14102E; }
|
||||
body { width: 720pt; height: 405pt; margin: 0; padding: 0; font-family: Arial, sans-serif; display: flex; background-image: url('../assets/cover-bg.png'); }
|
||||
.left { width: 440pt; margin: 44pt 0 44pt 48pt; display: flex; flex-direction: column; }
|
||||
.kicker { font-size: 10pt; color: #F59E0B; font-weight: bold; letter-spacing: 2pt; margin: 0 0 14pt 0; }
|
||||
h1 { font-size: 40pt; color: #FFFFFF; margin: 0 0 14pt 0; line-height: 1.1; }
|
||||
.sub { font-size: 14pt; color: #DDD6FE; margin: 0 0 26pt 0; line-height: 1.35; }
|
||||
.rule { background: #F59E0B; height: 4pt; width: 72pt; margin: 0 0 26pt 0; }
|
||||
.authors { font-size: 11pt; color: #EDE9FE; margin: 0 0 6pt 0; line-height: 1.4; }
|
||||
.affil { font-size: 9.5pt; color: #B8AEE8; margin: 0; }
|
||||
.card { width: 156pt; margin: 46pt 0 0 16pt; background: #FFFFFF; border-radius: 10pt; padding: 12pt; box-shadow: 4px 4px 18px rgba(0,0,0,0.4); height: 256pt; }
|
||||
.card img { height: 200pt; display: block; margin: 0 auto; }
|
||||
.cardcap { font-size: 8pt; color: #5B5876; text-align: center; margin: 8pt 0 0 0; }
|
||||
</style></head>
|
||||
<body>
|
||||
<div class="left">
|
||||
<p class="kicker">NEURIPS 2017 · ARXIV:1706.03762</p>
|
||||
<h1>Attention Is<br>All You Need</h1>
|
||||
<p class="sub">The Transformer: sequence transduction based entirely on attention — no recurrence, no convolution.</p>
|
||||
<div class="rule"></div>
|
||||
<p class="authors">Ashish Vaswani · Noam Shazeer · Niki Parmar · Jakob Uszkoreit<br>Llion Jones · Aidan N. Gomez · Łukasz Kaiser · Illia Polosukhin</p>
|
||||
<p class="affil">Google Brain · Google Research · University of Toronto</p>
|
||||
</div>
|
||||
<div class="card">
|
||||
<img src="../source_visuals/fig1-03.png">
|
||||
<p class="cardcap">The Transformer — model architecture<br>Figure 1, paper p. 3</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head><style>
|
||||
html { background: #FFFFFF; }
|
||||
body { width: 720pt; height: 405pt; margin: 0; padding: 0; background: #FAFAFF; font-family: Arial, sans-serif; display: flex; }
|
||||
.bar { width: 10pt; background: #4338CA; }
|
||||
.wrap { width: 644pt; margin: 26pt 32pt 22pt 34pt; display: flex; flex-direction: column; }
|
||||
.kicker { font-size: 9.5pt; color: #7C3AED; font-weight: bold; letter-spacing: 2pt; margin: 0 0 4pt 0; }
|
||||
h1 { font-size: 23pt; color: #1A1633; margin: 0 0 8pt 0; }
|
||||
.rule { background: #F59E0B; height: 3pt; width: 60pt; margin: 0 0 14pt 0; }
|
||||
.cols { display: flex; }
|
||||
.txt { width: 400pt; }
|
||||
ul { margin: 0; padding-left: 14pt; font-size: 11pt; color: #2A2740; line-height: 1.4; }
|
||||
li { margin-bottom: 9pt; }
|
||||
.stat { width: 200pt; margin-left: 30pt; background: #EEF0FF; border-radius: 10pt; padding: 14pt 16pt; }
|
||||
.stat p { margin: 0; }
|
||||
.bignum { font-size: 26pt; color: #4338CA; font-weight: bold; margin: 0; }
|
||||
.statlab { font-size: 9.5pt; color: #5B5876; margin: 2pt 0 12pt 0; }
|
||||
.foot { font-size: 8pt; color: #8A86A3; margin-top: auto; margin-bottom: 0; }
|
||||
</style></head>
|
||||
<body>
|
||||
<div class="bar"></div>
|
||||
<div class="wrap">
|
||||
<p class="kicker">01 · BACKGROUND</p>
|
||||
<h1>The Problem: The Limits of Recurrence</h1>
|
||||
<div class="rule"></div>
|
||||
<div class="cols">
|
||||
<div class="txt">
|
||||
<ul>
|
||||
<li>Sequence transduction (e.g., machine translation) was dominated by <b>recurrent</b> (LSTM / GRU) and <b>convolutional</b> encoder–decoder models.</li>
|
||||
<li>RNNs compute hidden states <b>one position at a time</b>: inherently sequential, so training cannot parallelize across positions in a sequence.</li>
|
||||
<li>Signals between distant positions must travel a path of <b>O(n) operations</b> — the longer the path, the harder long-range dependencies are to learn.</li>
|
||||
<li>Attention mechanisms already existed, but only as an <b>accessory</b> layered on top of RNNs or CNNs.</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="stat">
|
||||
<p class="bignum">O(n)</p>
|
||||
<p class="statlab">sequential operations per layer in a recurrent network</p>
|
||||
<p class="bignum">O(n)</p>
|
||||
<p class="statlab">maximum path length between any two positions</p>
|
||||
</div>
|
||||
</div>
|
||||
<p class="foot">Source: Vaswani et al., “Attention Is All You Need”, §1 Introduction (paper p. 1–2).</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head><style>
|
||||
html { background: #FFFFFF; }
|
||||
body { width: 720pt; height: 405pt; margin: 0; padding: 0; background: #FAFAFF; font-family: Arial, sans-serif; display: flex; }
|
||||
.bar { width: 10pt; background: #4338CA; }
|
||||
.wrap { width: 644pt; margin: 26pt 32pt 22pt 34pt; display: flex; flex-direction: column; }
|
||||
.kicker { font-size: 9.5pt; color: #7C3AED; font-weight: bold; letter-spacing: 2pt; margin: 0 0 4pt 0; }
|
||||
h1 { font-size: 23pt; color: #1A1633; margin: 0 0 8pt 0; }
|
||||
.rule { background: #F59E0B; height: 3pt; width: 60pt; margin: 0 0 16pt 0; }
|
||||
.cards { display: flex; }
|
||||
.card { width: 198pt; margin-right: 14pt; background: #4338CA; border-radius: 10pt; padding: 14pt 14pt 16pt 14pt; }
|
||||
.card p { margin: 0; }
|
||||
.ct { font-size: 13pt; color: #FFFFFF; font-weight: bold; margin: 0 0 6pt 0; }
|
||||
.cd { font-size: 9.5pt; color: #DDD6FE; line-height: 1.35; }
|
||||
ul { margin: 16pt 0 0 0; padding-left: 14pt; font-size: 11pt; color: #2A2740; line-height: 1.4; }
|
||||
li { margin-bottom: 8pt; }
|
||||
.foot { font-size: 8pt; color: #8A86A3; margin-top: auto; margin-bottom: 0; }
|
||||
</style></head>
|
||||
<body>
|
||||
<div class="bar"></div>
|
||||
<div class="wrap">
|
||||
<p class="kicker">02 · KEY IDEA</p>
|
||||
<h1>The Transformer: Attention Is All You Need</h1>
|
||||
<div class="rule"></div>
|
||||
<div class="cards">
|
||||
<div class="card">
|
||||
<p class="ct">No Recurrence</p>
|
||||
<p class="cd">Sequential RNN hidden states are removed entirely — positions are processed in parallel.</p>
|
||||
</div>
|
||||
<div class="card">
|
||||
<p class="ct">No Convolution</p>
|
||||
<p class="cd">No fixed-width kernels; every position can connect to every other position directly.</p>
|
||||
</div>
|
||||
<div class="card" style="margin-right: 0;">
|
||||
<p class="ct">Self-Attention Only</p>
|
||||
<p class="cd">Multi-headed self-attention computes all representations, in both encoder and decoder.</p>
|
||||
</div>
|
||||
</div>
|
||||
<ul>
|
||||
<li>First sequence transduction model based <b>entirely on attention</b>, replacing recurrent layers with multi-headed self-attention.</li>
|
||||
<li>Highly parallelizable — reaches a new state of the art in translation with a <b>fraction of the training cost</b>.</li>
|
||||
<li>Generalizes beyond translation (e.g., English constituency parsing) and yields interpretable attention patterns.</li>
|
||||
</ul>
|
||||
<p class="foot">Source: Vaswani et al., Abstract and §1 (paper p. 1–2).</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head><style>
|
||||
html { background: #FFFFFF; }
|
||||
body { width: 720pt; height: 405pt; margin: 0; padding: 0; background: #FAFAFF; font-family: Arial, sans-serif; display: flex; }
|
||||
.bar { width: 10pt; background: #4338CA; }
|
||||
.wrap { width: 644pt; margin: 26pt 32pt 22pt 34pt; display: flex; flex-direction: column; }
|
||||
.kicker { font-size: 9.5pt; color: #7C3AED; font-weight: bold; letter-spacing: 2pt; margin: 0 0 4pt 0; }
|
||||
h1 { font-size: 23pt; color: #1A1633; margin: 0 0 8pt 0; }
|
||||
.rule { background: #F59E0B; height: 3pt; width: 60pt; margin: 0 0 12pt 0; }
|
||||
.cols { display: flex; }
|
||||
.txt { width: 372pt; }
|
||||
ul { margin: 0; padding-left: 14pt; font-size: 10.5pt; color: #2A2740; line-height: 1.38; }
|
||||
li { margin-bottom: 8pt; }
|
||||
.fig { width: 240pt; margin-left: 26pt; background: #FFFFFF; border: 1px solid #E0DFF0; border-radius: 10pt; padding: 10pt; }
|
||||
.fig img { height: 262pt; display: block; margin: 0 auto; }
|
||||
.figcap { font-size: 8pt; color: #5B5876; text-align: center; margin: 6pt 0 0 0; }
|
||||
.foot { font-size: 8pt; color: #8A86A3; margin-top: auto; margin-bottom: 0; }
|
||||
</style></head>
|
||||
<body>
|
||||
<div class="bar"></div>
|
||||
<div class="wrap">
|
||||
<p class="kicker">03 · METHOD</p>
|
||||
<h1>Model Architecture: Stacked Self-Attention</h1>
|
||||
<div class="rule"></div>
|
||||
<div class="cols">
|
||||
<div class="txt">
|
||||
<ul>
|
||||
<li><b>Encoder–decoder</b> structure built from stacked self-attention and point-wise, fully connected layers (left and right halves of Figure 1).</li>
|
||||
<li><b>Encoder</b>: N = 6 identical layers — each with multi-head self-attention, then a position-wise feed-forward network.</li>
|
||||
<li><b>Decoder</b>: N = 6 layers; adds a <b>masked</b> multi-head self-attention sub-layer (positions only attend to earlier positions) plus attention over the encoder output.</li>
|
||||
<li>A <b>residual connection</b> wraps every sub-layer, followed by <b>layer normalization</b>.</li>
|
||||
<li>Inputs/outputs are embedded (d_model = 512) and combined with <b>positional encodings</b>, since the model has no notion of order on its own.</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="fig">
|
||||
<img src="../source_visuals/fig1-03.png">
|
||||
<p class="figcap">Encoder (left) and decoder (right) stacks.<br>Figure 1, paper p. 3.</p>
|
||||
</div>
|
||||
</div>
|
||||
<p class="foot">Visual: Figure 1, “The Transformer - model architecture” (paper p. 3); text: §3.1 (paper p. 3).</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head><style>
|
||||
html { background: #FFFFFF; }
|
||||
body { width: 720pt; height: 405pt; margin: 0; padding: 0; background: #FAFAFF; font-family: Arial, sans-serif; display: flex; }
|
||||
.bar { width: 10pt; background: #4338CA; }
|
||||
.wrap { width: 644pt; margin: 26pt 32pt 22pt 34pt; display: flex; flex-direction: column; }
|
||||
.kicker { font-size: 9.5pt; color: #7C3AED; font-weight: bold; letter-spacing: 2pt; margin: 0 0 4pt 0; }
|
||||
h1 { font-size: 23pt; color: #1A1633; margin: 0 0 8pt 0; }
|
||||
.rule { background: #F59E0B; height: 3pt; width: 60pt; margin: 0 0 12pt 0; }
|
||||
.cols { display: flex; }
|
||||
.txt { width: 300pt; }
|
||||
.formula { background: #1A1633; border-radius: 8pt; padding: 10pt 12pt; margin: 0 0 12pt 0; }
|
||||
.formula p { font-family: Courier New, monospace; font-size: 10.5pt; color: #FDE68A; margin: 0; text-align: center; }
|
||||
ul { margin: 0; padding-left: 14pt; font-size: 10.5pt; color: #2A2740; line-height: 1.38; }
|
||||
li { margin-bottom: 8pt; }
|
||||
.fig { width: 312pt; margin-left: 24pt; background: #FFFFFF; border: 1px solid #E0DFF0; border-radius: 10pt; padding: 10pt; }
|
||||
.fig img { width: 292pt; display: block; margin: 0 auto; }
|
||||
.figcap { font-size: 8pt; color: #5B5876; text-align: center; margin: 6pt 0 0 0; }
|
||||
.foot { font-size: 8pt; color: #8A86A3; margin-top: auto; margin-bottom: 0; }
|
||||
</style></head>
|
||||
<body>
|
||||
<div class="bar"></div>
|
||||
<div class="wrap">
|
||||
<p class="kicker">04 · METHOD</p>
|
||||
<h1>Scaled Dot-Product & Multi-Head Attention</h1>
|
||||
<div class="rule"></div>
|
||||
<div class="cols">
|
||||
<div class="txt">
|
||||
<div class="formula">
|
||||
<p>Attention(Q,K,V) = softmax(QK^T / √d_k)V</p>
|
||||
</div>
|
||||
<ul>
|
||||
<li>Attention maps a <b>query</b> and <b>key–value</b> pairs to an output: a weighted sum of values, weights from query–key compatibility.</li>
|
||||
<li>Dot products are scaled by <b>1/√d_k</b> — for large d_k they would push softmax into tiny-gradient regions.</li>
|
||||
<li><b>Multi-head</b>: queries, keys, values are linearly projected <b>h = 8</b> times (to d_k = d_v = 64), attention runs in parallel, outputs are concatenated and re-projected.</li>
|
||||
<li>Different heads jointly attend to information from <b>different representation subspaces</b> at different positions.</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="fig">
|
||||
<img src="../source_visuals/fig2-04.png">
|
||||
<p class="figcap">(left) Scaled Dot-Product Attention; (right) Multi-Head Attention — several attention layers in parallel. Figure 2, paper p. 4.</p>
|
||||
</div>
|
||||
</div>
|
||||
<p class="foot">Visual: Figure 2 (paper p. 4); formula and text: §3.2 (paper p. 4–5).</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head><style>
|
||||
html { background: #FFFFFF; }
|
||||
body { width: 720pt; height: 405pt; margin: 0; padding: 0; background: #FAFAFF; font-family: Arial, sans-serif; display: flex; }
|
||||
.bar { width: 10pt; background: #4338CA; }
|
||||
.wrap { width: 644pt; margin: 26pt 32pt 22pt 34pt; display: flex; flex-direction: column; }
|
||||
.kicker { font-size: 9.5pt; color: #7C3AED; font-weight: bold; letter-spacing: 2pt; margin: 0 0 4pt 0; }
|
||||
h1 { font-size: 23pt; color: #1A1633; margin: 0 0 8pt 0; }
|
||||
.rule { background: #F59E0B; height: 3pt; width: 60pt; margin: 0 0 14pt 0; }
|
||||
.grid { display: flex; margin-bottom: 12pt; }
|
||||
.card { width: 300pt; background: #FFFFFF; border: 1px solid #E0DFF0; border-left: 5pt solid #7C3AED; border-radius: 8pt; padding: 10pt 14pt; }
|
||||
.card p { margin: 0; }
|
||||
.ct { font-size: 12pt; color: #4338CA; font-weight: bold; margin: 0 0 5pt 0; }
|
||||
.cd { font-size: 10pt; color: #2A2740; line-height: 1.35; }
|
||||
.gap { width: 16pt; }
|
||||
.note { background: #FDF3E0; border-left: 5pt solid #F59E0B; border-radius: 6pt; padding: 9pt 14pt; margin-top: auto; }
|
||||
.note p { font-size: 10pt; color: #6B4E12; margin: 0; line-height: 1.35; }
|
||||
.foot { font-size: 8pt; color: #8A86A3; margin: 8pt 0 0 0; }
|
||||
</style></head>
|
||||
<body>
|
||||
<div class="bar"></div>
|
||||
<div class="wrap">
|
||||
<p class="kicker">05 · METHOD</p>
|
||||
<h1>Anatomy of the Building Blocks</h1>
|
||||
<div class="rule"></div>
|
||||
<div class="grid">
|
||||
<div class="card">
|
||||
<p class="ct">Multi-Head Attention</p>
|
||||
<p class="cd">h = 8 parallel heads; d_k = d_v = d_model/h = 64, so total compute stays close to single-head attention at full dimension.</p>
|
||||
</div>
|
||||
<div class="gap"></div>
|
||||
<div class="card">
|
||||
<p class="ct">Position-wise Feed-Forward</p>
|
||||
<p class="cd">FFN(x) = max(0, xW₁+b₁)W₂+b₂, applied identically to every position; inner dimension d_ff = 2048.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid">
|
||||
<div class="card">
|
||||
<p class="ct">Add & Norm</p>
|
||||
<p class="cd">Residual connection around each sub-layer: LayerNorm(x + Sublayer(x)); all sub-layers and embeddings output d_model = 512.</p>
|
||||
</div>
|
||||
<div class="gap"></div>
|
||||
<div class="card">
|
||||
<p class="ct">Positional Encoding</p>
|
||||
<p class="cd">Sine/cosine waves of different frequencies injected at the inputs, so the model can use token order; learned alternatives worked equally well.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="note">
|
||||
<p><b>Two configurations:</b> base — d_model 512, d_ff 2048, h 8, dropout 0.1 | big — d_model 1024, d_ff 4096, h 16, dropout 0.3.</p>
|
||||
</div>
|
||||
<p class="foot">Source: §3.2–3.5 (paper p. 4–5); §5.4 and Table 3 footnotes (paper p. 7–8).</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head><style>
|
||||
html { background: #FFFFFF; }
|
||||
body { width: 720pt; height: 405pt; margin: 0; padding: 0; background: #FAFAFF; font-family: Arial, sans-serif; display: flex; }
|
||||
.bar { width: 10pt; background: #4338CA; }
|
||||
.wrap { width: 644pt; margin: 26pt 32pt 22pt 34pt; display: flex; flex-direction: column; }
|
||||
.kicker { font-size: 9.5pt; color: #7C3AED; font-weight: bold; letter-spacing: 2pt; margin: 0 0 4pt 0; }
|
||||
h1 { font-size: 23pt; color: #1A1633; margin: 0 0 8pt 0; }
|
||||
.rule { background: #F59E0B; height: 3pt; width: 60pt; margin: 0 0 12pt 0; }
|
||||
.cols { display: flex; }
|
||||
.txt { width: 290pt; }
|
||||
ul { margin: 0; padding-left: 14pt; font-size: 10.5pt; color: #2A2740; line-height: 1.38; }
|
||||
li { margin-bottom: 9pt; }
|
||||
.tabwrap { width: 330pt; margin-left: 22pt; }
|
||||
.tablab { font-size: 9pt; color: #5B5876; margin: 0 0 4pt 0; font-weight: bold; }
|
||||
.tabcap { font-size: 8pt; color: #5B5876; margin: 6pt 0 0 0; }
|
||||
.foot { font-size: 8pt; color: #8A86A3; margin-top: auto; margin-bottom: 0; }
|
||||
</style></head>
|
||||
<body>
|
||||
<div class="bar"></div>
|
||||
<div class="wrap">
|
||||
<p class="kicker">06 · MOTIVATION</p>
|
||||
<h1>Why Self-Attention Wins</h1>
|
||||
<div class="rule"></div>
|
||||
<div class="cols">
|
||||
<div class="txt">
|
||||
<ul>
|
||||
<li><b>Parallelization:</b> a self-attention layer needs only O(1) sequential operations vs. O(n) for recurrence — training uses all positions at once.</li>
|
||||
<li><b>Long-range learning:</b> any two positions connect through a path of <b>constant length O(1)</b>, instead of O(n) for RNNs or O(log_k n) for dilated convolutions.</li>
|
||||
<li><b>Cost:</b> per-layer complexity O(n²·d) beats recurrence O(n·d²) whenever n < d — the common case with word-piece / BPE representations.</li>
|
||||
<li><b>Interpretability:</b> attention distributions expose what the model attends to; heads learn distinct, task-like behaviors.</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="tabwrap">
|
||||
<p class="tablab">PER-LAYER COMPLEXITY AND PATH LENGTHS</p>
|
||||
<div id="table-complexity" class="placeholder" style="width: 330pt; height: 150pt;"></div>
|
||||
<p class="tabcap">n = sequence length, d = representation dimension, k = conv. kernel width, r = neighborhood. Adapted from Table 1, paper p. 6.</p>
|
||||
</div>
|
||||
</div>
|
||||
<p class="foot">Table: adapted from Table 1 (paper p. 6); text: §4 (paper p. 6–7).</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head><style>
|
||||
html { background: #FFFFFF; }
|
||||
body { width: 720pt; height: 405pt; margin: 0; padding: 0; background: #FAFAFF; font-family: Arial, sans-serif; display: flex; }
|
||||
.bar { width: 10pt; background: #4338CA; }
|
||||
.wrap { width: 644pt; margin: 26pt 32pt 22pt 34pt; display: flex; flex-direction: column; }
|
||||
.kicker { font-size: 9.5pt; color: #7C3AED; font-weight: bold; letter-spacing: 2pt; margin: 0 0 4pt 0; }
|
||||
h1 { font-size: 23pt; color: #1A1633; margin: 0 0 8pt 0; }
|
||||
.rule { background: #F59E0B; height: 3pt; width: 60pt; margin: 0 0 14pt 0; }
|
||||
.cols { display: flex; }
|
||||
.card { width: 302pt; background: #FFFFFF; border: 1px solid #E0DFF0; border-radius: 10pt; padding: 12pt 16pt 4pt 16pt; }
|
||||
.card p { margin: 0; }
|
||||
.ct { font-size: 12.5pt; color: #4338CA; font-weight: bold; margin: 0 0 8pt 0; }
|
||||
ul { margin: 0; padding-left: 13pt; font-size: 10pt; color: #2A2740; line-height: 1.35; }
|
||||
li { margin-bottom: 7pt; }
|
||||
.gap { width: 20pt; }
|
||||
.mono { font-family: Courier New, monospace; font-size: 9pt; color: #4338CA; }
|
||||
.hw { background: #EEF0FF; border-radius: 8pt; padding: 9pt 14pt; margin-top: 14pt; }
|
||||
.hw p { font-size: 10pt; color: #2A2740; margin: 0; }
|
||||
.foot { font-size: 8pt; color: #8A86A3; margin-top: auto; margin-bottom: 0; }
|
||||
</style></head>
|
||||
<body>
|
||||
<div class="bar"></div>
|
||||
<div class="wrap">
|
||||
<p class="kicker">07 · EXPERIMENTS</p>
|
||||
<h1>Training Setup</h1>
|
||||
<div class="rule"></div>
|
||||
<div class="cols">
|
||||
<div class="card">
|
||||
<p class="ct">Data & Batching</p>
|
||||
<ul>
|
||||
<li><b>WMT 2014 English–German</b>: 4.5M sentence pairs; <b>English–French</b>: 36M sentences.</li>
|
||||
<li>Byte-pair encoding with a <b>shared source–target vocabulary of ~37K tokens</b>.</li>
|
||||
<li>Batches of ~25,000 source and ~25,000 target tokens, grouped by approximate sequence length.</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="gap"></div>
|
||||
<div class="card">
|
||||
<p class="ct">Optimization & Regularization</p>
|
||||
<ul>
|
||||
<li>Adam (β₁ = 0.9, β₂ = 0.98, ε = 10⁻⁹) with <b>warmup</b>: 4,000 linearly increasing steps, then inverse-square-root decay.</li>
|
||||
<li>Residual dropout 0.1 (base) / 0.3 (big); attention dropout on each sub-layer.</li>
|
||||
<li>Label smoothing ε_ls = 0.1 — hurts perplexity but <b>improves accuracy and BLEU</b>.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hw">
|
||||
<p><b>Hardware & time:</b> 8 × NVIDIA P100 GPUs — base model: 12 hours (100K steps); big model: 3.5 days (300K steps). Beam search with beam size 4, length penalty α = 0.6.</p>
|
||||
</div>
|
||||
<p class="foot">Source: §5 Training (paper p. 7); §6.1 (paper p. 8).</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head><style>
|
||||
html { background: #FFFFFF; }
|
||||
body { width: 720pt; height: 405pt; margin: 0; padding: 0; background: #FAFAFF; font-family: Arial, sans-serif; display: flex; }
|
||||
.bar { width: 10pt; background: #4338CA; }
|
||||
.wrap { width: 644pt; margin: 26pt 32pt 22pt 34pt; display: flex; flex-direction: column; }
|
||||
.kicker { font-size: 9.5pt; color: #7C3AED; font-weight: bold; letter-spacing: 2pt; margin: 0 0 4pt 0; }
|
||||
h1 { font-size: 23pt; color: #1A1633; margin: 0 0 8pt 0; }
|
||||
.rule { background: #F59E0B; height: 3pt; width: 60pt; margin: 0 0 12pt 0; }
|
||||
.cols { display: flex; }
|
||||
.fig { width: 396pt; background: #FFFFFF; border: 1px solid #E0DFF0; border-radius: 10pt; padding: 10pt; }
|
||||
.fig img { width: 376pt; display: block; margin: 0 auto; }
|
||||
.figcap { font-size: 8pt; color: #5B5876; text-align: center; margin: 6pt 0 0 0; }
|
||||
.stats { width: 196pt; margin-left: 22pt; }
|
||||
.stat { background: #4338CA; border-radius: 10pt; padding: 10pt 14pt; margin-bottom: 10pt; }
|
||||
.stat p { margin: 0; }
|
||||
.bignum { font-size: 22pt; color: #FFFFFF; font-weight: bold; }
|
||||
.statlab { font-size: 8.5pt; color: #DDD6FE; line-height: 1.3; margin-top: 2pt; }
|
||||
.stat.amber { background: #B45309; }
|
||||
.foot { font-size: 8pt; color: #8A86A3; margin-top: auto; margin-bottom: 0; }
|
||||
</style></head>
|
||||
<body>
|
||||
<div class="bar"></div>
|
||||
<div class="wrap">
|
||||
<p class="kicker">08 · RESULTS</p>
|
||||
<h1>Machine Translation: New State of the Art</h1>
|
||||
<div class="rule"></div>
|
||||
<div class="cols">
|
||||
<div class="fig">
|
||||
<img src="../source_visuals/table2-08.png">
|
||||
<p class="figcap">BLEU scores and training costs on WMT 2014 EN–DE / EN–FR (newstest2014). Table 2, paper p. 8.</p>
|
||||
</div>
|
||||
<div class="stats">
|
||||
<div class="stat">
|
||||
<p class="bignum">28.4 BLEU</p>
|
||||
<p class="statlab">EN→DE: >2.0 above the best previously reported model, including ensembles</p>
|
||||
</div>
|
||||
<div class="stat">
|
||||
<p class="bignum">41.8 BLEU</p>
|
||||
<p class="statlab">EN→FR: best single model, at under 1/4 of the prior training cost</p>
|
||||
</div>
|
||||
<div class="stat amber">
|
||||
<p class="bignum">3.3×10^18</p>
|
||||
<p class="statlab">FLOPs to train the base model — yet it already beats all prior models and ensembles</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p class="foot">Visual: Table 2 (paper p. 8); text: §6.1 Machine Translation (paper p. 8).</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head><style>
|
||||
html { background: #FFFFFF; }
|
||||
body { width: 720pt; height: 405pt; margin: 0; padding: 0; background: #FAFAFF; font-family: Arial, sans-serif; display: flex; }
|
||||
.bar { width: 10pt; background: #4338CA; }
|
||||
.wrap { width: 644pt; margin: 26pt 32pt 22pt 34pt; display: flex; flex-direction: column; }
|
||||
.kicker { font-size: 9.5pt; color: #7C3AED; font-weight: bold; letter-spacing: 2pt; margin: 0 0 4pt 0; }
|
||||
h1 { font-size: 23pt; color: #1A1633; margin: 0 0 8pt 0; }
|
||||
.rule { background: #F59E0B; height: 3pt; width: 60pt; margin: 0 0 10pt 0; }
|
||||
.chartwrap { margin: 0 auto; }
|
||||
#chart-bleu { margin: 0 auto; }
|
||||
.chartcap { font-size: 9pt; color: #5B5876; text-align: center; margin: 6pt 0 0 0; }
|
||||
.takeaway { background: #FDF3E0; border-left: 5pt solid #F59E0B; border-radius: 6pt; padding: 8pt 14pt; margin-top: auto; }
|
||||
.takeaway p { font-size: 10pt; color: #6B4E12; margin: 0; }
|
||||
.foot { font-size: 8pt; color: #8A86A3; margin: 8pt 0 0 0; }
|
||||
</style></head>
|
||||
<body>
|
||||
<div class="bar"></div>
|
||||
<div class="wrap">
|
||||
<p class="kicker">09 · RESULTS</p>
|
||||
<h1>EN→DE BLEU: Transformer vs. Prior Art</h1>
|
||||
<div class="rule"></div>
|
||||
<div class="chartwrap">
|
||||
<div id="chart-bleu" class="placeholder" style="width: 460pt; height: 218pt; margin: 0 auto;"></div>
|
||||
<p class="chartcap">WMT 2014 English→German newstest2014 BLEU scores — values from Table 2, paper p. 8.</p>
|
||||
</div>
|
||||
<div class="takeaway">
|
||||
<p>The big Transformer sets a new state of the art (28.4 BLEU) — more than 2.0 BLEU above the best previously reported models, including ensembles.</p>
|
||||
</div>
|
||||
<p class="foot">Data: Table 2 (paper p. 8); discussion: §6.1 (paper p. 8).</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head><style>
|
||||
html { background: #FFFFFF; }
|
||||
body { width: 720pt; height: 405pt; margin: 0; padding: 0; background: #FAFAFF; font-family: Arial, sans-serif; display: flex; }
|
||||
.bar { width: 10pt; background: #4338CA; }
|
||||
.wrap { width: 644pt; margin: 26pt 32pt 22pt 34pt; display: flex; flex-direction: column; }
|
||||
.kicker { font-size: 9.5pt; color: #7C3AED; font-weight: bold; letter-spacing: 2pt; margin: 0 0 4pt 0; }
|
||||
h1 { font-size: 23pt; color: #1A1633; margin: 0 0 8pt 0; }
|
||||
.rule { background: #F59E0B; height: 3pt; width: 60pt; margin: 0 0 14pt 0; }
|
||||
.cols { display: flex; }
|
||||
.txt { width: 380pt; }
|
||||
ul { margin: 0; padding-left: 14pt; font-size: 11pt; color: #2A2740; line-height: 1.4; }
|
||||
li { margin-bottom: 10pt; }
|
||||
.stats { width: 210pt; margin-left: 30pt; }
|
||||
.stat { background: #4338CA; border-radius: 10pt; padding: 12pt 16pt; margin-bottom: 12pt; }
|
||||
.stat p { margin: 0; }
|
||||
.bignum { font-size: 24pt; color: #FFFFFF; font-weight: bold; }
|
||||
.statlab { font-size: 9pt; color: #DDD6FE; line-height: 1.3; margin-top: 3pt; }
|
||||
.foot { font-size: 8pt; color: #8A86A3; margin-top: auto; margin-bottom: 0; }
|
||||
</style></head>
|
||||
<body>
|
||||
<div class="bar"></div>
|
||||
<div class="wrap">
|
||||
<p class="kicker">10 · RESULTS</p>
|
||||
<h1>Beyond Translation: Constituency Parsing</h1>
|
||||
<div class="rule"></div>
|
||||
<div class="cols">
|
||||
<div class="txt">
|
||||
<ul>
|
||||
<li>A <b>4-layer Transformer</b> was trained on English constituency parsing (Wall Street Journal portion of the Penn Treebank, ~40K training sentences).</li>
|
||||
<li>With almost <b>no task-specific tuning</b>, it outperforms the BerkeleyParser — even when trained only on the WSJ training set.</li>
|
||||
<li>In the <b>semi-supervised</b> setting (with a ~17M-sentence high-confidence corpus) it beats all previously reported models <b>except the Recurrent Neural Network Grammar</b>.</li>
|
||||
<li>The same architecture generalizes across tasks without structural changes.</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="stats">
|
||||
<div class="stat">
|
||||
<p class="bignum">91.3 F1</p>
|
||||
<p class="statlab">WSJ-only, discriminative setting (Section 23 of WSJ)</p>
|
||||
</div>
|
||||
<div class="stat">
|
||||
<p class="bignum">92.7 F1</p>
|
||||
<p class="statlab">Semi-supervised setting — above every prior model except RNNG</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p class="foot">Source: Table 4 (paper p. 10) and §6.2 / “English Constituency Parsing” (paper p. 9–10).</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head><style>
|
||||
html { background: #FFFFFF; }
|
||||
body { width: 720pt; height: 405pt; margin: 0; padding: 0; background: #FAFAFF; font-family: Arial, sans-serif; display: flex; }
|
||||
.bar { width: 10pt; background: #4338CA; }
|
||||
.wrap { width: 644pt; margin: 26pt 32pt 22pt 34pt; display: flex; flex-direction: column; }
|
||||
.kicker { font-size: 9.5pt; color: #7C3AED; font-weight: bold; letter-spacing: 2pt; margin: 0 0 4pt 0; }
|
||||
h1 { font-size: 23pt; color: #1A1633; margin: 0 0 8pt 0; }
|
||||
.rule { background: #F59E0B; height: 3pt; width: 60pt; margin: 0 0 12pt 0; }
|
||||
.cols { display: flex; }
|
||||
.txt { width: 282pt; }
|
||||
ul { margin: 0; padding-left: 14pt; font-size: 10.5pt; color: #2A2740; line-height: 1.38; }
|
||||
li { margin-bottom: 9pt; }
|
||||
.quote { background: #EEF0FF; border-left: 4pt solid #7C3AED; border-radius: 6pt; padding: 8pt 12pt; margin-top: 10pt; }
|
||||
.quote p { font-size: 9.5pt; color: #4338CA; font-style: italic; margin: 0; line-height: 1.35; }
|
||||
.fig { width: 330pt; margin-left: 24pt; background: #FFFFFF; border: 1px solid #E0DFF0; border-radius: 10pt; padding: 10pt; }
|
||||
.fig img { width: 310pt; display: block; margin: 0 auto; }
|
||||
.figcap { font-size: 8pt; color: #5B5876; text-align: center; margin: 6pt 0 0 0; }
|
||||
.foot { font-size: 8pt; color: #8A86A3; margin-top: auto; margin-bottom: 0; }
|
||||
</style></head>
|
||||
<body>
|
||||
<div class="bar"></div>
|
||||
<div class="wrap">
|
||||
<p class="kicker">11 · RESULTS</p>
|
||||
<h1>Interpretability: What Attention Sees</h1>
|
||||
<div class="rule"></div>
|
||||
<div class="cols">
|
||||
<div class="txt">
|
||||
<ul>
|
||||
<li>Individual attention heads learn to perform <b>different tasks</b>; many exhibit behavior tied to the syntactic and semantic structure of sentences.</li>
|
||||
<li>In this example (encoder self-attention, layer 5 of 6), many heads attend to a <b>distant dependency of the verb “making”</b>, completing the phrase “making…more difficult”.</li>
|
||||
<li>Other heads are involved in <b>anaphora resolution</b> (Figure 4 of the paper).</li>
|
||||
</ul>
|
||||
<div class="quote">
|
||||
<p>“Not only do individual attention heads clearly learn to perform different tasks, many appear to exhibit behavior related to the syntactic and semantic structure of the sentences.” — §4, p. 7</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="fig">
|
||||
<img src="../source_visuals/fig3-13.png">
|
||||
<p class="figcap">Attention for the word “making”; colors = different heads. Figure 3, paper p. 13.</p>
|
||||
</div>
|
||||
</div>
|
||||
<p class="foot">Visual: Figure 3 (paper p. 13); text: §4 (paper p. 7) and Appendix (paper p. 13).</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head><style>
|
||||
html { background: #14102E; }
|
||||
body { width: 720pt; height: 405pt; margin: 0; padding: 0; font-family: Arial, sans-serif; display: flex; background-image: url('../assets/cover-bg.png'); }
|
||||
.wrap { width: 620pt; margin: 30pt 50pt 24pt 50pt; display: flex; flex-direction: column; }
|
||||
.kicker { font-size: 9.5pt; color: #F59E0B; font-weight: bold; letter-spacing: 2pt; margin: 0 0 4pt 0; }
|
||||
h1 { font-size: 24pt; color: #FFFFFF; margin: 0 0 8pt 0; }
|
||||
.rule { background: #F59E0B; height: 3pt; width: 60pt; margin: 0 0 14pt 0; }
|
||||
ul { margin: 0; padding-left: 15pt; font-size: 11pt; color: #EDE9FE; line-height: 1.42; }
|
||||
li { margin-bottom: 8pt; }
|
||||
.quote { background: #3B2380; border-left: 4pt solid #F59E0B; border-radius: 6pt; padding: 10pt 14pt; margin-top: auto; }
|
||||
.quote p { font-size: 10pt; color: #DDD6FE; font-style: italic; margin: 0; line-height: 1.4; }
|
||||
.foot { font-size: 8pt; color: #B8AEE8; margin: 10pt 0 0 0; }
|
||||
</style></head>
|
||||
<body>
|
||||
<div class="wrap">
|
||||
<p class="kicker">12 · CONCLUSION</p>
|
||||
<h1>Conclusion & Legacy</h1>
|
||||
<div class="rule"></div>
|
||||
<ul>
|
||||
<li>The <b>Transformer</b>: the first sequence transduction model based entirely on attention — multi-headed self-attention replaces recurrent layers in encoder–decoder architectures.</li>
|
||||
<li>Trains <b>significantly faster</b> than recurrent or convolutional architectures thanks to full parallelization.</li>
|
||||
<li>New state of the art on <b>WMT 2014 EN→DE (28.4 BLEU)</b> and <b>EN→FR (41.8 BLEU)</b>, at a fraction of the previous training cost.</li>
|
||||
<li>The architecture became the foundation of modern large language models (BERT, GPT, and their successors) — attention really was all you needed.</li>
|
||||
</ul>
|
||||
<div class="quote">
|
||||
<p>“We are excited about the future of attention-based models and plan to apply them to other tasks.” — Vaswani et al., §7 Conclusion (paper p. 10)</p>
|
||||
</div>
|
||||
<p class="foot">Vaswani, Shazeer, Parmar, Uszkoreit, Jones, Gomez, Kaiser, Polosukhin. “Attention Is All You Need.” NeurIPS 2017 (arXiv:1706.03762). All figures/tables shown are cropped from the original paper PDF.</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
BIN
Binary file not shown.
|
After Width: | Height: | Size: 95 KiB |
BIN
Binary file not shown.
|
After Width: | Height: | Size: 64 KiB |
BIN
Binary file not shown.
|
After Width: | Height: | Size: 67 KiB |
+26
@@ -0,0 +1,26 @@
|
||||
[
|
||||
{
|
||||
"file": "fig1-03.png",
|
||||
"page": 3,
|
||||
"label": "Figure 1",
|
||||
"caption": "The Transformer - model architecture."
|
||||
},
|
||||
{
|
||||
"file": "fig2-04.png",
|
||||
"page": 4,
|
||||
"label": "Figure 2",
|
||||
"caption": "(left) Scaled Dot-Product Attention. (right) Multi-Head Attention consists of several attention layers running in parallel."
|
||||
},
|
||||
{
|
||||
"file": "table2-08.png",
|
||||
"page": 8,
|
||||
"label": "Table 2",
|
||||
"caption": "The Transformer achieves better BLEU scores than previous state-of-the-art models on the English-to-German and English-to-French newstest2014 tests at a fraction of the training cost."
|
||||
},
|
||||
{
|
||||
"file": "fig3-13.png",
|
||||
"page": 13,
|
||||
"label": "Figure 3",
|
||||
"caption": "An example of the attention mechanism following long-distance dependencies in the encoder self-attention in layer 5 of 6. Many of the attention heads attend to a distant dependency of the verb 'making', completing the phrase 'making...more difficult'. Attentions here shown only for the word 'making'. Different colors represent different heads. Best viewed in color."
|
||||
}
|
||||
]
|
||||
BIN
Binary file not shown.
|
After Width: | Height: | Size: 120 KiB |
@@ -0,0 +1,51 @@
|
||||
---
|
||||
name: pptx
|
||||
description: 从论文、大纲或结构化文本生成 PowerPoint (.pptx) 演示文稿。Use when 用户需要把一篇论文/文章/大纲做成幻灯片、slides、演示文稿、PPT、deck。Don't use when 只需纯文本总结、生成 Word/PDF、或修改已有 pptx 的单个像素级样式。
|
||||
---
|
||||
|
||||
# pptx Skill —— 从论文生成演示文稿
|
||||
|
||||
## 核心流程(第二层)
|
||||
|
||||
把一份来源文本(论文 / 大纲)转成 8-12 页的演示文稿,按以下步骤:
|
||||
|
||||
1. **通读来源**:理解论文的标题、作者、问题背景、方法、关键结果、结论。
|
||||
2. **规划页序**:一份合格的演示文稿总页数应为 8-12 页,至少覆盖——
|
||||
- 标题页(论文标题 + 作者/来源作为副标题)
|
||||
- 目录 / 大纲页
|
||||
- 研究背景 / 问题动机
|
||||
- 方法概述(**必须拆成 2 页**,例如「总体思路」与「关键机制」)
|
||||
- 关键结果 / 实验发现(**必须拆成 2 页**,例如「效率指标」与「效果对比」)
|
||||
- 局限性 / 讨论
|
||||
- 小结 / 结论页(要点式总结全篇)
|
||||
3. **提炼要点**:每页 3-5 条 bullet,每条一句话,避免整段照搬原文。
|
||||
4. **生成文件**:调用本 Skill 捆绑的脚本 `scripts/generate_pptx.py`
|
||||
(通过 `run_skill_script` 工具),传入下面约定的 JSON payload。
|
||||
|
||||
## 捆绑脚本调用约定
|
||||
|
||||
工具:`run_skill_script(name="pptx", script="generate_pptx.py", payload=<JSON字符串>)`
|
||||
|
||||
payload 的 JSON schema:
|
||||
|
||||
```json
|
||||
{
|
||||
"title": "演示文稿主标题(通常等于论文标题)",
|
||||
"subtitle": "副标题,通常是作者或来源,可留空",
|
||||
"slides": [
|
||||
{"title": "页标题", "bullets": ["要点1", "要点2", "要点3"]}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
约束:
|
||||
- `slides` **至少 8 项**(加上自动生成的标题页,总页数落在 8-12 页区间)。
|
||||
- 第一项通常是「目录 / 大纲」,最后一项应为「小结 / 结论」。
|
||||
- 每页 `bullets` 建议 3-5 条。
|
||||
|
||||
## 更详细的样式与实现细则(第三层)
|
||||
|
||||
如需了解版式、配色、python-pptx 的实现细节,或排查生成问题,
|
||||
再用 `read_skill_file` 读取本 Skill 内的:
|
||||
- `reference.md` —— 版式、配色与 python-pptx 技术细节
|
||||
- `scripts/generate_pptx.py` —— 生成器源码本身
|
||||
@@ -0,0 +1,43 @@
|
||||
# pptx Skill —— 技术细则(第三层 / 渐进式披露最深一层)
|
||||
|
||||
本文件对应本书「渐进式披露」的第三层:只有当 Agent 需要控制版式、配色,
|
||||
或排查生成问题时才会读取,平时不占用上下文。
|
||||
|
||||
## 版式约定
|
||||
|
||||
生成器使用 python-pptx 的空白版式(`slide_layouts[6]`),并手动摆放文本框,
|
||||
从而完全掌控排版,不依赖模板占位符:
|
||||
|
||||
- 画布尺寸:10 x 7.5 英寸(4:3)。
|
||||
- **标题页**:深蓝底(RGB 1F4E79),白色居中大标题(40pt)+ 浅蓝副标题(20pt)。
|
||||
- **内容页**:白底,顶部深蓝色条内放页标题(26pt 白字),下方为要点列表(18pt)。
|
||||
|
||||
## 配色
|
||||
|
||||
| 名称 | RGB | 用途 |
|
||||
|--------|----------|----------------|
|
||||
| ACCENT | #1F4E79 | 标题页底 / 色条 |
|
||||
| DARK | #222222 | 正文文字 |
|
||||
| LIGHT | #F2F5FA | 备用浅背景 |
|
||||
|
||||
## python-pptx 关键点
|
||||
|
||||
- `Presentation()` 新建演示文稿;`prs.slides.add_slide(layout)` 增页。
|
||||
- 文本必须放进 `text_frame`,逐段 `add_paragraph()`、逐段 `add_run()` 设置字体。
|
||||
- 纯色页背景:`slide.background.fill.solid()` 后设 `fore_color.rgb`。
|
||||
- 形状类型 `1` 对应矩形(MSO_SHAPE.RECTANGLE),用于顶部色条。
|
||||
- 保存:`prs.save(path)`,扩展名必须是 `.pptx`。
|
||||
|
||||
## 校验建议
|
||||
|
||||
生成后重新打开文件即可验证有效性:
|
||||
|
||||
```python
|
||||
from pptx import Presentation
|
||||
prs = Presentation("output/deck.pptx")
|
||||
print(len(list(prs.slides))) # 页数
|
||||
for s in prs.slides: # 每页第一个文本
|
||||
for shp in s.shapes:
|
||||
if shp.has_text_frame and shp.text_frame.text.strip():
|
||||
print(shp.text_frame.text.strip().splitlines()[0]); break
|
||||
```
|
||||
@@ -0,0 +1,151 @@
|
||||
"""
|
||||
pptx Skill 捆绑的可执行脚本:使用 python-pptx 从结构化大纲生成真实的 .pptx 文件。
|
||||
|
||||
这是 Agent Skills「渐进式披露」中第三层(细则 / 捆绑工具)的一部分:
|
||||
Agent 在读取 SKILL.md 后,得知需要通过 run_skill_script 工具调用本脚本,
|
||||
并按约定的 JSON schema 传入幻灯片大纲。本脚本负责把大纲落地为 PowerPoint。
|
||||
|
||||
payload JSON schema(由 SKILL.md 向 Agent 说明):
|
||||
{
|
||||
"title": "演示文稿主标题(字符串)",
|
||||
"subtitle": "副标题,通常是作者/来源(字符串,可选)",
|
||||
"slides": [
|
||||
{"title": "页标题", "bullets": ["要点1", "要点2", ...]},
|
||||
...
|
||||
]
|
||||
}
|
||||
|
||||
既可作为库被 import(build_presentation),也可作为 CLI 直接运行:
|
||||
python generate_pptx.py outline.json output/deck.pptx
|
||||
"""
|
||||
|
||||
import json
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
from pptx import Presentation
|
||||
from pptx.util import Pt, Inches
|
||||
from pptx.dml.color import RGBColor
|
||||
from pptx.enum.text import PP_ALIGN
|
||||
|
||||
|
||||
# 一套简单的品牌配色,作为设计起点(对应 SKILL.md 提到的「模板 / 设计起点」)
|
||||
ACCENT = RGBColor(0x1F, 0x4E, 0x79) # 深蓝
|
||||
DARK = RGBColor(0x22, 0x22, 0x22) # 近黑正文
|
||||
LIGHT = RGBColor(0xF2, 0xF5, 0xFA) # 浅色背景条
|
||||
|
||||
|
||||
def _set_slide_bg(slide, rgb):
|
||||
"""给整页填充一个纯色背景。"""
|
||||
fill = slide.background.fill
|
||||
fill.solid()
|
||||
fill.fore_color.rgb = rgb
|
||||
|
||||
|
||||
def _add_title_slide(prs, title, subtitle):
|
||||
slide = prs.slides.add_slide(prs.slide_layouts[6]) # 6 = 纯空白版式
|
||||
_set_slide_bg(slide, ACCENT)
|
||||
|
||||
# 主标题
|
||||
box = slide.shapes.add_textbox(Inches(0.8), Inches(2.2), Inches(8.4), Inches(2.0))
|
||||
tf = box.text_frame
|
||||
tf.word_wrap = True
|
||||
p = tf.paragraphs[0]
|
||||
p.alignment = PP_ALIGN.CENTER
|
||||
run = p.add_run()
|
||||
run.text = title
|
||||
run.font.size = Pt(40)
|
||||
run.font.bold = True
|
||||
run.font.color.rgb = RGBColor(0xFF, 0xFF, 0xFF)
|
||||
|
||||
# 副标题
|
||||
if subtitle:
|
||||
sbox = slide.shapes.add_textbox(Inches(0.8), Inches(4.3), Inches(8.4), Inches(1.0))
|
||||
stf = sbox.text_frame
|
||||
stf.word_wrap = True
|
||||
sp = stf.paragraphs[0]
|
||||
sp.alignment = PP_ALIGN.CENTER
|
||||
srun = sp.add_run()
|
||||
srun.text = subtitle
|
||||
srun.font.size = Pt(20)
|
||||
srun.font.color.rgb = RGBColor(0xD5, 0xDE, 0xEB)
|
||||
|
||||
|
||||
def _add_content_slide(prs, title, bullets):
|
||||
slide = prs.slides.add_slide(prs.slide_layouts[6])
|
||||
_set_slide_bg(slide, RGBColor(0xFF, 0xFF, 0xFF))
|
||||
|
||||
# 顶部标题色条
|
||||
bar = slide.shapes.add_shape(
|
||||
1, # MSO_SHAPE.RECTANGLE
|
||||
Inches(0), Inches(0), Inches(10), Inches(1.1),
|
||||
)
|
||||
bar.fill.solid()
|
||||
bar.fill.fore_color.rgb = ACCENT
|
||||
bar.line.fill.background()
|
||||
|
||||
tf = bar.text_frame
|
||||
tf.word_wrap = True
|
||||
tf.margin_left = Inches(0.5)
|
||||
p = tf.paragraphs[0]
|
||||
p.alignment = PP_ALIGN.LEFT
|
||||
run = p.add_run()
|
||||
run.text = title
|
||||
run.font.size = Pt(26)
|
||||
run.font.bold = True
|
||||
run.font.color.rgb = RGBColor(0xFF, 0xFF, 0xFF)
|
||||
|
||||
# 正文要点
|
||||
body = slide.shapes.add_textbox(Inches(0.7), Inches(1.5), Inches(8.6), Inches(5.2))
|
||||
btf = body.text_frame
|
||||
btf.word_wrap = True
|
||||
for i, bullet in enumerate(bullets):
|
||||
para = btf.paragraphs[0] if i == 0 else btf.add_paragraph()
|
||||
para.space_after = Pt(10)
|
||||
r = para.add_run()
|
||||
r.text = "• " + str(bullet)
|
||||
r.font.size = Pt(18)
|
||||
r.font.color.rgb = DARK
|
||||
|
||||
|
||||
def build_presentation(payload: dict, out_path: str) -> dict:
|
||||
"""从大纲 payload 构建 pptx,返回 {path, num_slides, titles} 供校验。"""
|
||||
title = payload.get("title", "Untitled Presentation")
|
||||
subtitle = payload.get("subtitle", "")
|
||||
slides = payload.get("slides", [])
|
||||
if not slides:
|
||||
raise ValueError("payload.slides 为空,至少需要一页内容")
|
||||
|
||||
prs = Presentation()
|
||||
prs.slide_width = Inches(10)
|
||||
prs.slide_height = Inches(7.5)
|
||||
|
||||
titles = []
|
||||
|
||||
# 标题页
|
||||
_add_title_slide(prs, title, subtitle)
|
||||
titles.append(title)
|
||||
|
||||
# 内容页
|
||||
for s in slides:
|
||||
s_title = s.get("title", "")
|
||||
bullets = s.get("bullets")
|
||||
if bullets is None:
|
||||
bullets = []
|
||||
_add_content_slide(prs, s_title, bullets)
|
||||
titles.append(s_title)
|
||||
|
||||
out = Path(out_path)
|
||||
out.parent.mkdir(parents=True, exist_ok=True)
|
||||
prs.save(str(out))
|
||||
|
||||
return {"path": str(out), "num_slides": len(list(prs.slides)), "titles": titles}
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) != 3:
|
||||
print("用法: python generate_pptx.py <outline.json> <output.pptx>", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
payload = json.loads(Path(sys.argv[1]).read_text(encoding="utf-8"))
|
||||
result = build_presentation(payload, sys.argv[2])
|
||||
print(json.dumps(result, ensure_ascii=False, indent=2))
|
||||
@@ -0,0 +1,67 @@
|
||||
from pathlib import Path
|
||||
|
||||
from prepare_official_skill import PROTOCOL
|
||||
from validate_official_run import (
|
||||
collect_kimi_metadata,
|
||||
collect_tool_calls,
|
||||
parse_stream,
|
||||
sha256,
|
||||
)
|
||||
|
||||
|
||||
def test_protocol_pins_exact_manuscript_workflow():
|
||||
assert PROTOCOL["runtime"]["official_skill_repository"] == "https://github.com/anthropics/skills.git"
|
||||
assert len(PROTOCOL["runtime"]["official_skill_revision"]) == 40
|
||||
assert PROTOCOL["output"]["minimum_slides"] == 10
|
||||
assert PROTOCOL["output"]["maximum_slides"] == 15
|
||||
assert PROTOCOL["output"]["minimum_paper_visuals"] == 3
|
||||
|
||||
|
||||
def test_protocol_records_runtime_agnostic_acceptance_policy():
|
||||
policy = PROTOCOL["runtime"]["acceptance_policy"].lower()
|
||||
assert "runtime-agnostic" in policy
|
||||
kimi = PROTOCOL["runtime"]["alternate_runtimes"]["kimi"]
|
||||
assert kimi["binary"] == "kimi"
|
||||
assert kimi["skills_flag"] == "--skills-dir"
|
||||
|
||||
|
||||
def test_sha256_reads_binary(tmp_path: Path):
|
||||
artifact = tmp_path / "x.bin"
|
||||
artifact.write_bytes(b"experiment-2-6")
|
||||
assert len(sha256(artifact)) == 64
|
||||
|
||||
|
||||
def test_collect_tool_calls_parses_kimi_stream(tmp_path: Path):
|
||||
stream = tmp_path / "kimi_stream.jsonl"
|
||||
stream.write_text(
|
||||
'{"role":"assistant","tool_calls":[{"type":"function","id":"t1",'
|
||||
'"function":{"name":"Skill","arguments":"{\\"skill\\":\\"pptx\\"}"}}]}\n'
|
||||
'{"role":"tool","tool_call_id":"t1","content":"Skill \\"pptx\\" loaded inline."}\n'
|
||||
'{"role":"assistant","content":"done"}\n',
|
||||
encoding="utf-8",
|
||||
)
|
||||
events, _ = parse_stream(stream)
|
||||
calls = collect_tool_calls(events)
|
||||
assert calls == [{"name": "Skill", "arguments": '{"skill":"pptx"}'}]
|
||||
|
||||
|
||||
def test_collect_kimi_metadata(tmp_path: Path):
|
||||
(tmp_path / "kimi_stream.jsonl").write_text(
|
||||
'{"role":"assistant","tool_calls":[{"type":"function","id":"t1",'
|
||||
'"function":{"name":"Read","arguments":"{\\"path\\":\\"x.md\\"}"}}]}\n'
|
||||
'{"role":"assistant","content":"final answer"}\n'
|
||||
'{"role":"meta","type":"session.resume_hint","session_id":"s1"}\n',
|
||||
encoding="utf-8",
|
||||
)
|
||||
(tmp_path / "kimi_exit.json").write_text('{"return_code": 0}', encoding="utf-8")
|
||||
(tmp_path / "runtime.json").write_text(
|
||||
'{"runtime": "kimi", "model_alias": "kimi-code/k3"}', encoding="utf-8"
|
||||
)
|
||||
events, _ = parse_stream(tmp_path / "kimi_stream.jsonl")
|
||||
metadata = collect_kimi_metadata(events, tmp_path)
|
||||
assert metadata["return_code"] == 0
|
||||
assert metadata["model_alias"] == "kimi-code/k3"
|
||||
assert metadata["num_tool_calls"] == 1
|
||||
assert metadata["tool_names"] == ["Read"]
|
||||
assert metadata["session_id"] == "s1"
|
||||
assert metadata["final_response"] == "final answer"
|
||||
@@ -0,0 +1,28 @@
|
||||
"""Shared bootstrap for agent-skills-ppt regression tests."""
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from types import ModuleType
|
||||
|
||||
|
||||
PROJECT_ROOT = Path(__file__).resolve().parents[1]
|
||||
if str(PROJECT_ROOT) not in sys.path:
|
||||
sys.path.insert(0, str(PROJECT_ROOT))
|
||||
|
||||
SCRIPTS_DIR = PROJECT_ROOT / "skills" / "pptx" / "scripts"
|
||||
if str(SCRIPTS_DIR) not in sys.path:
|
||||
sys.path.insert(0, str(SCRIPTS_DIR))
|
||||
|
||||
try:
|
||||
import openai # noqa: F401
|
||||
except ImportError:
|
||||
openai_stub = ModuleType("openai")
|
||||
openai_stub.OpenAI = object
|
||||
sys.modules["openai"] = openai_stub
|
||||
|
||||
try:
|
||||
import pptx # noqa: F401
|
||||
except ImportError:
|
||||
pptx_stub = ModuleType("pptx")
|
||||
pptx_stub.Presentation = object
|
||||
sys.modules["pptx"] = pptx_stub
|
||||
@@ -0,0 +1,66 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Regression tests for dispatch() in demo.py.
|
||||
|
||||
Bug: the agentic loop parses tool-call arguments with a JSONDecodeError
|
||||
fallback to {} and then calls dispatch() with no try/except. dispatch()
|
||||
used to do args["name"] / args["payload"] etc., so any malformed or
|
||||
incomplete LLM tool call crashed the whole run with KeyError. Fixed to
|
||||
return "[error] ..." strings that the agent can recover from.
|
||||
"""
|
||||
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
from demo import dispatch, scan_skill_catalog
|
||||
|
||||
OUT = Path("/tmp/test_dispatch_out.pptx")
|
||||
|
||||
|
||||
def test_missing_name_returns_error_not_keyerror():
|
||||
catalog = scan_skill_catalog()
|
||||
# {} is exactly what the JSONDecodeError fallback in run_agent produces
|
||||
result = dispatch(catalog, "read_skill", {}, OUT)
|
||||
assert result.startswith("[error]")
|
||||
assert "name" in result
|
||||
|
||||
|
||||
def test_missing_payload_returns_error_not_keyerror():
|
||||
catalog = scan_skill_catalog()
|
||||
result = dispatch(catalog, "run_skill_script",
|
||||
{"name": "pptx", "script": "generate_pptx.py"}, OUT)
|
||||
assert result.startswith("[error]")
|
||||
assert "payload" in result
|
||||
|
||||
|
||||
def test_unknown_tool_still_returns_error():
|
||||
catalog = scan_skill_catalog()
|
||||
result = dispatch(catalog, "no_such_tool", {}, OUT)
|
||||
assert result.startswith("[error]")
|
||||
|
||||
|
||||
def test_valid_read_skill_still_works():
|
||||
catalog = scan_skill_catalog()
|
||||
result = dispatch(catalog, "read_skill", {"name": "pptx"}, OUT)
|
||||
assert not result.startswith("[error]")
|
||||
assert len(result) > 0
|
||||
|
||||
|
||||
def test_run_skill_script_rejects_absolute_path(tmp_path):
|
||||
"""run_skill_script executes the file, so it must stay inside scripts/."""
|
||||
outside = tmp_path / "evil.py"
|
||||
outside.write_text("raise AssertionError('executed out-of-tree script')")
|
||||
catalog = scan_skill_catalog()
|
||||
result = dispatch(catalog, "run_skill_script",
|
||||
{"name": "pptx", "script": str(outside), "payload": "{}"}, OUT)
|
||||
assert result.startswith("[error]")
|
||||
|
||||
|
||||
def test_run_skill_script_rejects_parent_traversal(tmp_path):
|
||||
outside = tmp_path / "evil.py"
|
||||
outside.write_text("raise AssertionError('executed out-of-tree script')")
|
||||
catalog = scan_skill_catalog()
|
||||
scripts_dir = (catalog["pptx"]["dir"] / "scripts").resolve()
|
||||
rel = os.path.relpath(outside, scripts_dir)
|
||||
result = dispatch(catalog, "run_skill_script",
|
||||
{"name": "pptx", "script": rel, "payload": "{}"}, OUT)
|
||||
assert result.startswith("[error]")
|
||||
@@ -0,0 +1,31 @@
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
|
||||
from generate_pptx import build_presentation
|
||||
|
||||
|
||||
def test_null_bullets_like_omit():
|
||||
out = Path(tempfile.mkdtemp()) / "out.pptx"
|
||||
result = build_presentation(
|
||||
{
|
||||
"title": "Demo",
|
||||
"slides": [{"title": "Slide", "bullets": None}],
|
||||
},
|
||||
str(out),
|
||||
)
|
||||
assert out.exists()
|
||||
assert result["num_slides"] == 2
|
||||
assert "Slide" in result["titles"]
|
||||
|
||||
|
||||
def test_missing_bullets_still_works():
|
||||
out = Path(tempfile.mkdtemp()) / "out.pptx"
|
||||
result = build_presentation(
|
||||
{
|
||||
"title": "Demo",
|
||||
"slides": [{"title": "Slide"}],
|
||||
},
|
||||
str(out),
|
||||
)
|
||||
assert out.exists()
|
||||
assert result["num_slides"] == 2
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user