LLM について
LLMは、z-ai-web-dev-sdkとz-aiコマンドラインを使ったチャット補完の実装スキルです。会話アプリやテキスト生成機能を開発する人向けに、バックエンドでの利用、会話コンテキスト管理、応答処理の例を扱います。
主な機能
- 01SDKによるチャット補完の作成
- 02コマンドラインでの単発プロンプト実行
- 03複数ターンの会話履歴管理
- 04コンテンツ生成と要約
- 05エラー処理とリトライ
活用シーン
- 01チャットボットAPIの構築
- 02コードの生成やレビュー
- 03データの要約と分析
- 04テキスト生成の自動化
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ answerzhao/ agent-skills --skill llmインストール後、Claude Code で/llmを入力して読み込まれたか確認します。
同梱ファイルscripts/chat.tsLICENSE.txt
詳細
LLM(大規模言語モデル)スキル
このスキルでは、z-ai-web-dev-sdk パッケージを使用してチャット補完機能を実装し、強力な会話型 AI とテキスト生成機能を利用できるようにします。
スキルのパス
スキルの場所:{project_path}/skills/llm
このスキルは、プロジェクト内の上記のパスにあります。
参考スクリプト:すぐにテストしたり、参考にしたりできるサンプルテストスクリプトが、{Skill Location}/scripts/ ディレクトリにあります。動作するサンプルについては、{Skill Location}/scripts/chat.ts を参照してください。
概要
LLM スキルを使うと、大規模言語モデルを活用して自然言語の理解と生成を行うアプリケーションを構築できます。チャットボット、AI アシスタント、コンテンツ生成などに利用できます。
重要:z-ai-web-dev-sdk はバックエンドコードでのみ使用してください。クライアント側のコードでは絶対に使用しないでください。
前提条件
z-ai-web-dev-sdk パッケージはすでにインストールされています。以下の例に示すようにインポートしてください。
CLI の使用方法(シンプルなタスク向け)
シンプルな単発のチャット補完には、コードを書く代わりに z-ai CLI を使用できます。手早いテスト、簡単なクエリ、自動化スクリプトに最適です。
基本的なチャット
# Simple question
z-ai chat --prompt "What is the capital of France?"
# Save response to file
z-ai chat -p "Explain quantum computing" -o response.json
# Stream the response
z-ai chat -p "Write a short poem" --stream
システムプロンプトを指定する場合
# Custom system prompt for specific behavior
z-ai chat \
--prompt "Review this code: function add(a,b) { return a+b; }" \
--system "You are an expert code reviewer" \
-o review.json
思考を有効にする場合(思考の連鎖)
# Enable thinking for complex reasoning
z-ai chat \
--prompt "Solve this math problem: If a train travels 120km in 2 hours, what's its speed?" \
--thinking \
-o solution.json
CLI パラメーター
--prompt, -p <text>:必須 - ユーザーメッセージの内容--system, -s <text>:任意 - 動作をカスタマイズするシステムプロンプト--thinking, -t:任意 - 思考の連鎖による推論を有効にします(デフォルト:無効)--output, -o <path>:任意 - 出力ファイルのパス(JSON 形式)--stream:任意 - 応答をリアルタイムでストリーミングします
CLI と SDK の使い分け
CLI を使用するケース:
- 手早く単発の質問をする
- シンプルな自動化スクリプトを作成する
- プロンプトをテストする
- 単一ターンの会話を行う
SDK を使用するケース:
- コンテキストを含む複数ターンの会話を行う
- 会話を独自に管理する
- Web アプリケーションと統合する
- 複雑なチャットワークフローを実装する
- 本番アプリケーションを構築する
基本的なチャット補完
シンプルな質問と回答
import ZAI from 'z-ai-web-dev-sdk';
async function askQuestion(question) {
const zai = await ZAI.create();
const completion = await zai.chat.completions.create({
messages: [
{
role: 'assistant',
content: 'You are a helpful assistant.'
},
{
role: 'user',
content: question
}
],
thinking: { type: 'disabled' }
});
const response = completion.choices[0]?.message?.content;
return response;
}
// Usage
const answer = await askQuestion('What is the capital of France?');
console.log('Answer:', answer);
カスタムシステムプロンプト
import ZAI from 'z-ai-web-dev-sdk';
async function customAssistant(systemPrompt, userMessage) {
const zai = await ZAI.create();
const completion = await zai.chat.completions.create({
messages: [
{
role: 'assistant',
content: systemPrompt
},
{
role: 'user',
content: userMessage
}
],
thinking: { type: 'disabled' }
});
return completion.choices[0]?.message?.content;
}
// Usage - Code reviewer
const codeReview = await customAssistant(
'You are an expert code reviewer. Analyze code for bugs, performance issues, and best practices.',
'Review this function: function add(a, b) { return a + b; }'
);
// Usage - Creative writer
const story = await customAssistant(
'You are a creative fiction writer who writes engaging short stories.',
'Write a short story about a robot learning to paint.'
);
console.log(codeReview);
console.log(story);
複数ターンの会話
会話履歴の管理
import ZAI from 'z-ai-web-dev-sdk';
class ConversationManager {
constructor(systemPrompt = 'You are a helpful assistant.') {
this.messages = [
{
role: 'assistant',
content: systemPrompt
}
];
this.zai = null;
}
async initialize() {
this.zai = await ZAI.create();
}
async sendMessage(userMessage) {
// Add user message to history
this.messages.push({
role: 'user',
content: userMessage
});
// Get completion
const completion = await this.zai.chat.completions.create({
messages: this.messages,
thinking: { type: 'disabled' }
});
const assistantResponse = completion.choices[0]?.message?.content;
// Add assistant response to history
this.messages.push({
role: 'assistant',
content: assistantResponse
});
return assistantResponse;
}
getHistory() {
return this.messages;
}
clearHistory(systemPrompt = 'You are a helpful assistant.') {
this.messages = [
{
role: 'assistant',
content: systemPrompt
}
];
}
getMessageCount() {
// Subtract 1 for system message
return this.messages.length - 1;
}
}
// Usage
const conversation = new ConversationManager();
await conversation.initialize();
const response1 = await conversation.sendMessage('Hi, my name is John.');
console.log('AI:', response1);
const response2 = await conversation.sendMessage('What is my name?');
console.log('AI:', response2); // Should remember the name is John
console.log('Total messages:', conversation.getMessageCount());
コンテキストを考慮した会話
import ZAI from 'z-ai-web-dev-sdk';
class ContextualChat {
constructor() {
this.messages = [];
this.zai = null;
}
async initialize() {
this.zai = await ZAI.create();
}
async startConversation(role, context) {
// Set up system prompt with context
const systemPrompt = `You are ${role}. Context: ${context}`;
this.messages = [
{
role: 'assistant',
content: systemPrompt
}
];
}
async chat(userMessage) {
this.messages.push({
role: 'user',
content: userMessage
});
const completion = await this.zai.chat.completions.create({
messages: this.messages,
thinking: { type: 'disabled' }
});
const response = completion.choices[0]?.message?.content;
this.messages.push({
role: 'assistant',
content: response
});
return response;
}
}
// Usage - Customer support scenario
const support = new ContextualChat();
await support.initialize();
await support.startConversation(
'a customer support agent for TechCorp',
'The user has ordered product #12345 which is delayed due to shipping issues.'
);
const reply1 = await support.chat('Where is my order?');
console.log('Support:', reply1);
const reply2 = await support.chat('Can I get a refund?');
console.log('Support:', reply2);
高度なユースケース
コンテンツ生成
import ZAI from 'z-ai-web-dev-sdk';
class ContentGenerator {
constructor() {
this.zai = null;
}
async initialize() {
this.zai = await ZAI.create();
}
async generateBlogPost(topic, tone = 'professional') {
const completion = await this.zai.chat.completions.create({
messages: [
{
role: 'assistant',
content: `You are a professional content writer. Write in a ${tone} tone.`
},
{
role: 'user',
content: `Write a blog post about: ${topic}. Include an introduction, main points, and conclusion.`
}
],
thinking: { type: 'disabled' }
});
return completion.choices[0]?.message?.content;
}
async generateProductDescription(productName, features) {
const completion = await this.zai.chat.completions.create({
messages: [
{
role: 'assistant',
content: 'You are an expert at writing compelling product descriptions for e-commerce.'
},
{
role: 'user',
content: `Write a product description for "${productName}". Key features: ${features.join(', ')}.`
}
],
thinking: { type: 'disabled' }
});
return completion.choices[0]?.message?.content;
}
async generateEmailResponse(originalEmail, intent) {
const completion = await this.zai.chat.completions.create({
messages: [
{
role: 'assistant',
content: 'You are a professional email writer. Write clear, concise, and polite emails.'
},
{
role: 'user',
content: `Original email: "${originalEmail}"\n\nWrite a ${intent} response.`
}
],
thinking: { type: 'disabled' }
});
return completion.choices[0]?.message?.content;
}
}
// Usage
const generator = new ContentGenerator();
await generator.initialize();
const blogPost = await generator.generateBlogPost(
'The Future of Artificial Intelligence',
'informative'
);
console.log('Blog Post:', blogPost);
const productDesc = await generator.generateProductDescription(
'Smart Watch Pro',
['Heart rate monitoring', 'GPS tracking', 'Waterproof', '7-day battery life']
);
console.log('Product Description:', productDesc);
データ分析と要約
import ZAI from 'z-ai-web-dev-sdk';
async function analyzeData(data, analysisType) {
const zai = await ZAI.create();
const prompts = {
summarize: 'You are a data analyst. Summarize the key insights from the data.',
trend: 'You are a data analyst. Identify trends and patterns in the data.',
recommendation: 'You are a business analyst. Provide actionable recommendations based on the data.'
};
const completion = await zai.chat.completions.create({
messages: [
{
role: 'assistant',
content: prompts[analysisType] || prompts.summarize
},
{
role: 'user',
content: `Analyze this data:\n\n${JSON.stringify(data, null, 2)}`
}
],
thinking: { type: 'disabled' }
});
return completion.choices[0]?.message?.content;
}
// Usage
const salesData = {
Q1: { revenue: 100000, customers: 250 },
Q2: { revenue: 120000, customers: 280 },
Q3: { revenue: 150000, customers: 320 },
Q4: { revenue: 180000, customers: 380 }
};
const summary = await analyzeData(salesData, 'summarize');
const trends = await analyzeData(salesData, 'trend');
const recommendations = await analyzeData(salesData, 'recommendation');
console.log('Summary:', summary);
console.log('Trends:', trends);
console.log('Recommendations:', recommendations);
コード生成とデバッグ
import ZAI from 'z-ai-web-dev-sdk';
class CodeAssistant {
constructor() {
this.zai = null;
}
async initialize() {
this.zai = await ZAI.create();
}
async generateCode(description, language) {
const completion = await this.zai.chat.completions.create({
messages: [
{
role: 'assistant',
content: `You are an expert ${language} programmer. Write clean, efficient, and well-commented code.`
},
{
role: 'user',
content: `Write ${language} code to: ${description}`
}
],
thinking: { type: 'disabled' }
});
return completion.choices[0]?.message?.content;
}
async debugCode(code, issue) {
const completion = await this.zai.chat.completions.create({
messages: [
{
role: 'assistant',
content: 'You are an expert debugger. Identify bugs and suggest fixes.'
},
{
role: 'user',
content: `Code:\n${code}\n\nIssue: ${issue}\n\nFind the bug and suggest a fix.`
}
],
thinking: { type: 'disabled' }
});
return completion.choices[0]?.message?.content;
}
async explainCode(code) {
const completion = await this.zai.chat.completions.create({
messages: [
{
role: 'assistant',
content: 'You are a programming teacher. Explain code clearly and simply.'
},
{
role: 'user',
content: `Explain what this code does:\n\n${code}`
}
],
thinking: { type: 'disabled' }
});
return completion.choices[0]?.message?.content;
}
}
// Usage
const codeAssist = new CodeAssistant();
await codeAssist.initialize();
const newCode = await codeAssist.generateCode(
'Create a function that sorts an array of objects by a specific property',
'JavaScript'
);
console.log('Generated Code:', newCode);
const bugFix = await codeAssist.debugCode(
'function add(a, b) { return a - b; }',
'This function should add numbers but returns wrong results'
);
console.log('Debug Suggestion:', bugFix);
ベストプラクティス
1. プロンプトエンジニアリング
// Bad: Vague prompt
const bad = await askQuestion('Tell me about AI');
// Good: Specific and structured prompt
async function askWithContext(topic, format, audience) {
const zai = await ZAI.create();
const completion = await zai.chat.completions.create({
messages: [
{
role: 'assistant',
content: `You are an expert educator. Explain topics clearly for ${audience}.`
},
{
role: 'user',
content: `Explain ${topic} in ${format} format. Include practical examples.`
}
],
thinking: { type: 'disabled' }
});
return completion.choices[0]?.message?.content;
}
const good = await askWithContext('artificial intelligence', 'bullet points', 'beginners');
2. エラー処理
import ZAI from 'z-ai-web-dev-sdk';
async function safeCompletion(messages, retries = 3) {
let lastError;
for (let attempt = 1; attempt <= retries; attempt++) {
try {
const zai = await ZAI.create();
const completion = await zai.chat.completions.create({
messages: messages,
thinking: { type: 'disabled' }
});
const response = completion.choices[0]?.message?.content;
if (!response || response.trim().length === 0) {
throw new Error('Empty response from AI');
}
return {
success: true,
content: response,
attempts: attempt
};
} catch (error) {
lastError = error;
console.error(`Attempt ${attempt} failed:`, error.message);
if (attempt < retries) {
// Wait before retry (exponential backoff)
await new Promise(resolve => setTimeout(resolve, 1000 * attempt));
}
}
}
return {
success: false,
error: lastError.message,
attempts: retries
};
}
3. コンテキスト管理
class ManagedConversation {
constructor(maxMessages = 20) {
this.maxMessages = maxMessages;
this.systemPrompt = '';
this.messages = [];
this.zai = null;
}
async initialize(systemPrompt) {
this.zai = await ZAI.create();
this.systemPrompt = systemPrompt;
this.messages = [
{
role: 'assistant',
content: systemPrompt
}
];
}
async chat(userMessage) {
// Add user message
this.messages.push({
role: 'user',
content: userMessage
});
// Trim old messages if exceeding limit (keep system prompt)
if (this.messages.length > this.maxMessages) {
this.messages = [
this.messages[0], // Keep system prompt
...this.messages.slice(-(this.maxMessages - 1))
];
}
const completion = await this.zai.chat.completions.create({
messages: this.messages,
thinking: { type: 'disabled' }
});
const response = completion.choices[0]?.message?.content;
this.messages.push({
role: 'assistant',
content: response
});
return response;
}
getTokenEstimate() {
// Rough estimate: ~4 characters per token
const totalChars = this.messages
.map(m => m.content.length)
.reduce((a, b) => a + b, 0);
return Math.ceil(totalChars / 4);
}
}
4. 応答の処理
async function getStructuredResponse(query, format = 'json') {
const zai = await ZAI.create();
const formatInstructions = {
json: 'Respond with valid JSON only. No additional text.',
list: 'Respond with a numbered list.',
markdown: 'Respond in Markdown format.'
};
const completion = await zai.chat.completions.create({
messages: [
{
role: 'assistant',
content: `You are a helpful assistant. ${formatInstructions[format]}`
},
{
role: 'user',
content: query
}
],
thinking: { type: 'disabled' }
});
const response = completion.choices[0]?.message?.content;
// Parse JSON if requested
if (format === 'json') {
try {
return JSON.parse(response);
} catch (e) {
console.error('Failed to parse JSON response');
return { raw: response };
}
}
return response;
}
// Usage
const jsonData = await getStructuredResponse(
'List three programming languages with their primary use cases',
'json'
);
console.log(jsonData);
一般的なユースケース
- チャットボットとバーチャルアシスタント:カスタマーサポート向けの会話インターフェースを構築します
- コンテンツ生成:記事、商品説明、マーケティングコピーを作成します
- コード支援:コードの生成、説明、デバッグを行います
- データ分析:複雑なデータセットを分析して要約します
- 言語翻訳:言語間でテキストを翻訳します
- 教育ツール:個別指導や学習アプリケーションを作成します
- メールの自動化:ビジネス向けのメール返信を生成します
- 創作:物語、詩、創作コンテンツを生成します
統合例
Express.js チャットボット API
import express from 'express';
import ZAI from 'z-ai-web-dev-sdk';
const app = express();
app.use(express.json());
// Store conversations in memory (use database in production)
const conversations = new Map();
let zaiInstance;
async function initZAI() {
zaiInstance = await ZAI.create();
}
app.post('/api/chat', async (req, res) => {
try {
const { sessionId, message, systemPrompt } = req.body;
if (!message) {
return res.status(400).json({ error: 'Message is required' });
}
// Get or create conversation history
let history = conversations.get(sessionId) || [
{
role: 'assistant',
content: systemPrompt || 'You are a helpful assistant.'
}
];
// Add user message
history.push({
role: 'user',
content: message
});
// Get completion
const completion = await zaiInstance.chat.completions.create({
messages: history,
thinking: { type: 'disabled' }
});
const aiResponse = completion.choices[0]?.message?.content;
// Add AI response to history
history.push({
role: 'assistant',
content: aiResponse
});
// Save updated history
conversations.set(sessionId, history);
res.json({
success: true,
response: aiResponse,
messageCount: history.length - 1
});
} catch (error) {
res.status(500).json({
success: false,
error: error.message
});
}
});
app.delete('/api/chat/:sessionId', (req, res) => {
const { sessionId } = req.params;
conversations.delete(sessionId);
res.json({ success: true, message: 'Conversation cleared' });
});
initZAI().then(() => {
app.listen(3000, () => {
console.log('Chatbot API running on port 3000');
});
});
トラブルシューティング
問題:「SDK must be used in backend」
- 解決策:z-ai-web-dev-sdk がサーバー側のコードでのみインポート、使用されていることを確認してください
問題:応答が空、または不完全
- 解決策:completion.choices[0]?.message?.content が存在し、空でないことを確認してください
問題:会話のコンテキストが長くなりすぎる
- 解決策:メッセージをトリミングして、最近のメッセージだけを残すようにしてください
問題:応答に一貫性がない
- 解決策:より具体的なシステムプロンプトを使い、明確な指示を与えてください
問題:レート制限エラー
- 解決策:指数バックオフを使った再試行ロジックを実装してください
パフォーマンスに関するヒント
- SDK インスタンスの再利用:ZAI インスタンスを一度だけ作成し、リクエスト間で再利用します。
- コンテキスト長の管理:トークン制限を超えないよう、古いメッセージを削除します。
- キャッシュの実装:よくあるクエリへの応答をキャッシュします。
- 具体的なプロンプトの使用:明確なプロンプトを使用すると、より速く、より良い応答が得られます。
- エラーの適切な処理:再試行ロジックとフォールバック応答を実装します。
セキュリティに関する考慮事項
- 入力の検証:ユーザー入力は必ず検証し、サニタイズします。
- レート制限:不正利用を防ぐため、レート制限を実装します。
- API キーの保護:クライアント側のコードで SDK の認証情報を公開しないでください。
- コンテンツのフィルタリング:機密性の高いコンテンツや不適切なコンテンツをフィルタリングします。
- セッション管理:適切なセッション処理とクリーンアップを実装します。
覚えておくこと
- z-ai-web-dev-sdk は必ずバックエンドコードでのみ使用してください。
- SDK はすでにインストールされています。例に示すようにインポートしてください。
- システムプロンプトには
assistantロールを使用してください。 - 標準的な補完には
thinkingを{ type: 'disabled' }に設定してください。 - 本番環境では、適切なエラー処理と再試行を実装してください。
- トークン制限を超えないよう、会話履歴を管理してください。
- 明確で具体的なプロンプトを使用すると、より良い結果が得られます。
- クイックスタートの例については、
scripts/chat.tsを確認してください。