让 agent 自己造 agent:笔记本上的 kagent 上手实录

看过无代码 agent 构建器演示的人,都记得那个瞬间:有人敲了一句话,等一分钟,一个新 agent 就出现在那儿了——跑着,带着工具。很震撼。大概震撼十秒。

然后问题就来了:它跑在哪?它能碰什么?谁批准它建的?

CNCF 官方博客 10 月 12 日这篇(Antonio Berben / Solo.io 与 Felipe Vicens / Telefónica 合著)讲的就是”前十秒”:证明这事不神秘,一个下午、全开源、几乎不花 token 就能自己搭出来。工具是 kagent,一个把 AI agent 当 Kubernetes 资源来跑的 CNCF Sandbox 项目。至于后面那几个问题,作者留到最后——因为那才是真活儿。

为什么 kagent 让这件事变得”无聊”

在 kagent 里,agent 不是你手动拉起来的进程,而是一个自定义资源:写一个 Agent,配好系统提示词、模型、工具清单,apply 下去,controller 就把它变成一个跑着的 pod,对外说 A2A 协议。

agent 一旦只是 YAML,那么”会造 agent 的 agent”就只是”会写某一种 YAML 的 agent”。不用新框架,不用插件:一个 Agent、三个工具、一段知道自己长什么样的 prompt,齐活。

动手前:这个实验不做什么

作者把话说在前面——目标是构建器本身,安全是有意排除在范围外的,所以默认配置相当”裸”:

  • – kagent 跑在默认的 unsecure 认证模式,所有请求都当成同一个用户;
  • – chart 自带的 PostgreSQL 用它内置的密码;
  • – UI 和 API 只通过 kubectl port-forward 绑在 127.0.0.1 上。

这在笔记本上没问题,在共享集群里不行——为什么这个缺口要紧,后面还会回来讲。

准备清单:Docker、kind、kubectl、helm、jq 和 Ollama(也可以用 Claude、OpenAI 等各家 API key,但作者就想把它压到最便宜)。没有任何东西要 clone,所有文件从零手写:

mkdir kagent-agent-builder && cd kagent-agent-builder

第一步:挑一个真能把活干完的本地模型

这是最让作者意外的一环。通过工具调用写出一份合法的 Kubernetes manifest,比聊天难,小模型立刻露馅:

模型 实测表现
qwen2.5:7b-instruct 自己发明了工具块的写法,格式对不上
qwen2.5:14b-instruct 有时客客气气答完,压根没调用 apply 工具
qwen3-coder:30b-a3b-q4_K_M 每次运行都写对,全文用它
ollama pull qwen3-coder:30b-a3b-q4_K_M   # 磁盘上约 18 GB

集群通过 host.docker.internal:11434 找到 Ollama,Docker Desktop 开箱即用;Linux 上要把 values 里的这个地址换成 kind 节点能到达的地址,这条路作者没测过。想用托管模型也行,chart 里有 OpenAI、Anthropic、Azure OpenAI、Gemini 的 provider 块——那就谈不上免费了。

第二步:装 kagent,但把工具服务的权限收窄

先建集群:

kind create cluster --name kagent-builder

kagent 自带一个带 Kubernetes 工具的工具服务(tool server),而 chart 默认给它的 ServiceAccount 是 cluster-admin。作者的原话是:哪怕在笔记本上,一个背后挂着 cluster-admin 的构建器也是个好主意都算不上的主意。所以 values 文件要改:

providers:
  default: ollama
  ollama:
    provider: Ollama
    model: "qwen3-coder:30b-a3b-q4_K_M"
    config:
      host: host.docker.internal:11434
      options:
        num_ctx: "32768"
kagent-tools:
  tools:
    enabledTools:
      - k8s          # 只开 Kubernetes 工具
  rbac:
    readOnly: true
    additionalRules:
      - apiGroups: ["kagent.dev"]
        resources: ["agents"]
        verbs: ["get", "list", "watch", "create", "update", "patch"]
grafana-mcp: {enabled: false}
k8s-agent: {enabled: false}
kgateway-agent: {enabled: false}
# ……其余示例 agent 全部关掉,UI 里只看得到自己建的

于是:模型进 ModelConfig;工具服务只加载它那 22 个 Kubernetes 工具;权限是只读角色加一条额外规则——只允许写 agents.kagent.dev,别的都不行。最后那批开关关掉 chart 默认装的示例 agent。

装 CRD 和 kagent 0.10.2,等 pod 起来:

helm upgrade --install kagent-crds oci://ghcr.io/kagent-dev/kagent/helm/kagent-crds \
  --kube-context kind-kagent-builder --version 0.10.2 --namespace kagent --create-namespace
helm upgrade --install kagent oci://ghcr.io/kagent-dev/kagent/helm/kagent \
  --kube-context kind-kagent-builder --version 0.10.2 --namespace kagent --values kagent-values.yaml
