AI编排器与dsh集成实践:构建插件化AI工作流开发平台

如果你最近在关注 AI 开发工具,大概率会看到两个高频词: dsh AI编排器 。前者是 DeepSeek 推出的命令行工具,后者是构建复杂 AI 应用流的新范式。但你可能会有这样的困惑:dsh 看起来像个插件管理器,AI 编排器听起来又很复杂,它们之间到底有什么关系?更重要的是,作为一个开发者,我为什么要关心这个组合?

这篇文章要解决的,正是这个核心问题。我将分享一个深度实践:如何将 dsh 的核心能力,无缝集成到一个自研的 AI 编排器(我们称之为 MTNode)中。这不是简单的功能堆叠,而是一次从“工具使用”到“能力内化”的工程实践。通过这次“爆肝”50小时的集成,我们不仅让 MTNode 获得了管理海量 AI 插件和技能的能力,更重要的是,我们重构了 AI 应用的开发、分发和协作流程。

本文的核心判断是: dsh 的价值远不止于一个命令行工具,其背后“插件市场”和“技能编排”的生态思想,是构建下一代 AI 应用平台的关键基础设施。将其融入 AI 编排器,本质上是将离散的 AI 能力(Skill)标准化、模块化,并通过编排引擎进行智能调度,从而大幅降低复杂 AI 工作流开发的成本和门槛。

读完本文,你将获得:

  1. 对 dsh 和 AI 编排器关系的深度理解 ,超越表面功能。
  2. 一套可复现的集成方案 ,包含环境准备、核心流程、代码示例和避坑指南。
  3. 清晰的工程化最佳实践 ,帮助你在自己的项目中应用类似思路。
  4. 对 AI 应用开发未来形态的洞察 ,理解插件化与编排如何改变开发范式。

1. 为什么要把 dsh 融入 AI 编排器?解决什么真实痛点?

在深入技术细节之前,我们必须先回答“为什么”。这决定了集成的方向和价值。

痛点一:AI 能力碎片化与集成成本高。 当前,AI 能力散落在各处:OpenAI 的 API、各类开源模型、专门的图像生成、代码解释、爬虫工具等。开发者每接入一个新能力,都需要处理鉴权、API 调用、错误处理、数据格式转换等一系列重复劳动。dsh 通过插件机制,将各种能力封装成统一的“技能”(Skill),提供了标准化的接入方式。

痛点二:复杂工作流编排困难。 单一 AI 技能价值有限。真正的生产力来自多个技能的串联与协同。例如,“分析行业报告”可能涉及:网页爬取 -> 文本总结 -> 数据提取 -> 生成图表 -> 输出简报。传统方式需要写大量胶水代码来串联不同服务。AI 编排器(如 LangChain、AutoGen 的进阶思想,或我们自研的 MTNode)正是为了解决这类问题而生,它提供了可视化或代码化的方式来定义和执行这种工作流。

痛点三:技能的分发、发现与版本管理缺失。 团队内部或社区积累的 AI 技能,如何共享?如何确保大家使用的是最新、最稳定的版本?如何避免重复造轮子?dsh 内置的插件市场(dshmarket)概念和 dsh plugin 命令体系,为技能的包管理、安装、更新提供了现成的解决方案。

所以,集成的核心目标就是: 用 dsh 解决技能的“供给侧”(创建、打包、分发)问题,用 AI 编排器解决技能的“消费侧”(组合、调度、执行)问题。 让开发者可以像 npm install 一样安装 AI 技能,然后像搭积木一样在编排器中构建复杂应用。

2. 核心概念厘清:dsh, DeepSeek Harness, AI 编排器与 MTNode

为了避免混淆,我们先明确几个关键概念:

