adachsoft/ai-integration
Composer 安装命令:
composer require adachsoft/ai-integration
包简介
Unified AI tool-calling chat abstraction for PHP 8.3 with pluggable SPI providers (OpenAI, Deepseek) and a clean Public API.
README 文档
README
Unified AI tool-calling chat abstraction for PHP 8.3 with pluggable providers and a clean, framework-agnostic Public API.
- Public API: simple facade to send chat messages, define tools (function-calling), and receive results.
- Built-in providers: OpenAI and Deepseek.
- SPI: implement your own provider by fulfilling a tiny interface and DTO set.
- HTTP logging: optional, via a small logger interface.
- Zero-framework: no container required; everything is manually wired with a builder.
Requirements
- PHP 8.3+
- ext-json, ext-mbstring (standard in most PHP installations)
Installation
composer require adachsoft/ai-integration
Quick start (Public API)
use AdachSoft\AiIntegration\PublicApi\Builder\ToolCallingChatFacadeBuilder;
use AdachSoft\AiIntegration\PublicApi\ToolCalling\Dto\ChatMessageDto;
use AdachSoft\AiIntegration\PublicApi\ToolCalling\Dto\ChatRoleEnum;
use AdachSoft\AiIntegration\PublicApi\ToolCalling\Dto\Collection\ChatMessageDtoCollection;
use AdachSoft\AiIntegration\PublicApi\ToolCalling\Dto\Collection\ToolDefinitionDtoCollection;
use AdachSoft\AiIntegration\PublicApi\ToolCalling\Dto\ToolCallingChatRequestDto;
use AdachSoft\AiIntegration\PublicApi\ToolCalling\Dto\ToolDefinitionDto;
$builder = ToolCallingChatFacadeBuilder::create()
->withOpenAi(apiKey: getenv('OPENAI_API_KEY'));
$messages = new ChatMessageDtoCollection([
ChatMessageDto::createSystemMessage('You are a helpful assistant.'),
ChatMessageDto::createUserMessage('Add 2 and 3 using a tool and show the token.'),
]);
$tools = new ToolDefinitionDtoCollection([
new ToolDefinitionDto(
name: 'sum',
description: 'Returns JSON {result: string, token: string}',
parametersSchema: [
'type' => 'object',
'properties' => [
'a' => ['type' => 'number'],
'b' => ['type' => 'number'],
],
'required' => ['a', 'b'],
'additionalProperties' => false,
],
),
]);
$request = new ToolCallingChatRequestDto(
messages: $messages,
tools: $tools,
providerId: 'openai',
modelId: 'gpt-4o-mini',
parameters: [
// Free-form provider parameters.
// They are forwarded 1:1 to the provider payload (no defaults are injected).
// Example (only if your model supports it):
// 'temperature' => 0.0,
],
);
$facade = $builder->build();
$response = $facade->chat($request);
if ($response->result !== null) {
echo $response->result; // final model answer (should include tool token if your prompt enforces it)
}
foreach ($response->toolCalls as $call) {
// inspect tool calls if needed
}
Chat messages and tool calls (Public API)
ChatMessageDto is the main DTO used to build a conversation. Its content can be either a plain string or a list of structured blocks for multimodal payloads (see the next section):
public function __construct(
public ChatRoleEnum $role,
public string|array $content,
public ToolCallDtoCollection $toolCalls,
public array $metadata = [],
) { }
To make common cases easier and to guarantee that toolCalls is never null, use the static factories:
ChatMessageDto::createSystemMessage(string|array $content, array $metadata = []): self;
ChatMessageDto::createUserMessage(string|array $content, array $metadata = []): self;
ChatMessageDto::createAssistantMessage(string|array $content, ToolCallDtoCollection $toolCalls, array $metadata = []): self;
ChatMessageDto::createToolMessage(string|array $content, ToolCallDtoCollection $toolCalls, array $metadata = []): self;
Typical patterns:
- system/user messages: empty
ToolCallDtoCollection(created by the factory), - assistant messages: may include tool calls when the model proposes or summarizes tool usage,
- tool messages: should carry tool results and the corresponding
ToolCallDtoinstances intoolCalls.
Multimodal (image + text) chat with OpenAI
For OpenAI models that support vision (for example gpt-4o), you can send multimodal content by passing a list of content blocks as the content of a ChatMessageDto. The list is forwarded 1:1 to the provider payload.
Each block in the list follows the OpenAI format, for example:
['type' => 'text', 'text' => 'Describe this image']['type' => 'image_url', 'image_url' => ['url' => 'data:image/jpeg;base64,BASE64_ENCODED_IMAGE']]
A minimal example using the Public API:
use AdachSoft\AiIntegration\PublicApi\Builder\ToolCallingChatFacadeBuilder;
use AdachSoft\AiIntegration\PublicApi\ToolCalling\Dto\ChatMessageDto;
use AdachSoft\AiIntegration\PublicApi\ToolCalling\Dto\Collection\ChatMessageDtoCollection;
use AdachSoft\AiIntegration\PublicApi\ToolCalling\Dto\Collection\ToolDefinitionDtoCollection;
use AdachSoft\AiIntegration\PublicApi\ToolCalling\Dto\ToolCallingChatRequestDto;
$builder = ToolCallingChatFacadeBuilder::create()
->withOpenAi(apiKey: getenv('OPENAI_API_KEY'));
// Produce a JPEG binary using any method you like (GD, Imagick, file_get_contents, ...)
$imageBinary = /* string JPEG binary */;
// Encode it as a data URL understood by OpenAI vision models
$dataUrl = 'data:image/jpeg;base64,' . base64_encode($imageBinary);
$messages = new ChatMessageDtoCollection([
ChatMessageDto::createUserMessage([
[
'type' => 'text',
'text' => 'Read the text from this image and respond with the exact text only.',
],
[
'type' => 'image_url',
'image_url' => [
'url' => $dataUrl,
],
],
]),
]);
$request = new ToolCallingChatRequestDto(
messages: $messages,
tools: new ToolDefinitionDtoCollection([]), // no tools needed for pure vision OCR
providerId: 'openai',
modelId: 'gpt-4o', // or another OpenAI multimodal model
parameters: [
'max_tokens' => 100,
],
);
$facade = $builder->build();
$response = $facade->chat($request);
echo $response->result; // should contain the text read from the image
Notes:
- The library does not generate images; you are responsible for providing a valid JPEG/PNG binary and building the data URL.
- The
contentarray is passed as-is to the OpenAI-compatible payload builder, so you must follow the provider's multimodal format. - Always use a model that explicitly supports vision (for example
gpt-4o) when sending images.
Generation parameters (parameters)
Generation settings are a free-form associative array and are provider-specific. The library forwards them 1:1 to the provider payload.
Important:
- Do not rely on implicit defaults (e.g.
temperature). If you do not pass a key, it is not sent. - Passing unsupported parameters may result in a provider error.
Providers
- OpenAI (provider id:
openai)- Endpoint: https://api.openai.com/v1/chat/completions
- Env:
OPENAI_API_KEY
- Deepseek (provider id:
deepseek)- Endpoint: https://api.deepseek.com/chat/completions
- Env:
DEEPSEEK_API_KEY
If you pass modelId as null, each provider uses its default. For OpenAI, a safe starter is gpt-4o-mini; for Deepseek: deepseek-chat.
HTTP logging and CLI example
You can inject your own HTTP traffic logger via the builder. A convenient demonstration script is included:
php bin/test-ai-tool-chat.php --provider=openai --model=gpt-4o-mini --show-meta=on --log-http=1 --log-headers=0
The script runs 3 scenarios (smoke and two tool-calling flows) and optionally pretty-prints HTTP request/response payloads.
SPI (Service Provider Interface)
Do not depend on internals. External integrations should use only:
AdachSoft\AiIntegration\PublicApi- the facade and DTOs to call the model.AdachSoft\AiIntegration\Spi- the small interface and DTOs to implement your own provider.
In addition to the core Public API and SPI, the library exposes a reusable, public module under src/Support/OpenAiCompatible/* with DTOs, payload builders and HTTP helpers for OpenAI-compatible chat.completions endpoints. If you already have an OpenAI-compatible HTTP API, you can use the ready-to-use SPI provider OpenAiCompatibleToolCallingChatSpi to bridge your endpoint with the domain model.
All other namespaces (Application, Domain, Infrastructure) are internal and may change at any time.
For a complete SPI guide (interface, DTOs, exceptions, examples), see:
- docs/SPI.md
Production verification of built-in SPI providers
When you implement a new built-in ToolCalling provider inside this library
(for example, a new provider wired into ToolCallingChatFacadeBuilder), you
must add a production test that verifies the provider end-to-end using the
shared base test:
Tests\\Production\\ToolCalling\\AbstractToolCallingProviderProductionTestCase
To add a new provider production test:
- Ensure your provider is exposed on the builder, for example:
ToolCallingChatFacadeBuilder::withMyProvider(string $apiKey): self.
Create
tests/Production/ToolCalling/MyProviderProductionTest.php:use AdachSoft\\AiIntegration\\PublicApi\\Builder\\ToolCallingChatFacadeBuilder; use PHPUnit\\Framework\\Attributes\\Group; #[Group('external')] final class MyProviderProductionTest extends AbstractToolCallingProviderProductionTestCase { protected function getProviderId(): string { return 'my-provider'; } protected function getApiKeyEnvName(): string { return 'MY_PROVIDER_API_KEY'; } protected function getDefaultModelId(): string { return 'my-model-id'; } protected function configureBuilder(ToolCallingChatFacadeBuilder $builder, string $apiKey): ToolCallingChatFacadeBuilder { return $builder->withMyProvider(apiKey: $apiKey); } }- Provide a real API key via environment variable (
MY_PROVIDER_API_KEY) or.envfile. The base test will:- resolve the API key from env/
.envusingresolveApiKeyFromEnvironment(), - resolve the model id from env (for example,
MY-PROVIDER_MODEL) orgetDefaultModelId().
- resolve the API key from env/
- Run production tests for the provider (for example):
vendor/bin/phpunit tests/Production/ToolCalling/MyProviderProductionTest.php --group external
The base test will validate both:
- a simple smoke chat that must return a non-empty final result, and
- a minimal tool-calling scenario (sum of 2 and 3) that must:
- produce at least one tool call with non-empty arguments,
- keep a non-empty
toolCallId, - return a final answer that includes
5.
Testing
- Run unit and integration tests:
composer test - Production checks (require API keys): see
tests/Productionandbin/test-ai-tool-chat.php.
adachsoft/ai-integration 适用场景与选型建议
adachsoft/ai-integration 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 69 次下载、GitHub Stars 达 0, 最近一次更新时间为 2025 年 10 月 31 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「php」 「sdk」 「chat」 「ai」 「spi」 「public-api」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 adachsoft/ai-integration 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 adachsoft/ai-integration 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 adachsoft/ai-integration 相关的其它包
同方向 / 同关键字的高下载量 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
The Yii2 extension module to chat registered users.
Alfabank REST API integration
Chat Package for Laravel
统计信息
- 总下载量: 69
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 30
- 依赖项目数: 9
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2025-10-31