Create a Real-Time AI Chat Assistant using Webman, Neuron AI, and Baileian
This step‑by‑step tutorial shows how to install the Webman PHP framework, integrate the Neuron AI Agent, configure a custom Alibaba Cloud Baileian model provider, build an AssistantAgent, and expose a Server‑Sent Events controller for real‑time AI chat responses.
Overview
This guide shows how to integrate the Neuron AI Agent into a Webman application, use Alibaba Cloud Baileian (an OpenAI‑compatible large‑model service) as a custom AI provider, and expose the assistant via a Server‑Sent Events (SSE) controller that streams responses in real time.
Installation
Webman
composer create-project workerman/webman:~2.0Neuron AI Agent
composer require neuron-core/neuron-aiCustom Baileian Provider
Create BaiLianAI.php that extends NeuronAI\Providers\OpenAI\OpenAI and overrides the base URI to point to the Baileian endpoint.
<?php
/**
* @desc Alibaba Cloud Baileian large‑model service provider
*/
declare(strict_types=1);
namespace app\common\agent\provider;
use GuzzleHttp\Client;
use NeuronAI\Providers\HttpClientOptions;
use NeuronAI\Providers\OpenAI\OpenAI;
class BaiLianAI extends OpenAI {
protected string $baseUri = 'https://api.openai.com/v1';
public function __construct(
protected string $key,
protected string $model,
protected array $parameters = [],
protected bool $strict_response = false,
protected ?HttpClientOptions $httpOptions = null,
?string $baseUri = null // custom API address
) {
if ($baseUri !== null) {
$this->baseUri = $baseUri;
}
$config = [
'base_uri' => rtrim($this->baseUri, '/') . '/',
'headers' => [
'Accept' => 'application/json',
'Content-Type' => 'application/json',
'Authorization' => 'Bearer ' . $this->key,
],
];
if ($this->httpOptions instanceof HttpClientOptions) {
$config = $this->mergeHttpOptions($config, $this->httpOptions);
}
$this->client = new Client($config);
}
}Assistant Agent
Define AssistantAgent.php that returns a BaiLianAI instance with your API key, model, and Baileian base URI, and provides a system prompt for the AI.
<?php
declare(strict_types=1);
namespace app\common\agent;
use app\common\agent\provider\BaiLianAI;
use NeuronAI\Agent;
use NeuronAI\Providers\AIProviderInterface;
use NeuronAI\SystemPrompt;
class AssistantAgent extends Agent {
protected function provider(): AIProviderInterface {
// Replace with your own API key and model
$apiKey = 'sk-xxxxxxxxxxxxxxx';
$model = 'qwen-max';
return new BaiLianAI(
key: $apiKey,
model: $model,
baseUri: 'https://dashscope.aliyuncs.com/compatible-mode/v1',
);
}
public function instructions(): string {
return (string) new SystemPrompt([
"You are Tongyi Qianwen, an AI assistant developed by Alibaba Cloud.",
"You excel at answering questions and providing useful advice.",
"Please reply to users in Chinese."
]);
}
}SSE Controller
Implement AssistantController.php with two actions. index() renders the chat view. chat(Request $request) reads the user message, starts a short‑interval timer, streams the AI response via AssistantAgent::make()->stream(new UserMessage($message)), and pushes each chunk to the client using Workerman\Protocols\Http\ServerSentEvents. After the stream finishes, a completed event is sent and the connection is closed.
<?php
declare(strict_types=1);
namespace app\controller;
use app\common\agent\AssistantAgent;
use support\Request;
use Webman\Http\Response;
use Workerman\Connection\TcpConnection;
use Workerman\Protocols\Http\ServerSentEvents;
use Workerman\Timer;
use NeuronAI\Chat\Messages\UserMessage;
class AssistantController {
public function index(): Response {
return view('assistant/index', ['name' => 'webman']);
}
public function chat(Request $request): Response {
$message = $request->input('message', '介绍一下webman');
$connection = $request->connection;
$id = Timer::add(0.1, function () use ($connection, &$id, $message) {
if ($connection->getStatus() !== TcpConnection::STATUS_ESTABLISHED) {
Timer::del($id);
return;
}
$stream = AssistantAgent::make()->stream(new UserMessage($message));
foreach ($stream as $chunk) {
$content = is_string($chunk) ? $chunk : $chunk->getContent();
if (!empty($content)) {
$connection->send(new ServerSentEvents([
'event' => 'message',
'data' => $content,
]));
}
}
$connection->send(new ServerSentEvents([
'event' => 'completed',
'data' => 'done',
]));
Timer::del($id);
$connection->close();
}, [], false);
return response('', 200, [
'Content-Type' => 'text/event-stream',
'Cache-Control' => 'no-cache',
'Connection' => 'keep-alive',
'X-Accel-Buffering' => 'no',
]);
}
}SSE Requirements
Server must send Content-Type: text/event-stream with UTF‑8 encoding.
Client should use the browser EventSource API to listen for message and completed events.
Running the Example
Start the Webman server and open http://127.0.0.1:8787/assistant/chat in a browser. The page displays a simple chat UI that receives streamed AI replies in real time.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Open Source Tech Hub
Sharing cutting-edge internet technologies and practical AI resources.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
