小程序开放平台

文档中心
智能体API
对话 LLM
sendMessage
createModel
getAgentInfo
createRecordPair
getConversations
getHistoryMessages
queryTasks
uploadFile(新增)
消费侧(小组件/小程序)API

uploadFile(智能体服务)

应用开发
>
API和SDK
>
智能体API
>
对话 LLM
>
uploadFile(新增)
>
更新时间:2025-12-01 10:41:35

uploadFile

方法概述

uploadFile
是智能体框架中用于将文件上传到平台服务器(兼容 OpenAI Files 接口)的统一封装方法。
通过该方法,你可以在智能体侧完成文件上传,并获得一个 OpenAI 风格的文件对象,以便后续在对话请求中通过
files
字段进行引用和解析。

版本说明

createModel
不同,只要你的智能体是基于
@vectorx/agent-runtime
当前版本(
> 0.6.2
)开发或升级的,就天然支持该文件上传服务
,无需额外接入或手动实现该方法。

基本信息

  1. 函数签名(IAgent 接口侧)
    uploadFile(input: UploadFileInput): Promise<UploadFileResponse>
  2. 运行时基类默认实现(AgentRuntime)
    async uploadFile(input: any): Promise<UploadFileResponse>
  3. 服务 URI
    • 模拟器 / 云端统一入口:
      POST /upload-openai-file
    • 运行时内部映射:
      • POST:upload-openai-file -> AgentDriver.uploadFileFunc -> agent.uploadFile(...)
  4. 返回类型
    • UploadFileResponse
      - 包含 OpenAI 风格的文件对象的统一响应结构
  5. 调用方式
    • 外部服务调用:通过 HTTP 接口
      POST /upload-openai-file
      ,以
      multipart/form-data
      上传文件
    • 智能体内部调用:在自定义逻辑中可以直接调用
      this.uploadFile(...)
      (继承自
      AgentRuntime
      的方法)

代码演示

const { AgentRuntime, AgentDriver } = require("@vectorx/agent-runtime");

/**
 * @typedef {import('@vectorx/agent-runtime').IAgent} IAgent
 *
 * @class
 * @implements {IAgent}
 */
