Token导航 LogoToken导航

Agent Skill · 研究检索

streaming-api-patterns(streaming API 模式)

用于辅助 API 设计、接口文档、请求响应结构和服务集成说明。它适合让 Agent 梳理 endpoint、生成 OpenAPI 草稿、检查字段命名、整理错误码或辅助前后端联调。使用时需要确认真实业务语义、鉴权方式、分页和错误处理规则;涉及生成接口文档时,应避免凭空补字段,最好从现有代码、schema 或接口样例中提取事实。

streaming-api-patterns 是研究检索类 Agent Skill,可用宿主为 Codex、Claude、Cursor、Gemini CLI,通过GitHub 仓库获取,权限为调用外部服务;许可证为 MIT,暂无第三方扫描结果,按安装量在研究检索类的 73,675 个 Skill 里排第 57,350。

总安装 436周安装 18GitHub Stars 公开资料未说明下载 143核验 2026-05-01

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
GitHub
许可证
MIT

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:streaming-api-patterns(streaming API 模式)
来源仓库:https://github.com/yonatangross/skillforge-claude-plugin
仓库路径:skills/streaming-api-patterns
安装命令:
npx skills add yonatangross/skillforge-claude-plugin --skill "streaming-api-patterns"
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

AgentSkills.tonpx skills
npx skills add yonatangross/skillforge-claude-plugin --skill "streaming-api-patterns"

这个 Skill 是做什么的

研究检索类 Skill 主要解决「找资料、核对事实、把来源整理清楚」的问题,通常会让助手先检索再总结。

streaming-api-patterns 用于辅助 API 设计与接口文档生成,支持流式服务集成说明。帮助梳理 endpoint、字段命名、错误码与分页规则,提升前后端联调效率。通过 npx 命令从 GitHub 安装,建议查阅原始文档了解细节。使用时需确认真实业务语义、鉴权方式与数据来源,避免凭空补字段。

适用宿主包括 Codex、Claude、Cursor、Gemini CLI,接入前应确认版本、权限和运行环境要求。

来源仓库内路径:skills/streaming-api-patterns

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 Codex、Claude、Cursor、Gemini CLI;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    可以直接复制的命令是 npx skills add yonatangross/skillforge-claude-plugin --skill "streaming-api-patt…;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    它需要调用外部服务,先在测试目录或测试账号里跑,确认没问题再放到正式项目。

常见问题

6 条

streaming-api-patterns 怎么安装?

在终端执行 npx skills add yonatangross/skillforge-claude-plugin --skill "streaming-api-patterns"。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

streaming-api-patterns 支持哪些 AI 工具?

公开资料标注支持 Codex、Claude、Cursor、Gemini CLI。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

streaming-api-patterns 需要什么权限?

权限级别是调用外部服务。该 Skill 可能调用第三方服务、云服务或外部模型 API,使用前需要确认账号、额度、数据发送范围和服务条款。

streaming-api-patterns 是免费的吗?

来源标注的许可证是 MIT。本站不代收任何费用,也不托管安装包;能否商用、要不要署名,以许可证原文为准。

streaming-api-patterns 用的人多吗?

公开数据是累计安装 436 次,近一周安装 18 次,下载 143 次。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

streaming-api-patterns 安全吗?

没有查到第三方扫描结果,安全性无法从公开资料判断,安装前请自行审查源码、依赖和命令行为。

值得选的地方和要先想清楚的地方

值得选的地方

  • 同时适配 4 种工具,换客户端不用重新找替代品。
  • 许可证明确为 MIT,商用和分发边界好判断。

先想清楚的地方

  • 没有第三方扫描结果,安全性只能靠自己读源码判断。
  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 Codex,想直接扩展它能力的人。
  • 需要处理研究检索类任务、又不想每次都手写提示词的人。

不太适合

  • 要求有安全扫描结论才肯安装的团队。
  • 需要厂商级技术支持和 SLA 的生产系统。

研究检索类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
find-skills

寻找技能 · Codex、Claude

31,199,81316,486操作浏览器MIT有提醒
self-improving-agent

自我改进 Agent · OpenClaw

16,464,0023,396接触敏感数据MIT-0通过
soultrace

灵魂追踪 · Codex、Claude

