|
| 1 | +# Quickstart: Agno + DCP-AI |
| 2 | + |
| 3 | +[Agno](https://www.agno.com/) is a Python framework and runtime for building AI agents. The [`agno-dcp`](https://github.com/dcp-ai-protocol/agno-dcp) integration wraps Agno's `Agent`, `Team`, `Workflow`, and MCP primitives with the full DCP-AI governance stack: cryptographic identity (DCP-01), signed policy gating (DCP-02), tamper-evident audit (DCP-03), and signed inter-agent messaging (DCP-04). |
| 4 | + |
| 5 | +Unlike the other Python integrations (`dcp-ai[fastapi]`, `dcp-ai[langchain]`, ...), `agno-dcp` ships as a **separate package** because it depends on Agno as a peer dependency. The cryptographic primitives are imported from `dcp-ai>=2.8.1` so bundles produced by `agno-dcp` are byte-exact compatible with every DCP-AI verifier. |
| 6 | + |
| 7 | +The full source, end-to-end design notes, and API reference live in the dedicated repository: <https://github.com/dcp-ai-protocol/agno-dcp>. This page is a 60-second onramp. |
| 8 | + |
| 9 | +--- |
| 10 | + |
| 11 | +## Install |
| 12 | + |
| 13 | +```bash |
| 14 | +pip install agno-dcp |
| 15 | +``` |
| 16 | + |
| 17 | +For production with Postgres-backed storage: |
| 18 | + |
| 19 | +```bash |
| 20 | +pip install "agno-dcp[postgres]" |
| 21 | +``` |
| 22 | + |
| 23 | +Requires Python 3.11+. Agno itself is a peer dependency; install your preferred Agno version separately. |
| 24 | + |
| 25 | +--- |
| 26 | + |
| 27 | +## Wrap an Agno agent |
| 28 | + |
| 29 | +```python |
| 30 | +import asyncio |
| 31 | + |
| 32 | +from agno_dcp import ( |
| 33 | + DCPAgent, |
| 34 | + PolicyEngine, |
| 35 | + MerkleAuditChain, |
| 36 | + SQLiteStorage, |
| 37 | +) |
| 38 | + |
| 39 | + |
| 40 | +async def main() -> None: |
| 41 | + # 1. Storage and audit chain (DCP-03) |
| 42 | + storage = SQLiteStorage("./agent.db") |
| 43 | + audit = MerkleAuditChain(storage=storage) |
| 44 | + |
| 45 | + # 2. Policy engine from a YAML file (DCP-02) |
| 46 | + policy = PolicyEngine.from_yaml("policies.yaml") |
| 47 | + |
| 48 | + # 3. Wrap an Agno Agent |
| 49 | + agent = DCPAgent( |
| 50 | + # Native Agno arguments (forwarded as-is) |
| 51 | + name="Collections Agent", |
| 52 | + model="claude:sonnet-4", |
| 53 | + tools=[crm_lookup, payment_plan_offer], |
| 54 | + instructions="You help customers reschedule overdue invoices.", |
| 55 | + # DCP-AI governance arguments |
| 56 | + dcp_human_principal="ops@example.com", |
| 57 | + dcp_security_tier="tier-3", |
| 58 | + dcp_audit_chain=audit, |
| 59 | + dcp_policy_engine=policy, |
| 60 | + dcp_strict_mode=True, |
| 61 | + ) |
| 62 | + await agent.dcp_initialize() |
| 63 | + |
| 64 | + # 4. Run a tool through the full DCP-AI pipeline: |
| 65 | + # intent + policy gate + tool execution + audit |
| 66 | + result = await agent.run_tool( |
| 67 | + crm_lookup, |
| 68 | + {"customer_id": 12345}, |
| 69 | + ) |
| 70 | + |
| 71 | + # 5. Periodically seal a tamper-evident root signature |
| 72 | + root = await audit.seal_root() |
| 73 | + print(f"Sealed Merkle root: {root.root_hash}, entries: {root.entry_count}") |
| 74 | + |
| 75 | + |
| 76 | +asyncio.run(main()) |
| 77 | +``` |
| 78 | + |
| 79 | +The corresponding `policies.yaml`: |
| 80 | + |
| 81 | +```yaml |
| 82 | +version: "1.0" |
| 83 | +default: deny |
| 84 | +rules: |
| 85 | + - name: "Allow CRM lookups" |
| 86 | + when: |
| 87 | + action_type: tool_call |
| 88 | + tool_name: crm_lookup |
| 89 | + then: allow |
| 90 | + |
| 91 | + - name: "Limit payment discounts" |
| 92 | + when: |
| 93 | + action_type: tool_call |
| 94 | + tool_name: payment_plan_offer |
| 95 | + payload.discount_pct: |
| 96 | + gt: 20 |
| 97 | + then: deny |
| 98 | + reason: "Discounts above 20% require human approval" |
| 99 | +``` |
| 100 | +
|
| 101 | +The matcher supports dotted paths (`payload.discount_pct`) and the operators `eq`, `ne`, `gt`, `gte`, `lt`, `lte`, `in`, `nin`. The first matching rule wins; if none match, the `default` verdict applies. |
| 102 | + |
| 103 | +--- |
| 104 | + |
| 105 | +## What `run_tool` does under the hood |
| 106 | + |
| 107 | +``` |
| 108 | +DCPAgent.run_tool(tool, args) |
| 109 | + ├── 1. Build and sign IntentDeclaration with the agent's keypair |
| 110 | + ├── 2. PolicyGate.evaluate |
| 111 | + │ ├── verify intent signature |
| 112 | + │ ├── PolicyEngine.evaluate -> signed PolicyDecision |
| 113 | + │ ├── persist intent + decision |
| 114 | + │ └── append INTENT_DECLARED + POLICY_DECISION audit events |
| 115 | + ├── 3. If deny + strict_mode -> raise PolicyDenied |
| 116 | + ├── 4. Execute tool (sync or async) |
| 117 | + ├── 5. Append TOOL_EXECUTED (or ERROR) audit event |
| 118 | + └── 6. Return tool result |
| 119 | +``` |
| 120 | +
|
| 121 | +Strict vs observation mode: |
| 122 | +
|
| 123 | +* `dcp_strict_mode=True`: a deny verdict raises `PolicyDenied` and the tool does not run. |
| 124 | +* `dcp_strict_mode=False` (default): the deny is logged and audited, but the tool still runs. Useful for onboarding when you want audit trails before you have policy coverage. |
| 125 | +
|
| 126 | +--- |
| 127 | +
|
| 128 | +## Teams and workflows |
| 129 | +
|
| 130 | +```python |
| 131 | +from agno_dcp import DCPTeam, DCPWorkflow |
| 132 | +
|
| 133 | +team = DCPTeam( |
| 134 | + dcp_team_name="Collections + Risk", |
| 135 | + dcp_human_principal="ops@example.com", |
| 136 | + members=[collections_agent, risk_agent], |
| 137 | + dcp_audit_chain=audit, # shared chain across the team |
| 138 | +) |
| 139 | +await team.dcp_initialize() |
| 140 | +
|
| 141 | +workflow = DCPWorkflow( |
| 142 | + dcp_workflow_id="escalation", |
| 143 | + dcp_human_principal="ops@example.com", |
| 144 | + dcp_audit_chain=audit, |
| 145 | + dcp_strict_mode=True, |
| 146 | +) |
| 147 | +await workflow.dcp_initialize() |
| 148 | +result = await workflow.run_step("evaluate_credit", evaluate_credit_fn, {"amount": 5000}) |
| 149 | +``` |
| 150 | + |
| 151 | +Both wrappers reuse the team's audit chain so an external auditor sees a coherent ordering of agent actions and team coordination. |
| 152 | + |
| 153 | +--- |
| 154 | + |
| 155 | +## Verify an audit chain offline |
| 156 | + |
| 157 | +```bash |
| 158 | +agno-dcp verify --sqlite ./agent.db |
| 159 | +agno-dcp verify --postgres-url $DATABASE_URL --agent-id agent:abc123 --range 0:1000 |
| 160 | +``` |
| 161 | + |
| 162 | +The CLI walks the chain, recomputes every `entry_hash`, validates the `prev_hash` linkage, and verifies the embedded signature on every sealed Merkle root. Exits non-zero on corruption. |
| 163 | + |
| 164 | +--- |
| 165 | + |
| 166 | +## Compliance bundle export |
| 167 | + |
| 168 | +For auditor handoff, ship a signed ZIP: |
| 169 | + |
| 170 | +```python |
| 171 | +from pathlib import Path |
| 172 | +from agno_dcp import ComplianceBundleExporter |
| 173 | + |
| 174 | +exporter = ComplianceBundleExporter(audit, storage) |
| 175 | +zip_path = await exporter.export( |
| 176 | + framework="eu_ai_act", # or "nist_ai_rmf" |
| 177 | + output_dir=Path("./bundles"), |
| 178 | +) |
| 179 | +``` |
| 180 | + |
| 181 | +The archive contains the audit log in index order, every sealed Merkle root, the relevant Citizenship Bundles, and the framework mapping (EU AI Act articles 12, 13, 14, 15, 50, or NIST AI RMF Govern/Map/Measure/Manage subcategories). The whole archive is signed with the audit chain's keypair so an auditor detects tampering between export and review. |
| 182 | + |
| 183 | +--- |
| 184 | + |
| 185 | +## Production deployment |
| 186 | + |
| 187 | +Swap `SQLiteStorage` for `PostgresStorage` and the application code stays identical: |
| 188 | + |
| 189 | +```python |
| 190 | +from agno_dcp import PostgresStorage # requires the [postgres] extra |
| 191 | + |
| 192 | +storage = PostgresStorage("postgresql+psycopg://user:pass@host/db") |
| 193 | +await storage.initialize() |
| 194 | +audit = MerkleAuditChain(storage=storage) |
| 195 | +``` |
| 196 | + |
| 197 | +The bundled idempotent schema (`agno_dcp/storage/schema.sql`) reuses the same database that hosts Agno's own tables; the `dcp_*` prefix on every table avoids collisions. |
| 198 | + |
| 199 | +--- |
| 200 | + |
| 201 | +## Status |
| 202 | + |
| 203 | +`agno-dcp v0.1.0` (April 2026) is an **early access** release. Suitable for evaluation, demo work, and internal pilots. End-to-end demo, AWS / GCP KMS key custody, and DCP-05 through DCP-09 (lifecycle, succession, dispute, rights, delegation) are scheduled for future minor releases. |
| 204 | + |
| 205 | +Status of the package on the registries: |
| 206 | + |
| 207 | +* PyPI: <https://pypi.org/project/agno-dcp/> |
| 208 | +* Source: <https://github.com/dcp-ai-protocol/agno-dcp> |
| 209 | +* CI status: visible on the GitHub Actions tab of the repo. |
| 210 | + |
| 211 | +--- |
| 212 | + |
| 213 | +## Further reading |
| 214 | + |
| 215 | +* [agno-dcp README](https://github.com/dcp-ai-protocol/agno-dcp#readme) for the full quickstart and comparison table. |
| 216 | +* [agno-dcp `docs/why.md`](https://github.com/dcp-ai-protocol/agno-dcp/blob/main/docs/why.md) for the pitch (when to adopt it, when not to). |
| 217 | +* [agno-dcp `docs/architecture.md`](https://github.com/dcp-ai-protocol/agno-dcp/blob/main/docs/architecture.md) for the layered diagram and hook semantics. |
| 218 | +* [agno-dcp `docs/compliance_mapping.md`](https://github.com/dcp-ai-protocol/agno-dcp/blob/main/docs/compliance_mapping.md) for the EU AI Act and NIST AI RMF mappings. |
| 219 | +* [DCP-AI v2.0 spec](DCP-AI-v2.0.md) for the protocol-level normative reference. |
0 commit comments