for d in kagent-controller kagent-ui kagent-tools; do
  kubectl --context=kind-kagent-builder -n kagent rollout status deploy/$d --timeout=300s
done

第三步:构建器本身就是一个 agent

整个构建器就是下面这份 YAML(节选,完整版见原文)。spec.declarative.systemMessage 里写清了工作流程:先用 k8s_get_resources 列出现有 agent、挑一个没被占用的名字,永不覆盖已存在的 agent;按固定形状写出 manifest 并用 k8s_apply_manifest 应用;再用 k8s_get_resource_yaml 读回来,看 status 里的 Accepted、Ready 条件。

apiVersion: kagent.dev/v1alpha2
kind: Agent
metadata:
  name: agent-builder
  namespace: kagent
  labels:
    app.kubernetes.io/managed-by: agent-builder
spec:
  type: Declarative
  declarative:
    modelConfig: default-model-config
    systemMessage: |
      ……自由文本一律写成 YAML 块标量(description 用 |-、systemMessage 用 |)。
      普通标量里"冒号+空格"会让 YAML 失效,"空格+#"会把值悄悄截断。
      出问题时:照原样报告工具返回的错误,然后停手。不要为了搞清楚哪一步失败
      就再造一个 my-agent-v2、-test、-check。
    tools:
      - type: McpServer
        mcpServer:
          kind: RemoteMCPServer
          name: kagent-tool-server
          toolNames:                    # 22 个工具里,模型只看到 3 个
            - k8s_apply_manifest
            - k8s_get_resources
            - k8s_get_resource_yaml
          requireApproval:              # 人在环开关
            - k8s_apply_manifest

toolNames 是白名单,requireApproval 让人在环:列在里面的工具被调用时,这一跑就停下来,等人批准或驳回。

剩下的交给提示词:允许给新 agent 的工具只有五个只读工具(k8s_get_resources、k8s_get_resource_yaml、k8s_describe_resource、k8s_get_events、k8s_get_pod_logs),不许换 kind、不许换 namespace、不许用写工具、不许一次多个文档。里面还塞了几条作者”用踩坑换来的经验”。

但作者补了一句关键的话:提示词是一个请求,不是一份保证。真正的保证是白名单、审批和 RBAC。

apply 下去,等 kagent 报 Ready:

kubectl --context=kind-kagent-builder apply -f agent-builder.yaml
kubectl --context=kind-kagent-builder -n kagent wait --for=condition=Ready agent/agent-builder --timeout=300s

第四步:UI 里跑一遍

kubectl --context=kind-kagent-builder -n kagent port-forward --address 127.0.0.1 svc/kagent-ui 8080:8080

打开 http://localhost:8080,选中 agent-builder,用大白话提需求,比如”给支持团队建一个 agent,能回答集群里服务状态的问题”。半分钟出头,这一跑停下来。UI 把模型打算 apply 的 manifest 摆在你面前,下面两个按钮。

UI 上等待人工批准的 manifest(图源:CNCF 官方博客)
UI 上等待人工批准的 manifest(图源:CNCF 官方博客)

图:UI 上等待人工批准的 manifest——批准之前这是唯一一次人在落库前看清它(图源:CNCF 官方博客)

点之前先读一遍。这是整条流水线上唯一一次,人在东西落进集群之前看清楚它到底是什么。 批准后,构建器把它 apply 掉、读回来、报告真实状态:

批准之后 UI 给出的结果与真实状态(图源:CNCF 官方博客)
批准之后 UI 给出的结果与真实状态(图源:CNCF 官方博客)

图:批准之后 UI 给出的结果与真实状态——构建器读回资源,照实汇报 Accepted / Ready(图源:CNCF 官方博客)

新 agent 出现在列表里,可以直接和它聊天。问它 kagent 命名空间里有哪些服务——它用只读工具回答,因为构建器被允许给的只有这些。

第五步:不靠 UI,把整条流程脚本化

每个 kagent agent 都是 controller 上的一个 A2A 端点,所以全流程可以用 curl 走完。转发 controller 端口,然后发请求:

kubectl --context=kind-kagent-builder -n kagent port-forward --address 127.0.0.1 svc/kagent-controller 8083:8083 &
sleep 3

curl -s http://127.0.0.1:8083/api/a2a/kagent/agent-builder/ \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":"1","method":"message/send","params":{"message":{"role":"user","messageId":"1","parts":[{"kind":"text","text":"Create an agent that lists the pods that are not running in the kagent namespace"}]}}}' \
  > build.json

jq -r '.result.status.state' build.json      # input-required

input-required 的意思就是:apply 正在等你。待决的 manifest 挂在状态消息的一个 data part 里。要答复,就在同一个 task、同一个 context 里再发一条带决定的消息,decision_type 填 approve 或 reject——批准则 completed,驳回则什么都不创建。无论如何,集群会告诉你实际发生了什么:

