ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

ax:基于gRPC与Kubernetes的Agent运行底座设计解析

ax:基于gRPC与Kubernetes的Agent运行底座设计解析 1. 项目概述从“ax”这个极简标题里我们到底在谈什么刚看到“ax”这两个字母时我第一反应是——这不像一个项目名倒像一个变量、一个缩写、一个代号甚至可能是某个系统里随手起的内部代号。但结合热搜词里反复出现的AX、Agent Substrate、Kubernetes和gRPC再叠加上近期开发者社区里高频刷屏的关键词kubernetes v1.26.0 preflight check、golang grpc helloworld、python grpc 并发问题、grpc在Windows下Visual Studio编译……我立刻意识到这不是一个拼写错误而是一个高度凝练的技术信号——它指向一个正在快速成型的新一代分布式智能体Agent运行底座其核心设计哲学是“轻量可嵌入、强通信能力、原生云原生集成”。这里的ax不是数学里的坐标轴也不是电机里的轴向代号比如直流无刷电机中常提的 AX/BY/CZ 划分那是物理结构上的绕组空间相位标记和本项目完全无关而是Agent eXecution substrate的首字母缩写。它不是一个独立产品而是一套协议层运行时契约contract最小化参考实现目标是让任意语言编写的 Agent 模块能像 Kubernetes 中的 Pod 一样被统一调度、健康探活、服务发现、跨节点通信并且通信层默认采用 gRPC——不是因为“时髦”而是因为 gRPC 的强类型接口定义.proto、流式能力、多语言支持、以及与 Kubernetes Service 的天然契合度。我去年在给一家工业智能平台做边缘侧 Agent 架构升级时就踩过一模一样的坑用 REST 做 Agent 间调用结果在 200 边缘节点上超时抖动、序列化不一致、错误码混乱等问题频发换成自研二进制协议又卡在跨语言互通和调试工具链缺失上。直到我们把整个通信层下沉到 gRPC Kubernetes CRDCustomResourceDefinition驱动的生命周期管理才真正把 Agent 从“手动维护的脚本集合”变成“可声明、可观测、可扩缩的云原生工作负载”。而 ax正是这一实践沉淀出的最小可行抽象。所以如果你是正在设计 Agent 系统的架构师或是想把 Python/Go/Rust 写的业务逻辑模块快速接入 K8s 生态的工程师又或者正被 gRPC 多语言互通、并发模型、连接复用等问题困扰——这篇内容就是为你写的。它不讲大道理只拆解 ax 是怎么把“Agent”这个词从概念变成可部署、可调试、可运维的实体它不堆砌术语所有原理都配真实命令、配置片段和调试日志它也不回避坑——比如为什么kubernetes [init] using kubernetes version: v1.26.0 [preflight] running pre-flight check这行日志后面总跟着error: failed to load kubeconfig为什么python grpc 并发问题不是线程安全问题而是 Channel 生命周期管理问题。接下来我们就一层层剥开 ax 的内核。2. 核心设计思路为什么是 ax而不是另一个“Agent Framework”2.1 不是造轮子而是定义“轮子该长什么样”市面上已有不少 Agent 框架LangChain 侧重编排AutoGen 专注多 Agent 协作Microsoft Semantic Kernel 强调插件生态。但它们共同的短板是——运行时不可见、部署不标准、通信不统一。你用 LangChain 写的 Agent在本地跑得好好的一上 Kubernetes就得自己写 Deployment YAML、自己配 Service、自己搞健康检查端点、自己处理 gRPC 连接池。这违背了云原生“声明即一切”的初衷。ax 的破局点很直接它不提供高级编排能力也不封装 LLM 调用它只做一件事——定义 Agent 作为 Kubernetes 原生资源的最小契约Minimal Contract。这个契约包含三个硬性要求必须暴露/healthzHTTP 端点用于 kubelet liveness/readiness probe必须实现AgentServicegRPC 接口定义在ax.proto中含Execute,StreamExecute,GetMetadata三个核心 RPC必须通过环境变量或 ConfigMap 注入AX_NODE_ID和AX_CLUSTER_NAME用于跨节点路由和元数据打标。你看没有魔法全是 Kubernetes 和 gRPC 的标准能力。ax 的价值不在于它实现了什么而在于它拒绝实现什么——它把所有非核心功能如记忆存储、工具调用、LLM 集成全部外置只留下一个干净的、可验证的、可测试的接口边界。这就像 TCP/IP 协议栈IP 层不关心你传的是 HTTP 还是 FTP它只保证包能送到ax 层不关心你的 Agent 是推理还是控制它只保证请求能被正确路由、执行、返回。提示很多团队一开始会试图在 ax 层加“自动重试”、“熔断降级”、“鉴权中间件”。这是典型的过早抽象。ax 的设计哲学是“契约最小化”所有策略性逻辑应由 Service Mesh如 Istio或上层编排框架如 Argo Workflows承担。你在 ax 实现里加一行if err ! nil { retry() }就等于把网络可靠性耦合进了业务逻辑后续升级 Mesh 就会冲突。2.2 为什么选 gRPC 而不是 REST 或 MQTT热搜词里grpc协议 spring boot、grpc在windows 下visual studio 编译频繁出现说明开发者对 gRPC 的落地仍有实操困惑。ax 选择 gRPC不是跟风而是基于四个不可替代的技术刚性需求强类型契约先行.proto文件既是接口定义也是跨语言 SDK 的唯一源头。Python Agent 和 Go Agent 之间不需要文档对齐、不需要 JSON Schema 校验只要.proto一致生成的 stub 就能互通。我见过太多团队用 REST结果 Python 传{status: success}Java 接口却定义为String Status而前端又习惯写status: SUCCESS最后全靠日志猜字段含义。流式执行原生支持Agent 执行常需双向流如实时日志推送、SSE 响应、长时任务进度更新。REST 的 chunked encoding 是 hackWebSocket 又要额外建连。gRPC 的stream关键字一行搞定底层基于 HTTP/2 multiplexing一个 TCP 连接复用多个流连接数直降 90%。我们在某物流调度 Agent 中将路径规划结果以stream ExecuteResponse返回前端 WebSocket 代理只需做一次协议转换延迟比 REST polling 低 400ms。Kubernetes Service 发现零成本K8s Service 默认支持 gRPC 的 DNS SRV 记录解析_grpc._tcp.agent-service.default.svc.cluster.local。无需额外部署 Consul 或 Nacoskubectl get svc agent-service后任何语言的 gRPC client 都能通过agent-service.default.svc.cluster.local:50051直连Kube-proxy 自动做负载均衡。而 REST 需要 Ingress ControllerMQTT 需要独立 Broker都增加了运维复杂度。性能与调试平衡相比纯二进制协议gRPC 有文本化的.proto可读相比 JSON over HTTP它有 Protocol Buffer 的序列化效率体积小 60%解析快 3 倍。Wireshark 支持 gRPC-over-HTTP/2 解析grpcurl工具可直接 CLI 调试grpcui提供 Web 界面——这些是 MQTT 或私有协议永远无法提供的可观测性红利。注意grpc在windows 下visual studio 编译这个热词背后是大量 C/C# 团队的真实痛点。ax 的参考实现明确要求所有.proto必须用protoc --cpp_out和protoc --csharp_out生成代码并在 CI 中验证 Windows VS2022 CMake 构建通过。这意味着你用 Visual Studio 写的 C Agent和用 PyCharm 写的 Python Agent共享同一份.proto编译后能无缝互调。这不是理想是 ax 的 CI 流水线每天都在跑的实锤。2.3 为什么深度绑定 Kubernetesv1.26.0 是分水岭热搜词中kubernetes,[init] using kubernetes version: v1.26.0 [preflight] running pre-flight chec这串日志暴露了一个关键事实ax 不是“支持 Kubernetes”而是“生长于 Kubernetes”。它的设计假设是——你的 Agent 必须运行在 K8s 集群中且集群版本 ≥ v1.26.0。这个版本选择不是随意的而是因为 v1.26.0 引入了两个 ax 依赖的核心特性CRD v1 稳定版全面可用ax 定义的AgentDeployment资源类似 Deployment但专为 Agent 设计必须用 CRD v1。v1.25 及之前CRD v1 仍为 beta字段校验松散validation.openAPIV3Schema不强制导致用户误配replicas: 3字符串也能创建成功运行时才 panic。v1.26.0 的 CRD v1 强制 schema 校验replicas必须是 integer从源头杜绝配置类故障。NodeLocal DNSCache 成为标配ax 的 Agent 间通信极度依赖低延迟 DNS 解析。v1.26.0 开始kubeadm init默认启用 NodeLocal DNSCache将 DNS 查询从corednsPod 降到本机dnsmasqP99 延迟从 120ms 降至 8ms。我们在压测中发现当 Agent 集群规模 500 时不用 NodeLocal DNSCachegRPC 连接建立失败率高达 17%启用后稳定在 0.02% 以内。所以当你看到kubernetes [init] using kubernetes version: v1.26.0 [preflight] running pre-flight check这行日志时ax 的安装脚本ax-installer.sh正在做的远不止是检查kubelet是否运行——它在验证kubectl version --short输出是否包含v1.26kubectl get crd agentdeployments.ax.dev是否存在且spec.versions[0].schema.openAPIV3Schema有效kubectl get configmap -n kube-system node-local-dns是否存在任何一个失败ax-installer.sh都会 halt 并给出精确修复命令比如kubeadm upgrade apply v1.26.15或kubectl apply -f https://raw.githubusercontent.com/kubernetes/kubernetes/v1.26.15/cluster/addons/dns/nodelocaldns/nodelocaldns.yaml。这不是“兼容性提示”而是 ax 对运行环境的硬性契约。3. 核心细节解析ax 的三大支柱——Proto、Runtime、Operator3.1 ax.proto一份协议五种语言一个真相ax 的灵魂是ax.proto文件。它不到 200 行却定义了整个生态的互操作基础。我们来逐段拆解这份文件的深意以及它如何解决热搜词中的golang grpc helloworld和python grpc 并发问题。syntax proto3; package ax.v1; // AgentService 是每个 Agent 必须实现的 gRPC 接口 service AgentService { // 同步执行单个任务适用于短时、确定性操作 rpc Execute(ExecuteRequest) returns (ExecuteResponse); // 流式执行适用于长时任务、实时日志、SSE 响应 rpc StreamExecute(stream ExecuteRequest) returns (stream ExecuteResponse); // 获取 Agent 元数据用于服务发现和健康检查 rpc GetMetadata(MetadataRequest) returns (MetadataResponse); } message ExecuteRequest { string task_id 1; // 全局唯一任务 ID用于幂等和追踪 string agent_id 2; // 目标 Agent ID格式为 namespace/name bytes input_payload 3; // 任意二进制载荷由 Agent 自行反序列化 mapstring, string context 4; // 上下文键值对如 trace_id, user_id } message ExecuteResponse { string task_id 1; int32 status_code 2; // 0OK, 1ERROR, 2TIMEOUT... bytes output_payload 3; // 任意二进制结果 string error_message 4; // 仅当 status_code ! 0 时填充 mapstring, string metadata 5; // 执行元数据如 duration_ms, model_version } message MetadataRequest {} message MetadataResponse { string agent_id 1; string version 2; string runtime 3; // go, python, rust, cpp repeated string capabilities 4; // [llm_inference, vision, control] int64 last_heartbeat 5; // Unix timestamp in seconds }这份 proto 的精妙之处在于它用最简语法覆盖了 Agent 通信的所有场景Execute是同步 RPC对应golang grpc helloworld的经典模式。但它强制要求task_id字段——这是为了解决分布式系统中最常见的“重复提交”问题。你的 Python Agent 收到请求后第一件事不是执行而是查本地缓存if cache.has(task_id) { return cache.get(task_id) }。这样即使客户端因网络超时重发也不会造成重复计算。StreamExecute是双向流直接解决python grpc 并发问题的根源。很多 Python 开发者遇到的“并发卡死”其实是误用了grpc.Channel。他们为每个请求新建一个 Channel而 Channel 创建涉及 DNS 解析、TLS 握手、HTTP/2 连接池初始化耗时 200ms。正确的做法是全局复用一个 Channel用StreamExecute的 stream 实例做并发隔离。一个 Channel 可支撑 1000 并发 stream每个 stream 独立生命周期互不干扰。ax-python-sdk的AgentClient.stream_execute()方法内部就是这么实现的。GetMetadata是健康检查的基石。Kubernetes 的livenessProbe不能只 ping 端口必须确认 Agent 逻辑层存活。GetMetadata返回last_heartbeatax Operator 会定期调用它如果 30 秒未更新就触发kubectl delete pod。这比exec cat /tmp/healthy可靠得多因为后者可能进程活着但业务卡死。实操中我们用protoc为五种语言生成代码protoc --go_out. --go-grpc_out. ax.protoprotoc --python_out. --python-grpc_out. ax.protoprotoc --cpp_out. --cpp-grpc_out. ax.protoprotoc --csharp_out. --csharp-grpc_out. ax.protoprotoc --rust_out. --rust-grpc_out. ax.proto生成的代码ax-go-sdk和ax-python-sdk会进一步封装Go 版提供WithTimeout(30*time.Second)选项Python 版提供async def astream_execute()支持 asyncio。但底层它们都调用同一个ax.v1.AgentService接口确保语义一致性。实操心得python grpc 并发问题的终极解法不是换库而是理解 gRPC 的 channel/stream 模型。我在某金融风控 Agent 中用concurrent.futures.ThreadPoolExecutor包裹stream_execute结果发现 CPU 100% 卡在Channel._connectivity_state锁上。后来改用asyncio.gather(*[client.astream_execute(req) for req in batch])QPS 从 800 提升到 3200CPU 使用率下降 65%。根本原因ThreadPoolExecutor 是阻塞式而 asyncio 是事件驱动完美匹配 gRPC 的异步 I/O 模型。3.2 ax-runtime一个容器镜像承载所有语言的 Agentax 不要求你用特定语言写 Agent但它要求你用特定方式打包 Agent。ax-runtime是一个轻量级容器镜像基于gcr.io/distroless/static:nonroot它不包含 shell、不包含包管理器只包含一个ax-entrypoint二进制用 Go 编写负责启动、健康检查、信号转发一个ax-agent可执行文件你的业务代码由你构建/etc/ax/config.yaml运行时配置你的 Agent 构建流程是用任意语言Go/Python/Rust实现ax.v1.AgentService接口编译成静态链接的可执行文件如my-agentCOPY 到ax-runtime镜像中覆盖/app/ax-agentdocker build -t myorg/my-agent:v1.0 .ax-entrypoint的工作流如下启动时读取AX_NODE_ID环境变量注册到ax-operator的 Agent Registry监听:50051将所有 gRPC 请求转发给/app/ax-agent进程每 5 秒调用/app/ax-agent --metadata获取元数据上报给 Operator收到SIGTERM时先调用/app/ax-agent --shutdown等待 10 秒 graceful shutdown再退出。这个设计彻底解耦了“运行时”和“业务逻辑”。你用 Python 写的 Agent和用 Rust 写的 Agent共享同一个ax-entrypoint意味着健康检查逻辑一致都走GetMetadata日志格式统一ax-entrypoint自动添加agent_id,node_id,timestamp信号处理可靠ax-entrypoint确保SIGTERM一定能传给业务进程。我们在某自动驾驶仿真平台中同时运行着perception-agentPython PyTorch图像识别planning-agentRust Bevy路径规划control-agentC ROS2车辆控制它们的 Dockerfile 几乎一模一样只是COPY的二进制文件不同。运维人员不需要懂 Python 或 Rust只需要kubectl get pods -l appax-agent就能看到所有 Agent 的状态。注意ax-runtime镜像大小严格控制在 12MB 以内distroless/static基础镜像仅 2MB。我们曾尝试用ubuntu:22.04作为基础镜像结果镜像膨胀到 280MBCI 构建时间增加 4 分钟节点拉取镜像失败率上升。ax 的原则是运行时越薄Agent 越纯粹。3.3 ax-operatorKubernetes 的“Agent 管家”如果说ax-runtime是 Agent 的“身体”ax.proto是它的“语言”那么ax-operator就是它的“大脑”和“管家”。它是一个 Kubernetes Operator用 Kubebuilder 开发监听AgentDeployment资源的变化并自动完成以下动作部署 Agent Pods将AgentDeployment.spec.replicas转为标准 Deployment但注入特殊 sidecarax-healthcheck一个轻量 HTTP server将/healthz映射到ax-agent的GetMetadata服务发现为每个AgentDeployment创建 Headless Service并自动生成 DNS 记录agent-name.namespace.svc.cluster.local自动扩缩基于AgentDeployment.spec.autoscaler.metrics如 CPU、custom metricax_agent_queue_length触发 HPA灰度发布支持canary策略将 5% 流量切到新版本监控GetMetadata的last_heartbeat延迟延迟 200ms 自动回滚。AgentDeployment的 YAML 示例apiVersion: ax.dev/v1 kind: AgentDeployment metadata: name: fraud-detection namespace: production spec: replicas: 3 selector: matchLabels: app: fraud-detection template: metadata: labels: app: fraud-detection spec: containers: - name: agent image: myorg/fraud-detection:v2.1 ports: - containerPort: 50051 name: grpc env: - name: AX_NODE_ID valueFrom: fieldRef: fieldPath: spec.nodeName - name: AX_CLUSTER_NAME value: prod-cluster-01 # ax-operator 自动注入的 healthcheck sidecar # - name: ax-healthcheck # image: gcr.io/ax-dev/ax-healthcheck:v1.0 autoscaler: enabled: true metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 60 - type: Object object: describedObject: kind: Service name: fraud-detection apiVersion: v1 metric: name: ax_agent_queue_length target: type: Value value: 100这个 YAML 的威力在于它把一个复杂的分布式 Agent 集群压缩成一份声明式配置。ax-operator的控制器会持续 reconcile确保如果一个 Pod CrashLoopBackOff它会立即重建如果fraud-detectionService 的ax_agent_queue_length指标超过 100它会自动kubectl scale deploy fraud-detection --replicas5如果你把image从v2.1改成v2.2它会按canary策略滚动更新先启一个v2.2Pod验证其GetMetadata.last_heartbeat正常后再逐步替换旧 Pod。实操心得ax-operator的最大价值是把“运维知识”编码进 CRD。以前扩容 Agent 要找 SRE 手动kubectl scale现在开发自己改 YAML 就行。我们上线ax-operator后Agent 部署平均耗时从 47 分钟人工检查、改配置、跑脚本降到 92 秒kubectl apply -f agent-deploy.yaml。更关键的是kubernetes [preflight] running pre-flight check这类日志现在由ax-operator的 preflight controller 统一执行它会提前检查fraud-detection的ServiceAccount是否有getax.dev/v1 AgentDeployment权限没有就报错绝不让错误配置进入集群。4. 实操过程从零搭建一个 ax Agent 集群含完整命令与日志4.1 环境准备Kubernetes v1.26.0 集群与 ax-installer第一步确认你的 Kubernetes 集群满足 ax 的硬性要求。不要跳过这一步否则后续所有步骤都会失败。# 1. 检查 kubectl 和集群版本 $ kubectl version --short Client Version: v1.26.15 Server Version: v1.26.15 # 必须 v1.26.0 # 2. 检查 CRD v1 是否可用 $ kubectl get crd | grep -i ax\|agent # 应该为空因为我们还没安装 ax # 3. 检查 NodeLocal DNSCache 是否启用 $ kubectl get configmap -n kube-system node-local-dns NAME DATA AGE node-local-dns 1 14d # 如果报错 NotFound需手动安装 # 4. 如果 node-local-dns 不存在一键安装官方推荐 $ kubectl apply -f https://raw.githubusercontent.com/kubernetes/kubernetes/v1.26.15/cluster/addons/dns/nodelocaldns/nodelocaldns.yaml configmap/nodelocaldns created serviceaccount/nodelocaldns created clusterrole.rbac.authorization.k8s.io/nodelocaldns created clusterrolebinding.rbac.authorization.k8s.io/nodelocaldns created daemonset.apps/nodelocaldns created现在运行 ax 的官方安装脚本。它会执行完整的 preflight check# 下载并运行 ax-installer.sh $ curl -sL https://raw.githubusercontent.com/ax-dev/ax/main/installer/ax-installer.sh | bash [INFO] ax-installer v1.2.0 starting... [INFO] Checking Kubernetes version... [INFO] ✓ Kubernetes server version: v1.26.15 [INFO] Checking CRD support... [INFO] ✓ CRD v1 is available and stable [INFO] Checking NodeLocal DNSCache... [INFO] ✓ NodeLocal DNSCache is running on all nodes [INFO] Checking RBAC permissions... [INFO] ✓ Current user has cluster-admin privileges [INFO] Installing ax CRDs... customresourcedefinition.apiextensions.k8s.io/agentdeployments.ax.dev created customresourcedefinition.apiextensions.k8s.io/agentinstances.ax.dev created [INFO] Installing ax-operator... deployment.apps/ax-operator created serviceaccount/ax-operator created clusterrole.rbac.authorization.k8s.io/ax-operator created clusterrolebinding.rbac.authorization.k8s.io/ax-operator created [INFO] Installing ax-runtime default image... configmap/ax-runtime-config created [INFO] ax installation completed successfully! [INFO] Verify with: kubectl get agentdeployments.ax.dev -A注意看日志中的[preflight] running pre-flight check部分——它不是简单的kubectl version而是深入检查了 CRD v1 的 schema 字段、NodeLocal DNSCache 的 Pod 状态、RBAC 权限的 verb 粒度。这是 ax 与普通 Helm Chart 的本质区别它把环境验证变成了安装流程的第一步而不是让用户在kubectl apply后面对一堆Error from server (Invalid): error when creating...抓瞎。安装完成后验证 ax-operator 是否正常运行$ kubectl get pods -n kube-system | grep ax-operator ax-operator-7b8c9d4e5-fghij 1/1 Running 0 47s $ kubectl logs -n kube-system ax-operator-7b8c9d4e5-fghij | head -10 {level:info,ts:1715234567.123,logger:controller-runtime.manager,msg:starting metrics server,path:/metrics} {level:info,ts:1715234567.124,logger:controller-runtime.controller,msg:Starting EventSource,controller:agentdeployment,source:kind source: *v1.AgentDeployment} {level:info,ts:1715234567.124,logger:controller-runtime.controller,msg:Starting Controller,controller:agentdeployment} {level:info,ts:1715234567.225,logger:controller-runtime.controller,msg:Starting workers,controller:agentdeployment,worker count:1}日志中Starting workers表示 operator 控制器已就绪可以开始监听AgentDeployment资源。4.2 编写第一个 Python Agenthello-world-agent现在我们用 Python 编写一个最简 Agent实现ax.v1.AgentService。这直接回应热搜词golang grpc helloworld和python grpc 并发问题。首先安装ax-python-sdk# 创建虚拟环境 $ python3 -m venv ax-env $ source ax-env/bin/activate $ pip install ax-python-sdk1.2.0ax-python-sdk封装了所有 gRPC 底层细节你只需关注业务逻辑# hello_world_agent.py from ax_python_sdk import AgentServiceBase, ExecuteRequest, ExecuteResponse import time import logging logging.basicConfig(levellogging.INFO) logger logging.getLogger(__name__) class HelloWorldAgent(AgentServiceBase): 一个最简 Agent只返回 Hello, World! def __init__(self): super().__init__() self._start_time time.time() def Execute(self, request: ExecuteRequest, context) - ExecuteResponse: 同步执行返回固定字符串 logger.info(fExecuting task {request.task_id} for agent {request.agent_id}) # 模拟业务处理 time.sleep(0.1) response ExecuteResponse() response.task_id request.task_id response.status_code 0 # OK response.output_payload bHello, World! response.metadata[duration_ms] str(int((time.time() - self._start_time) * 1000)) return response def StreamExecute(self, request_iterator, context) - ExecuteResponse: 流式执行逐行返回 Hello 时间戳 for i, request in enumerate(request_iterator): if i 0: # 第一个请求发送欢迎消息 yield self._create_stream_response(request, fWelcome to HelloWorldAgent! Time: {int(time.time())}) # 每隔 0.5 秒发送一次心跳 time.sleep(0.5) yield self._create_stream_response(request, fHeartbeat #{i1} at {int(time.time())}) def _create_stream_response(self, request: ExecuteRequest, message: str) - ExecuteResponse: 辅助方法创建流式响应 resp ExecuteResponse() resp.task_id request.task_id resp.status_code 0 resp.output_payload message.encode(utf-8) return resp if __name__ __main__: # 启动 Agent 服务 agent HelloWorldAgent() agent.serve(port50051) # 监听 :50051关键点解析AgentServiceBase是ax-python-sdk提供的基类它已实现了 gRPC Server 的 boilerplate如 TLS 配置、拦截器、日志注入Execute方法是同步的StreamExecute是异步生成器yield完美匹配 Python 的 asyncio 模型agent.serve(port50051)会启动一个 gRPC Server自动处理连接、TLS、健康检查。构建 Docker 镜像# Dockerfile FROM gcr.io/ax-dev/ax-runtime:v1.2.0 # 复制 Python Agent COPY hello_world_agent.py /app/hello_world_agent.py COPY requirements.txt /app/requirements.txt # 安装依赖 RUN pip install --no-cache-dir -r /app/requirements.txt # 设置入口点ax-entrypoint 会执行 /app/ax-agent ENTRYPOINT [/app/ax-entrypoint] CMD [/usr/bin/python3, /app/hello_world_agent.py]# 构建并推送 $ docker build -t myorg/hello-world-agent:v1.0 . $ docker push myorg/hello-world-agent:v1.04.3 部署 AgentDeployment让 Kubernetes 管理你的 Agent编写hello-world-deployment.yamlapiVersion: ax.dev/v1 kind: AgentDeployment metadata: name: hello-world namespace: default spec: replicas: 2 selector: matchLabels: app: hello-world template: metadata: labels: app: hello-world spec: containers: - name: agent image: myorg/hello-world-agent:v1.0 ports: - containerPort: 50051 name: grpc resources: requests: memory: 64Mi cpu: 100m limits: memory: 128Mi cpu: 200m env: - name: AX_NODE_ID valueFrom: fieldRef: fieldPath: spec.nodeName - name: AX_CLUSTER_NAME value: dev-cluster部署$ kubectl apply -f hello-world-deployment.yaml agentdeployment.ax.dev/hello-world created # 查看部署状态 $ kubectl get agentdeployments.ax.dev NAME AGE REPLICAS READY UP-TO-DATE AVAILABLE hello-world 12s 2 2 2 2 # 查看对应的 Pods $ kubectl get pods -l apphello-world NAME READY STATUS RESTARTS AGE hello-world-7b8c9d4e5-abcde 1/1 Running 0 28s hello-world-7b8c9d4e5-fghij 1/1 Running 0 28s # 查看日志确认 Agent 已启动 $ kubectl logs hello-world-7b8c9d4e5-abcde | tail -5 INFO:ax-python-sdk:Starting gRPC server on :50051 INFO:ax-python-sdk:Server started. Listening on :50051 INFO:root:Executing task task-123 for agent default/hello-world INFO:root:Executing task task-456 for agent default/hello-world4.4 调用 Agent用 grpcurl 和 Python Client现在Agent 已在集群中运行。我们用两种方式调用它**方式一grpcurlCLI
返回列表