首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >PHP Agentic 实战〡05. Message 消息与多模态实操

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

作者头像
Tinywan
发布2026-07-01 18:09:26
发布2026-07-01 18:09:26
1070
举报
文章被收录于专栏:开源技术小栈开源技术小栈

统一消息层

在 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

代码语言:javascript
复制
use NeuronAI\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

代码语言:javascript
复制
<?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;

class ZAITurboAgent extends Agent
{
    publicfunction provider(): AIProviderInterface
    {
        returnnew ZAI(
            key: getenv('ZAI_KEY'),
            model: 'glm-5v-turbo',
        );
    }

    publicfunction instructions(): string
    {
        return'你是是智谱首个多模态 Coding 基座模型,面向视觉编程任务打造';
    }
}

多模态调用

代码语言:javascript
复制
<?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;

class IndexController
{
    publicfunction image(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 发票,你需要让大模型提取信息:

代码语言:javascript
复制
use NeuronAI\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:组合多条文本与图片

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

代码语言:javascript
复制
$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 块拼接成一个字符串返回。

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

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

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

代码语言:javascript
复制
use NeuronAI\Chat\Messages\ContentBlocks\TextContent;
use NeuronAI\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() —— 仅获取文本块数组

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

代码语言:javascript
复制
$textBlocks = $response->getTextBlocks();
foreach ($textBlocks as $block) {
    echo $block->content . "\n";
}

总结与最佳实践

  1. 统一接口:无论底层是 OpenAI 还是 Anthropic,你的代码只需操作 UserMessageAssistantMessage,这就是 Neuron AI 提供的核心价值。
  2. 按需使用 SourceType
    • 测试或临时使用:选择 URL
    • 本地文件隐私保护:选择 BASE64
    • 生产环境高频处理大文件:先调用提供商的上传 API 获取 ID,然后使用 ID,可大幅降低 Token 消耗和延迟。
  3. 多模态支持验证:在发送 ImageContentFileContent 之前,请确保你在 provider() 中配置的模型(如 gpt-4oclaude-3-5-sonnet)支持对应的多模态输入能力。
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2026-06-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 开源技术小栈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 统一消息层
  • Message 结构
  • 核心消息类型
    • 1. UserMessage(用户消息)
    • 2. AssistantMessage(助手消息)
  • 多模态内容块
    • 多模态数据的来源类型
  • 完整使用案例
    • 案例 1:发送包含图片的消息(URL 方式)
    • 案例 2:发送本地 PDF 文件(Base64 方式)
    • 案例 3:组合多条文本与图片
  • 如何读取大模型的返回内容
    • 1. getContent() —— 获取纯文本(最常用)
    • 2. getContentBlocks() —— 获取所有内容块(高级用法)
    • 3. getTextBlocks() —— 仅获取文本块数组
  • 总结与最佳实践
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档