术语 定义与角色 类比
dsh DeepSeek Harness 的命令行工具。它是生态的 入口和管理器 ,负责插件的安装、卸载、更新、运行环境配置等。 类似于 npm pip ,但管理的是 AI 技能包。
DeepSeek Harness 一个更广泛的 AI 工具开发平台或框架,dsh 是其命令行界面。它可能包含桌面端、插件市场等组件。 类似于 Node.js 生态(包含 npm、node、众多包)。
AI 编排器 (AI Orchestrator) 一种用于设计、执行和监控多个 AI 智能体或技能协作工作流的系统。它关注流程的逻辑控制、状态管理、错误处理和结果传递。 类似于 Apache Airflow(用于任务流)或 Node-RED(用于 IoT 流),但专为 AI 交互设计。
MTNode 本文示例中 自研的 AI 编排器项目 。它是一个具体的、可运行的编排器实现,我们将把 dsh 的能力集成进去。你可以将其理解为类 LangChain 但更侧重工程化集成的系统。 本文的“实验平台”和集成目标。
Skill / 插件 一个可独立执行的 AI 功能单元。例如:一个调用 GPT-4 进行文本总结的函数,一个调用 Stable Diffusion 生成图片的服务。在 dsh 生态中,Skill 通常以插件形式分发。 类似于一个 npm 包,封装了特定功能。

它们的关系: 开发者使用 dsh 从市场(如 dshmarket )安装一个“天气预报查询” Skill 插件。然后,在 MTNode(AI 编排器) 中,可以将这个“天气预报”技能作为一个节点,与“邮件发送”技能、“日程安排”技能连接起来,构建一个“雨天提醒”自动化工作流。

3. 环境准备与前置条件

开始集成前,请确保你的开发环境满足以下要求。这是后续所有操作的基础。

3.1 基础运行环境

  • 操作系统 : Linux (Ubuntu 20.04+)、macOS 或 Windows Subsystem for Linux 2 (WSL2)。推荐 Linux 环境以避免路径和权限的兼容性问题。
  • Node.js : 版本 18 或更高。这是运行 dsh 和现代 JavaScript/TypeScript 项目的基础。
  • 包管理器 : pnpm 。从网络热词中频繁出现的 pnpm dsh web 可知,dsh 生态强烈依赖 pnpm。安装命令:
    npm install -g pnpm
    
  • Python : 版本 3.8+。许多 AI 相关的插件或后端服务可能依赖 Python。
  • Git : 用于克隆代码仓库。

3.2 安装与验证 dsh 这是集成的前提。根据官方或社区指南安装 dsh。

# 通常的安装方式(请以最新官方文档为准)
npm install -g @deepseek/dsh
# 或使用 pnpm
pnpm add -g @deepseek/dsh

安装后,验证是否成功:

dsh --version
# 或查看帮助
dsh --help

如果遇到 ‘dsh’ 不是内部或外部命令 的错误,请将 Node.js 的全局安装目录(如 ~/.npm-global/bin /usr/local/bin )添加到系统的 PATH 环境变量中。

3.3 初始化 MTNode 项目 MTNode 是我们的 AI 编排器项目。你需要一个基础框架。这里我们以一个简化的 TypeScript 项目为例。

# 1. 创建项目目录
mkdir mtnode-orchestrator
cd mtnode-orchestrator

# 2. 初始化项目(使用 pnpm)
pnpm init

# 3. 安装基础依赖
pnpm add typescript ts-node @types/node express axios
pnpm add -D @types/express nodemon

# 4. 初始化 TypeScript 配置
npx tsc --init

编辑生成的 tsconfig.json ,确保 "outDir": "./dist" 等配置正确。

3.4 项目结构预览 集成前,先规划好项目结构:

mtnode-orchestrator/
├── package.json
├── tsconfig.json
├── src/
│   ├── core/
│   │   ├── orchestrator.ts    # 编排器核心引擎
│   │   └── skill-manager.ts   # 技能管理器(与dsh集成关键)
│   ├── skills/                # 本地技能存放目录(从dsh安装的插件会链接或复制到这里)
│   │   └── .gitkeep
│   ├── workflows/             # 工作流定义文件
│   ├── server.ts              # HTTP API 服务器
│   └── index.ts               # 应用入口
├── plugins/                   # dsh 插件安装的目录(可选,另一种管理方式)
└── .env                       # 环境变量(如API密钥)

4. 集成核心流程拆解:让编排器“认识”dsh的技能

集成不是简单调用 dsh 命令,而是要让 MTNode 具备 发现、加载、管理 来自 dsh 生态的技能的能力。核心流程分为四步:

步骤一:技能发现与元数据获取 MTNode 需要知道有哪些技能可用。我们通过解析 dsh plugin list 的输出或直接读取 dsh 插件安装目录的元数据文件来实现。

