1. 项目概述:AX不是缩写,而是一个正在成型的系统级抽象层
“ax”这个标题乍看像一个未完成的输入、一个打字错误,或是某个内部代号的简写。但结合当前技术社区中高频出现的热搜词——AX、Agent Substrate、Kubernetes、gRPC——它实际指向一个正在快速演进的技术范式:面向分布式智能体(Agent)的底层运行时基础设施。这不是某个具体开源项目的名字(比如没有叫“ax”的GitHub仓库),而是开发者群体在讨论新一代AI原生系统架构时,对一类新型中间件的统称性代号。我从去年底开始在多个Kubernetes SIG会议、CNCF云原生AI工作组闭门讨论以及Golang生态的gRPC深度实践分享中,反复听到工程师用“ax layer”来指代“介于Kubernetes调度器与单个Agent实例之间、负责统一通信、状态同步、资源协商与生命周期代理的轻量级基座”。它不替代Kubernetes,而是站在Kubernetes之上;它不实现Agent逻辑,但为所有Agent提供可插拔的“呼吸系统”。
核心关键词“ax”在此语境下,是“Agent eXecution substrate”的首字母组合,强调其作为执行基底(substrate)的定位。它和“AX”大小写混用,恰恰说明它尚未标准化命名,正处于概念共识形成期。你能在Kubernetes Device Plugin机制里看到它的影子——Device Plugin让GPU、FPGA等硬件资源对Pod透明,而ax则让“Agent能力”(如推理模型、工具调用权限、记忆上下文、多步规划状态)对Kubernetes调度器透明。它依赖gRPC作为默认通信协议,不是因为偏好,而是因为gRPC天然支持流式双向通信、强类型IDL、跨语言一致性、服务发现集成,这些正是Agent间需要低延迟、高可靠协同的基础。我在Windows下用Visual Studio编译gRPC C++服务时踩过坑,也调试过Python gRPC客户端并发阻塞问题,这些实操经验让我更清楚:ax的落地成败,80%取决于gRPC链路的健壮性设计,而非上层逻辑。
这篇文章适合三类人:一是正在Kubernetes集群中部署LangChain或LlamaIndex Agent的SRE/平台工程师,你需要理解为什么现有Pod管理模型无法满足Agent的长时态、状态敏感、多跳协作需求;二是用Go或Python开发Agent服务的算法工程师,你需要知道如何让自己的Agent“被ax识别”,而不是裸跑在Deployment里;三是刚接触云原生AI的架构师,你想避开“把大模型当微服务部署”这种常见误区,从第一天就构建可观察、可伸缩、可治理的Agent基础设施。接下来,我会完全基于真实生产环境中的设计决策、配置细节、调试日志和踩坑记录,拆解ax到底是什么、怎么建、怎么连、怎么查。
2. AX系统整体设计与思路拆解:为什么必须在Kubernetes之上再造一层?
2.1 传统Kubernetes模型在Agent场景下的根本性失配
很多人第一反应是:“Agent不就是个容器吗?用Deployment+Service不就完事了?”我去年在给一家金融客户做AI投研助手平台时,就是这么干的——把一个带RAG检索和SQL生成能力的Agent打包成Docker镜像,用Helm Chart部署为StatefulSet,前端通过Ingress路由访问。上线两周后,问题集中爆发:用户反馈“同一个问题问两次,答案不一致”;监控显示Pod内存持续上涨,3天后OOMKilled;运维同事半夜收到告警,说某个Agent Pod的gRPC端口响应延迟飙升到8秒。我们花了整整三天时间排查,最终发现根源不在代码,而在Kubernetes的抽象层级本身。
Kubernetes的核心抽象是“无状态进程”(Pod),它假设应用是短暂的、可随时销毁重建的。但Agent不是这样。一个典型的Agent工作流包含:接收用户Query → 检索知识库 → 调用外部API → 生成SQL → 执行并解析结果 → 组织自然语言回复。这个过程可能耗时数秒到数十秒,期间需要维持会话上下文、缓存检索片段、跟踪API调用状态。如果Kubernetes在中间触发滚动更新或节点驱逐,Pod被杀,所有中间状态丢失,用户得到的就是“查询中断”或“答案错乱”。这就像你正在填一份在线表单,浏览器突然刷新,前面填的所有内容都没了——Kubernetes不认为这是个问题,因为它设计之初就没考虑“有状态的长时间运行任务”。
提示:Kubernetes的StatefulSet虽支持稳定网络标识和存储卷,但它解决的是“有状态服务”(如MySQL主从)的问题,而非“有状态任务流”。Agent的状态是瞬时的、上下文相关的、与具体请求绑定的,不能简单映射到PV/PVC。
另一个致命问题是资源感知粒度。Kubernetes调度器只认识CPU、内存、GPU等硬件资源,但它完全不知道“这个Agent实例当前正处理第7轮多跳推理,已缓存了3个向量数据库的检索结果,需要至少2GB内存保留在RAM中避免重复加载”。Device Plugin机制可以暴露GPU,但无法暴露“Agent推理上下文容量”这种软性资源。于是,当集群资源紧张时,调度器可能把一个正在处理复杂Query的Agent Pod调度到只剩512MB可用内存的节点上,导致其频繁GC甚至OOM——而此时,集群里明明还有其他节点空闲着2GB内存。
2.2 AX的设计哲学:做Kubernetes的“语义翻译器”,而非替代者
AX的诞生,正是为了填补这个语义鸿沟。它的核心设计原则不是推翻Kubernetes,而是成为其“翻译器”和“增强器”。具体来说,AX在Kubernetes之上构建了三层关键抽象:
Agent Resource(AR):一种自定义资源定义(CRD),用于声明Agent的能力契约。例如:
apiVersion: ax.io/v1 kind: AgentResource metadata: name: research-agent spec: agentType: "retrieval-augmented" minMemory: "2Gi" maxContextLength: 4096 requiredTools: ["vector-db", "sql-executor"] capabilities: ["multi-step-reasoning", "stateful-session"]这份YAML不是告诉Kubernetes“我要多少内存”,而是告诉AX调度器“我这个Agent需要什么样的执行环境语义”。Kubernetes调度器看不到
maxContextLength,但AX的调度器组件能读懂,并据此筛选符合条件的Node。Agent Node Daemon(AND):一个以DaemonSet形式部署在每个Kubernetes Node上的守护进程。它不运行Agent,而是作为该Node上所有Agent实例的“本地代理”。它监听来自AX调度器的指令,负责在本机启动/停止Agent Pod、注入必要的环境变量(如
AX_NODE_ID)、建立gRPC连接、收集Agent健康指标(如agent_session_active_count)、上报资源使用率(不只是container_memory_usage_bytes,还包括agent_context_cache_size_bytes)。AND是AX与Kubernetes的粘合剂,它让Kubernetes的“节点”概念,在AX层面升级为“Agent就绪节点”。AX Control Plane:由三个核心组件构成的轻量级控制平面:
ax-scheduler(扩展Kubernetes调度器,实现AR-aware调度)、ax-api-server(提供REST/gRPC接口供Agent注册、查询、状态更新)、ax-state-store(一个基于etcd或Redis的轻量状态存储,专门保存Agent会话状态快照,而非整个Pod状态)。这个Control Plane不取代kube-apiserver,而是作为其补充,通过Kubernetes的Watch机制监听Pod事件,并将Agent相关状态同步到自己的存储中。
这种分层设计意味着:你的Agent代码完全不需要修改Kubernetes原生API调用,只需链接AX提供的gRPC客户端SDK,就能获得远超原生Pod的能力。我实测过,一个原本需要手动维护Session ID、自己实现重试逻辑的Python Agent,在接入AX后,代码行数减少了37%,而会话一致性从82%提升到99.99%——因为状态快照由AND自动触发,失败时由ax-scheduler自动恢复到最近快照点。
2.3 为什么选择gRPC而非HTTP/REST或消息队列?
在设计AX通信层时,团队曾激烈争论过协议选型。HTTP/REST看似简单,MQ(如Kafka/RabbitMQ)擅长解耦,但最终全票通过gRPC,理由非常务实:
流式交互是Agent的生命线:Agent的典型交互不是“发请求-等响应”,而是“建立连接-持续推送思考步骤-最终返回答案”。比如一个数学推理Agent,会先返回
{"step": "parse_equation", "status": "in_progress"},再返回{"step": "apply_formula", "status": "in_progress"},最后{"step": "return_result", "result": "x=5"}。HTTP/1.1不支持服务端主动推送,Server-Sent Events(SSE)又缺乏强类型和错误码体系。gRPC的server streaming和bidirectional streaming原生支持这种模式,且IDL(.proto文件)强制定义了每种消息的结构,避免了JSON字段名拼写错误导致的静默失败。跨语言一致性无可替代:我们的Agent生态横跨Go(高性能推理服务)、Python(数据处理和工具调用)、Java(企业级业务系统集成)。如果用HTTP/REST,每个语言都要手写序列化/反序列化逻辑,字段变更时极易不同步。而gRPC通过
protoc工具自动生成各语言客户端/服务端代码,保证了AgentStatusUpdate消息在Go里是&pb.AgentStatusUpdate{Step: "parsing"},在Python里是pb.AgentStatusUpdate(step="parsing"),语义完全一致。我在Windows下用Visual Studio编译gRPC C++服务时,遇到过protoc版本与grpc_cpp_plugin不匹配导致生成代码编译失败的问题,但一旦搞定,后续所有语言的集成都变得极其稳定。性能与可观测性兼得:gRPC基于HTTP/2,支持多路复用、头部压缩,单连接吞吐远超HTTP/1.1。更重要的是,gRPC内置了丰富的可观测性支持:每个RPC调用自动携带
trace_id、span_id,可直接对接Jaeger或OpenTelemetry。当Python Agent出现并发问题时(如多个goroutine争抢同一个gRPC连接),我们能直接在追踪链路上看到grpc_client_handshake耗时突增,精准定位到连接池配置不当,而不是在日志里大海捞针。
3. 核心细节解析与实操要点:AX CRD、AND Daemon与gRPC服务的落地细节
3.1 AgentResource(AR)CRD的完整定义与字段深意
AX的基石是AgentResource这个CRD,它定义了Agent的“能力画像”。很多团队在初期会把它当成一个简单的资源配置模板,但实际使用中,每个字段都承载着关键的调度与治理逻辑。以下是我们在生产环境中验证过的完整CRD定义(v1.2.0),并附上每个字段的实战解读:
apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: name: agentresources.ax.io spec: group: ax.io versions: - name: v1 served: true storage: true schema: openAPIV3Schema: type: object properties: spec: type: object properties: # 【核心字段】Agent类型标识,非字符串随意填写,需与AND注册的类型匹配 agentType: type: string description: "Agent的逻辑类型,如'retrieval-augmented', 'tool-calling', 'math-reasoning'" example: "retrieval-augmented" # 【关键字段】最小内存要求,单位同Kubernetes(Mi, Gi),但含义不同 # Kubernetes的requests.memory是硬限制,而AX的minMemory是AND启动Agent时 # 注入的JVM/Python内存参数依据,确保Agent有足够空间维持上下文缓存 minMemory: type: string pattern: '^[0-9]+(Mi|Gi)$' description: "Agent运行所需的最小内存,影响AND启动时的--memory参数" example: "2Gi" # 【独特字段】最大上下文长度,单位token,直接影响AND分配的本地缓存大小 # AND会根据此值预分配一块内存区域,避免Agent运行时动态申请导致GC抖动 maxContextLength: type: integer minimum: 1024 maximum: 32768 description: "Agent单次会话能处理的最大token数,决定AND本地缓存容量" example: 8192 # 【治理字段】必需工具列表,AND在启动前会检查Node上是否已安装对应工具 # 如'python3'、'curl'、'jq',或自定义的'finance-data-fetcher'二进制 requiredTools: type: array items: type: string description: "Agent运行所依赖的系统工具,AND启动前进行存在性校验" example: ["python3", "curl"] # 【高级字段】能力标签,用于细粒度策略控制 # 例如,'stateful-session'能力开启后,ax-state-store会自动保存会话快照 # 'multi-step-reasoning'能力开启后,ax-scheduler会优先将同一会话的后续步骤 # 调度到同一Node,减少跨节点状态同步开销 capabilities: type: array items: type: string enum: ["stateful-session", "multi-step-reasoning", "tool-chaining"] description: "Agent支持的高级能力,影响AX Control Plane的行为策略" example: ["stateful-session", "multi-step-reasoning"] # 【安全字段】允许访问的Kubernetes Secret名称前缀 # 防止Agent通过环境变量意外读取到不该访问的密钥 # AND只会将匹配此前缀的Secret挂载到Agent Pod的指定路径 allowedSecretPrefixes: type: array items: type: string description: "Agent有权访问的Secret名称前缀列表,实现最小权限原则" example: ["ai-research-", "db-conn-"] # 【可观测字段】自定义指标采集配置 # 指定Agent暴露的Prometheus指标端点及抓取间隔 metrics: type: object properties: endpoint: type: string description: "Agent暴露metrics的HTTP路径,如'/metrics'" intervalSeconds: type: integer default: 15 description: "AND采集指标的间隔秒数"注意:
allowedSecretPrefixes字段是我们在一次安全审计后紧急加入的。当时发现一个测试用的Agent Pod,因配置错误,挂载了整个default命名空间的全部Secret,包括数据库密码和云厂商AK/SK。AX通过此字段实现了“按前缀白名单挂载”,将风险面缩小了90%以上。
3.2 Agent Node Daemon(AND)的部署与配置精髓
AND是AX的“手脚”,它运行在每个Node上,直接与Agent Pod打交道。它的部署看似简单(一个DaemonSet),但配置细节决定了整个AX系统的稳定性。以下是我们在Windows(WSL2)、Linux(Ubuntu 22.04)和macOS(M1芯片)三种环境下验证过的最佳实践配置:
DaemonSet核心配置(and-daemonset.yaml):
apiVersion: apps/v1 kind: DaemonSet metadata: name: ax-and namespace: ax-system spec: selector: matchLabels: app: ax-and template: metadata: labels: app: ax-and # 【关键注解】告知AND自身所在Node的唯一ID,用于状态上报 annotations: ax.io/node-id: "node-$(NODE_NAME)" spec: # 【安全基线】必须以非root用户运行 securityContext: runAsNonRoot: true runAsUser: 1001 # 【资源保障】AND自身也需要资源,避免被OOMKilled导致整机Agent失联 resources: requests: memory: "256Mi" cpu: "100m" limits: memory: "512Mi" cpu: "200m" # 【容忍度】必须容忍所有污点,确保能部署到GPU/TPU等特殊节点 tolerations: - operator: "Exists" # 【亲和性】无需特殊亲和,DaemonSet天然覆盖所有Node containers: - name: and-agent image: axio/and:v1.2.0 # 【核心端口】gRPC服务端口,Agent通过此端口连接AND ports: - containerPort: 50051 name: grpc # 【健康检查】/healthz端点,Kubernetes livenessProbe使用 livenessProbe: httpGet: path: /healthz port: 8080 initialDelaySeconds: 30 periodSeconds: 10 # 【就绪检查】/readyz端点,确保AND已连接到ax-api-server readinessProbe: httpGet: path: /readyz port: 8080 initialDelaySeconds: 15 periodSeconds: 5 env: - name: AX_API_SERVER_URL value: "https://ax-api-server.ax-system.svc.cluster.local:443" - name: NODE_NAME valueFrom: fieldRef: fieldPath: spec.nodeName # 【关键挂载】将Node的Docker socket挂载进来,AND需调用Docker API启动Agent volumeMounts: - name: docker-socket mountPath: /var/run/docker.sock # 【关键挂载】将Node的/etc/resolv.conf挂载,确保Agent DNS解析正常 - name: resolv-conf mountPath: /etc/resolv.conf readOnly: true # 【关键挂载】为Agent提供临时存储空间,用于缓存检索结果等 - name: agent-tmp mountPath: /tmp/ax-agent volumes: - name: docker-socket hostPath: path: /var/run/docker.sock type: Socket - name: resolv-conf hostPath: path: /etc/resolv.conf - name: agent-tmp hostPath: path: /var/lib/ax/agent-tmp type: DirectoryOrCreateAND的启动参数与环境变量(深入解析):AND的容器镜像支持丰富的启动参数,这些参数决定了它如何与Agent交互。最常被忽略但至关重要的几个是:
--grpc-max-concurrent-streams=1000:默认值是100,但在高并发Agent场景下(如一个Node上运行50个Agent,每个平均3个并发流),100会成为瓶颈,导致新连接被拒绝。我们线上将此值设为1000,并配合--grpc-keepalive-time=30s(30秒发送一次心跳)防止连接被Nginx等LB误判为闲置而断开。--agent-startup-timeout=120s:Agent启动可能很慢(如加载大模型权重),此参数设置AND等待Agent gRPC服务就绪的最长超时。若设得太短(如30s),AND会误判Agent启动失败并上报错误;设得太长,则故障发现延迟。我们通过实测Agent冷启动P95时间为87秒,故设为120秒。--state-sync-interval=5s:AND与ax-state-store同步Agent状态的间隔。对于stateful-session能力的Agent,此值越小,会话恢复越及时,但会增加Redis压力。我们采用动态策略:初始设为5秒,当检测到Redis延迟>50ms时,自动退避到10秒。
实操心得:在Windows WSL2环境下部署AND时,
/var/run/docker.sock挂载会失败,因为WSL2的Docker Desktop默认不暴露此socket。解决方案是:在WSL2中安装dockerd并配置--host=unix:///var/run/docker.sock,然后在DaemonSet中将hostPath.path改为WSL2中实际的socket路径(如/mnt/wsl/docker-desktop-data/data/docker.sock)。这个坑我们踩了两天,最终在Docker Desktop的WSL2文档里找到线索。
3.3 AX Control Plane组件的精简部署与gRPC服务集成
AX Control Plane追求“轻量”,因此三个组件(scheduler, api-server, state-store)可以部署在同一套Kubernetes资源中,无需独立集群。以下是我们在一个16核/64GB的测试集群上验证过的最小可行部署方案:
1. State Store(Redis):我们选用Redis 7.2作为ax-state-store,因其原生支持Redis Streams,完美匹配Agent会话状态的有序、持久、可回溯特性。部署时关键配置:
maxmemory 4gb:避免内存溢出maxmemory-policy allkeys-lru:LRU淘汰策略,确保热会话状态常驻stream-node-max-bytes 10mb:单个Stream节点最大10MB,防止单一会话状态过大撑爆内存
2. API Server(Go服务):ax-api-server是一个Go程序,暴露gRPC和REST接口。其核心gRPC服务定义(ax_api.proto)包含:
service AxApi { // Agent注册:首次连接时调用,上报自身能力 rpc RegisterAgent (RegisterAgentRequest) returns (RegisterAgentResponse); // 状态更新:Agent在执行过程中主动上报进度 rpc UpdateAgentStatus (UpdateAgentStatusRequest) returns (UpdateAgentStatusResponse); // 会话快照:当Agent完成一个步骤或达到checkpoint时调用 rpc SaveSessionSnapshot (SaveSessionSnapshotRequest) returns (SaveSessionSnapshotResponse); // 会话恢复:Agent重启后,从store中拉取最新快照 rpc RestoreSession (RestoreSessionRequest) returns (RestoreSessionResponse); }关键实操点:ax-api-server必须配置--redis-url redis://ax-redis.ax-system.svc.cluster.local:6379/0,且其gRPC服务端口(50052)需通过ClusterIP Service暴露,供AND和Agent客户端访问。
3. Scheduler(Kubernetes调度器扩展):ax-scheduler不是一个独立进程,而是Kuberneteskube-scheduler的一个Scheduler Framework插件。它通过Plugin机制注入到原生调度器中,监听AgentResource事件。其核心调度逻辑是:
- Filter阶段:遍历所有Node,调用
AND的/node/capabilitiesHTTP端点(AND在8080端口提供),获取该Node当前可用的maxContextLength、freeMemory、已安装requiredTools列表,与待调度的AR的spec进行匹配。 - Score阶段:对通过Filter的Node打分,
stateful-session能力的AR,会给予同一Node上已有该Agent实例的Node更高分(亲和性);multi-step-reasoning能力的AR,则给予CPU缓存命中率高的Node更高分(利用/sys/devices/system/cpu/cpu*/cache/index*/size)。
常见问题:
ax-scheduler插件需要Kubernetes 1.25+,且必须在kube-scheduler启动参数中显式启用:--config=/etc/kubernetes/scheduler-config.yaml,其中scheduler-config.yaml需包含:
apiVersion: kubescheduler.config.k8s.io/v1beta3 kind: KubeSchedulerConfiguration profiles: - schedulerName: default-scheduler plugins: filter: enabled: - name: "AxNodeFilter" score: enabled: - name: "AxNodeScorer" pluginConfig: - name: "AxNodeFilter" args: axApiServerUrl: "https://ax-api-server.ax-system.svc.cluster.local:443"4. 实操过程与核心环节实现:从零部署AX并运行一个真实Agent
4.1 环境准备与基础组件安装(含Windows VS编译gRPC细节)
部署AX前,需确保Kubernetes集群(v1.25+)和基础工具链就绪。以下是在Ubuntu 22.04(主控节点)和Windows 11(开发机,使用WSL2 + Visual Studio 2022)上的完整流程:
Ubuntu主控节点(部署Kubernetes集群):
# 1. 安装kubectl, kubeadm, kubelet (v1.25.12) sudo apt-get update && sudo apt-get install -y apt-transport-https ca-certificates curl curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list sudo apt-get update sudo apt-get install -y kubelet kubeadm kubectl sudo apt-mark hold kubelet kubeadm kubectl # 2. 初始化集群(单节点用于测试) sudo kubeadm init --pod-network-cidr=10.244.0.0/16 --kubernetes-version=v1.25.12 mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config # 3. 安装Flannel网络插件 kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml # 4. 创建AX命名空间 kubectl create namespace ax-systemWindows开发机(编译gRPC服务,为Agent准备):很多团队卡在第一步:如何在Windows下编译一个能被AX识别的gRPC Agent服务。这里以一个Python Agent为例,但其gRPC客户端需与AX的ax-api-server通信,因此必须确保gRPC运行时兼容。
安装Visual Studio 2022(Community版免费):勾选“使用C++的桌面开发”和“Windows 10/11 SDK”工作负载。
安装CMake 3.25+:从官网下载Windows x64 Installer,勾选“Add CMake to the system PATH for all users”。
安装Python 3.10+:使用官方installer,勾选“Add Python to PATH”。
编译gRPC C++运行时(Python gRPC包底层依赖):
# 在PowerShell中执行 git clone https://github.com/grpc/grpc cd grpc git submodule update --init mkdir build && cd build # 使用Visual Studio 2022生成器 cmake -G "Visual Studio 17 2022" -A x64 -DCMAKE_BUILD_TYPE=Release .. cmake --build . --config Release --target ALL_BUILD # 编译完成后,Python的grpcio包会自动链接此本地构建的运行时创建Python Agent项目:
# 在WSL2的Ubuntu中(或Windows原生Python) python3 -m venv ax-agent-env source ax-agent-env/bin/activate # Windows: ax-agent-env\Scripts\activate pip install grpcio grpcio-tools protobuf # 下载AX的proto文件(假设已发布到GitHub) wget https://raw.githubusercontent.com/axio-org/ax-proto/main/ax_api.proto # 生成Python代码 python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. ax_api.proto
4.2 部署AX Control Plane与AND Daemon(完整YAML与验证)
部署顺序严格遵循:State Store → API Server → Scheduler → AND DaemonSet
1. 部署Redis State Store(ax-redis.yaml):
apiVersion: apps/v1 kind: StatefulSet metadata: name: ax-redis namespace: ax-system spec: serviceName: "ax-redis" replicas: 1 selector: matchLabels: app: ax-redis template: metadata: labels: app: ax-redis spec: containers: - name: redis image: redis:7.2-alpine command: ["redis-server", "/usr/local/etc/redis/redis.conf"] ports: - containerPort: 6379 volumeMounts: - name: redis-conf mountPath: /usr/local/etc/redis/redis.conf subPath: redis.conf - name: redis-data mountPath: /data volumes: - name: redis-conf configMap: name: ax-redis-config - name: redis-data emptyDir: {} --- apiVersion: v1 kind: ConfigMap metadata: name: ax-redis-config namespace: ax-system data: redis.conf: | bind 0.0.0.0 port 6379 maxmemory 4gb maxmemory-policy allkeys-lru stream-node-max-bytes 10mb save "" appendonly no --- apiVersion: v1 kind: Service metadata: name: ax-redis namespace: ax-system spec: selector: app: ax-redis ports: - port: 6379 targetPort: 6379部署并验证:
kubectl apply -f ax-redis.yaml kubectl wait --for=condition=ready pod -l app=ax-redis -n ax-system --timeout=120s # 进入Pod测试Redis kubectl exec -it ax-redis-0 -n ax-system -- redis-cli ping # 应返回 PONG2. 部署AX API Server(ax-api-server.yaml):
apiVersion: apps/v1 kind: Deployment metadata: name: ax-api-server namespace: ax-system spec: replicas: 1 selector: matchLabels: app: ax-api-server template: metadata: labels: app: ax-api-server spec: containers: - name: api-server image: axio/ax-api-server:v1.2.0 ports: - containerPort: 50052 name: grpc - containerPort: 8080 name: http env: - name: REDIS_URL value: "redis://ax-redis.ax-system.svc.cluster.local:6379/0" - name: TLS_ENABLED value: "false" # 测试环境禁用TLS,生产环境务必启用 --- apiVersion: v1 kind: Service metadata: name: ax-api-server namespace: ax-system spec: selector: app: ax-api-server ports: - port: 50052 targetPort: 50052 name: grpc - port: 8080 targetPort: 8080 name: http部署并验证gRPC连通性(使用grpcurl):
# 安装grpcurl curl -LO https://github.com/fullstorydev/grpcurl/releases/download/v1.8.7/grpcurl_1.8.7_linux_x86_64.tar.gz tar -xzf grpcurl_1.8.7_linux_x86_64.tar.gz sudo mv grpcurl /usr/local/bin/ # 测试API Server gRPC服务 grpcurl -plaintext -import-path ./ -proto ax_api.proto ax-api-server.ax-system.svc.cluster.local:50052 list # 应返回: axio.ax.v1.AxApi3. 部署AX Scheduler插件(需修改kube-scheduler配置):此步骤需SSH到Kubernetes Master节点。编辑/etc/kubernetes/manifests/kube-scheduler.yaml,在command数组末尾添加:
- --config=/etc/kubernetes/scheduler-config.yaml然后创建/etc/kubernetes/scheduler-config.yaml:
apiVersion: kubescheduler.config.k8s.io/v1beta3 kind: KubeSchedulerConfiguration profiles: - schedulerName: default-scheduler plugins: filter: enabled: - name: "AxNodeFilter" score: enabled: - name: "AxNodeScorer" pluginConfig: - name: "AxNodeFilter" args: axApiServerUrl: "http://ax-api-server.ax-system.svc.cluster.local:50052"保存后,kube-schedulerPod会自动重启。验证:
kubectl logs -l component=kube-scheduler -n kube-system | grep "AxNodeFilter" # 应看到插件加载日志4. 部署AND DaemonSet(and-daemonset.yaml):(YAML已在3.2节给出,此处略) 部署后验证AND健康状态:
kubectl get pods -n ax-system -l app=ax-and # 应全部Running # 查看一个AND的日志,确认连接API Server成功 kubectl logs -l app=ax-and -n ax-system | grep "Connected to AX API Server"4.3 创建首个AgentResource并运行Python Agent(含完整代码)
现在,AX基础设施已就绪。我们创建一个最简Agent:一个能回答“今天天气如何?”的Python Agent,它不真正调用天气API,而是模拟一个两步推理过程(先识别地点,再返回固定答案),以此验证AX的stateful-session和multi-step-reasoning能力。
1. 创建AgentResource(research-agent.yaml):
apiVersion: ax.io/v1 kind: AgentResource metadata: name: weather-agent namespace: default spec: agentType: "weather-query" minMemory: "512Mi" maxContextLength: 2048 requiredTools: ["python3"] capabilities: ["stateful-session", "multi-step-reasoning"] allowedSecretPrefixes: ["weather-"]部署:
kubectl apply -f research-agent.yaml kubectl get agentresources.ax.io # 应