7,588,94412需要联网未明确有提醒
self-improving

自我完善 · OpenClaw

6,829,2841,046需要联网MIT-0通过
microsoft-foundry

微软代工厂 · Codex、Claude

6,614,144764调用外部服务未明确有提醒
streaming-api-patterns

streaming API 模式 · 本页

436—调用外部服务MIT未收录

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文

Streaming API Patterns

Overview

When to use this skill:

  • Streaming LLM responses (ChatGPT-style interfaces)
  • Real-time notifications and updates
  • Live data feeds (stock prices, analytics)
  • Chat applications
  • Progress updates for long-running tasks
  • Collaborative editing features

Core Technologies

1. Server-Sent Events (SSE)

Best for: Server-to-client streaming (LLM responses, notifications)

// Next.js Route Handler
export async function GET(req: Request) {
  const encoder = new TextEncoder()

  const stream = new ReadableStream({
    async start(controller) {
      // Send data
      controller.enqueue(encoder.encode('data: Hello\n\n'))

      // Keep connection alive
      const interval = setInterval(() => {
        controller.enqueue(encoder.encode(': keepalive\n\n'))
      }, 30000)

      // Cleanup
      req.signal.addEventListener('abort', () => {
        clearInterval(interval)
        controller.close()
      })
    }
  })

  return new Response(stream, {
    headers: {
      'Content-Type': 'text/event-stream',
      'Cache-Control': 'no-cache',
      'Connection': 'keep-alive',
    }
  })
}

// Client
const eventSource = new EventSource('/api/stream')
eventSource.onmessage = (event) => {
  console.log(event.data)
}

2. WebSockets

Best for: Bidirectional real-time communication (chat, collaboration)

// WebSocket Server (Next.js with ws)
import { WebSocketServer } from 'ws'

const wss = new WebSocketServer({ port: 8080 })

wss.on('connection', (ws) => {
  ws.on('message', (data) => {
    // Broadcast to all clients
    wss.clients.forEach((client) => {
      if (client.readyState === WebSocket.OPEN) {
        client.send(data)
      }
    })
  })
})

// Client
const ws = new WebSocket('ws://localhost:8080')
ws.onmessage = (event) => console.log(event.data)
ws.send(JSON.stringify({ type: 'message', text: 'Hello' }))

3. ReadableStream API

Best for: Processing large data streams with backpressure

async function* generateData() {
  for (let i = 0; i < 1000; i++) {
    await new Promise(resolve => setTimeout(resolve, 100))
    yield "data-" + i
  }
}

const stream = new ReadableStream({
  async start(controller) {
    for await (const chunk of generateData()) {
      controller.enqueue(new TextEncoder().encode(chunk + '\n'))
    }
    controller.close()
  }
})

LLM Streaming Pattern

// Server
import OpenAI from 'openai'

const openai = new OpenAI()

export async function POST(req: Request) {
  const { messages } = await req.json()

  const stream = await openai.chat.completions.create({
    model: 'gpt-4-turbo-preview',
    messages,
    stream: true
  })

  const encoder = new TextEncoder()

  return new Response(
    new ReadableStream({
      async start(controller) {
        for await (const chunk of stream) {
          const content = chunk.choices[0]?.delta?.content
          if (content) {
            controller.enqueue(encoder.encode("data: " + JSON.stringify({ content }) + "\n\n"))
          }
        }
        controller.enqueue(encoder.encode('data: [DONE]\n\n'))
        controller.close()
      }
    }),
    {
      headers: {
        'Content-Type': 'text/event-stream',
        'Cache-Control': 'no-cache'
      }
    }
  )
}

// Client
async function streamChat(messages) {
  const response = await fetch('/api/chat', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ messages })
  })

  const reader = response.body.getReader()
  const decoder = new TextDecoder()

  while (true) {
    const { done, value } = await reader.read()
    if (done) break

    const chunk = decoder.decode(value)
    const lines = chunk.split('\n')

    for (const line of lines) {
      if (line.startsWith('data: ')) {
        const data = line.slice(6)
        if (data === '[DONE]') return

        const json = JSON.parse(data)
        console.log(json.content) // Stream token
      }
    }
  }
}

Reconnection Strategy