步骤二:技能加载与适配器模式 dsh 插件可能有不同的启动方式(CLI命令、HTTP服务、JS模块)。MTNode 需要统一的接口来调用它们。这里要设计一个 Skill Adapter(技能适配器) ,将不同插件的调用方式,统一成 MTNode 引擎理解的 execute(input: any): Promise<any> 方法。

步骤三:技能注册与生命周期管理 将加载后的技能实例注册到 MTNode 的核心技能注册表中。管理技能的初始化、健康检查、资源清理等生命周期。

步骤四:工作流编排与执行 用户在设计工作流时,可以从技能注册表中选择技能节点。MTNode 引擎负责按流程执行这些节点,处理节点间的数据传递、条件分支、循环和错误处理。

5. 核心代码实现:构建 Skill Manager

下面我们聚焦于最关键的 Skill Manager(技能管理器) 的实现。它负责与 dsh 交互并管理技能。

5.1 定义技能接口 (ISkill.ts) 首先,定义所有技能必须遵守的契约。

// src/core/interfaces/ISkill.ts
export interface ISkillMeta {
  id: string;          // 技能唯一ID,如 “dsh-market/weather”
  name: string;        // 技能显示名称
  version: string;
  author?: string;
  description: string;
  inputSchema: any;    // 输入参数JSON Schema
  outputSchema: any;   // 输出参数JSON Schema
}

export interface ISkill extends ISkillMeta {
  // 核心执行方法
  execute(params: Record<string, any>, context?: any): Promise<any>;
  // 初始化(如加载模型、连接API)
  initialize?(): Promise<void>;
  // 清理资源
  cleanup?(): Promise<void>;
}

5.2 实现 DSH 技能适配器 (DshSkillAdapter.ts) 这个适配器负责调用具体的 dsh 插件。假设插件通过 CLI 命令调用。

// src/core/adapters/DshSkillAdapter.ts
import { ISkill, ISkillMeta } from '../interfaces/ISkill';
import { exec } from 'child_process';
import { promisify } from 'util';
const execAsync = promisify(exec);

export class DshSkillAdapter implements ISkill {
  public meta: ISkillMeta;
  private pluginCommand: string; // 例如 “dsh-weather”

  constructor(meta: ISkillMeta, pluginCommand: string) {
    this.meta = meta;
    this.pluginCommand = pluginCommand;
  }

  async initialize(): Promise<void> {
    // 可以在这里检查插件是否安装:`dsh plugin list | grep ${this.pluginCommand}`
    console.log(`Skill ${this.meta.id} initialized.`);
  }

  async execute(params: Record<string, any>, context?: any): Promise<any> {
    // 将参数转换为命令行参数或标准输入
    // 例如,假设插件接受 --city 参数
    const args = Object.entries(params)
      .map(([key, value]) => `--${key}="${value}"`)
      .join(' ');

    const command = `${this.pluginCommand} ${args}`;
    
    try {
      console.log(`Executing dsh command: ${command}`);
      const { stdout, stderr } = await execAsync(command, { timeout: 30000 }); // 30秒超时
      
      if (stderr) {
        console.warn(`Skill ${this.meta.id} stderr:`, stderr);
      }
      
      // 解析 stdout 为结构化数据,这里简单返回字符串,实际应根据插件输出格式解析
      return { success: true, output: stdout.trim(), raw: { stdout, stderr } };
    } catch (error: any) {
      console.error(`Failed to execute skill ${this.meta.id}:`, error);
      return { 
        success: false, 
        error: error.message,
        code: error.code 
      };
    }
  }

  async cleanup(): Promise<void> {
    // 清理临时文件或连接
  }
}

5.3 实现技能管理器 (SkillManager.ts) 这是集成的大脑,负责发现、加载、注册技能。

// src/core/SkillManager.ts
import { ISkill, ISkillMeta } from './interfaces/ISkill';
import { DshSkillAdapter } from './adapters/DshSkillAdapter';
import * as fs from 'fs/promises';
import * as path from 'path';

export class SkillManager {
  private skills: Map<string, ISkill> = new Map();
  private dshPluginPath: string; // dsh 全局插件安装路径

  constructor(dshPluginPath?: string) {
    // 默认路径,不同系统需调整
    this.dshPluginPath = dshPluginPath || path.join(process.env.HOME || '', '.dsh', 'plugins');
  }

