This guide shows how to use Agentic Programming within OpenClaw — as a skill, a utility library, or an MCP tool provider.
Agentic Programming and OpenClaw solve different problems:
- OpenClaw orchestrates agents, manages sessions, routes messages
- Agentic Programming gives individual functions the ability to think (LLM-in-the-loop)
They compose naturally: OpenClaw's skills can use agentic functions internally.
# In your OpenClaw workspace
cd ~/.openclaw/workspace
# Clone OpenProgram
git clone https://github.com/Fzkuji/OpenProgram.git
# Prepare the source checkout
cd OpenProgram
uv sync --lockedThe simplest integration — use agentic functions as building blocks within an OpenClaw skill.
Skill structure:
~/.openclaw/workspace/skills/my-agentic-skill/
├── SKILL.md
└── scripts/
└── analyze.py
scripts/analyze.py:
#!/usr/bin/env python3
"""
OpenClaw skill script that uses Agentic Programming internally.
Called by the agent via the exec tool.
"""
import sys
import os
# Add the source checkout to the script path
sys.path.insert(0, os.path.expanduser("~/.openclaw/workspace/OpenProgram"))
from openprogram import agentic_function
from openprogram.agentic_programming import llm
from openprogram.providers.registry import create_runtime
runtime = create_runtime(provider="claude-code", model="haiku")
@agentic_function
def decompose(task, runtime=None):
"""Break a complex task into actionable steps."""
return llm([
{"type": "text", "text": f"Break this task into 3-5 concrete, actionable steps:\n{task}\n\nNumber each step. Be specific."},
])
@agentic_function
def assess(step, runtime=None):
"""Assess difficulty and time estimate for a step."""
return llm([
{"type": "text", "text": f"For this step, give: difficulty (easy/medium/hard) and time estimate.\nFormat: [difficulty] ~Xh\n\nStep: {step}"},
])
@agentic_function
def plan(task, runtime=None):
"""Create a detailed plan for a task."""
steps_text = decompose(task=task, runtime=runtime)
lines = [l.strip() for l in steps_text.split("\n") if l.strip() and l.strip()[0].isdigit()]
assessments = []
for line in lines[:5]:
a = assess(step=line, runtime=runtime)
assessments.append(f"{line}\n → {a}")
return "\n\n".join(assessments)
if __name__ == "__main__":
task = " ".join(sys.argv[1:]) if len(sys.argv) > 1 else "Build a REST API with authentication"
result = plan(task=task, runtime=runtime)
print(result)SKILL.md (OpenClaw requires the YAML front matter — name and description are what the agent matches on):
---
name: my-agentic-skill
description: Plan and decompose tasks using Agentic Programming with automatic context tracking.
---
# my-agentic-skill
When the user asks to plan, decompose, or break down a task, run:
\`\`\`bash
uv run --project ~/.openclaw/workspace/OpenProgram python \
~/.openclaw/workspace/skills/my-agentic-skill/scripts/analyze.py \
"the task description"
\`\`\`This runs the script with the source checkout's locked environment. Do not run it with the system Python, which does not contain OpenProgram's dependencies.
OpenClaw and OpenProgram use the same AgentSkills-compatible SKILL.md format, so user, project, or plugin skills can be shared between them. OpenProgram does not ship default skills; product workflows are Programs.
If your OpenClaw agent runs Python scripts, you can import agentic functions directly:
"""
Code review script called by an OpenClaw agent.
"""
from openprogram import agentic_function
from openprogram.agentic_programming import llm
from openprogram.providers.registry import create_runtime
runtime = create_runtime(provider="claude-code", model="haiku")
@agentic_function
def review_code(code, language="python", runtime=None):
"""Review code for bugs, style issues, and improvements."""
return llm([
{"type": "text", "text": f"Review this {language} code. List:\n1. Bugs (if any)\n2. Style issues\n3. Suggested improvements\n\n```{language}\n{code}\n```"},
])
@agentic_function
def suggest_tests(code, runtime=None):
"""Suggest test cases for the given code."""
return llm([
{"type": "text", "text": f"Suggest 3 test cases for this code. For each, give: test name, input, expected output.\n\n```python\n{code}\n```"},
])
@agentic_function
def code_analysis(code, runtime=None):
"""Full code analysis: review + test suggestions."""
review = review_code(code=code, runtime=runtime)
tests = suggest_tests(code=code, runtime=runtime)
return f"## Code Review\n{review}\n\n## Suggested Tests\n{tests}"Wrap agentic functions as MCP tools that OpenClaw can call:
#!/usr/bin/env python3
"""
MCP-compatible tool server that exposes agentic functions.
"""
import json
import sys
from openprogram import agentic_function
from openprogram.agentic_programming import llm
from openprogram.providers.registry import create_runtime
runtime = create_runtime(provider="claude-code", model="haiku")
@agentic_function
def summarize_text(text, style="bullet_points", runtime=None):
"""Summarize text in the specified style."""
style_instructions = {
"bullet_points": "Summarize as 3-5 bullet points.",
"one_paragraph": "Summarize in one paragraph.",
"eli5": "Explain like I'm 5.",
}
instruction = style_instructions.get(style, style_instructions["bullet_points"])
return llm([
{"type": "text", "text": f"{instruction}\n\nText:\n{text}"},
])
if __name__ == "__main__":
request = json.loads(sys.stdin.read())
tool = request.get("tool")
args = request.get("args", {})
if tool == "summarize":
result = summarize_text(**args, runtime=runtime)
print(json.dumps({"result": result}))
else:
print(json.dumps({"error": f"Unknown tool: {tool}"}))| Without Agentic Programming | With Agentic Programming |
|---|---|
| Agent does all reasoning in one LLM call | Reasoning is split into focused function calls |
| Context grows unboundedly | Context is a structured DAG, scoped per function |
| Hard to debug what the agent "thought" | Every call is recorded as a session DAG node, reviewable in the Web UI or the session files |
| Retry = retry the entire agent turn | Retry = retry just the failed function |
- Start with the
claude-codeprovider — no extra API key needed; a Claude Code login is enough, and it runs on your subscription. See Claude Code integration. - Pick the provider by billing —
create_runtime(provider="claude-code")runs on your Claude subscription,create_runtime(provider="anthropic")bills against an Anthropic API key. - Review execution traces — every function call is recorded in the session DAG; find the session with the Web UI or
openprogram sessions listand review it there. - Keep functions small and focused — each
@agentic_functionshould do one thing; let Python compose them.