APIを使った開発が初めての方も、このガイド读完すればSSE(Server-Sent Events)を使ったリアルタイム通信を完全に理解できるようになります。HolyShehe AIでは、レートが¥1=$1(公式¥7.3=$1比85%節約)で、登録時に無料クレジットを獲得できます。
SSE(Server-Sent Events)とは?
SSEは、服务器からクライアントへリアルタイムでデータを送り続ける技術です。従来のHTTPリクエスト不同的是、接続を开后したまま随时数据を送信できます。
このような場面で使えます
- チャット приложениеの实时応答
- AIチャットのタイピング效果(文字が1つずつ表示される)
- リアルタイムダッシュボードの更新
- ロングポーリングの代わりに効率的な数据传输
前提条件
このガイドでは以下のものを使います:
- JavaScript(ブラウザまたはNode.js)
- またはPython
- HolySheep AIのアカウント(無料登録でクレジット付与)
JavaScriptでの実装(ブラウザ編)
まずはブラウザで動くシンプルなストリーミングデモを作りましょう。HTMLファイルを作成して以下のコードを貼り付けてください。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>HolySheep AI Streaming Demo</title>
<style>
body { font-family: Arial, sans-serif; max-width: 800px; margin: 50px auto; padding: 20px; }
#output {
background: #f5f5f5;
padding: 20px;
border-radius: 8px;
min-height: 200px;
white-space: pre-wrap;
}
button {
background: #4CAF50;
color: white;
padding: 15px 30px;
border: none;
border-radius: 5px;
cursor: pointer;
font-size: 16px;
}
button:hover { background: #45a049; }
</style>
</head>
<body>
<h1>🤖 HolySheep AI Streaming Demo</h1>
<textarea id="prompt" rows="3" style="width: 100%; margin: 10px 0;" placeholder="質問を入力してください...">日本の四季について教えてください</textarea>
<button onclick="startStreaming()">Stream Start(ストリーミング開始)</button>
<div id="output"></div>
<script>
async function startStreaming() {
const output = document.getElementById('output');
const prompt = document.getElementById('prompt').value;
// HolySheep AI API endpoint
const baseUrl = 'https://api.holysheep.ai/v1';
output.textContent = '接続中...\n';
try {
const response = await fetch(${baseUrl}/chat/completions, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer YOUR_HOLYSHEEP_API_KEY'
},
body: JSON.stringify({
model: 'gpt-4o-mini',
messages: [
{ role: 'user', content: prompt }
],
stream: true // ★重要:streamをtrueに設定
})
});
if (!response.ok) {
throw new Error(HTTPエラー: ${response.status});
}
const reader = response.body.getReader();
const decoder = new TextDecoder();
let fullResponse = '';
output.textContent = '応答中...\n';
while (true) {
const { done, value } = await reader.read();
if (done) break;
const chunk = decoder.decode(value);
// SSE形式を解析(data: {...} 行を処理)
const lines = chunk.split('\n');
for (const line of lines) {
if (line.startsWith('data: ')) {
const data = line.slice(6);
if (data === '[DONE]') {
console.log('ストリーミング完了');
return;
}
try {
const parsed = JSON.parse(data);
const content = parsed.choices?.[0]?.delta?.content;
if (content) {
fullResponse += content;
output.textContent = fullResponse;
}
} catch (e) {
// JSON解析エラーは無視(途中のデータ対応)
}
}
}
}
} catch (error) {
output.textContent = エラー発生: ${error.message};
console.error('ストリーミングエラー:', error);
}
}
</script>
</body>
</html>
ポイント解説:
stream: true设置为关键——这告诉API使用SSEresponse.body.getReader()获取流数据- 逐行解析
data: {...}格式
Pythonでの実装(リクエストライブラリ)
バックエンドでPythonを使う場合、以下のコードでストリーミングを実装できます。HolySheep AIのAPIは下延迟<50ms的超低延迟特点があります。
import requests
import json
HolySheep AI API設定
BASE_URL = "https://api.holysheep.ai/v1"
API_KEY = "YOUR_HOLYSHEEP_API_KEY"
def stream_chat():
"""ストリーミングチャットデモ"""
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
payload = {
"model": "gpt-4o-mini",
"messages": [
{"role": "user", "content": "PythonでのSSEストリーミングの実装方法を教えて"}
],
"stream": True # ★ストリーミングモードON
}
print("🤖 HolySheep AI 接続中...\n")
try:
# POSTリクエストを送信(SSE用的是EventSource形式)
response = requests.post(
f"{BASE_URL}/chat/completions",
headers=headers,
json=payload,
stream=True # ★重要:stream=True必须设置
)
response.raise_for_status()
full_response = ""
# 逐行読み取り
for line in response.iter_lines():
if line:
# SSE格式: "data: {...}"
line_text = line.decode('utf-8')
if line_text.startswith('data: '):
data_content = line_text[6:] # 移除 "data: " 前缀
if data_content == '[DONE]':
print("\n\n✅ ストリーミング完了!")
break
try:
data = json.loads(data_content)
# 提取内容片段
delta = data.get('choices', [{}])[0].get('delta', {})
content = delta.get('content', '')
if content:
print(content, end='', flush=True)
full_response += content
except json.JSONDecodeError:
# JSON解析エラーは無視
pass
print(f"\n\n📊 合計文字数: {len(full_response)}")
except requests.exceptions.RequestException as e:
print(f"❌ リクエストエラー: {e}")
if __name__ == "__main__":
stream_chat()
Pythonでの実装(aiohttp版:异步并发处理)
より高度な実装として、aiohttpを使った非同期バージョンも紹介します。複数の同時ストリームを管理する場合に有効です。
import aiohttp
import asyncio
import json
BASE_URL = "https://api.holysheep.ai/v1"
API_KEY = "YOUR_HOLYSHEEP_API_KEY"
async def stream_chat_async(session, prompt: str):
"""非同期ストリーミング関数"""
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
payload = {
"model": "gpt-4o-mini",
"messages": [
{"role": "user", "content": prompt}
],
"stream": True
}
try:
async with session.post(
f"{BASE_URL}/chat/completions",
headers=headers,
json=payload
) as response:
full_response = ""
async for line in response.content:
line_text = line.decode('utf-8').strip()
if line_text.startswith('data: '):
data_content = line_text[6:]
if data_content == '[DONE]':
break
try:
data = json.loads(data_content)
content = data.get('choices', [{}])[0].get('delta', {}).get('content', '')
if content:
print(content, end='', flush=True)
full_response += content
except json.JSONDecodeError:
pass
return full_response
except aiohttp.ClientError as e:
print(f"接続エラー: {e}")
return None
async def main():
"""メイン関数:複数同時リクエスト"""
async with aiohttp.ClientSession() as session:
# 同時実行したい質問リスト
tasks = [
stream_chat_async(session, "AI的好处是什么?"),
stream_chat_async(session, "请介绍一下你自己"),
]
# asyncio.gatherで並列実行
results = await asyncio.gather(*tasks)
print(f"\n\n✅ {len(results)}件の応答を完了")
if __name__ == "__main__":
asyncio.run(main())
SSEプロトコルの详细说明
SSE响应数据的格式如下:
data: {"id":"chatcmpl-xxx","object":"chat.completion.chunk","created":1234567890,"model":"gpt-4o-mini","choices":[{"index":0,"delta":{"content":"你好"},"finish_reason":null}]}
data: {"id":"chatcmpl-xxx","object":"chat.completion.chunk","created":1234567890,"model":"gpt-4o-mini","choices":[{"index":0,"delta":{"content":","},"finish_reason":null}]}
data: [DONE]
每行的结构:
data:前缀标记SSE数据行- JSON格式的实际内容
choices[0].delta.content是实际文本内容data: [DONE]表示流结束
実践例:聊天应用の構築
ここからは实际のアプリケーションに組み込む方法を説明します。React + Node.jsの構成で完全なチャットUIを作成します。
バックエンド(Node.js/Express)
const express = require('express');
const fetch = require('node-fetch');
const app = express();
app.use(express.json());
// HolySheep AI API設定
const HOLYSHEEP_BASE_URL = 'https://api.holysheep.ai/v1';
const API_KEY = process.env.HOLYSHEEP_API_KEY || 'YOUR_HOLYSHEEP_API_KEY';
app.post('/api/chat', async (req, res) => {
const { message, history = [] } = req.body;
// SSEヘッダー設定
res.setHeader('Content-Type', 'text/event-stream');
res.setHeader('Cache-Control', 'no-cache');
res.setHeader('Connection', 'keep-alive');
res.setHeader('Access-Control-Allow-Origin', '*');
try {
const response = await fetch(${HOLYSHEEP_BASE_URL}/chat/completions, {
method: 'POST',
headers: {
'Authorization': Bearer ${API_KEY},
'Content-Type': 'application/json'
},
body: JSON.stringify({
model: 'gpt-4o-mini',
messages: [
...history.map(h => ({ role: h.role, content: h.content })),
{ role: 'user', content: message }
],
stream: true
})
});
// ストリームをリアルタイムで転送
for await (const chunk of response.body) {
res.write(chunk);
}
res.write('data: [DONE]\n\n');
res.end();
} catch (error) {
console.error('APIエラー:', error);
res.status(500).json({ error: '内部サーバーエラー' });
}
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(🚀 サーバー起動: http://localhost:${PORT});
});
フロントエンド(React)
import React, { useState } from 'react';
function ChatApp() {
const [messages, setMessages] = useState([]);
const [input, setInput] = useState('');
const [isStreaming, setIsStreaming] = useState(false);
const sendMessage = async () => {
if (!input.trim() || isStreaming) return;
const userMessage = { role: 'user', content: input };
setMessages(prev => [...prev, userMessage]);
setInput('');
setIsStreaming(true);
// _assistant用の临时状态
const assistantMessage = { role: 'assistant', content: '' };
setMessages(prev => [...prev, assistantMessage]);
try {
const response = await fetch('/api/chat', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
message: input,
history: messages
})
});
const reader = response.body.getReader();
const decoder = new TextDecoder();
let fullContent = '';
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]') {
setIsStreaming(false);
return;
}
try {
const parsed = JSON.parse(data);
const content = parsed.choices?.[0]?.delta?.content;
if (content) {
fullContent += content;
// 最後のメッセージをリアルタイム更新
setMessages(prev => {
const updated = [...prev];
updated[updated.length - 1] = {
...updated[updated.length - 1],
content: fullContent
};
return updated;
});
}
} catch (e) {}
}
}
}
} catch (error) {
console.error('エラー:', error);
}
setIsStreaming(false);
};
return (
<div style={{ maxWidth: '600px', margin: '0 auto', padding: '20px' }}>
<h1>🤖 HolySheep AI Chat</h1>
<div style={{ height: '400px', overflowY: 'auto', border: '1px solid #ccc', padding: '10px' }}>
{messages.map((msg, i) => (
<div key={i} style={{
textAlign: msg.role === 'user' ? 'right' : 'left',
margin: '10px 0'
}}>
<strong>{msg.role === 'user' ? 'あなた' : 'AI'}: </strong>
{msg.content}
</div>
))}
</div>
<div style={{ marginTop: '10px' }}>
<input
value={input}
onChange={(e) => setInput(e.target.value)}
onKeyPress={(e) => e.key === 'Enter' && sendMessage()}
disabled={isStreaming}
style={{ width: '80%', padding: '10px' }}
/>
<button onClick={sendMessage} disabled={isStreaming} style={{ padding: '10px 20px' }}>
{isStreaming ? '送信中...' : '送信'}
</button>
</div>
</div>
);
}
export default ChatApp;
よくあるエラーと対処法
実装中に遭遇する可能性があるエラーとその解决方案をまとめました。
エラー1: CORSポリシーエラー
// ❌ エラー内容
Access to fetch at 'https://api.holysheep.ai/v1/chat/completions'
from origin 'http://localhost:3000' has been blocked by CORS policy
// ✅ 解決方法
// ブラウザから直接APIを呼ぶ場合は、バックエンドプロキシを使用
// Expressサーバーの設定に以下を追加
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization');
res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
if (req.method === 'OPTIONS') {
return res.sendStatus(200);
}
next();
});
エラー2: Streamモードが無効
// ❌ エラー内容
{
"error": {
"message": "Invalid request: stream option required for streaming",
"type": "invalid_request_error",
"code": "stream_required"
}
}
// ✅ 解決方法
// payloadにstream: trueを追加
const payload = {
model: 'gpt-4o-mini',
messages: [{ role: 'user', content: 'こんにちは' }],
stream: true // ★これを必ず含める
};
// またはfetch.thenでエラー処理
fetch(url, {
method: 'POST',
headers: headers,
body: JSON.stringify({
// ...
stream: true // 大文字ではなく小文字
})
})
エラー3: JSON解析エラー(途中のデータ)
// ❌ エラー内容
JSON.parse error: Unexpected end of JSON input
// ✅ 解決方法
// SSEのchunkは途中で切れる場合があるため、try-catchで包む
async function parseStream(response) {
const reader = response.body.getReader();
const decoder = new TextDecoder();
let buffer = ''; // バッファを使って途中データ不退不失
while (true) {
const { done, value } = await reader.read();
if (done) break;
buffer += decoder.decode(value, { stream: true });
const lines = buffer.split('\n');
buffer = lines.pop() || ''; // 最後の不完全な行を保持
for (const line of lines) {
if (line.startsWith('data: ')) {
try {
const data = JSON.parse(line.slice(6));
if (data === '[DONE]') return;
// 正常なデータを処理
console.log(data.choices?.[0]?.delta?.content);
} catch (e) {
// JSON解析エラーは無視して次へ
continue;
}
}
}
}
}
エラー4: API Key認証エラー
// ❌ エラー内容
{
"error": {
"message": "Incorrect API key provided",
"type": "authentication_error"
}
}
// ✅ 解決方法
// 1. ヘッダーの形式を確認(大文字小文字を正確に)
headers: {
'Authorization': 'Bearer YOUR_HOLYSHEEP_API_KEY' // Bearerが必要
}
// 2. 環境変数からの読み込みを推奨
const API_KEY = process.env.HOLYSHEEP_API_KEY;
if (!API_KEY) {
throw new Error('HOLYSHEEP_API_KEYが設定されていません');
}
// 3. キーの先頭・末尾に空白が入っていないか確認
const cleanKey = API_KEY.trim();
エラー5: 接続超时・ネットワークエラー
// ❌ エラー内容
TypeError: Failed to fetch
net::ERR_CONNECTION_TIMED_OUT
// ✅ 解決方法(fetch APIの場合)
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 60000); // 60秒
try {
const response = await fetch(url, {
method: 'POST',
headers: headers,
body: JSON.stringify(payload),
signal: controller.signal
});
clearTimeout(timeoutId);
// 正常処理
} catch (error) {
if (error.name === 'AbortError') {
console.error('リクエストがタイムアウトしました');
}
}
// Python (requests) の場合
import requests
response = requests.post(
url,
headers=headers,
json=payload,
stream=True,
timeout=60 # タイムアウト設定
)