class ReconnectingEventSource {
  private eventSource: EventSource | null = null
  private reconnectDelay = 1000
  private maxReconnectDelay = 30000

  constructor(private url: string, private onMessage: (data: string) => void) {
    this.connect()
  }

  private connect() {
    this.eventSource = new EventSource(this.url)

    this.eventSource.onmessage = (event) => {
      this.reconnectDelay = 1000 // Reset on success
      this.onMessage(event.data)
    }

    this.eventSource.onerror = () => {
      this.eventSource?.close()

      // Exponential backoff
      setTimeout(() => this.connect(), this.reconnectDelay)
      this.reconnectDelay = Math.min(this.reconnectDelay * 2, this.maxReconnectDelay)
    }
  }

  close() {
    this.eventSource?.close()
  }
}

Python Async Generator Cleanup (2026 Best Practice)

CRITICAL: Async generators can leak resources if not properly cleaned up. Python 3.10+ provides aclosing() from contextlib to guarantee cleanup.

The Problem

# ❌ DANGEROUS: Generator not closed if exception occurs mid-iteration
async def stream_analysis():
    async for chunk in external_api_stream():  # What if exception here?
        yield process(chunk)  # Generator may be garbage collected without cleanup

# ❌ ALSO DANGEROUS: Using .aclose() manually is error-prone
gen = stream_analysis()
try:
    async for chunk in gen:
        process(chunk)
finally:
    await gen.aclose()  # Easy to forget, verbose

The Solution: aclosing()

from contextlib import aclosing

# ✅ CORRECT: aclosing() guarantees cleanup
async def stream_analysis():
    async with aclosing(external_api_stream()) as stream:
        async for chunk in stream:
            yield process(chunk)

# ✅ CORRECT: Using aclosing() at consumption site
async def consume_stream():
    async with aclosing(stream_analysis()) as gen:
        async for chunk in gen:
            handle(chunk)

Real-World Pattern: LLM Streaming

from contextlib import aclosing
from langchain_core.runnables import RunnableConfig

async def stream_llm_response(prompt: str, config: RunnableConfig | None = None):
    """Stream LLM tokens with guaranteed cleanup."""
    async with aclosing(llm.astream(prompt, config=config)) as stream:
        async for chunk in stream:
            yield chunk.content

# Consumption with proper cleanup
async def generate_response(user_input: str):
    result_chunks = []
    async with aclosing(stream_llm_response(user_input)) as response:
        async for token in response:
            result_chunks.append(token)
            yield token  # Stream to client

    # Post-processing after stream completes
    full_response = "".join(result_chunks)
    await log_response(full_response)

Database Connection Pattern

from contextlib import aclosing
from typing import AsyncIterator
from sqlalchemy.ext.asyncio import AsyncSession

async def stream_large_query(
    session: AsyncSession,
    batch_size: int = 1000
) -> AsyncIterator[Row]:
    """Stream large query results with automatic connection cleanup."""
    result = await session.execute(
        select(Model).execution_options(stream_results=True)
    )

    async with aclosing(result.scalars()) as stream:
        async for row in stream:
            yield row

When to Use aclosing()

ScenarioUse aclosing()
External API streaming (LLM, HTTP)✅ Always
Database streaming results✅ Always
File streaming✅ Always
Simple in-memory generators⚠️ Optional (no cleanup needed)
Generator with try/finally cleanup✅ Always

Anti-Patterns to Avoid

# ❌ NEVER: Consuming without aclosing
async for chunk in stream_analysis():
    process(chunk)

# ❌ NEVER: Manual try/finally (verbose, error-prone)
gen = stream_analysis()
try:
    async for chunk in gen:
        process(chunk)
finally:
    await gen.aclose()

# ❌ NEVER: Assuming GC will handle cleanup
gen = stream_analysis()
# ... later gen goes out of scope without close

Testing Async Generators

import pytest
from contextlib import aclosing

@pytest.mark.asyncio
async def test_stream_cleanup_on_error():
    """Test that cleanup happens even when exception raised."""
    cleanup_called = False

    async def stream_with_cleanup():
        nonlocal cleanup_called
        try:
            yield "data"
            yield "more"
        finally:
            cleanup_called = True

    with pytest.raises(ValueError):
        async with aclosing(stream_with_cleanup()) as gen:
            async for chunk in gen:
                raise ValueError("simulated error")

    assert cleanup_called, "Cleanup must run even on exception"

