当前位置:首页>php>PHP Agentic 实战〡05. Message 消息与多模态实操

PHP Agentic 实战〡05. Message 消息与多模态实操

  • 2026-10-11 06:40:13
PHP Agentic 实战〡05. Message 消息与多模态实操

统一消息层

在 Neuron AI 中,Message(消息)是与大语言模型(LLM)交互的统一上下文单元。不同 AI 提供商(如 OpenAI、Anthropic、Gemini)的 API 请求格式差异巨大,Neuron AI 通过统一的 Message 对象屏蔽了这些底层差异,让你只需编写一次代码即可无缝切换不同的 LLM 提供商。

Message 结构

一条标准的 Message 对象由以下三个核心部分组成:

  1. Role(角色):标识消息的来源,通常是 user(用户)或 assistant(助手)。
  2. Content Blocks(内容块):消息的实际载荷。一条消息可以包含一个或多个内容块(例如:一段文本 + 一张图片)。
  3. Metadata(元数据):可选的附加信息,例如 LLM 响应中的 Token 使用量等。

核心消息类型

Neuron AI 提供了两个主要的类来表示对话中的双方:

1. UserMessage(用户消息)

代表用户的输入,作为 Agent 的 chat() 方法的参数传入。

2. AssistantMessage(助手消息)

代表大模型生成的回复,作为 chat()->getMessage() 的返回值。

基础纯文本用法:

当你直接传入字符串时,框架会自动将其转换为包含一个 TextContent 块的 UserMessage。

useNeuronAI\Chat\Messages\UserMessage;// 构造一个简单的文本消息$message = new UserMessage("你好,请介绍一下开源技术小栈。");// 传入 Agent 执行$response = MyAgent::make()->chat($message)->getMessage(); // $response 是一个 AssistantMessage 对象

多模态内容块

为了支持图片、文件、音频和视频等输入,Neuron AI 引入了 ContentBlock 的概念。以下是官方支持的内置内容块类型:

内容块类名
描述
适用场景
TextContent
文本内容
标准的文字对话
ImageContent
图片内容
图像识别、图表分析
FileContent
文件内容
PDF 解析、文档总结
AudioContent
音频内容
语音转文字、音频分析
VideoContent
视频内容
视频内容理解、片段分析
ReasoningContent
推理链内容
捕获推理模型(如 o1)的思考步骤

多模态数据的来源类型

对于非文本内容(图片、文件等),Neuron AI 支持三种数据来源(SourceType):

  • SourceType::URL:通过公网 URL 引用资源。(最简单,无需本地读取)
  • SourceType::BASE64:将本地文件编码为 Base64 字符串传输。
  • SourceType::ID:使用提供商平台已上传文件的 ID。(最省钱,避免每次请求都重复传输大文件消耗 Token)

完整使用案例

下面演示如何在实际业务中构建各种类型的多模态消息。

这里使用智普多模态 GLM-5V-Turbo 模型。 

GLM-5V-Turbo 是智谱首个多模态 Coding 基座模型,面向视觉编程任务打造。能够原生处理图片、视频、文本等多模态输入,同时擅长长程规划、复杂编程和动作执行;深度适配 Agent 工作流,能够与 Claude Code、OpenClaw 等 Agent 深度协同,完成”看懂环境→规划动作→执行任务”的完整闭环。

文档:https://docs.bigmodel.cn/cn/guide/models/vlm/glm-5v-turbo

案例 1:发送包含图片的消息(URL 方式)

假设你的应用需要让大模型分析一张网络上的图片:

多模态Agent ZAITurboAgent

<?php/** * @desc ZAIImageAgent.php 描述信息 * @author Tinywan(ShaoBo Wan) * @link 模型概览 https://docs.bigmodel.cn/cn/guide/start/model-overview */declare(strict_types=1);namespace app\neuron\agent;use NeuronAI\Agent\Agent;use NeuronAI\Providers\AIProviderInterface;use NeuronAI\Providers\ZAI\ZAI;classZAITurboAgentextendsAgent{publicfunctionprovider(): AIProviderInterface{returnnew ZAI(            key: getenv('ZAI_KEY'),            model: 'glm-5v-turbo',        );    }publicfunctioninstructions(): string{return'你是是智谱首个多模态 Coding 基座模型,面向视觉编程任务打造';    }}

多模态调用

