☰
面向AI计算层的新型编程语言构想:从张量到Agent的原语化设计
2026/10/15 9:12:25 网站建设 项目流程

这两年我做AI基础设施的时间越长,心里越有一种别扭。Python写研究原型是真的方便,可一旦要把模型推理、数据预处理、Agent决策循环这些“计算层”的东西做成稳定服务,代码总量会一下子膨胀,而且大部分时间不是在解决模型问题,而是在处理张量搬运、格式转换、设备同步和跨进程通信。于是我在业余时间开始琢磨一门面向人工智能计算层的新型编程语言,暂时命名为AI语言。它不是一门“AI生成代码的语言”,也不是一个深度学习框架,而是一种把张量、模型、推理管线、工具调用和Agent控制流做成语言原语的编程语言。如果你也在做AI工程化、Agent基建或边缘推理,或者单纯对“让语言更懂AI”这件事感兴趣,这篇构想笔记应该能给你一些可讨论的素材。

1. 为什么我们需要一门“AI语言”

1.1 现在写AI代码,痛点到底在哪

想象一个最简单的部署任务:用Python读取用户上传的图片,预处理之后喂给目标检测模型,再把结果结构化返回。用PyTorch写出来,你至少要经历一次model.eval()、一次with torch.no_grad()、一次np.asarray(..., dtype=...),还要手动把torch.Tensor从显存拷回内存。这些代码本身不难,难的是当模型数量从1个变成10个、当输入从一张图变成多模态流、当部署环境从一台带GPU的服务器变成CPU边缘盒子时,这些“胶水代码”会成为维护黑洞。

我做过的几个项目里,最典型的情况是:训练和推理用PyTorch,数据处理用NumPy/Pillow/ffmpeg,API服务用FastAPI,异步任务用Celery,模型版本管理用另一个内部工具。整条链路里只有20%的代码真正和模型数学相关,剩余80%都在做类型转换、生命周期管理、异常兜底和参数透传。通用语言给了我们无限自由度,却没有给AI开发提供结构性约束,这是我认为最大的痛点。

简单列一下,这套传统技术栈给计算层带来的压力其实很集中:

痛点场景Python常见做法AI语言期望做到
张量搬运手动to(device)、cpu()、numpy()编译器根据变量标注自动插入传输
形状错误运行时才暴露shape mismatch编译期检查张量形状是否对齐
设备资源torch.cuda.empty_cache()碰运气运行前预计算显存占用,静态预分配
Agent状态用字典/JSON保存上下文和工具结果用语言级状态机描述循环与分支
算子集成在C++/CUDA和Python之间写胶水层语言直接导出C ABI,桥接成本降低

这里面每一行都对应我看到过的生产事故。拿形状错误来说,在Python里经常是模型上线后跑前几条数据才发现维度不对,运气不好就要凌晨爬起来看Kibana日志。如果一门语言能在编译期就告知“resize(640, 640)之后的张量和你模型输入的[1, 3, 640, 640]对不上”,这些事故完全可以前置到代码保存时。

1.2 从训练脚本到AI Agent,边界已经变了

过去我们说人工智能编程语言,默认就是Python+TensorFlow/PyTorch;现在再看这个领域,AI应用的重心已经从“训练好一个模型”转向“把多个模型、多个工具串成一个能自主决策的Agent”。这意味着语言要承载的不只是张量算子,还包括大模型上下文管理、工具注册与调用、记忆检索、条件分支和循环回退。最新热词里“基于rust语言ai agent”能成为话题,说明大家已经意识到,用Python写Agent原型很快,但一旦要压并发、控延迟、做类型安全,Rust这类拥有严格类型和所有权系统的语言更适合当底座。