  // 方法1:扫描 dsh 插件目录,自动注册
  async discoverDshPlugins(): Promise<void> {
    try {
      const pluginDirs = await fs.readdir(this.dshPluginPath, { withFileTypes: true });
      
      for (const dir of pluginDirs) {
        if (dir.isDirectory()) {
          const pluginName = dir.name;
          const metaPath = path.join(this.dshPluginPath, pluginName, 'package.json');
          
          try {
            const pkgContent = await fs.readFile(metaPath, 'utf-8');
            const pkg = JSON.parse(pkgContent);
            
            // 从 package.json 中提取技能元数据
            const skillMeta: ISkillMeta = {
              id: `dsh:${pkg.name}`,
              name: pkg.name,
              version: pkg.version,
              author: pkg.author,
              description: pkg.description || 'No description',
              // 这里需要约定插件在 package.json 中如何声明输入输出 schema
              inputSchema: pkg.contributes?.inputSchema || {},
              outputSchema: pkg.contributes?.outputSchema || {},
            };
            
            // 创建适配器并注册
            // 假设插件包的主入口提供了一个可执行命令,名字与包名相关
            const commandName = pkg.bin ? Object.keys(pkg.bin)[0] : `dsh-${pkg.name.replace('@dsh-market/', '')}`;
            const skill = new DshSkillAdapter(skillMeta, commandName);
            
            await skill.initialize?.();
            this.registerSkill(skill);
            console.log(`Discovered and registered dsh plugin: ${skillMeta.id}`);
            
          } catch (error) {
            console.warn(`Failed to parse plugin ${pluginName}:`, error.message);
          }
        }
      }
    } catch (error) {
      console.error(`Could not read dsh plugin directory at ${this.dshPluginPath}:`, error.message);
      // 可能是 dsh 未安装或路径不对,不影响后续手动注册
    }
  }

  // 方法2:手动注册技能(用于本地开发的技能)
  registerSkill(skill: ISkill): void {
    if (this.skills.has(skill.meta.id)) {
      console.warn(`Skill ${skill.meta.id} already registered, overwriting.`);
    }
    this.skills.set(skill.meta.id, skill);
  }

  // 根据ID获取技能实例
  getSkill(skillId: string): ISkill | undefined {
    return this.skills.get(skillId);
  }

  // 获取所有已注册技能
  getAllSkills(): ISkillMeta[] {
    return Array.from(this.skills.values()).map(s => s.meta);
  }

  // 执行指定技能
  async executeSkill(skillId: string, params: Record<string, any>, context?: any): Promise<any> {
    const skill = this.getSkill(skillId);
    if (!skill) {
      throw new Error(`Skill not found: ${skillId}`);
    }
    return await skill.execute(params, context);
  }
}

5.4 在编排器引擎中使用 Skill Manager (orchestrator.ts)

// src/core/orchestrator.ts (简化版)
import { SkillManager } from './SkillManager';

export class MTNodeOrchestrator {
  private skillManager: SkillManager;
  
  constructor() {
    this.skillManager = new SkillManager();
  }
  
  async init(): Promise<void> {
    // 启动时自动发现 dsh 插件
    await this.skillManager.discoverDshPlugins();
    console.log('Orchestrator initialized with skills:', this.skillManager.getAllSkills().map(s => s.id));
  }
  
  // 定义一个简单的工作流:技能A -> 技能B
  async runSequentialWorkflow(skillIdA: string, paramsA: any, skillIdB: string, paramsBProvider: (resultA: any) => any): Promise<any> {
    const resultA = await this.skillManager.executeSkill(skillIdA, paramsA);
    if (!resultA.success) {
      throw new Error(`Workflow failed at skill A: ${resultA.error}`);
    }
    
    const paramsB = paramsBProvider(resultA.output);
    const resultB = await this.skillManager.executeSkill(skillIdB, paramsB);
    
    return { resultA, resultB };
  }
}

6. 运行与验证:构建一个真实的工作流

理论需要实践验证。让我们假设已经通过 dsh 安装了两个插件:一个用于文本总结 ( dsh-summarize ),一个用于情感分析 ( dsh-sentiment )。

6.1 启动服务器并初始化

// src/server.ts
import express from 'express';
import { MTNodeOrchestrator } from './core/orchestrator';

