Skip to main content

Semantic Kernel

A Semantic Kernel pipeline with Kernel.invoke and plugin functions across 3 agents: a parent orchestrator, a runner executing SummarizePlugin and WriterPlugin, and an evaluator running ReviewPlugin with quality scoring. Demonstrates the SK pattern of chaining plugin functions with kernel context.

Environment variables

This example requires OPENAI_API_KEY, WAXELL_API_KEY, and WAXELL_API_URL. Use --dry-run to run without any API keys.

Architecture

Key Code

SK plugin functions as @tool decorators

Each Semantic Kernel plugin invocation is recorded as a tool call with tool_type="function".

@waxell.tool(tool_type="function")
async def invoke_summarize_plugin(query: str, openai_client) -> dict:
"""Kernel.invoke(SummarizePlugin.summarize)"""
response = await openai_client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "system", "content": "Summarize into 2-3 key points."},
{"role": "user", "content": query}],
)
return {"plugin": "SummarizePlugin", "function": "summarize",
"result": response.choices[0].message.content}

@waxell.tool(tool_type="function")
async def invoke_writer_plugin(summary: str, openai_client) -> dict:
"""Kernel.invoke(WriterPlugin.expand)"""
response = await openai_client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "system", "content": "Expand into detailed explanation."},
{"role": "user", "content": f"Summary: {summary}"}],
)
return {"plugin": "WriterPlugin", "function": "expand",
"result": response.choices[0].message.content}

Evaluator with @reasoning, decide(), and score()

The evaluator runs the ReviewPlugin, assesses pipeline quality, and attaches scores.

@waxell.reasoning_dec(step="pipeline_quality_assessment")
async def assess_pipeline_quality(summary: str, expanded: str, review: str) -> dict:
expansion_ratio = len(expanded) / max(len(summary), 1)
return {
"thought": f"Summary expanded to {expansion_ratio:.1f}x. Review provided.",
"evidence": [f"Expansion ratio: {expansion_ratio:.1f}x"],
"conclusion": "Pipeline produced well-structured output"
if expansion_ratio > 1.5 else "Expansion may be insufficient",
}

waxell.decide("output_format", chosen="structured",
options=["raw", "structured", "markdown"],
reasoning="Full pipeline -- structured format best", confidence=0.90)

waxell.score("summary_quality", 0.85, comment="conciseness and coverage")
waxell.score("expansion_quality", 0.88, comment="detail and structure")
waxell.score("review_score", 0.82, comment="reviewer assessment")

What this demonstrates

  • @waxell.observe -- parent-child agent hierarchy with automatic lineage
  • @waxell.step_dec -- kernel context preparation recorded as execution step
  • @waxell.tool -- SummarizePlugin, WriterPlugin, and ReviewPlugin invocations
  • @waxell.decision -- plugin chain selection via OpenAI
  • waxell.decide() -- manual output format decision
  • @waxell.reasoning_dec -- pipeline quality assessment with expansion ratio analysis
  • waxell.score() -- summary, expansion, and review quality scores
  • Auto-instrumented LLM calls -- three OpenAI calls captured without extra code
  • SK plugin pattern -- Kernel.invoke(Plugin.function) with sequential chaining

Run it

# Dry-run (no API keys needed)
cd dev/waxell-dev
python -m app.demos.semantic_kernel_agent --dry-run

# Live (real OpenAI)
export OPENAI_API_KEY="sk-..."
python -m app.demos.semantic_kernel_agent

# Custom query
python -m app.demos.semantic_kernel_agent --query "Explain AI governance principles"

Source

dev/waxell-dev/app/demos/semantic_kernel_agent.py