与此同时,国内工程界也在讨论像仓颉这样的通用语言。这类新语言的出现说明一个趋势:语言设计正在从“什么都能干”走向“每个领域都值得有一门表达力更贴合的语言”。AI语言正是这个趋势在人工智能计算层的投射。可它和仓颉不是竞争关系——仓颉更像系统语言,AI语言更像一种专门服务AI工作负载的“业务语言”,未来完全可以互相调用,一个管系统,一个管智能逻辑。

从学习路径来看,过去提到“深度学习所需要的编程语言”,答案无外乎Python和C++;现在我会再加上Rust、Mojo、仓颉这类新选手。Mojo想用Python超集的方式加速AI计算,仓颉想成为通用系统语言,而“AI语言”想走一条不同的路:直接定义一套带有张量和模型语义的语言,不兼容Python语法,但能简单翻译成Python能调用的产物。三者并不冲突,反而能互相验证“给AI做专用语言”这件事是可行的。

2. AI语言的核心设计思路

2.1 目标不是替代Python,而是接管计算层

在我的构想里,AI语言有四个核心目标。第一,让张量、模型、Pipeline和Agent成为语言内建概念,而不是靠框架类库模拟。第二,通过静态类型系统和编译期推导,提前检查shape是否对齐、设备是否匹配、内存生命周期是否安全。第三,代码同时支持“脚本模式”和“编译执行模式”:脚本模式方便研究者做探索,编译执行模式适合工程师做生产部署。第四,和现有Python生态无缝互操作,不能把用户锁在一个封闭岛上。

这四个目标决定了语言整体是“分层”的。最底层是一套张量和算子抽象,类似PyTorch的Tensor但更强调形状和设备信息;中间层是模型与Pipeline抽象,负责把多个算子、多个子模型组合成一个可执行的计算图;最上层是Agent抽象,负责描述上下文、工具、循环和策略。这三层之间用明确定义的接口衔接,每层都可以单独替换实现。

为什么不做成Python库而是新语言?因为库只能在Python的语法边界内做事,改变不了if分支、for循环和平常用的dict/list本身不具备张量语义这个事实。新语言可以从语法层面规定“每个变量都带一个可推导的数据布局”,编译器拿到完整程序后再做全局分析和优化。这个差异化是我觉得新语言成立的关键。

2.2 语法设计:让AI逻辑“按直觉写”

我试着设计过一段AI语言草图,目标是让读代码的人一眼看出“这是个模型推理管线”。下面这段代码定义了一个文件预处理节点和一个目标检测模型节点,再把它们串起来:

input = load.image("file://upload/{user_id}.jpg") box = preprocess.to_float32(input) .resize(640, 640) .normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) det = Model("yolov8s.onnx") .inputs(box) .device("gpu:0") .fp16(true) results = det.outputs.map(parse_detections)

这段代码看起来和Python很像,但注意两点:第一,preprocess.to_float32返回的是一个“数据处理节点”,而不是立刻执行;第二,Model(...).inputs(...)会把前面的数据节点注册为输入依赖,编译期就能推导出box的shape是不是符合模型输入要求。如果不符合,编译器直接报错,而不是等到运行时才炸。

同样的逻辑用PyTorch写,会变成一堆函数调用和上下文管理;用AI语言写,更像是描述一张数据流图。尤其det.outputs.map(parse_detections),会把模型输出映射成一个后处理节点,整个过程没有出现一次显式的dict传递。我认为好的领域语言就应该让业务语义跃然纸上,类型系统在背后默默兜底。

在实际落地时,语法设计一定要克制。我已经砍掉过好几版“语法糖”,比如自动把string格式化成Prompt、自动给HTTP请求加重试等。原因很简单:语言特性越多,编译器优化的确定性就越差。用户期望AI语言描述计算流,而不是描述整个世界。正因为如此,我给每一层都定了一个“特性预算”——张量层只有五种运算符重载,Pipeline层只有四种组合关键字,Agent层只有两种控制流结构,多一个都不加。

2.3 计算图与自动微分:不是新故事,但要服务新场景

