我差点用 LangGraph 做社交媒体自动化(但我改而构建 MCP 服务器的原因)

发布: (2025年12月12日 GMT+8 20:50)
7 min read
原文: Dev.to

Source: Dev.to

引言

我刚在 X 上发布了我的第一条 AI 生成的推文。它由 Groq 的免费 AI 生成,经过我自建的 MCP 服务器处理,并通过 Ayrshare 发布——全部 $0/月
总构建时间? 不到一天

我差点用了 LangGraph。我花了好几天研究 LangChain 那个 2000 行的社交媒体代理。它已可投入生产,经过实战检验,令人印象深刻。但我走了另一条路,并在此过程中省下了 $45/月

为什么我没有使用 LangGraph

LangGraph 很强大。LangChain 的社交媒体代理仓库(1.7k+ 星)提供了:

  • 带审批门的人工在环工作流
  • 用于复杂流程的状态检查点
  • 多步骤代理编排
  • 经受实战考验的参考实现

对于社交媒体自动化,LangGraph 提供了一切:内容生成、审阅循环、发布工作流以及分析——并内置状态管理。

不匹配之处

我的使用场景要简单得多:

  1. 用户提供内容
  2. AI 为平台进行优化
  3. 保存为草稿
  4. 准备好后发布

我不需要图结构,我只需要一次函数调用。当我完成一半的 LangGraph Cloud 设置时,我意识到自己在解决错误的问题。

LangGraph 的要求

  • 持久运行时(LangGraph Cloud 最低 $29/月,或自行部署 VPS)
  • 用于检查点的 PostgreSQL/MongoDB
  • 持续在线的基础设施
  • 框架特定概念(图、节点、边)

LangGraph 不能在 Cloudflare Workers 上运行,而 Workers 依赖无状态、边缘部署的函数且没有冷启动。切换框架还意味着要重写所有代码。

为什么我选择模型上下文协议(MCP)

MCP 是一种 协议,而不是框架。任何 MCP 客户端(Claude Desktop、VS Code + Continue、自定义 UI)都可以在不修改的情况下使用我的服务器。

架构假设

  • 无状态请求/响应
  • SQLite(Cloudflare D1)用于持久化
  • 没有冷启动
  • 全球分布

实现快照

  • 约 800 行 TypeScript
  • 8 个工具,3 个资源,3 个提示词
  • 完整的草稿 CRUD
  • AI 内容生成
  • 多平台发布

随着 MCP 的采纳增长(Anthropic、Zed、Continue、Cody),服务器的价值会倍增,因为它不依赖于特定框架的生命周期。

成本对比

组件MCP 方案LangGraph 方案
服务器 / 运行时Cloudflare Workers $5/月(含 D1、KV、Vectorize、R2)LangGraph Cloud $29/月(或 VPS $10‑20)
LLM APIGroq 免费层OpenAI $20‑30/月
数据库SQLite (D1) $0‑10/月PostgreSQL/MongoDB $0‑10/月
社交媒体 APIAyrshare 免费(每月 10 条帖子)
总计$5/月$50‑80/月

对于自由职业者试验想法来说,$5$50 的差距意义重大。

架构图

Claude Desktop (Client)
   ↓ JSON‑RPC over stdio
MCP Server (TypeScript)
├── Tools (LLM‑controlled actions)
│   ├── draft_post
│   ├── schedule_post
│   ├── post_immediately
│   ├── generate_thread
│   └── analyze_engagement
├── Resources (App‑controlled data)
│   ├── drafts://list
│   ├── scheduled://posts
│   └── stats://summary
├── Prompts (User‑invoked templates)
│   ├── write_tweet
│   ├── linkedin_post
│   └── thread_generator
├── Storage (SQLite → D1)
└── Integrations
    ├── Ayrshare (multi‑platform posting)
    └── Groq (AI content generation)

每一层都是独立且可替换的。

关键组件

存储 (SQLite → Cloudflare D1)

import Database from 'better-sqlite3';

export class StorageService {
  private db: Database.Database;

  constructor(dbPath: string) {
    this.db = new Database(dbPath);
    this.initializeSchema();
  }

  createDraft(data: DraftData): Draft {
    const id = crypto.randomUUID();
    const now = new Date().toISOString();

    this.db.prepare(`
      INSERT INTO drafts (id, content, platform, tone, status, created_at)
      VALUES (?, ?, ?, ?, 'draft', ?)
    `).run(id, data.content, data.platform, data.tone, now);

    return this.getDraft(id);
  }
}

迁移到 Cloudflare D1

// 本地开发
const db = new Database('./social_media.db');

// Edge 运行时
const db = env.DB; // Cloudflare D1 绑定

相同的 SQL,不同的运行时。

社交媒体 API (Ayrshare)

export class SocialMediaAPI {
  private apiKey: string;
  private baseUrl = 'https://app.ayrshare.com/api';

  async postImmediately(content: string, platforms: string[]) {
    const response = await fetch(`${this.baseUrl}/post`, {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${this.apiKey}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        post: content,
        platforms,
      }),
    });

    return response.json();
  }
}

一个 API,覆盖十个平台。

内容生成器 (Groq 免费层)

import Groq from 'groq-sdk';

export class ContentGenerator {
  private client: Groq;

  async generate(request: GenerateRequest): Promise {
    const systemPrompt = this.buildSystemPrompt(request);

    const response = await this.client.chat.completions.create({
      model: 'llama-3.3-70b-versatile', // FREE
      messages: [
        { role: 'system', content: systemPrompt },
        { role: 'user', content: request.input },
      ],
      max_tokens: 1000,
      temperature: 0.7,
    });

    const text = response.choices[0]?.message?.content || '';
    return this.parseResponse(text, request);
  }

  private buildSystemPrompt(request: GenerateRequest): string {
    const platformPrompts = {
      twitter: `Create engaging tweets that:
- Stay under ${request.maxLength} characters (STRICT)
- Use ${request.tone} tone
- Hook readers in the first line
- End with engagement (question or CTA)`,

      linkedin: `Create professional posts that:
- Are detailed (1,300‑1,500 characters)
- Use ${request.tone} tone
- Start with a compelling hook
- Include 3‑5 key insights with takeaways`,
    };

    return platformPrompts[request.platform];
  }
}

质量极佳,成本为 $0。速率限制:30 请求/分钟,绰绰有余。

MCP 服务器骨架

import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';

const server = new Server(
  { name: 'social-media-server', version: '1.0.0' },
  { capabilities: { tools: {}, resources: {}, prompts: {} } }
);

// Define tools
server.setRequestHandler(ListToolsRequestSchema, async () => ({
  tools: [
    {
      name: 'draft_post',
      // …
    },
    // other tools …
  ],
}));

服务器通过简单的 JSON‑RPC 接口公开工具、资源和提示,任何兼容 MCP 的客户端都可以使用。

结论

通过在 Cloudflare Workers 上部署轻量级 模型上下文协议 服务器,我:

  • 摒弃了持久运行时和复杂状态管理的需求
  • 将月费用从 约 $50 降至 $5
  • 不到一天 的时间内交付了完整的社交媒体自动化流水线

如果你的 AI 工作流很直接——生成、审阅、执行——采用协议优先的方式往往比引入像 LangGraph 这样的大型框架更经济、更灵活。

Back to Blog

相关文章

阅读更多 »

我放弃做 FinOps 咨询

几个月前,我开始支持不同的客户实施资源和基础设施优化策略。这是一个复杂的决定……