<?php/** * @desc TinywanAgent * @author Tinywan(ShaoBo Wan) */declare(strict_types=1);namespace app\controller;use app\neuron\agent\ZAITurboAgent;use NeuronAI\Chat\Enums\SourceType;use NeuronAI\Chat\Messages\ContentBlocks\ImageContent;use NeuronAI\Chat\Messages\UserMessage;use support\Request;classIndexController{publicfunctionimage(Request $request): ?string{// 1. 图片地址        $imageUrl = 'https://www.tinywan.com/assets/c008d6e8-0dab-421c-b8f1-c482891f045d-BDTJKrAD.png';// 2. 创建 UserMessage        $message = new UserMessage('请帮我分析这张图片的内容');// 3. 添加图片内容块(ZAI API 只接受 base64 格式)        $message->addContent(new ImageContent(                content: $imageUrl,                sourceType: SourceType::URL,                mediaType: 'image/png'            )        );// 4. 发送给 Agent        $agent = ZAITurboAgent::make()            ->chat($message)            ->getMessage();return $agent->getContent();    }}

案例 2:发送本地 PDF 文件(Base64 方式)

假设用户上传了一个 PDF 发票,你需要让大模型提取信息:

useNeuronAI\Chat\Messages\UserMessage;use NeuronAI\Chat\Messages\ContentBlocks\FileContent;use NeuronAI\Chat\Messages\ContentBlocks\SourceType;$filePath = '/var/www/uploads/invoice.pdf';$message = new UserMessage("请提取这张发票上的金额和日期。");$message->addContent(new FileContent(// 将本地文件读取并转为 Base64 编码        source: base64_encode(file_get_contents($filePath)),        sourceType: SourceType::BASE64,        mediaType: 'application/pdf'    ));$response = MyAgent::make()->chat($message)->getMessage();

案例 3:组合多条文本与图片

一条消息可以包含任意数量的内容块:

$message = new UserMessage("这里有两组设计图,请对比它们的差异。");$message->addContent(new TextContent("第一组设计图:"));$message->addContent(new ImageContent('https://example.com/design1.jpg', SourceType::URL, 'image/jpeg'));$message->addContent(new TextContent("第二组设计图:"));$message->addContent(new ImageContent('https://example.com/design2.jpg', SourceType::URL, 'image/jpeg'));

如何读取大模型的返回内容

大模型返回的内容(AssistantMessage)可能包含纯文本,也可能包含推理链或其他内容。Neuron AI 提供了不同的方法来读取这些内容:

1. getContent() —— 获取纯文本(最常用)

如果你只关心最终的文字回答,直接使用此方法。它会将消息中所有的 TextContent 块拼接成一个字符串返回。

$response = MyAgent::make()->chat(new UserMessage("讲个笑话"))->getMessage();echo $response->getContent(); // 输出: 为什么程序员不喜欢户外?因为有太多的 bug!

2. getContentBlocks() —— 获取所有内容块(高级用法)

如果大模型返回了推理过程(如 OpenAI o1 模型),或者你想处理多模态输出,需要遍历内容块数组。

useNeuronAI\Chat\Messages\ContentBlocks\TextContent;useNeuronAI\Chat\Messages\ContentBlocks\ReasoningContent;$response = MyAgent::make()->chat(new UserMessage("证明勾股定理"))->getMessage();foreach ($response->getContentBlocks() as $block) {if ($block instanceof ReasoningContent) {echo"[大模型的思考过程]: " . $block->content . "\n";    } elseif ($block instanceof TextContent) {echo"[最终回复]: " . $block->content . "\n";    }}

3. getTextBlocks() —— 仅获取文本块数组

如果你明确知道返回内容中只有文本,但希望以数组形式处理,可以使用此方法。

$textBlocks = $response->getTextBlocks();foreach ($textBlocks as $block) {echo $block->content . "\n";}

总结与最佳实践

  1. 统一接口:无论底层是 OpenAI 还是 Anthropic,你的代码只需操作 UserMessage 和 AssistantMessage,这就是 Neuron AI 提供的核心价值。
  2. 按需使用 SourceType:
    • 测试或临时使用:选择 URL。
    • 本地文件隐私保护:选择 BASE64。
    • 生产环境高频处理大文件:先调用提供商的上传 API 获取 ID,然后使用 ID,可大幅降低 Token 消耗和延迟。
  3. 多模态支持验证:在发送 ImageContent 或 FileContent 之前,请确保你在 provider() 中配置的模型(如 gpt-4o 或 claude-3-5-sonnet)支持对应的多模态输入能力。

最新文章

随机文章