计算图和自动微分是老生常谈,AI语言不打算在这两条路上另起炉灶,而是要把它们改造成更适合AI Agent的形态。传统训练场景里,计算图是静态的、形状确定的,编译期可以做非常激进的前置优化。但Agent场景完全不同:模型调用会根据上下文动态变化,工具选择是运行期分支,循环次数也不固定。如果只支持静态图,Agent会非常难写;如果只支持动态图,又丢掉编译优化能力。

我的倾向是“两级图”:一层是静态数据流图,用来描述模型推理和前处理/后处理链路,这些链路结构在运行前基本确定;另一层是动态控制流图,专门描述Agent的循环、条件、回溯和工具分支。静态图编译到后端算子,动态图编译成状态机。这样既能拿到静态图的高性能,又不会限制Agent的灵活性。

在自动微分方面,AI语言会把梯度函数作为一等公民,但不强制每个算子都可微。比如一个协作工具调用节点,它可能只是在HTTP层面拿数据,不需要梯度;语言允许用户标记no_grad并把这类节点放进独立子图,避免反向传播污染Agent的逻辑判断。这个设计让“训练”和“推理”在语言层就没有硬边界:同一个Pipeline既能跑前向推理,也能用在微调阶段,只是编译器会根据是否启用反向模式来决定要不要给每个节点保留中间变量。

3. 关键实现环节与工具链

3.1 选Rust做编译器内核,不止是性能

关于实现语言,我在“用C++写编译器核心”和“用Rust写编译器核心”之间反复横跳过,最后倾向Rust。理由不只是性能——C++也不差,而是Rust的所有权模型对编译器这类大量操作中间表示的程序非常友好。编译器的IR(中间表示)构建、图优化、内存生命周期分析,本质上是不断把一个节点集合变换到另一个节点集合,Rust的所有权系统能在编译期挡住很多悬垂引用和并发修改问题。

更重要的是,当前AI基建的底层正在出现一批Rust成果:Rust绑定的推理引擎、基于Rust的Agent运行时、以及像LLVM/MLIR这样的工具链接口,都提供了相对清晰的C ABI边界。用Rust写AI语言的前端和后端,等于踩在一条已经被验证过的路上。我们在做原型时,前端可以用chumsky做词法/语法分析,图优化层直接用petgraph管理节点依赖,后端先把IR lower到MLIR,再由MLIR分发到LLVM或者不同AI加速器。这条路线最核心的收益是:项目早期就能拿到一个“能跑通但很简陋”的完整编译器,而不必等到把所有优化算法写完才有成果。

不过要提醒一句:选择Rust不等于放弃和C++生态互操作。AI语言需要一个稳固的FFI层,我比较推荐用#[no_mangle]导出C ABI函数,再用一个薄薄的glue crate包住PyTorch LibTorch、ONNX Runtime这些引擎。踩坑时要注意,C ABI一旦发布就很难改,所以接口里尽量不要出现Rust特有的切片、引用和智能指针;宁可多拷贝一次数据,也要保证ABI稳定。

3.2 运行时与资源调度:CPU/GPU/NPU的抽象

语言是壳,运行时才是真正让AI计算流转起来的心脏。AI语言运行时的核心抽象是一个“计算设备”,它不直接暴露cudaSetDevice这类API,而是提供Device类型和Placement语义。用户只要写device("gpu:0")或device("npu:1"),编译器把设备信息写入IR,运行时负责真正的内存分配、内核启动和传输。

异构调度是最容易翻车的部分。我的做法是分成三块:内存池、任务队列、传输引擎。内存池需要按设备维护独立的分配器,GPU侧用缓存池复用显存,CPU/内存侧用对齐分配器;任务队列记录每个ComputeOp与设备的依赖关系,支持在逻辑上串行、物理上并行的算子启动;传输引擎专门处理Host与Device之间的拷贝,优先使用异步DMA,并尽量把多次小拷贝合并成一次大拷贝。这三块各自独立,再用一张全局ResourceTable做统一登记。