class MyAgent extends AgentRuntime {
  async sendMessage(message) {
    try {
      // 创建 qwen-doc-turbo 模型
      const model = this.createModel("qwen-doc-turbo");

      // 组装消息数组
      const messages = [];

      // 1. 处理文件:根据 fileSource 区分处理
      if (Array.isArray(message?.files) && message.files.length > 0) {
        message.files.forEach((file) => {
          if (file.fileSource === "openai") {
            // OpenAI 上传的文件:使用 file-id,通过 system role 传入
            const fileId = file.id;
            if (fileId) {
              messages.push({
                role: "system",
                content: `fileid://${fileId}`,
              });
              console.log(`==== 添加 OpenAI 文件 file-id: ${fileId} ====`);
            }
          }
      }

      // 2. 添加 user 消息
      const userContent = [];

      // 2.1 添加标准上传的文件(doc_url)
      if (Array.isArray(message?.files) && message.files.length > 0) {
        message.files.forEach((file) => {
          if ((file.fileSource === "standard" || !file.fileSource) && file.url) {
            userContent.push({
              type: "doc_url",
              doc_url: [file.url],
            });
          }
        });
      }

      // 2.2 添加用户文本提示
      const userPrompt = message?.msg || "请分析这个文档";
      if (userPrompt.trim()) {
        userContent.push({
          type: "text",
          text: userPrompt.trim(),
        });
      }

      messages.push({
        role: "user",
        content: userContent,
      });

      console.log("==== 构建的消息 ====", JSON.stringify(messages, null, 2));

      // 3. 调用模型
      const modelResponse = await model.streamText({
        messages,
        parameters: {
          temperature: 0.3,
          max_tokens: 2000,
        },
        enable_thinking: true,
      });

      // 4. 流式返回结果
      for await (const chunk of modelResponse) {
        this.sseSender.send({ data: chunk });
      }
      this.sseSender.end();
    } catch (error) {
      console.error("qwen-doc-turbo stream error:", error);
      this.sseSender.end();
    }
  }
}

exports.main = function (event, context) {
  return AgentDriver.run(event, context, new MyAgent(context));
};

功能说明

  • 文件上传封装
    将前端/上游通过
    multipart/form-data
    传入的文件,统一转换为 DashScope 兼容的上传请求,并返回 OpenAI 风格的文件对象。
  • 统一日志与观测
    内置详细的访问日志,包括文件元信息解析、上传请求的 URL、状态码、响应数据、错误栈等,方便排查问题。
  • 安全与临时文件管理
    对文件名进行安全清洗,仅保留安全扩展名,并在本地临时目录下写入/清理上传文件,避免路径注入和磁盘残留。
  • 统一返回结构
    无论 DashScope 返回何种结构,都会包装为
    { code, msg, data }
    的统一响应格式,
    data
    中是 OpenAI 风格文件对象。

入参定义

UploadFileInput(IAgent 类型定义)

interface UploadFileInput {
  /** 文件内容(模拟器 / 中间件会保证该字段) */
  file: File | Buffer | string;
  /** 文件名 */
  filename: string;
  /** 文件用途,默认 "file-extract" */
  purpose?: string;
}

在当前

AgentRuntime
默认实现中,出于与上传中间件的兼容考虑,
input
实际会按如下结构解析(典型场景):

type RuntimeUploadInput = {
  file: {
    /** 文件二进制内容 */
    buffer: Buffer;
    /** 原始文件名及其变体 */
    name?: string;
    newFilename?: string;
    originalFilename?: string;
    /** MIME 类型 */
    type?: string;
    mimetype?: string;
    /** 可选临时路径 */
    filepath?: string;
    size?: number;
  } | Buffer;
  /** 文件用途 */
  purpose?: string; // 默认 "file-extract"
};

在默认实现中,框架会自动完成以下处理:

  • file
    中提取
    buffer
    、文件名、
    mimetype
    等信息;
  • 生成安全文件名、构造临时文件路径并写入磁盘;
  • 通过
    form-data
    file
    +
    purpose
    字段向服务器进行上传。

可选 JSON Schema 入参(高级用法)

如果你不走

multipart/form-data
,而是在自定义
agent.uploadFile
实现里自己做 Schema 校验,可以采用下述 JSON 结构(base64 模式):

export const uploadFileInputSchema = z.object({
  /** 文件名 */
  filename: z.string().min(1, "文件名不能为空"),
  /** 文件用途,固定为 "file-extract" */
  purpose: z.string().optional().default("file-extract"),
  /** 文件内容(base64 编码字符串) */
  fileContent: z.string().min(1, "文件内容不能为空"),
  /** 文件 MIME 类型 */
  mimeType: z.string().optional(),
});

此时你可以在进入

AgentRuntime.uploadFile
前,将该 JSON 转换为
RuntimeUploadInput
的格式再传入。

出参定义

UploadFileResponse

interface BaseResponse<T = any> {
  /** 状态码 */
  code: number;
  /** 消息 */
  msg: string;
  /** 数据 */
  data?: T;
}

/** 真正的文件数据(OpenAI 风格) */
interface UploadFileData {
  /** 文件 ID */
  id: string;
  /** 对象类型 */
  object: string;
  /** 文件大小(字节) */
  bytes: number;
  /** 创建时间戳(Unix) */
  created_at: number;
  /** 文件名 */
  filename: string;
  /** 文件用途 */
  purpose: string;
  /** 文件状态 */
  status: string;
  /** 状态详情 */
  status_details?: any;
}

/** 文件上传响应 */
type UploadFileResponse = BaseResponse<UploadFileData>;
  • 成功时
    • code = 0
    • msg = "success"
    • data
      为 OpenAI 风格文件对象(可直接塞入后续
      files
      字段)
  • DashScope 返回非 2xx 状态时
    • code = response.statusCode
    • msg = response.data?.error?.message || "文件上传失败"
    • data = response.data
  • 发生异常时(网络/解析等)
    • code = -1
    • msg = error.message || "文件上传失败"

使用示例

1. 外部调用(前端 / 后端)通过 REST 上传文件

// 浏览器侧示例(multipart/form-data)
async function uploadOpenAiFile(file: File, purpose = "file-extract") {
  const formData = new FormData();
  formData.append("file", file);
  formData.append("purpose", purpose);

  const resp = await fetch("/api/agent/upload-openai-file", {
    method: "POST",
    body: formData,
  });

  const res = await resp.json();
  if (res.code !== 0) throw new Error(res.msg || "文件上传失败");
  return res.data as UploadFileData;
}

上传成功后得到的

UploadFileData
,可以直接在后续对话请求中作为
files
数组元素传入(遵循运行时的消息 Schema 要求)。

2. 智能体内部调用(继承 AgentRuntime)

class MyAgent extends AgentRuntime {
  async sendMessage(input: any) {
    // 假设你在上游已经通过 HTTP 上传过文件,并拿到了 UploadFileData
    const uploadedFile: UploadFileData = input.uploadedFile;

    const requestData = {
      msg: input.msg,
      files: [
        {
          id: uploadedFile.id,
          filename: uploadedFile.filename,
          purpose: uploadedFile.purpose || "file-extract",
          bytes: uploadedFile.bytes,
          created_at: uploadedFile.created_at,
        },
      ],
      history: [],
    };

    // 后续直接走模型调用逻辑(略)
  }
}

如果你在某些自定义场景下需要主动上传本地文件(不经过 HTTP 中间件),也可以直接调用基类的

uploadFile

class LocalFileAgent extends AgentRuntime {
  async uploadLocalFileExample() {
    const fs = await import("fs");
    const buffer = fs.readFileSync("/path/to/file.pdf");

    const res = await this.uploadFile({
      file: buffer,
      purpose: "file-extract",
      filename: "file.pdf",
    });

    if (res.code !== 0 || !res.data) throw new Error(res.msg || "上传失败");
    return res.data; // UploadFileData
  }
}

注意事项

  1. 智能体版本
    @vectorx/agent-runtime
    > 0.6.2
    )开发或升级,即自动具备
    uploadFile
    能力**,
  2. 您可以在模拟器中的直接调试 OpenAI 文件上传调试说明

界面效果可参考:

Description

请使用

@vectorx/xhs-cloud-cli@0.4.2
及以上版本,就可以在本地使用「智能体模拟器」完整调试
POST /upload-openai-file
这个 OpenAI 标准文件上传接口