kubectl --context=kind-kagent-builder -n kagent get agents

为什么是三条护栏,而不是一条

三道不依赖提示词的护栏(图源:CNCF 官方博客)
三道不依赖提示词的护栏(图源:CNCF 官方博客)

图:三道不依赖提示词的护栏——白名单、审批、RBAC,各兜住上一层放过去的东西(图源:CNCF 官方博客)

觉得”提示词写清楚就够了”很自然。但不够——不是因为模型心怀不轨,而是因为模型会把 YAML 写错、会用富有创造力的方式重试、会理解偏你的要求。

作者在核对本文命令时就撞上一次:提示词里明明白白写着工具服务名 kagent-tool-server,有一次运行还是产出了一个指向 kagent-tools 的 Agent。他的 curl 像所有脚本那样无条件批准了。然后 controller 拒绝:Accepted=False, RemoteMCPServer "kagent-tools" not found。什么都没坏,但这正好说明真正的检查在哪一层。三层各兜住上一层放过去的东西:

  • – 白名单:模型想伸手拿 k8s_delete_resource?工具根本不存在。
  • – 审批:它写出你没打算要的 manifest?在东西真的存在之前你就看见它。
  • – RBAC:你批准了不该批的?API server 依然会拒绝一切非 Agent 的操作。

最后一层可以自己验:

命令(--as=system:serviceaccount:kagent:kagent-tools) 结果
auth can-i create agents.kagent.dev -n kagent yes
auth can-i create deployments -n kagent no
auth can-i get secrets -n kagent no

这个实验故意留下的问题

造一个 agent 花了一个 YAML 文件和两次 helm install。这是简单的那部分,也正因为简单,作者认为它已经不再是有趣的部分。

回头看那张”三道护栏”图的底部:在这台笔记本上,没人知道是谁来提的需求,因为所有人都是同一个用户;没人知道它的模型调用花了多少钱、为哪个团队花的;也没人真正决策过这个 agent 该不该存在——就是聊天窗口里在场某人的一个点击。现在想象一家公司:一个这样的构建器、几套框架、一个托管 agent 平台、若干台开发机上的助手。每一家都用不同的方式回答这三个问题,如果它们回答的话。

这就是那个论点的完整形态:治理层应该站在 agent 前面,不管它们从哪来,而不是塞在每个 agent 里面。开源世界里一个选项是 agentgateway(Linux Foundation 项目):代理 LLM、MCP、A2A 三种流量,带认证(JWT、API key)、基于 CEL 的细粒度授权,以及每次调用的 OpenTelemetry 指标、日志与追踪。把这套东西接到本实验前面,是个不错的下一步练习,作者说大概就是他下一篇的主题。

收尾与延伸

所有东西都在 kind 集群里,一条命令清空:

kind delete cluster --name kagent-builder

kagent 文档里还有更多工具服务、其他模型 provider,以及用代码写的 agent;项目在 github.com/kagent-dev/kagent。作者说,如果谁在这套基础上做了东西,或者找到某个更小的本地模型也能把构建器干好,他很愿意听说。

小夏点评

  1. 1. 这篇最有价值的不是”十分钟搭完”,而是那句”提示词是请求,不是保证”。作者用一次真实翻车证明:白名单、人工审批、RBAC 这三道不依赖模型自觉的关口,才是 agent 进生产的门票——顺序也不能反,prompt 只是最外面那层装饰。
  2. 2. “唯一一次人在东西落库前看清它”这个设计,比大多数所谓 human-in-the-loop 诚实:审批门必须开在写操作之前、且展示的就是要写的那个对象。同理,input-required 状态能被 curl 出来,说明审批是运行时状态而不是 UI 彩蛋,这条很重要——审批要能被审计,才可能被合规接受。
  3. 3. 对国内做 K8s 上 agent 落地的团队,最实用的是三点:agent 即 CRD 意味着现有 RBAC、命名空间、审计、GitOps 全部直接复用,不必新造一套权限模型;本地跑 30B 级模型写 manifest 这件事,实测门槛是磁盘约 18GB、上下文开到 32K;以及治理层站”前面”而不是站”里面”——多框架、多平台混跑的现场,这是唯一能收敛的路径,agentgateway 这类 MCP/A2A 网关会很快变成标配。

来源

  • – 原文:From zero to agent builder: Running kagent on your laptop(CNCF 官方博客,2026-10-12,Antonio Berben / Felipe Vicens)https://www.cncf.io/blog/2026-10-12/from-zero-to-agent-builder-running-kagent-on-your-laptop/
  • – kagent 项目:https://github.com/kagent-dev/kagent | 文档:https://kagent.dev/docs
  • – A2A 协议:https://github.com/a2aproject/A2A
  • – agentgateway:https://agentgateway.dev

您可能还喜欢...

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注