有一个很容易被忽略的细节:设备与设备之间的数据传输并不对称。比如GPU到GPU,如果是同一台机器、走NVLink就很快;如果跨节点,走RDMA和走普通TCP语义差别很大。AI语言需要在类型系统里区分LocalDevice和RemoteDevice,否则运行时根本不知道能不能安全地做零拷贝。这个区分在实际调度中很关键,我见过好几次因为“误以为所有GPU都在同一台机器”而把张量直接当指针传递,最后崩得莫名其妙。

能力CPU设备GPU设备NPU设备跨节点设备
零拷贝传输不支持支持同机PCIe/NVLink看厂商驱动依赖RDMA
线程亲和性强中弱弱
动态shape很好一般较差一般
适合算子数据预处理、小模型大矩阵、Transformer定点量化、视频编解码分布式并行

运行时实现阶段我建议从小处着手:先支持单机CPU+GPU,把内存池和任务队列跑稳,再扩展NPU和RDMA。千万不要一开始就追求所有设备全支持,因为每种设备的错误语义差异很大——GPU常见的“非法内存访问”和NPU常见的“句柄过期”完全是两类问题,需要不同的重试策略。

3.3 与现有生态的互操作设计

新语言最大的敌人是生态。AI语言设计之初就定了“不拒绝Python”:语言里提供一个python关键字,可以直接嵌入Python表达式或者调用Python模块。看下面这个例子:

import python.requests @task def fetch_context(url: str) -> str: # 这段代码交给Python执行,返回值通过序列化桥接回AI语言 resp = python.requests.get(url, timeout=5) return resp.text

反过来,也不需要用户改用AI语言重训PyTorch模型。AI语言原生支持加载PyTorch导出的torchscript、ONNX、TensorRT engine,以及HuggingFace的AutoModel格式。同时AI语言编译器会把生成代码编译成一个Python可调用的扩展库,传统FastAPI服务可以import ailang_compiled as det,然后像调用Python函数一样调用AI语言写出的推理Pipeline。

互操作的桥接层我建议用“数据标准格式”来做,而不是用语言绑定。所有跨语言边界的张量和中间结果都统一序列化成内存描述符:(device, data_ptr, shape, dtype, strides)。这样AI语言和Python之间交换的只是一组指针和元数据,不产生拷贝;只有在真正需要“让Python持有张量”的时候,才转为torch.Tensor。这套设计实测下来能省掉约80%的跨语言开销,但代价是调试时看不了“偏口的Python对象”,需要提供专门的内存转储工具。

实际操作里,我给互操作层定了一条纪律:所有@python块里抛出的异常,进入AI语言之后必须重新包装成带错误码的AIError,绝不允许直接透传Python traceback。宁可信息丢一点,也不能让编译器后端在处理异常时被Python解释器状态卡住。

4. 落地场景与生态展望

4.1 大模型推理与Agent编排场景

最先受益的场景一定是大模型推理服务。AI语言把模型节点、上下文窗口、KV Cache和采样参数都变成类型系统的一部分,编译器可以在编译期算出最大显存占用,提前执行显存预分配和KV Cache调度,而不是在运行时靠torch.cuda.empty_cache()碰运气。

Agent编排场景更明显。比如要设计一个“用户提问 -> 检索知识库 -> 调用工具 -> 生成答复”的Agent,传统Python写法要维护一堆变量保存历史消息,还要反复判断工具调用返回后的状态。AI语言把Agent循环做成了一个语法结构,可以这样描述:

agent ChatAgent: llm = Model("qwen-local") tools = [search_api, weather_api, calculator] loop: state = llm.generate(input_history, tools=tools) if state.tool_call: result = state.tool_call.execute() input_history.append(result) elif state.final_answer: return state.final_answer