const app = express();
app.use(express.json());

const orchestrator = new MTNodeOrchestrator();

// 初始化编排器(会自动发现dsh插件)
orchestrator.init().then(() => {
  console.log('MTNode Orchestrator is ready.');
});

// API: 获取所有可用技能
app.get('/api/skills', (req, res) => {
  // 这里需要从 orchestrator 中暴露 skillManager
  // 假设我们通过一个 getter 获取
  const skills = orchestrator.getSkillManager().getAllSkills();
  res.json({ skills });
});

// API: 执行一个技能
app.post('/api/skills/:skillId/execute', async (req, res) => {
  const { skillId } = req.params;
  const params = req.body;
  
  try {
    const result = await orchestrator.getSkillManager().executeSkill(skillId, params);
    res.json(result);
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

// API: 执行一个简单工作流(总结 -> 情感分析)
app.post('/api/workflows/summarize-then-analyze', async (req, res) => {
  const { text } = req.body;
  if (!text) {
    return res.status(400).json({ error: 'Text is required' });
  }
  
  try {
    const finalResult = await orchestrator.runSequentialWorkflow(
      'dsh:summarize', // 假设的ID
      { text, maxLength: 100 },
      'dsh:sentiment',
      (summaryResult) => ({ text: summaryResult.output }) // 将总结结果作为情感分析的输入
    );
    res.json(finalResult);
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`MTNode Server running on http://localhost:${PORT}`);
});

6.2 启动服务并测试

  1. 编译并运行:
    npx nodemon src/server.ts
    
  2. 使用 curl 或 Postman 测试:
    • 获取技能列表
      curl http://localhost:3000/api/skills
      
      预期返回包含 dsh:summarize dsh:sentiment 的 JSON 数组。
    • 执行工作流
      curl -X POST http://localhost:3000/api/workflows/summarize-then-analyze \
        -H "Content-Type: application/json" \
        -d '{"text": "这是一段非常长的产品评测,用户表达了复杂的心情,既有对功能的赞赏,也有对价格的抱怨。总的来说,产品不错但太贵了。"}'
      
      预期返回一个 JSON,包含总结结果和情感分析结果(如 positive , negative , mixed )。

7. 常见问题与排查思路 (FAQ)

在实际集成中,你几乎一定会遇到下面这些问题。

问题现象 可能原因 排查方式 解决方案
dsh 命令未找到 Node.js 全局路径未正确配置,或 dsh 未全局安装。 1. 运行 which dsh where dsh
2. 检查 npm list -g --depth=0
1. 重新安装: pnpm add -g @deepseek/dsh
2. 将 ~/.pnpm-global/bin 或类似路径加入 PATH。
dsh plugin list 无输出或报错 dsh 配置文件损坏,或网络问题导致插件市场无法访问。 1. 检查 ~/.dsh 目录权限。
2. 尝试 dsh --profile web 看是否能打开 Web UI。
1. 尝试重置配置(备份后删除 ~/.dsh 目录)。
2. 检查网络代理设置。
Skill Manager 扫描不到插件 dshPluginPath 路径设置错误。dsh 可能将插件安装在其他位置。 1. 在终端执行 dsh plugin list --json 查看插件安装路径。
2. 手动查找 ~/.dsh ~/.local/share/dsh 等目录。
修改 SkillManager 构造函数中的 dshPluginPath ,或从环境变量读取。
插件执行超时或失败 1. 插件本身有 bug 或依赖缺失。
2. 参数格式不正确。
3. 插件需要网络或 API 密钥。
1. 直接在终端运行该插件的命令,看是否正常。
2. 检查 execAsync stderr 输出。
3. 查看插件文档,确认输入参数格式。
1. 确保插件已正确安装 ( dsh plugin install <name> )。
2. 在 DshSkillAdapter.execute 中增加详细的日志,打印最终执行的命令。
3. 确保必要的环境变量(如 OPENAI_API_KEY )已设置。
WSL 环境下 dsh tui 错位 这是终端兼容性问题,与集成无关。 在 Windows Terminal 或更现代的终端中尝试。 1. 使用 dsh --profile web 启动 Web 界面。
2. 或直接使用 CLI 命令,避免 TUI。
pnpm dsh web 卡住 pnpm 进程或依赖安装问题。 检查网络,查看进程是否在下载。 1. 设置国内镜像源。
2. 尝试 pnpm store prune 清理后重试。
3. 直接使用 dsh 命令,而非通过 pnpm 执行。
技能输入输出 Schema 不匹配 插件 package.json 中的 contributes 字段格式不符合预期。 打印出读取到的 pkg.contributes 进行查看。 1. 为 Skill Manager 定义更灵活的 Schema 解析逻辑。
2. 或要求插件遵循特定的元数据约定。

8. 最佳实践与工程化建议

将 dsh 集成到 AI 编排器只是一个开始。要让这个系统在生产环境中可靠运行,还需要考虑以下几点:

8.1 技能元数据标准化 与插件开发者约定一个标准的元数据格式(如在 package.json 中使用固定的 contributes 字段),明确声明技能的输入、输出、版本、作者、图标、所需环境变量等。这能极大提升自动发现的可靠性。

8.2 安全与沙箱化 直接通过 child_process.exec 执行外部命令存在安全风险(特别是安装来源不明的插件)。在生产环境中,应考虑:

  • 权限控制 :为不同技能设置不同的执行权限和资源限制。
  • 沙箱环境 :使用 Docker 容器或更轻量的沙箱技术(如 nsjail , gVisor )来隔离插件的运行环境。
  • 输入验证与净化 :对所有传入插件的参数进行严格的验证和转义,防止命令注入攻击。

8.3 性能与缓存

  • 连接池与预热 :对于需要建立网络连接的技能(如数据库、API客户端),实现连接池和预热机制。
  • 结果缓存 :对计算成本高、输入相同的技能执行结果进行缓存,可以显著提升工作流执行效率。考虑使用 Redis 或内存缓存。
  • 异步与流式处理 :对于长耗时技能,支持异步执行和状态查询。对于生成类技能(如文本流、图片生成),考虑支持流式输出。

8.4 可观测性与监控

  • 全链路日志 :为每个技能的执行记录详细的日志,包括输入、输出、耗时、错误信息。使用结构化日志(如 JSON)。
  • 指标收集 :收集技能调用次数、成功率、延迟等指标,便于监控和告警。
  • 工作流可视化与调试 :提供界面,能够可视化工作流的执行过程,查看每个节点的状态和中间数据,这是 AI 编排器的核心价值之一。

8.5 版本管理与依赖隔离

  • 技能版本锁定 :工作流定义应锁定所用技能的具体版本,避免因插件自动更新导致流程异常。
  • 依赖冲突解决 :不同技能可能依赖同一库的不同版本。考虑为每个技能创建独立的虚拟环境(如使用 venv 或容器)来彻底隔离依赖。

9. 总结与展望:超越集成的思考

通过以上步骤,我们成功地将 dsh 的技能生态接入了自研的 AI 编排器 MTNode。这不仅仅是技术上的连通,更是一种开发范式的转变:

  • 对开发者而言 ,意味着可以从一个庞大的市场(dshmarket)即插即用地获取 AI 能力,并像搭积木一样构建复杂应用,焦点从“如何实现某个功能”转向“如何组合功能解决问题”。
  • 对技能开发者而言 ,提供了一个标准的分发渠道和运行环境,只需关注单一技能的打磨。
  • 对项目架构而言 ,实现了关注点分离:技能供给(dsh生态)与流程编排(MTNode引擎)解耦,系统更清晰、更易维护。

后续可以深入的方向:

  1. 开发图形化编排界面 :让非开发者也能通过拖拽方式设计 AI 工作流。
  2. 实现技能组合的自动优化 :根据历史执行数据,自动推荐或优化技能的执行顺序和参数。
  3. 探索技能间的语义理解 :让编排器能理解技能的输入输出语义,实现更智能的自动连接。
  4. 构建私有技能市场 :基于 dsh 的协议,搭建团队或企业内部的私有技能仓库,沉淀组织特有的 AI 能力。

这次集成实践揭示了 AI 应用开发的一个未来趋势: 工具链的垂直整合与生态开放并存 。dsh 这样的工具负责建立标准和生态,而像 MTNode 这样的编排器则负责将生态中的能力转化为实际的生产力。作为开发者,理解并参与构建这样的中间层,将是在 AI 时代构建复杂应用的关键竞争力。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值