-
Notifications
You must be signed in to change notification settings - Fork 50
feat: Publish new blog post and documentation example on kagent human… #325
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
396d33d
feat: Publish new blog post and documentation example on kagent human…
ProfessorSeb 752b028
Update src/blogContent/human-in-the-loop-kagent.mdx
ProfessorSeb d189e9d
Update src/app/docs/kagent/examples/human-in-the-loop/page.mdx
ProfessorSeb 9a71ba4
Update src/app/blog/authors.ts
ProfessorSeb File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
245 changes: 245 additions & 0 deletions
245
src/app/docs/kagent/examples/human-in-the-loop/page.mdx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,245 @@ | ||
| --- | ||
| title: "Human-in-the-Loop" | ||
| pageOrder: 7 | ||
| description: "Build a Kubernetes-native AI agent that pauses and asks for your approval before taking destructive actions." | ||
| --- | ||
|
|
||
| export const metadata = { | ||
| title: "Human-in-the-Loop with kagent", | ||
| description: "Build a Kubernetes-native AI agent that pauses and asks for your approval before taking destructive actions.", | ||
| author: "kagent.dev" | ||
| }; | ||
|
|
||
| # Human-in-the-Loop with kagent | ||
|
|
||
| AI agents that can take action are powerful — but you don't always want them acting without your say-so. This tutorial walks you through building a Kubernetes-native AI agent that **pauses and asks for your approval** before doing anything destructive. | ||
|
|
||
| ## What You'll Build | ||
|
|
||
| By the end of this tutorial, you'll have an agent running on a local Kind cluster that: | ||
|
|
||
| - **Reads cluster resources** freely (no approval needed) | ||
| - **Pauses for your approval** before creating, modifying, or deleting resources | ||
| - **Asks you questions** when it needs more information | ||
|
|
||
| --- | ||
|
|
||
| ## Prerequisites | ||
|
|
||
| Make sure you have these installed before starting: | ||
|
|
||
| | Tool | Install Link | | ||
| |------|-------------| | ||
| | Docker | [get-docker](https://docs.docker.com/get-docker/) | | ||
| | Kind | [quick-start](https://kind.sigs.k8s.io/docs/user/quick-start/#installation) | | ||
| | kubectl | [install-tools](https://kubernetes.io/docs/tasks/tools/) | | ||
| | Helm | [install](https://helm.sh/docs/intro/install/) | | ||
|
|
||
| You'll also need an **OpenAI API key**. | ||
|
|
||
| --- | ||
|
|
||
| ## Step 1 — Create a Kind Cluster | ||
|
|
||
| Spin up a local Kubernetes cluster: | ||
|
|
||
| ```bash | ||
| kind create cluster --name kagent-hitl | ||
| ``` | ||
|
|
||
| Verify it's running: | ||
|
|
||
| ```bash | ||
| kubectl cluster-info --context kind-kagent-hitl | ||
| ``` | ||
|
|
||
| You should see the control plane address printed. If so, you're good to go. | ||
|
|
||
| --- | ||
|
|
||
| ## Step 2 — Install kagent | ||
|
|
||
| There are two Helm charts to install: the CRDs first, then kagent itself. | ||
|
|
||
| **Install the CRDs:** | ||
|
|
||
| ```bash | ||
| helm install kagent-crds oci://ghcr.io/kagent-dev/kagent/helm/kagent-crds \ | ||
| --namespace kagent \ | ||
| --create-namespace | ||
| ``` | ||
|
|
||
| **Set your API key:** | ||
|
|
||
| ```bash | ||
| export OPENAI_API_KEY="your-api-key-here" | ||
| ``` | ||
|
|
||
| **Install kagent:** | ||
|
|
||
| ```bash | ||
| helm install kagent oci://ghcr.io/kagent-dev/kagent/helm/kagent \ | ||
| --namespace kagent \ | ||
| --set providers.default=openAI \ | ||
| --set providers.openAI.apiKey=$OPENAI_API_KEY | ||
| ``` | ||
|
|
||
| **Wait for everything to come up:** | ||
|
|
||
| ```bash | ||
| kubectl wait --for=condition=ready pod --all -n kagent --timeout=120s | ||
| ``` | ||
|
|
||
| Once all pods report `condition met`, move on. | ||
|
|
||
| --- | ||
|
|
||
| ## Step 3 — Deploy the Agent | ||
|
|
||
| This is the core of the tutorial. You'll create an agent that uses kagent's **built-in Kubernetes tools** (served via the kagent tool server), with **approval gates** on the destructive ones. | ||
|
|
||
| Save this as `hitl-agent.yaml`: | ||
|
|
||
| ```yaml | ||
| apiVersion: kagent.dev/v1alpha2 | ||
| kind: Agent | ||
| metadata: | ||
| name: hitl-agent | ||
| namespace: kagent | ||
| spec: | ||
| description: A Kubernetes agent with human-in-the-loop approval for destructive operations. | ||
| type: Declarative | ||
| declarative: | ||
| modelConfig: default-model-config | ||
| systemMessage: | | ||
| You are a Kubernetes management agent. You help users inspect and manage | ||
| resources in the cluster. Before making any changes, explain what you | ||
| plan to do. If the user's request is ambiguous, use the ask_user tool | ||
| to clarify before proceeding. | ||
| tools: | ||
| - type: McpServer | ||
| mcpServer: | ||
| name: kagent-tool-server | ||
| kind: RemoteMCPServer | ||
| apiGroup: kagent.dev | ||
| toolNames: | ||
| - k8s_get_resources | ||
| - k8s_describe_resource | ||
| - k8s_get_pod_logs | ||
| - k8s_get_events | ||
| - k8s_get_resource_yaml | ||
| - k8s_apply_manifest | ||
| - k8s_delete_resource | ||
| - k8s_patch_resource | ||
| requireApproval: | ||
| - k8s_apply_manifest | ||
| - k8s_delete_resource | ||
| - k8s_patch_resource | ||
| ``` | ||
|
|
||
| Create the agent: | ||
|
|
||
| ```bash | ||
| kubectl apply -f hitl-agent.yaml | ||
| ``` | ||
|
|
||
| **Here's what each tool does:** | ||
|
|
||
| | Tool | What Happens | | ||
| |------|-------------| | ||
| | `k8s_get_resources` | Runs immediately — lists pods, services, deployments, etc. | | ||
| | `k8s_describe_resource` | Runs immediately — shows resource details | | ||
| | `k8s_get_pod_logs` | Runs immediately — reads pod logs | | ||
| | `k8s_get_events` | Runs immediately — shows cluster events | | ||
| | `k8s_get_resource_yaml` | Runs immediately — exports resource YAML | | ||
| | `k8s_apply_manifest` | **Pauses for approval** — creates or updates resources | | ||
| | `k8s_delete_resource` | **Pauses for approval** — deletes resources | | ||
| | `k8s_patch_resource` | **Pauses for approval** — modifies resources | | ||
| | `ask_user` | Built-in on every agent — asks you questions anytime | | ||
|
|
||
| The key is `requireApproval` — any tool listed there will pause execution until you explicitly approve it. Read-only tools run freely; write operations need your sign-off. | ||
|
|
||
| --- | ||
|
|
||
| ## Step 4 — Open the UI | ||
|
|
||
| Port-forward the kagent dashboard: | ||
|
|
||
| ```bash | ||
| kubectl port-forward -n kagent svc/kagent-ui 8080:8080 | ||
| ``` | ||
|
|
||
| Open [http://localhost:8080](http://localhost:8080) in your browser. You should see the kagent UI with your **hitl-agent** listed. | ||
|
|
||
| --- | ||
|
|
||
| ## Step 5 — Try It Out | ||
|
|
||
| Now for the fun part. Run through these tests to see human-in-the-loop in action. | ||
|
|
||
| ### Test 1: Read Without Approval | ||
|
|
||
| 1. Select the **hitl-agent** in the UI | ||
| 2. Type: `List all pods in the kagent namespace` | ||
| 3. The agent calls `k8s_get_resources` — it runs **immediately** with no approval prompt | ||
| 4. You see the pod listing right away | ||
|
|
||
| This shows that read-only tools are not gated. | ||
|
|
||
| ### Test 2: Approve a Create | ||
|
|
||
| 1. Type: `Create a ConfigMap called test-config in the default namespace with the key message set to "hello from kagent"` | ||
| 2. The agent calls `k8s_apply_manifest` — execution **pauses** | ||
| 3. You'll see **Approve / Reject** buttons appear, along with the YAML it wants to apply | ||
| 4. Click **Approve** | ||
| 5. The agent creates the ConfigMap and confirms | ||
|
|
||
| ### Test 3: Reject a Delete | ||
|
|
||
| 1. Type: `Delete the ConfigMap test-config in the default namespace` | ||
| 2. The agent calls `k8s_delete_resource` — execution **pauses** | ||
| 3. Click **Reject** and enter a reason: `I want to keep this ConfigMap for now` | ||
| 4. The agent sees your reason and responds accordingly — it doesn't delete anything | ||
|
|
||
| ### Test 4: Agent Asks You a Question | ||
|
|
||
| 1. Type: `Set up a namespace for my application` | ||
| 2. The request is vague, so the agent calls `ask_user` to clarify (e.g., "What should the namespace be called?") | ||
| 3. Answer the question and the agent continues with your input | ||
|
|
||
| --- | ||
|
|
||
| ## How It Works | ||
|
|
||
| The flow is straightforward: | ||
|
|
||
| ``` | ||
ProfessorSeb marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| You send a message | ||
| -> Agent decides which tool to call | ||
| -> Is the tool in requireApproval? | ||
| -> YES: Execution pauses, you see Approve/Reject in the UI | ||
| -> Approve: tool runs normally | ||
| -> Reject: agent receives your reason and adapts | ||
| -> NO: Tool runs immediately | ||
| ``` | ||
|
|
||
| The `ask_user` tool works the same way — the agent pauses, you answer, and it continues. Both use the same underlying confirmation mechanism, which keeps things simple. | ||
|
|
||
| --- | ||
|
|
||
| ## Cleanup | ||
|
|
||
| Delete the cluster when you're done: | ||
|
|
||
| ```bash | ||
| kind delete cluster --name kagent-hitl | ||
| ``` | ||
|
|
||
| --- | ||
|
|
||
| ## Key Takeaways | ||
|
|
||
| - **`requireApproval`** is all you need — list the tools that need human sign-off | ||
| - **Read-only tools run freely**, write operations pause for approval | ||
| - **`ask_user`** is built-in on every agent — no extra config required | ||
| - **Rejection reasons** are sent back to the LLM so it can adjust its approach | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.