这段代码底层会被编译成一个状态机,每个状态包含可序列化的上下文、工具调用记录和超时策略。比Python手写字典+循环要健壮得多,而且类型系统能确保input_history里的每一条消息都符合Chat协议。用“基于rust语言ai agent”的思路来看,AI语言相当于是把Rust的严谨性提升到了语言层面,而Agent开发者不再需要自己管理底层线程和所有权。

对“人工智能正从尝鲜工具变日常帮手”这句话,我特别有感触。当AI从演示变成日常服务,稳定性就不再是可有可无的要求。AI语言必须让“工具调用超时怎么办”“Agent陷入死循环怎么办”“上下文超过窗口怎么办”这些问题在语言层面就有默认答案,而不是每家公司都自己造一套prompt工程+重试机制。这也是我为什么坚持在Agent语法里内置timeout、max_retry和max_loop这些参数。

4.2 端侧AI与低延迟场景

第二个落地场景是端侧AI。现在边缘设备上跑模型,要么用TensorFlow Lite,要么用ONNX Runtime Mobile,再配一堆手写预处理代码;换个NPU又要重写算子。AI语言因为把设备和算子抽象做成语言原语,可以针对不同后端生成不同实现——同一段模型描述,编译成x86 CPU版本时用AVX2优化,编译成ARM版本时用NEON指令,编译成NPU版本时直接生成厂商SDK调用。

我对低延迟场景的建议是:把AI语言里的推理节点标记为realtime,编译器会为这类节点生成无分配路径、固定优先级线程池和提前锁内存的代码。这个特性对自动驾驶、无人机避障这类每帧几毫秒预算的系统非常关键。虽然这些场景现在主要还在C++手里,但AI语言如果能提供直接到机器码的表达力,完全有资格挤进去。

从生态角度讲,端侧AI是很有意思的突破口:它不像大模型训练那样被Python生态牢牢锁死,反而更需要可预测的性能和低功耗调度。如果AI语言能把“同一段模型描述,无缝编译到CPU/GPU/NPU”这件事做到足够简单,它就有机会成为边缘推理领域的“可移植层”。这个定位比在大模型训练上和PyTorch硬碰硬要聪明得多。

4.3 挑战与我的做法

当然,这个构想离真正可用还有很长的路。首先,语言设计最容易犯的错误是贪多嚼不烂。AI语言如果试图同时做好通用语言、深度学习框架和Agent编排平台,注定哪个都做不精。我的做法是严格守住“计算层”这个边界,凡是涉及UI、网络协议、文件系统等通用能力,直接交还给宿主语言。

其次,和Python生态的竞争不是靠“更好”就能赢。开发者的习惯、库的丰富度、社区积累都是时间壁垒。哪怕去翻编程语言排行榜,Python现在依然是AI领域的绝对王者。我的策略是先做“编译器+Rust运行时”的最小闭环,只支持两三个模型格式和一套Pipeline语法,先在一个内部项目里跑通,再逐步开放。很多新语言死在一开始想支持所有算子,其实完全没必要。

最后一点,我会刻意保留“escape hatch”。不管领域语言设计得多好,总有人会遇到类型系统表达不了的场景。AI语言必须允许用户在任意节点上插入自定义C/C++/Rust函数,也允许@python块绕过类型检查。这不是打自己脸,而是承认现实——领域语言的价值是提高大多数场景的表达效率,而不是取代程序员的所有判断。

说到底,AI语言不是要发明一套“更高级的Python”,而是想为人工智能计算层提供一个足够清晰、足够安全的工程表达方式。我在实际做原型的过程中,最深的体会是:语言设计最难的不是语法,不是编译器,而是“边界感”——每一行新语法都要问自己,它到底是在帮助用户表达AI逻辑,还是仅仅在炫技。如果你也在琢磨类似的方向,欢迎从最小的编译链路开始试起,哪怕只是把一个ONNX模型包成一条语言里可调用的Pipeline,也会对这个领域有完全不一样的理解。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询