みんな大好き pptx 生成。日頃は gpt-5.4/5.5 か opus-4.7 に最近はお任せすることが多いのですが、これらはかなり高価なモデルなので、正直このモデルに pptx を作らせるのは無駄だなぁって思ってました。
一度の pptx 生成で普通に 1,000 円超えるし、正直社外向けのかっちょいい pptx でもなければ社内向けはシンプルなスライド、または word の方が良かったりもするわけで、日頃の業務で使う pptx をこのモデルでやるのはなぁ... と悶々としていました。
というわけでもっとお安いが opus 相当と表明されている alibaba/qwen3.6-27b で pptx 生成させたら opus みたいにいい感じの資料が作られるのかやってみました。
条件
- モデル: alibaba/qwen3.6-27b
- pptx tool: ppptxgenjs
- プロンプト: 以下の通り
現在のディレクトリに pptxgenjs を用いて openai の概要や特徴 anthropic の違いを技術者向けに説明するプレゼンテーション資料 pptx を作成しなさい。中身のコンテンツやデザインはあなたに完全にお任せします。 pptxgenjs はすでにインストール済みです。
一発ポンだしで出てきた js
/**
* OpenAI vs Anthropic 技術者向け比較プレゼンテーション
* pptxgenjs を用いて生成
*/
const pptxgen = require("pptxgenjs");
const fs = require("fs");
const path = require("path");
// カラーパレット
const colors = {
darkBg: "1B1B2F",
accentBlue: "4A90D9",
accentOrange: "FF6B35",
accentGreen: "2ECC71",
white: "FFFFFF",
lightGray: "E0E0E0",
darkText: "2C2C2C",
codeBg: "2D2D2D",
openaiBlue: "10A37F",
anthropicPurple: "7B6CF0",
};
// プレゼンテーションを作成
const pres = new pptxgen();
pres.layout = "LAYOUT_WIDE";
pres.author = "AI Presentation Generator";
pres.company = "Tech Talk";
pres.subject = "OpenAI vs Anthropic - Technical Comparison";
pres.title = "OpenAI vs Anthropic: Technical Comparison for Engineers";
// ============================================================
// Slide 1: タイトルスライド
// ============================================================
const slide1 = pres.addSlide();
slide1.background = { color: colors.darkBg };
// 装飾ライン
slide1.addShape("rect", {
x: 0,
y: 0,
w: "100%",
h: 0.05,
fill: { color: colors.accentBlue },
});
// タイトル
slide1.addText("OpenAI vs Anthropic", {
x: 1,
y: 1.5,
w: "80%",
h: 1.5,
fontSize: 44,
fontFace: "Arial",
color: colors.white,
bold: true,
align: "center",
});
// サブタイトル
slide1.addText("Technical Comparison for Engineers", {
x: 1,
y: 3,
w: "80%",
h: 1,
fontSize: 24,
fontFace: "Arial",
color: colors.accentBlue,
align: "center",
});
// 装飾ライン
slide1.addShape("rect", {
x: "35%",
y: 4,
w: "30%",
h: 0.04,
fill: { color: colors.accentOrange },
});
// 説明テキスト
slide1.addText("LLM アーキテクチャ・安全性・エコシステムを比較", {
x: 1,
y: 4.3,
w: "80%",
h: 0.8,
fontSize: 18,
fontFace: "Arial",
color: colors.lightGray,
align: "center",
});
// 日付
slide1.addText(new Date().toLocaleDateString("ja-JP"), {
x: 1,
y: 7.2,
w: "80%",
h: 0.5,
fontSize: 14,
fontFace: "Arial",
color: colors.lightGray,
align: "center",
});
// ============================================================
// Slide 2: アジェンダ
// ============================================================
const slide2 = pres.addSlide();
slide2.background = { color: colors.darkBg };
slide2.addShape("rect", {
x: 0,
y: 0,
w: "100%",
h: 0.05,
fill: { color: colors.accentBlue },
});
// ヘッダー
slide2.addText("Agenda", {
x: 0.5,
y: 0.3,
w: 3,
h: 0.8,
fontSize: 32,
fontFace: "Arial",
color: colors.white,
bold: true,
});
const agendaItems = [
{ num: "01", title: "OpenAI Overview", desc: "概要と技術スタック" },
{ num: "02", title: "Anthropic Overview", desc: "概要と安全AIの理念" },
{ num: "03", title: "Architecture Comparison", desc: "アーキテクチャの違い" },
{ num: "04", title: "Model Capabilities", desc: "モデル性能の比較" },
{ num: "05", title: "Safety & Alignment", desc: "安全性とアライメント" },
{ num: "06", title: "Ecosystem & Tools", desc: "エコシステムと開発者ツール" },
{ num: "07", title: "Pricing & Performance", desc: "コストとパフォーマンス" },
{
num: "08",
title: "Use Case Selection",
desc: "ユースケース別の選択ガイド",
},
];
agendaItems.forEach((item, index) => {
const yPos = 1.3 + index * 0.75;
// 番号
slide2.addText(item.num, {
x: 0.8,
y: yPos,
w: 1,
h: 0.6,
fontSize: 20,
fontFace: "Arial",
color: colors.accentBlue,
bold: true,
});
// タイトル
slide2.addText(item.title, {
x: 1.8,
y: yPos,
w: 4,
h: 0.35,
fontSize: 18,
fontFace: "Arial",
color: colors.white,
bold: true,
});
// 説明
slide2.addText(item.desc, {
x: 1.8,
y: yPos + 0.35,
w: 4,
h: 0.3,
fontSize: 14,
fontFace: "Arial",
color: colors.lightGray,
});
// 横線
slide2.addShape("rect", {
x: 0.8,
y: yPos + 0.65,
w: 8.4,
h: 0.01,
fill: { color: "333355" },
});
});
// ============================================================
// Slide 3: OpenAI Overview
// ============================================================
const slide3 = pres.addSlide();
slide3.background = { color: colors.darkBg };
slide3.addShape("rect", {
x: 0,
y: 0,
w: "100%",
h: 0.05,
fill: { color: colors.openaiBlue },
});
slide3.addText("01", {
x: 0.5,
y: 0.3,
w: 1,
h: 0.6,
fontSize: 24,
fontFace: "Arial",
color: colors.openaiBlue,
bold: true,
});
slide3.addText("OpenAI Overview", {
x: 1.5,
y: 0.3,
w: 8,
h: 0.8,
fontSize: 32,
fontFace: "Arial",
color: colors.white,
bold: true,
});
const openaiContent = [
{
label: "Founded",
value: "2015年 / San Francisco, CA",
},
{
label: "Mission",
value: "Ensure AGI is developed beneficially for humanity",
},
{
label: "Key Models",
value: "GPT-4o, GPT-4.1, o3, o4-mini, o3-pro",
},
{
label: "Architecture",
value: "Transformer-based (Decoder-only / Hybrid)",
},
{
label: "Training Scale",
value: "Multi-hundred billion parameters, massive compute",
},
{
label: "Key Strengths",
value: "Reasoning, Coding, Multimodal, Ecosystem maturity",
},
];
openaiContent.forEach((item, index) => {
const yPos = 1.4 + index * 0.95;
// アイコン背景
slide3.addShape("roundRect", {
x: 0.8,
y: yPos,
w: 0.5,
h: 0.5,
fill: { color: colors.openaiBlue },
rectRadius: 0.08,
});
// ラベル
slide3.addText(item.label, {
x: 1.5,
y: yPos,
w: 2.5,
h: 0.4,
fontSize: 16,
fontFace: "Arial",
color: colors.openaiBlue,
bold: true,
});
// 値
slide3.addText(item.value, {
x: 1.5,
y: yPos + 0.35,
w: 8,
h: 0.5,
fontSize: 15,
fontFace: "Arial",
color: colors.white,
});
});
// 注記ボックス
slide3.addShape("roundRect", {
x: 0.5,
y: 7,
w: 9,
h: 0.7,
fill: { color: "2A2A4A" },
rectRadius: 0.1,
});
slide3.addText(
"OpenAIは「Reasoning Models (o-series)」で推論能力に注力。Chain-of-Thoughtを内部で隠蔽し、ユーザーは結果のみを確認。",
{
x: 0.8,
y: 7.1,
w: 8.5,
h: 0.5,
fontSize: 13,
fontFace: "Arial",
color: colors.lightGray,
},
);
// ============================================================
// Slide 4: Anthropic Overview
// ============================================================
const slide4 = pres.addSlide();
slide4.background = { color: colors.darkBg };
slide4.addShape("rect", {
x: 0,
y: 0,
w: "100%",
h: 0.05,
fill: { color: colors.anthropicPurple },
});
slide4.addText("02", {
x: 0.5,
y: 0.3,
w: 1,
h: 0.6,
fontSize: 24,
fontFace: "Arial",
color: colors.anthropicPurple,
bold: true,
});
slide4.addText("Anthropic Overview", {
x: 1.5,
y: 0.3,
w: 8,
h: 0.8,
fontSize: 32,
fontFace: "Arial",
color: colors.white,
bold: true,
});
const anthropicContent = [
{
label: "Founded",
value: "2021年 / San Francisco, CA (ex-OpenAI researchers)",
},
{
label: "Mission",
value: "Develop safe AI through rigorous research & transparency",
},
{
label: "Key Models",
value: "Claude Opus, Sonnet, Haiku (Claude 4 series)",
},
{
label: "Architecture",
value: "Transformer-based (Constitutional AI approach)",
},
{
label: "Core Philosophy",
value: "Constitutional AI: Safety-by-design, not safety-by-prompt",
},
{
label: "Key Strengths",
value: "Safety, Long context, Nuanced reasoning, Transparency",
},
];
anthropicContent.forEach((item, index) => {
const yPos = 1.4 + index * 0.95;
slide4.addShape("roundRect", {
x: 0.8,
y: yPos,
w: 0.5,
h: 0.5,
fill: { color: colors.anthropicPurple },
rectRadius: 0.08,
});
slide4.addText(item.label, {
x: 1.5,
y: yPos,
w: 2.5,
h: 0.4,
fontSize: 16,
fontFace: "Arial",
color: colors.anthropicPurple,
bold: true,
});
slide4.addText(item.value, {
x: 1.5,
y: yPos + 0.35,
w: 8,
h: 0.5,
fontSize: 15,
fontFace: "Arial",
color: colors.white,
});
});
// 注記ボックス
slide4.addShape("roundRect", {
x: 0.5,
y: 7,
w: 9,
h: 0.7,
fill: { color: "2A2A4A" },
rectRadius: 0.1,
});
slide4.addText(
"Anthropicは「Constitutional AI」で有名。AIが自らの行動原則に基づいて自己改善・自己規制するフレームワーク。",
{
x: 0.8,
y: 7.1,
w: 8.5,
h: 0.5,
fontSize: 13,
fontFace: "Arial",
color: colors.lightGray,
},
);
// ============================================================
// Slide 5: Architecture Comparison
// ============================================================
const slide5 = pres.addSlide();
slide5.background = { color: colors.darkBg };
slide5.addShape("rect", {
x: 0,
y: 0,
w: "100%",
h: 0.05,
fill: { color: colors.accentBlue },
});
slide5.addText("03", {
x: 0.5,
y: 0.3,
w: 1,
h: 0.6,
fontSize: 24,
fontFace: "Arial",
color: colors.accentBlue,
bold: true,
});
slide5.addText("Architecture Comparison", {
x: 1.5,
y: 0.3,
w: 8,
h: 0.8,
fontSize: 32,
fontFace: "Arial",
color: colors.white,
bold: true,
});
// テーブルヘッダー
const tableHeaders = ["Aspect", "OpenAI", "Anthropic"];
const tableData = [
["Base Architecture", "Transformer (Decoder)", "Transformer (Decoder)"],
[
"Training Approach",
"RLHF + Constitutional-like",
"Constitutional AI (RLAIF)",
],
["Reasoning", "Internal CoT (hidden)", "Transparent reasoning options"],
["Context Window", "Up to 200K tokens", "Up to 200K tokens"],
[
"Multimodal",
"Native (vision, audio, text)",
"Vision + text (audio via API)",
],
["Model Sizes", "Multiple (mini → large)", "Haiku → Sonnet → Opus"],
["Open Weights", "No (API-only)", "No (API-only)"],
["Custom Fine-tuning", "Yes (API)", "Yes (API + Bedrock)"],
];
// テーブル描画
const tableStartY = 1.3;
const rowHeight = 0.6;
const colWidths = [2.5, 3.8, 3.8];
// ヘッダー行
tableHeaders.forEach((header, colIndex) => {
slide5.addShape("rect", {
x: 0.5 + colWidths.slice(0, colIndex).reduce((a, b) => a + b, 0),
y: tableStartY,
w: colWidths[colIndex],
h: rowHeight,
fill: { color: "2A2A4A" },
});
slide5.addText(header, {
x: 0.5 + colWidths.slice(0, colIndex).reduce((a, b) => a + b, 0) + 0.1,
y: tableStartY + 0.05,
w: colWidths[colIndex] - 0.2,
h: rowHeight - 0.1,
fontSize: 14,
fontFace: "Arial",
color: colors.accentBlue,
bold: true,
});
});
// データ行
tableData.forEach((row, rowIndex) => {
const y = tableStartY + rowHeight + rowIndex * rowHeight;
const bgColor = rowIndex % 2 === 0 ? "1F1F35" : "1B1B2F";
row.forEach((cell, colIndex) => {
const x = 0.5 + colWidths.slice(0, colIndex).reduce((a, b) => a + b, 0);
slide5.addShape("rect", {
x,
y,
w: colWidths[colIndex],
h: rowHeight,
fill: { color: bgColor },
line: { color: "333355", width: 0.25 },
});
slide5.addText(cell, {
x: x + 0.1,
y: y + 0.05,
w: colWidths[colIndex] - 0.2,
h: rowHeight - 0.1,
fontSize: 12,
fontFace: "Arial",
color: colors.white,
});
});
});
// ============================================================
// Slide 6: Model Capabilities
// ============================================================
const slide6 = pres.addSlide();
slide6.background = { color: colors.darkBg };
slide6.addShape("rect", {
x: 0,
y: 0,
w: "100%",
h: 0.05,
fill: { color: colors.accentBlue },
});
slide6.addText("04", {
x: 0.5,
y: 0.3,
w: 1,
h: 0.6,
fontSize: 24,
fontFace: "Arial",
color: colors.accentBlue,
bold: true,
});
slide6.addText("Model Capabilities", {
x: 1.5,
y: 0.3,
w: 8,
h: 0.8,
fontSize: 32,
fontFace: "Arial",
color: colors.white,
bold: true,
});
// 比較カード
const capabilities = [
{
category: "Coding",
openai: "★★★★★",
anthropic: "★★★★☆",
note: "OpenAI: DeepCoder/o-series excels in complex coding tasks",
},
{
category: "Reasoning",
openai: "★★★★★",
anthropic: "★★★★★",
note: "Both strong; OpenAI hides CoT, Anthropic offers transparency",
},
{
category: "Long Context",
openai: "★★★★☆",
anthropic: "★★★★★",
note: "Anthropic: Better needle-in-haystack retrieval in 200K context",
},
{
category: "Safety",
openai: "★★★★☆",
anthropic: "★★★★★",
note: "Anthropic: Constitutional AI provides more robust safety guarantees",
},
{
category: "Multimodal",
openai: "★★★★★",
anthropic: "★★★★☆",
note: "OpenAI: Native audio I/O (GPT-4o), structured vision analysis",
},
{
category: "Speed/Cost",
openai: "★★★★☆",
anthropic: "★★★★☆",
note: "Both offer tiered pricing; Haiku/o4-mini are budget-friendly",
},
];
capabilities.forEach((cap, index) => {
const yPos = 1.3 + index * 1.05;
// カテゴリ
slide6.addText(cap.category, {
x: 0.8,
y: yPos,
w: 1.8,
h: 0.35,
fontSize: 15,
fontFace: "Arial",
color: colors.accentBlue,
bold: true,
});
// OpenAI スコア
slide6.addText(`OpenAI: ${cap.openai}`, {
x: 2.8,
y: yPos,
w: 2.5,
h: 0.35,
fontSize: 14,
fontFace: "Arial",
color: colors.openaiBlue,
});
// Anthropic スコア
slide6.addText(`Anthropic: ${cap.anthropic}`, {
x: 5.5,
y: yPos,
w: 3,
h: 0.35,
fontSize: 14,
fontFace: "Arial",
color: colors.anthropicPurple,
});
// 注記
slide6.addText(cap.note, {
x: 0.8,
y: yPos + 0.4,
w: 8.5,
h: 0.4,
fontSize: 11,
fontFace: "Arial",
color: colors.lightGray,
});
// 区切り線
if (index < capabilities.length - 1) {
slide6.addShape("rect", {
x: 0.8,
y: yPos + 0.85,
w: 8.5,
h: 0.01,
fill: { color: "333355" },
});
}
});
// ============================================================
// Slide 7: Safety & Alignment
// ============================================================
const slide7 = pres.addSlide();
slide7.background = { color: colors.darkBg };
slide7.addShape("rect", {
x: 0,
y: 0,
w: "100%",
h: 0.05,
fill: { color: colors.accentGreen },
});
slide7.addText("05", {
x: 0.5,
y: 0.3,
w: 1,
h: 0.6,
fontSize: 24,
fontFace: "Arial",
color: colors.accentGreen,
bold: true,
});
slide7.addText("Safety & Alignment", {
x: 1.5,
y: 0.3,
w: 8,
h: 0.8,
fontSize: 32,
fontFace: "Arial",
color: colors.white,
bold: true,
});
// OpenAI セクション
slide7.addText("OpenAI Approach", {
x: 0.8,
y: 1.4,
w: 4,
h: 0.5,
fontSize: 20,
fontFace: "Arial",
color: colors.openaiBlue,
bold: true,
});
const openaiSafety = [
"RLHF (Reinforcement Learning from Human Feedback)",
"Red teaming with external partners",
"Internal safety review boards",
"Gradual capability rollouts",
"System-level content filters",
];
openaiSafety.forEach((item, index) => {
slide7.addText(">", {
x: 1,
y: 2 + index * 0.45,
w: 0.5,
h: 0.4,
fontSize: 16,
fontFace: "Arial",
color: colors.openaiBlue,
});
slide7.addText(item, {
x: 1.4,
y: 2 + index * 0.45,
w: 4,
h: 0.4,
fontSize: 14,
fontFace: "Arial",
color: colors.white,
});
});
// Anthropic セクション
slide7.addText("Anthropic Approach", {
x: 5.8,
y: 1.4,
w: 4,
h: 0.5,
fontSize: 20,
fontFace: "Arial",
color: colors.anthropicPurple,
bold: true,
});
const anthropicSafety = [
"Constitutional AI: AI self-evaluates against principles",
"RLAIF (RL from AI Feedback) at scale",
"Public research papers & transparency reports",
"Interpretability research (mechanistic)",
"Built-in refusal patterns for harmful requests",
];
anthropicSafety.forEach((item, index) => {
slide7.addText(">", {
x: 6,
y: 2 + index * 0.45,
w: 0.5,
h: 0.4,
fontSize: 16,
fontFace: "Arial",
color: colors.anthropicPurple,
});
slide7.addText(item, {
x: 6.4,
y: 2 + index * 0.45,
w: 4,
h: 0.4,
fontSize: 14,
fontFace: "Arial",
color: colors.white,
});
});
// 比較ボックス
slide7.addShape("roundRect", {
x: 0.5,
y: 4.6,
w: 9,
h: 1.2,
fill: { color: "2A2A4A" },
rectRadius: 0.15,
});
slide7.addText("Key Difference", {
x: 0.8,
y: 4.7,
w: 2,
h: 0.4,
fontSize: 16,
fontFace: "Arial",
color: colors.accentGreen,
bold: true,
});
slide7.addText(
"OpenAI: Safety is layered on top of capability development.\nAnthropic: Safety is baked into the training process from day one (Safety-by-design).",
{
x: 0.8,
y: 5.1,
w: 8.5,
h: 0.6,
fontSize: 13,
fontFace: "Arial",
color: colors.white,
},
);
// 追加の技術的詳細
slide7.addShape("roundRect", {
x: 0.5,
y: 6.1,
w: 9,
h: 1.5,
fill: { color: colors.codeBg },
rectRadius: 0.1,
});
slide7.addText("Constitutional AI Workflow (Anthropic)", {
x: 0.8,
y: 6.2,
w: 4,
h: 0.35,
fontSize: 14,
fontFace: "Arial",
color: colors.accentGreen,
bold: true,
});
const workflowSteps = [
"1. Train base model -> 2. Define constitution (principles) -> 3. AI critiques its own outputs -> 4. AI rewrites based on critique -> 5. Train preference model on rewrites",
];
slide7.addText(workflowSteps[0], {
x: 0.8,
y: 6.6,
w: 8.5,
h: 0.8,
fontSize: 12,
fontFace: "Courier New",
color: colors.lightGray,
});
// ============================================================
// Slide 8: Ecosystem & Tools
// ============================================================
const slide8 = pres.addSlide();
slide8.background = { color: colors.darkBg };
slide8.addShape("rect", {
x: 0,
y: 0,
w: "100%",
h: 0.05,
fill: { color: colors.accentBlue },
});
slide8.addText("06", {
x: 0.5,
y: 0.3,
w: 1,
h: 0.6,
fontSize: 24,
fontFace: "Arial",
color: colors.accentBlue,
bold: true,
});
slide8.addText("Ecosystem & Tools", {
x: 1.5,
y: 0.3,
w: 8,
h: 0.8,
fontSize: 32,
fontFace: "Arial",
color: colors.white,
bold: true,
});
// OpenAI エコシステム
slide8.addText("OpenAI Ecosystem", {
x: 0.8,
y: 1.4,
w: 4,
h: 0.5,
fontSize: 20,
fontFace: "Arial",
color: colors.openaiBlue,
bold: true,
});
const openaiTools = [
"Chat Completions API (standardized)",
"Assistants API (agents, code interpreter)",
"Functions / Tool Calling (structured output)",
"Whisper (speech-to-text)",
"TTS (text-to-speech, real-time voice)",
"DALL-E (image generation)",
"Embeddings (vector search)",
"Fine-tuning API (custom models)",
"OpenAI SDK (Python, Node.js)",
"ChatGPT / Canvas / Code Interpreter UI",
];
openaiTools.forEach((tool, index) => {
const col = index % 2;
const row = Math.floor(index / 2);
const x = col === 0 ? 0.8 : 5.2;
slide8.addText("[x]", {
x,
y: 2 + row * 0.45,
w: 0.4,
h: 0.4,
fontSize: 14,
fontFace: "Arial",
color: colors.openaiBlue,
});
slide8.addText(tool, {
x: x + 0.4,
y: 2 + row * 0.45,
w: 4,
h: 0.4,
fontSize: 13,
fontFace: "Arial",
color: colors.white,
});
});
// Anthropic エコシステム
slide8.addText("Anthropic Ecosystem", {
x: 0.8,
y: 4.4,
w: 4,
h: 0.5,
fontSize: 20,
fontFace: "Arial",
color: colors.anthropicPurple,
bold: true,
});
const anthropicTools = [
"Messages API (OpenAI-compatible format)",
"Tool Use (function calling)",
"Prompt Caching (cost optimization)",
"Extended Thinking (reasoning mode)",
"AWS Bedrock / Vertex AI integration",
"Claude SDK (Python, JS)",
"Computer Use (autonomous UI control)",
"Project Nautilus (agentic workflows)",
];
anthropicTools.forEach((tool, index) => {
const col = index % 2;
const row = Math.floor(index / 2);
const x = col === 0 ? 0.8 : 5.2;
slide8.addText("[x]", {
x,
y: 5 + row * 0.45,
w: 0.4,
h: 0.4,
fontSize: 14,
fontFace: "Arial",
color: colors.anthropicPurple,
});
slide8.addText(tool, {
x: x + 0.4,
y: 5 + row * 0.45,
w: 4,
h: 0.4,
fontSize: 13,
fontFace: "Arial",
color: colors.white,
});
});
// ============================================================
// Slide 9: Pricing Comparison
// ============================================================
const slide9 = pres.addSlide();
slide9.background = { color: colors.darkBg };
slide9.addShape("rect", {
x: 0,
y: 0,
w: "100%",
h: 0.05,
fill: { color: colors.accentOrange },
});
slide9.addText("07", {
x: 0.5,
y: 0.3,
w: 1,
h: 0.6,
fontSize: 24,
fontFace: "Arial",
color: colors.accentOrange,
bold: true,
});
slide9.addText("Pricing & Performance", {
x: 1.5,
y: 0.3,
w: 8,
h: 0.8,
fontSize: 32,
fontFace: "Arial",
color: colors.white,
bold: true,
});
// 価格比較テーブル
const pricingHeaders = [
"Model Tier",
"OpenAI",
"Price (input/output)",
"Anthropic",
"Price (input/output)",
];
const pricingData = [
["Budget", "o4-mini", "$1.10 / $4.40 /M", "Claude Haiku", "$0.80 / $4.00 /M"],
[
"Standard",
"GPT-4o",
"$2.50 / $10.00 /M",
"Claude Sonnet",
"$3.00 / $15.00 /M",
],
[
"Premium",
"o3-pro",
"$15.00 / $60.00 /M",
"Claude Opus",
"$15.00 / $75.00 /M",
],
];
const pricingColWidths = [1.2, 1.5, 2, 1.8, 2];
const pricingStartY = 1.3;
// ヘッダー
pricingHeaders.forEach((header, colIndex) => {
const x =
0.3 + pricingColWidths.slice(0, colIndex).reduce((a, b) => a + b, 0);
slide9.addShape("rect", {
x,
y: pricingStartY,
w: pricingColWidths[colIndex],
h: 0.55,
fill: { color: "2A2A4A" },
});
slide9.addText(header, {
x: x + 0.05,
y: pricingStartY + 0.05,
w: pricingColWidths[colIndex] - 0.1,
h: 0.45,
fontSize: 12,
fontFace: "Arial",
color: colors.accentOrange,
bold: true,
});
});
// データ
pricingData.forEach((row, rowIndex) => {
const y = pricingStartY + 0.55 + rowIndex * 0.55;
const bgColor = rowIndex % 2 === 0 ? "1F1F35" : "1B1B2F";
row.forEach((cell, colIndex) => {
const x =
0.3 + pricingColWidths.slice(0, colIndex).reduce((a, b) => a + b, 0);
slide9.addShape("rect", {
x,
y,
w: pricingColWidths[colIndex],
h: 0.55,
fill: { color: bgColor },
line: { color: "333355", width: 0.25 },
});
slide9.addText(cell, {
x: x + 0.05,
y: y + 0.05,
w: pricingColWidths[colIndex] - 0.1,
h: 0.45,
fontSize: 11,
fontFace: "Arial",
color: colors.white,
});
});
});
// 注記
slide9.addText(
"* Prices are approximate (per 1M tokens). Check official docs for latest pricing.",
{
x: 0.5,
y: 3.2,
w: 9,
h: 0.4,
fontSize: 11,
fontFace: "Arial",
color: colors.lightGray,
italic: true,
},
);
// パフォーマンスノート
slide9.addShape("roundRect", {
x: 0.5,
y: 3.8,
w: 9,
h: 3,
fill: { color: "2A2A4A" },
rectRadius: 0.15,
});
slide9.addText("Performance Notes", {
x: 0.8,
y: 3.95,
w: 3,
h: 0.4,
fontSize: 16,
fontFace: "Arial",
color: colors.accentOrange,
bold: true,
});
const perfNotes = [
"OpenAI o-series: Slower latency (reasoning) but higher quality on complex tasks",
"Anthropic Sonnet: Best price/performance ratio for most enterprise workloads",
"Prompt Caching (Anthropic): Up to 90% cost reduction for repeated prefix patterns",
"Extended Thinking (Anthropic): Toggleable reasoning depth for cost control",
"Both support streaming, function calling, and structured JSON output",
];
perfNotes.forEach((note, index) => {
slide9.addText(note, {
x: 0.8,
y: 4.4 + index * 0.42,
w: 8.5,
h: 0.4,
fontSize: 12,
fontFace: "Arial",
color: colors.white,
});
});
// ============================================================
// Slide 10: Use Case Selection Guide
// ============================================================
const slide10 = pres.addSlide();
slide10.background = { color: colors.darkBg };
slide10.addShape("rect", {
x: 0,
y: 0,
w: "100%",
h: 0.05,
fill: { color: colors.accentBlue },
});
slide10.addText("08", {
x: 0.5,
y: 0.3,
w: 1,
h: 0.6,
fontSize: 24,
fontFace: "Arial",
color: colors.accentBlue,
bold: true,
});
slide10.addText("Use Case Selection Guide", {
x: 1.5,
y: 0.3,
w: 8,
h: 0.8,
fontSize: 32,
fontFace: "Arial",
color: colors.white,
bold: true,
});
const useCases = [
{
useCase: "Code Generation / IDE Assist",
recommendation: "OpenAI",
reason: "DeepCoder, better code understanding, GitHub Copilot integration",
color: colors.openaiBlue,
},
{
useCase: "Enterprise Document Analysis",
recommendation: "Anthropic",
reason:
"Superior long-context retrieval, consistent quality over 200K tokens",
color: colors.anthropicPurple,
},
{
useCase: "Customer Support Chatbot",
recommendation: "Either",
reason: "Both excellent; Anthropic for safety, OpenAI for multimodal",
color: colors.accentGreen,
},
{
useCase: "Creative Writing / Content",
recommendation: "Anthropic",
reason:
"More nuanced tone control, less repetitive, better style adherence",
color: colors.anthropicPurple,
},
{
useCase: "Data Analysis / Math",
recommendation: "OpenAI",
reason: "o-series reasoning models excel at math and logic puzzles",
color: colors.openaiBlue,
},
{
useCase: "Compliance-Heavy Applications",
recommendation: "Anthropic",
reason: "Constitutional AI, transparent safety, audit-friendly behavior",
color: colors.anthropicPurple,
},
];
useCases.forEach((uc, index) => {
const yPos = 1.3 + index * 0.95;
// ユースケース名
slide10.addText(uc.useCase, {
x: 0.8,
y: yPos,
w: 3.5,
h: 0.35,
fontSize: 14,
fontFace: "Arial",
color: colors.white,
bold: true,
});
// 推奨
slide10.addShape("roundRect", {
x: 4.4,
y: yPos,
w: 1.5,
h: 0.35,
fill: { color: uc.color },
rectRadius: 0.08,
});
slide10.addText(uc.recommendation, {
x: 4.4,
y: yPos,
w: 1.5,
h: 0.35,
fontSize: 12,
fontFace: "Arial",
color: colors.white,
bold: true,
align: "center",
});
// 理由
slide10.addText(uc.reason, {
x: 6,
y: yPos,
w: 3.5,
h: 0.6,
fontSize: 11,
fontFace: "Arial",
color: colors.lightGray,
});
// 区切り線
if (index < useCases.length - 1) {
slide10.addShape("rect", {
x: 0.8,
y: yPos + 0.8,
w: 8.5,
h: 0.01,
fill: { color: "333355" },
});
}
});
// ============================================================
// Slide 11: API Code Comparison
// ============================================================
const slide11 = pres.addSlide();
slide11.background = { color: colors.darkBg };
slide11.addShape("rect", {
x: 0,
y: 0,
w: "100%",
h: 0.05,
fill: { color: colors.accentBlue },
});
slide11.addText("API Code Comparison", {
x: 0.5,
y: 0.3,
w: 9,
h: 0.8,
fontSize: 32,
fontFace: "Arial",
color: colors.white,
bold: true,
});
// OpenAI コード
slide11.addText("OpenAI (Python)", {
x: 0.8,
y: 1.3,
w: 4,
h: 0.4,
fontSize: 16,
fontFace: "Arial",
color: colors.openaiBlue,
bold: true,
});
slide11.addShape("roundRect", {
x: 0.5,
y: 1.8,
w: 4.5,
h: 4.5,
fill: { color: colors.codeBg },
rectRadius: 0.1,
});
const openaiCode = `from openai import OpenAI
client = OpenAI()
response = client.chat.completions.create(
model="gpt-4o",
messages=[
{"role": "user",
"content": "Explain quantum computing"}
],
temperature=0.7,
max_tokens=1000
)
print(response.choices[0]
.message.content)`;
slide11.addText(openaiCode, {
x: 0.7,
y: 1.9,
w: 4.1,
h: 4.2,
fontSize: 10,
fontFace: "Courier New",
color: "A8E6CF",
lineSpacingMultiple: 1.2,
});
// Anthropic コード
slide11.addText("Anthropic (Python)", {
x: 5.8,
y: 1.3,
w: 4,
h: 0.4,
fontSize: 16,
fontFace: "Arial",
color: colors.anthropicPurple,
bold: true,
});
slide11.addShape("roundRect", {
x: 5.5,
y: 1.8,
w: 4.5,
h: 4.5,
fill: { color: colors.codeBg },
rectRadius: 0.1,
});
const anthropicCode = `from anthropic import Anthropic
client = Anthropic()
message = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1000,
temperature=0.7,
messages=[
{"role": "user",
"content": "Explain quantum computing"}
]
)
print(message.content[0].text)`;
slide11.addText(anthropicCode, {
x: 5.7,
y: 1.9,
w: 4.1,
h: 4.2,
fontSize: 10,
fontFace: "Courier New",
color: "DDA0DD",
lineSpacingMultiple: 1.2,
});
// 類似性の注記
slide11.addShape("roundRect", {
x: 0.5,
y: 6.6,
w: 9,
h: 0.8,
fill: { color: "2A2A4A" },
rectRadius: 0.1,
});
slide11.addText(
"Both APIs follow similar patterns. Anthropic's Messages API is designed to be familiar to OpenAI developers. Migration between the two is relatively straightforward.",
{
x: 0.8,
y: 6.7,
w: 8.5,
h: 0.6,
fontSize: 13,
fontFace: "Arial",
color: colors.lightGray,
},
);
// ============================================================
// Slide 12: Summary / Key Takeaways
// ============================================================
const slide12 = pres.addSlide();
slide12.background = { color: colors.darkBg };
slide12.addShape("rect", {
x: 0,
y: 0,
w: "100%",
h: 0.05,
fill: { color: colors.accentBlue },
});
slide12.addText("Key Takeaways", {
x: 0.5,
y: 0.3,
w: 9,
h: 0.8,
fontSize: 36,
fontFace: "Arial",
color: colors.white,
bold: true,
});
const takeaways = [
{
icon: "[1]",
title: "Both are World-Class",
desc: "OpenAI and Anthropic offer production-ready LLMs with different philosophies. Neither is universally 'better' - choice depends on your use case.",
},
{
icon: "[2]",
title: "OpenAI: Capability-First",
desc: "Pushes the frontier of reasoning, coding, and multimodal. Best when raw capability and ecosystem breadth matter most.",
},
{
icon: "[3]",
title: "Anthropic: Safety-First",
desc: "Constitutional AI provides more predictable, auditable behavior. Best for compliance-heavy, enterprise, and long-document workloads.",
},
{
icon: "[4]",
title: "Interoperability is High",
desc: "Similar API patterns, shared tool-calling standards, and frameworks like LangChain/LlamaIndex abstract the provider layer.",
},
{
icon: "[5]",
title: "Recommendation",
desc: "Prototype with both. Use OpenAI for coding/reasoning-heavy tasks, Anthropic for document analysis and safety-critical applications.",
},
];
takeaways.forEach((t, index) => {
const yPos = 1.3 + index * 1.15;
slide12.addText(t.icon, {
x: 0.8,
y: yPos,
w: 0.6,
h: 0.5,
fontSize: 24,
});
slide12.addText(t.title, {
x: 1.5,
y: yPos,
w: 3,
h: 0.35,
fontSize: 18,
fontFace: "Arial",
color: colors.accentBlue,
bold: true,
});
slide12.addText(t.desc, {
x: 1.5,
y: yPos + 0.35,
w: 8,
h: 0.6,
fontSize: 13,
fontFace: "Arial",
color: colors.white,
});
if (index < takeaways.length - 1) {
slide12.addShape("rect", {
x: 0.8,
y: yPos + 1,
w: 8.5,
h: 0.01,
fill: { color: "333355" },
});
}
});
// ============================================================
// Slide 13: Thank You / Q&A
// ============================================================
const slide13 = pres.addSlide();
slide13.background = { color: colors.darkBg };
slide13.addShape("rect", {
x: 0,
y: 0,
w: "100%",
h: 0.05,
fill: { color: colors.accentBlue },
});
// 装飾
slide13.addShape("roundRect", {
x: "25%",
y: 2,
w: "50%",
h: 3,
fill: { color: "2A2A4A" },
rectRadius: 0.3,
});
slide13.addText("Thank You", {
x: 1,
y: 2.3,
w: "80%",
h: 1,
fontSize: 48,
fontFace: "Arial",
color: colors.white,
bold: true,
align: "center",
});
slide13.addText("Q & A", {
x: 1,
y: 3.3,
w: "80%",
h: 0.8,
fontSize: 32,
fontFace: "Arial",
color: colors.accentBlue,
align: "center",
});
// 装飾ライン
slide13.addShape("rect", {
x: "35%",
y: 4.2,
w: "30%",
h: 0.04,
fill: { color: colors.accentOrange },
});
slide13.addText("OpenAI vs Anthropic: Technical Comparison", {
x: 1,
y: 4.5,
w: "80%",
h: 0.6,
fontSize: 18,
fontFace: "Arial",
color: colors.lightGray,
align: "center",
});
// 参考リンク
slide13.addText(
"openai.com/index | anthropic.com/index | docs.anthropic.com",
{
x: 1,
y: 6.5,
w: "80%",
h: 0.5,
fontSize: 14,
fontFace: "Arial",
color: colors.accentBlue,
align: "center",
},
);
// ファイルを保存
const outputPath = path.join(__dirname, "output", "openai_vs_anthropic.pptx");
// outputディレクトリが存在しない場合は作成
const outputDir = path.dirname(outputPath);
if (!fs.existsSync(outputDir)) {
fs.mkdirSync(outputDir, { recursive: true });
}
pres
.write()
.then((blob) => {
return blob.arrayBuffer();
})
.then((arrayBuffer) => {
const buffer = Buffer.from(arrayBuffer);
fs.writeFileSync(outputPath, buffer);
console.log(`Presentation saved to: ${outputPath}`);
})
.catch((err) => {
console.error("Error saving presentation:", err);
});
出力された pptx
ちゃんとスライドのスタイルとかコンテンツの条件をちゃんと指定すれば普通に行けそう。
かかったコスト
| Date | Model | Credits Used |
|---|---|---|
| 05/04/26, 2:03 AM | qwen3.6-27b | $0.0729 |
| 05/04/26, 2:02 AM | qwen3.6-27b | $0.0713 |
| 05/04/26, 2:02 AM | qwen3.6-27b | $0.0711 |
| 05/04/26, 2:01 AM | qwen3.6-27b | $0.0636 |
| 05/04/26, 2:00 AM | qwen3.6-27b | $0.0627 |
| 05/04/26, 1:59 AM | qwen3.6-27b | $0.0559 |
| 05/04/26, 1:59 AM | qwen3.6-27b | $0.0542 |
| 05/04/26, 1:58 AM | qwen3.6-27b | $0.0850 |
| 05/04/26, 1:55 AM | qwen3.6-27b | $0.0290 |
| 05/04/26, 1:55 AM | qwen3.6-27b | $0.0275 |
| Total | $0.5932 |