Best Practices

SSE

  • ✅ Use for one-way server-to-client streaming
  • ✅ Implement automatic reconnection
  • ✅ Send keepalive messages every 30s
  • ✅ Handle browser connection limits (6 per domain)
  • ✅ Use HTTP/2 for better performance

WebSockets

  • ✅ Use for bidirectional real-time communication
  • ✅ Implement heartbeat/ping-pong
  • ✅ Handle reconnection with exponential backoff
  • ✅ Validate and sanitize messages
  • ✅ Implement message queuing for offline periods

Backpressure

  • ✅ Use ReadableStream with proper flow control
  • ✅ Monitor buffer sizes
  • ✅ Pause production when consumer is slow
  • ✅ Implement timeouts for slow consumers

Performance

  • ✅ Compress data (gzip/brotli)
  • ✅ Batch small messages
  • ✅ Use binary formats (MessagePack, Protobuf) for large data
  • ✅ Implement client-side buffering
  • ✅ Monitor connection count and resource usage

Resources

Related Skills

  • llm-streaming - LLM-specific streaming patterns for token-by-token responses
  • api-design-framework - REST API design patterns for streaming endpoints
  • caching-strategies - Cache invalidation patterns for real-time data updates
  • edge-computing-patterns - Edge function streaming for low-latency delivery

Key Decisions

DecisionChoiceRationale
Server-to-Client StreamingSSESimple protocol, auto-reconnect, HTTP/2 compatible
Bidirectional CommunicationWebSocketsFull-duplex, low latency, binary support
LLM Token StreamingReadableStream + SSEBackpressure control, standard format
Reconnection StrategyExponential BackoffPrevents thundering herd, graceful recovery
Async Generator Cleanupaclosing()Guaranteed resource cleanup on exceptions

Capability Details

sse

Keywords: sse, server-sent events, event stream, one-way stream Solves:

  • How do I implement SSE?
  • Stream data from server to client
  • Real-time notifications

sse-protocol

Keywords: sse protocol, event format, event types, sse headers Solves:

  • SSE protocol fundamentals
  • Event format and types
  • SSE HTTP headers

sse-buffering

Keywords: event buffering, sse race condition, late subscriber, buffer events Solves:

  • How do I buffer SSE events?
  • Fix SSE race condition
  • Handle late-joining subscribers

sse-reconnection

Keywords: sse reconnection, reconnect, last-event-id, retry, exponential backoff Solves:

  • How do I handle SSE reconnection?
  • Implement automatic reconnection
  • Resume from Last-Event-ID

orchestkit-sse

Keywords: orchestkit sse, event broadcaster, workflow events, analysis progress Solves:

  • How does OrchestKit SSE work?
  • EventBroadcaster implementation
  • Real-world SSE example

websocket

Keywords: websocket, ws, bidirectional, real-time chat, socket Solves:

  • How do I set up WebSocket server?
  • Build a chat application
  • Bidirectional real-time communication

llm-streaming

Keywords: llm stream, chatgpt stream, ai stream, token stream, openai stream Solves:

  • How do I stream LLM responses?
  • ChatGPT-style streaming interface
  • Stream tokens as they arrive

backpressure

Keywords: backpressure, flow control, buffer, readable stream, transform stream Solves:

  • Handle slow consumers
  • Implement backpressure
  • Stream large files efficiently

reconnection

Keywords: reconnect, connection lost, retry, resilient, heartbeat Solves:

  • Handle connection drops
  • Implement automatic reconnection
  • Keep-alive and heartbeat

平台分布

Claude Code

29.26%
按下载量换算42

OpenCode

20.16%
按下载量换算29

Antigravity

18.95%
按下载量换算27

Gemini CLI

12.23%
按下载量换算17

windsurf

7.26%
按下载量换算10

trae

3.08%
按下载量换算4

安全审计

暂无安全审计结果可展示。

权限和风险

调用外部服务

该 Skill 可能调用第三方服务、云服务或外部模型 API,使用前需要确认账号、额度、数据发送范围和服务条款。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。目前只有一个公开来源,建议同时核对源仓库。

继续浏览同类 Skills