๐ 10๋ถ ๋ง์ ๋๋ด๋ ์์ด์ ํธ ๊ฑฐ๋ฒ๋์ค ์์ ๊ฐ์ด๋¶
10๋ถ ์์ ๊ฑฐ๋ฒ๋์ค๊ฐ ์ ์ฉ๋ AI ์์ด์ ํธ ํ๊ฒฝ์ ๊ตฌ์ถํด ๋ณด์ธ์.
์ฌ์ ์๊ตฌ ์ฌํญ: Python 3.11+ / Node.js 18+ / .NET 8.0+ ์ค ํ๋ ์ด์.
์ํคํ ์ฒ ๊ฐ์¶
๊ฑฐ๋ฒ๋์ค ๋ ์ด์ด๋ ๋ชจ๋ ์์ด์ ํธ์ ํ๋์ด ์คํ๋๊ธฐ ์ ์ ์ด๋ฅผ ๊ฐ๋ก์ฑ์(intercept) ํ๊ฐํฉ๋๋ค.
graph LR
A[AI ์์ด์ ํธ] -->|๋๊ตฌ ํธ์ถ| B{๊ฑฐ๋ฒ๋์ค ๋ ์ด์ด}
B -->|์ ์ฑ
ํ์ธ| C{์ ์ฑ
์์ง}
C -->|ํ์ฉ| D[๋๊ตฌ ์คํ]
C -->|์ฐจ๋จ| E[๋ณด์ ์ฐจ๋จ]
D --> F[๊ฐ์ฌ ๋ก๊ทธ]
E --> F
F --> G[OTEL / ๊ตฌ์กฐํ๋ ๋ก๊ทธ] 1. ์ค์น¶
๊ฑฐ๋ฒ๋์ค ํดํท ํตํฉ ํจํค์ง๋ฅผ ์ค์นํฉ๋๋ค.
๋๋ ํจํค์ง๋ฅผ ๊ฐ๋ณ๋ก ์ค์นํ ์ ์์ต๋๋ค.
pip install agent-os-kernel # ์ ์ฑ
๊ฐ์ + ํ๋ ์์ํฌ ์ฐ๋
pip install agentmesh-platform # ์ ๋ก ํธ๋ฌ์คํธ ์ ์์ฆ๋ช
+ ์ ๋ขฐ ์นด๋
pip install agent-governance-toolkit # OWASP ASI ๊ฒ์ฆ + ๋ฌด๊ฒฐ์ฑ CLI
pip install agent-sre # SLO, ์๋ฌ ๋ฒ์ง, ์นด์ค์ค ํ
์คํธ
pip install agentmesh-runtime # ์คํ ๊ฐ๋
๊ด + ๊ถํ ๊ฒฉ๋ฆฌ ๋ง
pip install agentmesh-marketplace # ํ๋ฌ๊ทธ์ธ ๋ผ์ดํ์ฌ์ดํด ๊ด๋ฆฌ
pip install agentmesh-lightning # ๊ฐํํ์ต(RL) ํ๋ จ ๊ฑฐ๋ฒ๋์ค
TypeScript / Node.js¶
.NET¶
.csproj ํ์ผ์ด ์๋ ๋๋ ํฐ๋ฆฌ๊ฐ ์๋๋ผ๋ฉด ํ๋ก์ ํธ ๊ฒฝ๋ก๋ฅผ ๋ช
์ํด์ ์คํํ์ธ์.
Visual Studio Package Manager Console์์๋ Default project ๋๋กญ๋ค์ด์์ ๋์ ํ๋ก์ ํธ๋ฅผ ๊ณ ๋ฅธ ๋ค ๋ค์ ๋ช ๋ น์ ์ฌ์ฉํ์ธ์.
2. ์ค์น ํ์ธ¶
๋ฏธ๋ฆฌ ํฌํจ๋ ์ ๊ฒ ์คํฌ๋ฆฝํธ๋ฅผ ์คํํฉ๋๋ค.
๋๋ agt CLI๋ฅผ ์ง์ ์ฌ์ฉํ์ฌ ํ์ธํด๋ณผ ์๋ ์์ต๋๋ค.
3. ์ฒซ ๋ฒ์งธ ๊ฑฐ๋ฒ๋์ค ์์ด์ ํธ ๋ง๋ค๊ธฐ¶
governed_agent.py ํ์ผ์ ์์ฑํฉ๋๋ค.
from agent_os.policies import PolicyEvaluator
from agent_os.policies.schema import (
PolicyDocument, PolicyRule, PolicyCondition,
PolicyAction, PolicyOperator, PolicyDefaults,
)
# --- 1๋จ๊ณ: ์์ด์ ํธ ๋๊ตฌ(tool) ์ ์ ---
def web_search(query: str) -> str:
"""์น ๊ฒ์ ๋๊ตฌ ์๋ฎฌ๋ ์ด์
"""
return f"๊ฒ์ ๊ฒฐ๊ณผ: {query}"
def delete_file(path: str) -> str:
"""์ํํ ๋๊ตฌ โ ์ ์ฑ
์ ์ํด ์ฐจ๋จ๋์ด์ผ ํจ"""
return f"์ญ์ ๋จ: {path}"
TOOLS = {
"web_search": web_search,
"delete_file": delete_file,
}
# --- 2๋จ๊ณ: ๊ฑฐ๋ฒ๋์ค ์ ์ฑ
์ ์ ---
policy = PolicyDocument(
name="agent-safety",
version="1.0",
description="์ฐ๊ตฌ์ฉ ์์ด์ ํธ๋ฅผ ์ํ ์์ ์ ์ฑ
",
defaults=PolicyDefaults(action=PolicyAction.ALLOW),
rules=[
PolicyRule(
name="block-dangerous-tools",
condition=PolicyCondition(
field="tool_name",
operator=PolicyOperator.IN,
value=["delete_file", "shell_exec", "execute_code"],
),
action=PolicyAction.DENY,
message="์์ ์ ์ฑ
์ ์ํด ๋๊ตฌ๊ฐ ์ฐจ๋จ๋์์ต๋๋ค.",
priority=100,
),
PolicyRule(
name="block-ssn-patterns",
condition=PolicyCondition(
field="input_text",
operator=PolicyOperator.MATCHES,
value=r"\b\d{3}-\d{2}-\d{4}\b",
),
action=PolicyAction.DENY,
message="๊ฐ์ธ์ ๋ณด์ ํด๋นํ๋ ์ฌํ๋ณด์ฅ๋ฒํธ(SSN) ํจํด ๊ฐ์ง โ ์ฐจ๋จ๋จ",
priority=90,
),
],
)
evaluator = PolicyEvaluator(policies=[policy])
# --- 3๋จ๊ณ: ๊ฑฐ๋ฒ๋์ค ์์ด์ ํธ ๊ตฌ์ถ ---
class GovernedAgent:
"""๋ชจ๋ ๋๊ตฌ(Tool) ํธ์ถ ์ ์ ์ ์ฑ
์ ํ์ธํ๋ ๊ฐ๋จํ ์์ด์ ํธ"""
def __init__(self, name, tools, evaluator):
self.name = name
self.tools = tools
self.evaluator = evaluator
def call_tool(self, tool_name: str, params: dict) -> str:
# ์คํ๊ด๋ จ ์ฌ์ ์ ์ฑ
ํ์ธ (Pre-execution check)
decision = self.evaluator.evaluate({
"tool_name": tool_name,
"input_text": str(params),
"agent_id": self.name,
})
if not decision.allowed:
print(f" โ ์ฐจ๋จ๋จ: {decision.reason}")
return f"[์ฐจ๋จ๋จ] {decision.reason}"
# ๋๊ตฌ ์คํ
print(f" โ ํ์ฉ๋จ: {tool_name}")
tool_fn = self.tools[tool_name]
return tool_fn(**params)
# --- 4๋จ๊ณ: ์คํ ---
agent = GovernedAgent("research-agent", TOOLS, evaluator)
print("์์ด์ ํธ: ์น ๊ฒ์ ์ค...")
result = agent.call_tool("web_search", {"query": "์ต์ AI ๊ฑฐ๋ฒ๋์ค ๋ด์ค"})
print(f" ๊ฒฐ๊ณผ: {result}\n")
print("์์ด์ ํธ: ํ์ผ ์ญ์ ์๋ ์ค...")
result = agent.call_tool("delete_file", {"path": "/etc/passwd"})
print(f" ๊ฒฐ๊ณผ: {result}\n")
print("์์ด์ ํธ: ์ฟผ๋ฆฌ์ SSN์ ํฌํจํ์ฌ ๊ฒ์ ์ค...")
result = agent.call_tool("web_search", {"query": "lookup 123-45-6789"})
print(f" ๊ฒฐ๊ณผ: {result}")
์คํ ๊ฒฐ๊ณผ ํ์ธ:
์์ ์ถ๋ ฅ:
์์ด์ ํธ: ์น ๊ฒ์ ์ค...
โ ํ์ฉ๋จ: web_search
๊ฒฐ๊ณผ: ๊ฒ์ ๊ฒฐ๊ณผ: ์ต์ AI ๊ฑฐ๋ฒ๋์ค ๋ด์ค
์์ด์ ํธ: ํ์ผ ์ญ์ ์๋ ์ค...
โ ์ฐจ๋จ๋จ: ์์ ์ ์ฑ
์ ์ํด ๋๊ตฌ๊ฐ ์ฐจ๋จ๋์์ต๋๋ค.
๊ฒฐ๊ณผ: [์ฐจ๋จ๋จ] ์์ ์ ์ฑ
์ ์ํด ๋๊ตฌ๊ฐ ์ฐจ๋จ๋์์ต๋๋ค.
์์ด์ ํธ: ์ฟผ๋ฆฌ์ SSN์ ํฌํจํ์ฌ ๊ฒ์ ์ค...
โ ์ฐจ๋จ๋จ: ์ฌํ๋ณด์ฅ๋ฒํธ(SSN) ํจํด ๊ฐ์ง โ ์ฐจ๋จ๋จ
๊ฒฐ๊ณผ: [์ฐจ๋จ๋จ] ์ฌํ๋ณด์ฅ๋ฒํธ(SSN) ํจํด ๊ฐ์ง โ ์ฐจ๋จ๋จ
๊ฑฐ๋ฒ๋์ค ๋ ์ด์ด๋ ์คํ ์ ๋ชจ๋ ๋๊ตฌ ํธ์ถ์ ๊ฐ๋ก์ฑ๋๋ค. ๋ฐ๋ผ์ ์์ด์ ํธ๊ฐ delete_file์ ์คํํ๊ฑฐ๋ ๊ฐ์ธ ์ ๋ณด(PII)๋ฅผ ์ ์ถํ ์ ์์ต๋๋ค.
YAML ํ์ผ๋ก๋ถํฐ ์ ์ฑ ๋ก๋ฉ¶
์ค๋ฌด ํ๊ฒฝ์์๋ ์ธ๋ผ์ธ ์ฝ๋ ๋์ YAML ํ์ผ๋ก ์ ์ฑ ์ ์ ์ํ์ธ์.
from agent_os.policies import PolicyEvaluator
evaluator = PolicyEvaluator()
evaluator.load_policies("policies/") # ๋ชจ๋ *.yaml ํ์ผ์ ๋ก๋ํฉ๋๋ค.
result = evaluator.evaluate({"tool_name": "web_search", "agent_id": "analyst-1"})
print(f"ํ์ฉ ์ฌ๋ถ: {result.allowed}")
์ฒซ ๋ฒ์งธ ๊ฑฐ๋ฒ๋์ค ์์ด์ ํธ โ TypeScript¶
governed_agent.ts ํ์ผ์ ์์ฑํฉ๋๋ค.
import { PolicyEngine, AgentIdentity, AuditLogger } from "@microsoft/agent-governance-sdk";
const identity = AgentIdentity.generate("my-agent", ["web_search", "read_file"]);
const engine = new PolicyEngine([
{ action: "web_search", effect: "allow" },
{ action: "delete_file", effect: "deny" },
]);
console.log(engine.evaluate("web_search")); // "allow" (ํ์ฉ)
console.log(engine.evaluate("delete_file")); // "deny" (์ฐจ๋จ)
์ฒซ ๋ฒ์งธ ๊ฑฐ๋ฒ๋์ค ์์ด์ ํธ โ .NET¶
GovernedAgent.cs ํ์ผ์ ์์ฑํฉ๋๋ค.
using AgentGovernance;
using AgentGovernance.Policy;
var kernel = new GovernanceKernel(new GovernanceOptions
{
PolicyPaths = new() { "policies/default.yaml" },
EnablePromptInjectionDetection = true,
});
var result = kernel.EvaluateToolCall("did:mesh:agent-1", "web_search", new() { ["query"] = "AI news" });
Console.WriteLine($"Allowed: {result.Allowed}"); // ์ ์ฑ
์ด ํ์ฉํ ๊ฒฝ์ฐ True
result = kernel.EvaluateToolCall("did:mesh:agent-1", "delete_file", new() { ["path"] = "/etc/passwd" });
Console.WriteLine($"Allowed: {result.Allowed}"); // False
4. ๊ธฐ์กด ํ๋ ์์ํฌ ์ฐ๋¶
์ด ํดํท์ ์ฃผ์ํ ์์ด์ ํธ ํ๋ ์์ํฌ์ ์ฐ๋์ด ๊ฐ๋ฅํฉ๋๋ค. ๋ค์์ LangChain ์์์ ๋๋ค.
from agent_os.policies import PolicyEvaluator
# ๊ฑฐ๋ฒ๋์ค ์ ์ฑ
๋ก๋
evaluator = PolicyEvaluator()
evaluator.load_policies("policies/")
# ํ๋ ์์ํฌ์ ๋ชจ๋ ๋๊ตฌ ํธ์ถ ์ ํ๊ฐ ์ํ
decision = evaluator.evaluate({
"agent_id": "langchain-agent-1",
"tool_name": "web_search",
"action": "tool_call",
})
if decision.allowed:
# LangChain ๋๊ตฌ ํธ์ถ ์งํ
result = your_langchain_agent.run(...)
else:
print(f"์ฐจ๋จ๋จ: {decision.reason}")
์ฌํ๋ ์ฐ๋ ๊ตฌํ์ ์ํด ํ๋ ์์ํฌ๋ณ ์ ์ฉ ์ด๋ํฐ๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
pip install agentmesh-langchain # LangChain ์ด๋ํฐ
pip install llamaindex-agentmesh # LlamaIndex ์ด๋ํฐ
pip install crewai-agentmesh # CrewAI ์ด๋ํฐ
์ง์๋๋ ํ๋ ์์ํฌ: LangChain, OpenAI Agents SDK, AutoGen, CrewAI, Google ADK, Semantic Kernel, LlamaIndex, Anthropic, Mistral, Gemini ๋ฑ.
5. OWASP ASI 2026 ์ปค๋ฒ๋ฆฌ์ง ํ์ธ¶
๋ฐฐํฌ ํ๊ฒฝ์ด OWASP ์์ด์ ํธ ๋ณด์ ์ํ์ ์ปค๋ฒํ๋์ง ํ์ธํฉ๋๋ค.
# ํ
์คํธ ์์ฝ ๋ณด๊ณ ์
agt verify
# CI/CD ํ์ดํ๋ผ์ธ์ ์ํ JSON ์ถ๋ ฅ
agt verify --json
# README์ฉ ๋ฐฐ์ง(Badge) ์์ฑ
agt verify --badge
์์ ํ ์๋ฌ ์ฒ๋ฆฌ¶
ํดํท์ ๋ชจ๋ CLI ๋๊ตฌ๋ ๋ด๋ถ ์ ๋ณด ์ ์ถ์ ๋ฐฉ์งํ๋๋ก ์ค๊ณ๋์์ต๋๋ค. JSON ๋ชจ๋์์ ๋ช ๋ น์ด ์คํจํ ๊ฒฝ์ฐ ๋ค์๊ณผ ๊ฐ์ด ์ ์ ๋ ์คํค๋ง๋ฅผ ๋ฐํํฉ๋๋ค.
{
"status": "error",
"message": "An internal error occurred during verification",
"type": "InternalError"
}
"File not found(ํ์ผ์ ์ฐพ์ ์ ์์)"์ฒ๋ผ ์ ์๋ ค์ง ์๋ฌ๋ ๊ตฌ์ฒด์ ์ธ ๋ฉ์์ง๋ฅผ ํฌํจํ์ง๋ง, ์์์น ๋ชปํ ์์คํ ์๋ฌ๋ ๋ณด์ ๋ฌด๊ฒฐ์ฑ์ ์ํด ๋ง์คํน ์ฒ๋ฆฌ๋ฉ๋๋ค.
6. ๋ชจ๋ ๋ฌด๊ฒฐ์ฑ ๊ฒ์ฆ¶
๊ฑฐ๋ฒ๋์ค ๋ชจ๋์ด ๋ณ์กฐ๋์ง ์์๋์ง ํ์ธํฉ๋๋ค.
# ๊ธฐ์ค ๋ฌด๊ฒฐ์ฑ ๋งค๋ํ์คํธ ์์ฑ(Baseline integrity manifest)
agt integrity --generate integrity.json
# ์ดํ ํด๋น ๋งค๋ํ์คํธ๋ฅผ ๊ธฐ์ค์ผ๋ก ๊ฒ์ฆ ์ํ
agt integrity --manifest integrity.json
๋ ์์๋ณด๊ธฐ¶
| ํญ๋ชฉ | ์์น |
|---|---|
| ์ ์ฒด API ๋ ํผ๋ฐ์ค (Python) | agent-governance-python/agent-os/README.md |
| TypeScript ํจํค์ง ๋ฌธ์ | agent-governance-typescript/README.md |
| .NET ํจํค์ง ๋ฌธ์ | agent-governance-dotnet/README.md |
| OWASP ์ปค๋ฒ๋ฆฌ์ง ๋งต | ../../docs/compliance/owasp-agentic-top10-architecture.md |
| ํ๋ ์์ํฌ ํตํฉ ๊ฐ์ด๋ | agent-governance-python/agent-os/src/agent_os/integrations/ |
| ์์ ์ ํ๋ฆฌ์ผ์ด์ | agent-governance-python/agent-os/examples/ |
| ๊ธฐ์ฌํ๊ธฐ | CONTRIBUTING.md |
| ๋ณ๊ฒฝ ์ด๋ ฅ | CHANGELOG.md |
๋ณธ ๊ฐ์ด๋๋ @davidequarracino ๋์ด ์์ฑํ์ ์ด๊ธฐ ํต ์คํํธ ๋ฌธ์๋ค(#106, #108)์ ๋ฐํ์ผ๋ก ์์ฑ๋์์ต๋๋ค.