PageSourceSearch

https://docs.controlzero.ai/assets/js/ef47a40f.f1902fd7.js

js controlzero.ai collected 2026-10-05 13:54:07 UTC 14,642 bytes, 1 lines download raw bytes

1"use strict";(globalThis.webpackChunkcontrolzero_docs||=[]).push([[2600],{39973(e,n,o){o.r(n),o.d(n,{assets:()=>a,contentTitle:()=>l,default:()=>h,frontMatter:()=>i,metadata:()=>t,toc:()=>c});const t=JSON.parse('{"id":"integrations/autogen","title":"AutoGen","description":"Enforce Control Zero policies on Microsoft AutoGen agents, tool calls, and multi-agent teams.","source":"@site/docs/integrations/autogen.md","sourceDirName":"integrations","slug":"/integrations/autogen","permalink":"/docs/integrations/autogen","draft":false,"unlisted":false,"tags":[],"version":"current","sidebarPosition":5,"frontMatter":{"sidebar_position":5,"title":"AutoGen"},"sidebar":"docsSidebar","previous":{"title":"CrewAI","permalink":"/docs/integrations/crewai"},"next":{"title":"OpenAI Agents SDK","permalink":"/docs/integrations/openai-agents"}}');var r=o(74848),s=o(28453);const i={sidebar_position:5,title:"AutoGen"},l="AutoGen Integration",a={},c=[{value:"Overview",id:"overview",level:2},{value:"Installation",id:"installation",level:2},{value:"Setup",id:"setup",level:2},{value:"Governing Tool Functions",id:"governing-tool-functions",level:3},{value:"Using a Guard Decorator",id:"using-a-guard-decorator",level:3},{value:"What Gets Enforced",id:"what-gets-enforced",level:2},{value:"Full Example: Research Pipeline with Guards",id:"full-example-research-pipeline-with-guards",level:2},{value:"Example Policy",id:"example-policy",level:2},{value:"Pairing with AutoGen's Termination Conditions",id:"pairing-with-autogens-termination-conditions",level:2},{value:"Local Policy File",id:"local-policy-file",level:2},{value:"Next Steps",id:"next-steps",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"autogen-integration",children:"AutoGen Integration"})}),"\n",(0,r.jsx)(n.p,{children:"Enforce Control Zero policies on Microsoft AutoGen agents, tool calls, and multi-agent teams."}),"\n",(0,r.jsx)(n.admonition,{title:"First-party SDK integration",type:"note",children:(0,r.jsxs)(n.p,{children:["The Python SDK provides ",(0,r.jsx)(n.code,{children:"governed_tool"})," and ",(0,r.jsx)(n.code,{children:"GovernedAssistantAgent"})," in ",(0,r.jsx)(n.code,{children:"controlzero.integrations.autogen"}),".\nThe examples on this page also show how to add ",(0,r.jsx)(n.code,{children:"cz.guard()"})," calls manually to your AutoGen tools and agents."]})}),"\n",(0,r.jsx)(n.h2,{id:"overview",children:"Overview"}),"\n",(0,r.jsxs)(n.p,{children:["AutoGen v0.4+ is a complete rewrite of the framework with a new agent architecture built around the ",(0,r.jsx)(n.code,{children:"on_messages"})," method. Agents are composed into teams (e.g. ",(0,r.jsx)(n.code,{children:"RoundRobinGroupChat"}),") and tools are plain async functions registered directly on agents. Control Zero integrates by wrapping tool functions with ",(0,r.jsx)(n.code,{children:"cz.guard()"})," calls before the tool logic executes."]}),"\n",(0,r.jsx)(n.h2,{id:"installation",children:"Installation"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"pip install autogen-agentchat autogen-ext controlzero\n"})}),"\n",(0,r.jsx)(n.h2,{id:"setup",children:"Setup"}),"\n",(0,r.jsx)(n.h3,{id:"governing-tool-functions",children:"Governing Tool Functions"}),"\n",(0,r.jsxs)(n.p,{children:["Wrap tool functions with ",(0,r.jsx)(n.code,{children:"cz.guard()"})," before registering them on an agent:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:'from autogen_agentchat.agents import AssistantAgent\nfrom autogen_ext.models.openai import OpenAIChatCompletionClient\nfrom controlzero import Client, PolicyDeniedError\n\ncz = Client(api_key="cz_live_your_api_key_here")\n\n\n# Govern a tool function by calling cz.guard() inside it\nasync def search_web(query: str) -> str:\n    cz.guard("search", method="web", args={"query": query}, raise_on_deny=True)\n    # ... actual search implementation\n    return f"Results for: {query}"\n\n\nasync def calculator(expression: str) -> str:\n    cz.guard("calculator", args={"expression": expression}, raise_on_deny=True)\n    # use a safe math parser in production\n    return str(expression)\n\n\n# Register governed tools on the agent\nagent = AssistantAgent(\n    name="research_agent",\n    model_client=OpenAIChatCompletionClient(model="gpt-5.4"),\n    tools=[search_web, 
1calculator],\n)\n'})}),"\n",(0,r.jsx)(n.h3,{id:"using-a-guard-decorator",children:"Using a Guard Decorator"}),"\n",(0,r.jsx)(n.p,{children:"For cleaner code across many tools, use a decorator pattern:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:'import functools\nfrom controlzero import Client\n\ncz = Client(api_key="cz_live_your_api_key_here")\n\n\ndef guarded(action: str):\n    """Decorator that enforces a Control Zero policy before a tool runs."""\n    def decorator(func):\n        @functools.wraps(func)\n        async def wrapper(*args, **kwargs):\n            cz.guard(action, args={"tool": func.__name__}, raise_on_deny=True)\n            return await func(*args, **kwargs)\n        return wrapper\n    return decorator\n\n\n@guarded("search")\nasync def search_web(query: str) -> str:\n    return f"Results for: {query}"\n\n\n@guarded("retrieve_docs")\nasync def retrieve_docs(query: str) -> str:\n    return f"Documents for: {query}"\n'})}),"\n",(0,r.jsx)(n.h2,{id:"what-gets-enforced",children:"What Gets Enforced"}),"\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"AutoGen Event"}),(0,r.jsx)(n.th,{children:"Policy Action"}),(0,r.jsx)(n.th,{children:"Policy Resource"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"Tool call"}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"tool.call"})}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"tool/{function_name}"})})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"Code execution"}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"tool.call"})}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"tool/execute_code"})})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"Python REPL"}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"tool.call"})}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"tool/python_repl"})})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"Shell execution"}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"tool.call"})}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"tool/shell_exec"})})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"Inter-agent message"}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"agent.message"})}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"agent/{recipient_name}"})})]})]})]}),"\n",(0,r.jsx)(n.h2,{id:"full-example-research-pipeline-with-guards",children:"Full Example: Research Pipeline with Guards"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:'import asyncio\nfrom autogen_agentchat.agents import AssistantAgent, UserProxyAgent\nfrom autogen_agentchat.conditions import TextMentionTermination\nfrom autogen_agentchat.teams import RoundRobinGroupChat\nfrom autogen_agentchat.ui import Console\nfrom autogen_ext.models.openai import OpenAIChatCompletionClient\nfrom controlzero import Client, PolicyDeniedError\n\n# --- Control Zero setup ---\ncz = Client(api_key="cz_live_your_api_key_here")\n\n\n# --- Define guarded tools ---\nasync def search(query: str) -> str:\n    """Search the web for information."""\n    cz.guard("search", args={"agent_id": "research-pipeline"}, raise_on_deny=True)\n    return f"Search results for: {query}"\n\n\nasync def retrieve_docs(query: str) -> str:\n    """Retrieve documents from the knowledge base."""\n    cz.guard("retrieve_docs", args={"agent_id": "research-pipeline"}, raise_on_deny=True)\n    return f"Documents for: {query}"\n\n\nasync def safe_calculate(expression: str) -> str:\n    """Evaluate a mathematical expression safely."""\n    cz.guard("calculator", args={"agent_id": "research-pipeline"}, raise_on_deny=True)\n    # use a safe math parser (e.g. simpleeval) in production\n    return f"Result: {expression}"\n\n\n# --- Configure agents ---\nmodel_client = OpenAIChatCompletionClient(model="gpt-5.4")\n\nassistant = AssistantAgent(\n    name="research_assistant",\n    model_client=model_client,\n    tools=[search, retrieve_docs, safe_calculate],\n)\n\nuser_proxy = UserProxyAgent(name="user_proxy")\n\n\n# --- Run the conversation ---\nasync def main():\n    termination = TextMentionTermination("TERMINATE")\n    team = RoundRobinGroupChat(\n        [assistant, user_proxy],\n        termination_condition=termination,\n    )\n    try:\n        await Console(\n            team.run_stream(\n                task="Find the latest quarterly revenue and calculate year-over-year growth."\n            )\n        )\n    except PolicyDeniedError as e:\n        print(f"Blocked by policy: {e.decision.reason}")\n\n\nasyncio.run(main())\n'})}),"\n",(0,r.jsx)(n.h2,{id:"example-policy",children:"Example Policy"}),"\n",(0,r.jsx)(n.p,{children:"Allow research tools but block code execution and outbound actions:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-json",children:'{\n  "name": "autogen-research-policy",\n  "rules": [\n    {\n      "effect": "allow",\n      "action": "tool:call",\n      "resource": "tool/search"\n    },\n    {\n      "effect": "allow",\n      "action": "tool:call",\n      "resource": "tool/retrieve_docs"\n    },\n    {\n      "effect": "allow",\n      "action": "tool:call",\n      "resource": "tool/calculator"\n    },\n    {\n      "effect": "deny",\n      "action": "tool:call",\n      "resource": "tool/execute_code"\n    },\n    {\n      "effect": "deny",\n      "action": "tool:call",\n      "resource": "tool/python_repl*"\n    },\n    {\n      "effect": "deny",\n      "action": "tool:call",\n      "resource": "tool/shell_exec*"\n    },\n    {\n      "effect": "deny",\n      "action": "tool:call",\n      "resource": "tool/send_*"\n    },\n    {\n      "effect": "deny",\n      "action": "tool:call",\n      "resource": "tool/post_*"\n    }\n  ]\n}\n'})}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"What happens at runtime:"})}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"search"})," and ",(0,r.jsx)(n.code,{children:"retrieve_docs"})," calls: ",(0,r.jsx)(n.strong,{children:"ALLOWED"}),"."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"calculator"})," calls: ",(0,r.jsx)(n.strong,{children:"ALLOWED"}),"."]}),"\n",(0,r.jsxs)(n.li,{children:["Any attempt to run ",(0,r.jsx)(n.code,{children:"execute_code"}),", ",(0,r.jsx)(n.code,{children:"python_repl"}),", or ",(0,r.jsx)(n.code,{children:"shell_exec"}),": ",(0,r.jsx)(n.strong,{children:"BLOCKED"}),". The agent receives a ",(0,r.jsx)(n.code,{children:"PolicyDeniedError"}),"."]}),"\n",(0,r.jsxs)(n.li,{children:["Any outbound ",(0,r.jsx)(n.code,{children:"send_*"})," or ",(0,r.jsx)(n.code,{children:"post_*"})," actions: ",(0,r.jsx)(n.strong,{children:"BLOCKED"}),"."]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"pairing-with-autogens-termination-conditions",children:"Pairing with AutoGen's Termination Conditions"}),"\n",(0,r.jsxs)(n.p,{children:["AutoGen v0.4+ uses termination conditions (e.g. ",(0,r.jsx)(n.code,{children:"TextMentionTermination"}),", ",(0,r.jsx)(n.code,{children:"MaxMessageTermination"}),") to stop team runs. Control Zero complements this:"]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Autonomous teams"})," (",(0,r.jsx)(n.code,{children:"MaxMessageTermination"}),"): Fully autonomous execution with Control Zero enforcing guardrails on every tool call automatically."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Human-in-the-loop"})," (",(0,r.jsx)(n.code,{children:"UserProxyAgent"}),"): The user reviews messages, and Control Zero blocks policy violations before the user sees the tool result."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Token-limited runs"})," (",(0,r.jsx)(n.code,{children:"TokenUsageTermination"}),"): Useful for cost-capped pipelines; pair with Control Zero to block high-risk tools after budget thresholds."]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"local-policy-file",children:"Local Policy File"}),"\n",(0,r.jsxs)(n.p,{children:["For local development, use the ",(0,r.jsx)(n.code,{children:"controlzero init"})," command to generate an AutoGen-specific policy template:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"controlzero init --template autogen\n"})}),"\n",(0,r.jsxs)(n.p,{children:["This creates a ",(0,r.jsx)(n.code,{children:"controlzero.yaml"})," that denies bare code execution and shell access while allowing named research and retrieval tools."]}),"\n",(0,r.jsx)(n.h2,{id:"next-steps",children:"Next Steps"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsxs)(n.strong,{children:[(0,r.jsx)(n.a,{href:"/docs/integrations/langchain",children:"LangChain Integration"}),":"]})," Single-agent LLM governance with callback handlers."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsxs)(n.strong,{children:[(0,r.jsx)(n.a,{href:"/docs/integrations/crewai",children:"CrewAI Integration"}),":"]})," Multi-agent crew governance."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsxs)(n.strong,{children:[(0,r.jsx)(n.a,{href:"/docs/sdk/python",children:"Python SDK"}),":"]})," Full API reference for enforcement, wrapping, and audit."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsxs)(n.strong,{children:[(0,r.jsx)(n.a,{href:"/docs/concepts/policies",children:"Policies"}),":"]})," Learn how to construct dashboard policies."]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453(e,n,o){o.d(n,{R:()=>i,x:()=>l});var t=o(96540);const r={},s=t.createContext(r);function i(e){const n=t.useContext(s);return t.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),t.createElement(s.Provider,{value:n},e.children)}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.