skald/skald-php
Composer 安装命令:
composer require skald/skald-php
包简介
Official PHP SDK for Skald API - Knowledge base management with semantic search, AI chat, and document generation
README 文档
README
Official PHP SDK for Skald API - A knowledge base management system that automatically processes memos (summarizes, chunks, and indexes them) and provides semantic search, AI chat, and document generation capabilities.
Features
- Memo Management: Create and store memos with automatic processing (summarization, chunking, indexing)
- Semantic Search: Search through your knowledge base using vector search or title matching
- AI Chat: Ask questions about your knowledge base with AI-powered responses and inline citations
- Document Generation: Generate documents based on prompts with context from your knowledge base
- Streaming Support: Real-time streaming for chat and document generation operations
- Type-Safe: Fully typed with PHP 8.1+ features including enums and readonly properties
Requirements
- PHP 8.1 or higher
- cURL extension
- JSON extension
Installation
Install via Composer:
composer require skald/skald-php
Quick Start
<?php require 'vendor/autoload.php'; use Skald\Skald; use Skald\Types\MemoData; use Skald\Types\SearchRequest; use Skald\Types\SearchMethod; use Skald\Types\ChatRequest; // Initialize the client $skald = new Skald('sk_proj_your_api_key'); // Create a memo $result = $skald->createMemo(new MemoData( title: 'Meeting Notes - Q1 Planning', content: 'Discussed quarterly goals, hiring plans, and budget allocation...', tags: ['meeting', 'planning', 'q1'], source: 'notion' )); // Search for memos $results = $skald->search(new SearchRequest( query: 'quarterly goals', searchMethod: SearchMethod::CHUNK_VECTOR_SEARCH, limit: 10 )); foreach ($results->results as $result) { echo "Title: {$result->title}\n"; echo "Summary: {$result->summary}\n"; echo "Relevance: {$result->distance}\n\n"; } // Ask questions about your knowledge base $response = $skald->chat(new ChatRequest( query: 'What are our main goals for Q1?' )); echo $response->response; // "The main Q1 goals are... [[1]]"
API Reference
Client Initialization
$skald = new Skald(string $apiKey, ?string $baseUrl = null);
$apiKey: Your Skald API key (required)$baseUrl: Optional custom API base URL (defaults tohttps://api.useskald.com)
Creating Memos
$response = $skald->createMemo(MemoData $memoData): CreateMemoResponse;
Parameters:
new MemoData( title: string, // Required - memo title (max 255 chars) content: string, // Required - memo content metadata: ?array = null, // Optional - custom JSON metadata reference_id: ?string = null, // Optional - external ID mapping tags: ?array = null, // Optional - array of tags source: ?string = null // Optional - source system (e.g., "notion") );
Example:
$result = $skald->createMemo(new MemoData( title: 'Product Requirements', content: 'The new mobile app should support offline mode...', metadata: ['author' => 'John Doe', 'version' => '1.0'], tags: ['product', 'mobile', 'requirements'], source: 'confluence' )); // Returns: CreateMemoResponse { ok: true }
Updating Memos
$response = $skald->updateMemo( string $memoId, UpdateMemoData $updateData, string $idType = 'memo_uuid', ?string $projectId = null ): CreateMemoResponse;
Update an existing memo with partial or complete changes. All fields are optional - only include the fields you want to update.
Important: When content is updated, the memo is automatically reprocessed by the API (summary, tags, and chunks are regenerated). Other field updates preserve existing processing results.
Parameters:
$memoId(string): The memo UUID or client reference ID$updateData(UpdateMemoData): The fields to update$idType(string, optional): Type of identifier -'memo_uuid'(default) or'reference_id'$projectId(string|null, optional): Project UUID (required when using Token Authentication)
new UpdateMemoData( title: ?string = null, // Optional - memo title (max 255 chars) content: ?string = null, // Optional - memo content (triggers reprocessing) metadata: ?array = null, // Optional - custom JSON metadata client_reference_id: ?string = null, // Optional - external ID mapping (max 255 chars) source: ?string = null, // Optional - source system (max 255 chars) expiration_date: ?string = null // Optional - expiration date (ISO 8601 format) );
Examples:
use Skald\Types\UpdateMemoData; // Update by memo UUID (default) $skald->updateMemo('memo-uuid-here', new UpdateMemoData( title: 'Updated Title' )); // Update by client reference ID $skald->updateMemo('external-id-123', new UpdateMemoData( title: 'Updated via Reference ID' ), 'reference_id'); // Update with project ID (for Token Authentication) $skald->updateMemo('memo-uuid-here', new UpdateMemoData( content: 'New content' ), 'memo_uuid', 'project-uuid-123'); // Update content (triggers automatic reprocessing) $skald->updateMemo('memo-uuid-here', new UpdateMemoData( content: 'New content - this will regenerate summary, tags, and chunks' )); // Update multiple fields $skald->updateMemo('memo-uuid-here', new UpdateMemoData( title: 'Updated Title', metadata: ['updated_at' => time(), 'editor' => 'Jane'], source: 'notion', expiration_date: '2025-12-31T23:59:59Z' )); // Update metadata without triggering reprocessing $skald->updateMemo('memo-uuid-here', new UpdateMemoData( metadata: ['last_viewed' => time(), 'view_count' => 42] ));
Deleting Memos
$skald->deleteMemo( string $memoId, string $idType = 'memo_uuid', ?string $projectId = null ): void;
Delete a memo and all its associated data (content, summary, tags, chunks).
Parameters:
$memoId(string): The memo UUID or client reference ID$idType(string, optional): Type of identifier -'memo_uuid'(default) or'reference_id'$projectId(string|null, optional): Project UUID (required when using Token Authentication)
Examples:
// Delete by memo UUID (default) $skald->deleteMemo('memo-uuid-here'); // Delete by client reference ID $skald->deleteMemo('external-id-123', 'reference_id'); // Delete with project ID (for Token Authentication) $skald->deleteMemo('memo-uuid-here', 'memo_uuid', 'project-uuid-123'); // Delete by reference ID with project ID $skald->deleteMemo('external-id-456', 'reference_id', 'project-uuid-789');
Searching Memos
$response = $skald->search(SearchRequest $searchParams): SearchResponse;
Search Methods:
SearchMethod::CHUNK_VECTOR_SEARCH- Semantic search on memo chunks (returns distance scores 0-2)SearchMethod::TITLE_CONTAINS- Case-insensitive substring match on titlesSearchMethod::TITLE_STARTSWITH- Case-insensitive prefix match on titles
Parameters:
new SearchRequest( query: string, // Required - search query searchMethod: SearchMethod, // Required - search method limit: ?int = null, // Optional - results limit (1-50, default 10) filters: ?array = null // Optional - array of Filter objects );
Example:
use Skald\Types\Filter; use Skald\Types\FilterOperator; // Basic search $results = $skald->search(new SearchRequest( query: 'product requirements', searchMethod: SearchMethod::CHUNK_VECTOR_SEARCH, limit: 5 )); foreach ($results->results as $result) { echo "UUID: {$result->uuid}\n"; echo "Title: {$result->title}\n"; echo "Summary: {$result->summary}\n"; echo "Snippet: {$result->content_snippet}\n"; echo "Distance: {$result->distance}\n\n"; // Lower = more relevant } // Search with filters $results = $skald->search(new SearchRequest( query: 'product requirements', searchMethod: SearchMethod::CHUNK_VECTOR_SEARCH, limit: 5, filters: [ Filter::nativeField('tags', FilterOperator::IN, ['product', 'requirements']), Filter::nativeField('source', FilterOperator::EQ, 'confluence') ] ));
AI Chat (Non-Streaming)
$response = $skald->chat(ChatRequest $chatParams): ChatResponse;
Parameters:
new ChatRequest( query: string, // Required - question to ask );
Example:
$response = $skald->chat(new ChatRequest( query: 'What are the key features of our mobile app?' )); echo $response->response; // Output: "The mobile app has several key features: 1. Offline mode [[1]] // 2. Push notifications [[2]] 3. Biometric authentication [[1]]" // Citations [[1]], [[2]], etc. reference source memos
AI Chat (Streaming)
$stream = $skald->streamedChat(ChatRequest $chatParams): Generator<ChatStreamEvent>;
Example:
$stream = $skald->streamedChat(new ChatRequest( query: 'Summarize our product roadmap' )); foreach ($stream as $event) { if ($event->isToken()) { echo $event->content; // Print each token as it arrives } elseif ($event->isDone()) { echo "\nDone!\n"; break; } }
Document Generation (Non-Streaming)
$response = $skald->generateDoc(GenerateDocRequest $generateParams): GenerateDocResponse;
Parameters:
new GenerateDocRequest( prompt: string, // Required - document generation prompt rules: ?string = null, // Optional - style/format rules );
Example:
$response = $skald->generateDoc(new GenerateDocRequest( prompt: 'Create a product requirements document for the mobile app', rules: 'Use formal business language. Include sections: Overview, Requirements, Timeline' )); echo $response->response; // Outputs a full document with inline citations
Document Generation (Streaming)
$stream = $skald->streamedGenerateDoc(GenerateDocRequest $generateParams): Generator<GenerateDocStreamEvent>;
Example:
$stream = $skald->streamedGenerateDoc(new GenerateDocRequest( prompt: 'Write a technical specification for our API', rules: 'Include Architecture, Endpoints, and Security sections' )); foreach ($stream as $event) { if ($event->isToken()) { echo $event->content; } elseif ($event->isDone()) { echo "\n[Generation complete]\n"; break; } }
Error Handling
All API errors throw Skald\Exceptions\SkaldException:
use Skald\Exceptions\SkaldException; try { $result = $skald->createMemo(new MemoData( title: 'Test', content: 'Content' )); } catch (SkaldException $e) { // Error format: "Skald API error (STATUS_CODE): ERROR_MESSAGE" echo "Error: " . $e->getMessage(); echo "HTTP Status: " . $e->getCode(); }
Type Reference
Enums
SearchMethod
enum SearchMethod: string { case CHUNK_VECTOR_SEARCH = 'chunk_vector_search'; case TITLE_CONTAINS = 'title_contains'; case TITLE_STARTSWITH = 'title_startswith'; }
Request Types
MemoData
title: string- Memo title (max 255 characters)content: string- Memo contentmetadata: ?array- Custom metadatareference_id: ?string- External reference IDtags: ?array- Array of tag stringssource: ?string- Source system identifier
UpdateMemoData
title: ?string- Memo title (max 255 characters)content: ?string- Memo content (triggers reprocessing when updated)metadata: ?array- Custom metadataclient_reference_id: ?string- External reference ID (max 255 characters)source: ?string- Source system identifier (max 255 characters)expiration_date: ?string- Expiration date in ISO 8601 format
SearchRequest
query: string- Search querysearchMethod: SearchMethod- Search method to uselimit: ?int- Results limit (1-50, default 10)filters: ?array- Array of Filter objects to narrow results
ChatRequest
query: string- Question to ask
GenerateDocRequest
prompt: string- Document generation promptrules: ?string- Style/format guidelines
Response Types
CreateMemoResponse
ok: bool- Success status
SearchResponse
results: SearchResult[]- Array of search results
SearchResult
uuid: string- Memo unique identifiertitle: string- Memo titlesummary: string- Auto-generated summarycontent_snippet: string- Content snippetdistance: ?float- Relevance score (0-2 for vector search, null for title searches)
ChatResponse
ok: bool- Success statusresponse: string- AI response with inline citationsintermediate_steps: array- Debug information
GenerateDocResponse
ok: bool- Success statusresponse: string- Generated document with citationsintermediate_steps: array- Debug information
Stream Event Types
ChatStreamEvent & GenerateDocStreamEvent
type: string- Event type ('token' or 'done')content: ?string- Token content (only for 'token' events)isToken(): bool- Check if event is a tokenisDone(): bool- Check if event signals completion
Examples
See the examples/ directory for complete working examples:
create_memo.php- Creating memos with various optionsupdate_memo.php- Updating existing memos (including by reference ID)delete_memo.php- Deleting memos (by UUID or reference ID)search.php- All search methods with exampleschat.php- Non-streaming chatchat_streaming.php- Streaming chat with real-time outputgenerate_doc.php- Document generationgenerate_doc_streaming.php- Streaming document generation
Testing
Run the test suite:
# Install dependencies composer install # Run unit tests composer test # Run with coverage vendor/bin/phpunit --coverage-html coverage # Run static analysis composer phpstan # Check code style composer cs-check # Fix code style composer cs-fix
Integration Tests
Integration tests require a valid Skald API key:
export SKALD_API_KEY=sk_proj_your_api_key composer test
Development
Code Quality Tools
This library uses:
- PHPUnit for testing
- PHPStan (level 8) for static analysis
- PHP_CodeSniffer for PSR-12 compliance
Run all checks:
composer test # Run tests composer phpstan # Static analysis composer cs-check # Code style check
License
MIT License - Copyright (c) 2025 Skald Labs, Inc.
See LICENSE file for details.
Contributing
If you've spotted a bug or want a new feature, feel free to submit a PR.
skald/skald-php 适用场景与选型建议
skald/skald-php 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 3 次下载、GitHub Stars 达 1, 最近一次更新时间为 2025 年 10 月 16 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「chat」 「API-Client」 「ai」 「knowledge-base」 「document-generation」 「semantic-search」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 skald/skald-php 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 skald/skald-php 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 skald/skald-php 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
This simple PHP class allows you to easily generate Smartsupp.com JS chat code.
Client for the REST API plugin of the OpenFire Server
Skolkovo API Client
The Yii2 extension module to chat registered users.
A client library for the OpenPLZ API project
统计信息
- 总下载量: 3
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 1
- 点击次数: 19
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2025-10-16