AI Agent 宪章编写与策略引擎指南
⚠️ No-Go Disclaimer: MSGChain 主网裁决为 No-Go。本文件所有内容反映的是开发阶段的技术设计,不代表主网未独立核验上线状态。生产部署状态请以白皮书为准:https://msgchain.org/whitepaper/
目录
1. 概述
1.1 为什么AI Agent需要宪章
AI Agent在去中心化网络中自主执行操作时,面临三大核心挑战:
- 安全性:如何防止Agent被恶意利用或执行越权操作?
- 可预测性:如何确保Agent的行为在已知边界内可被信赖?
- 问责性:当Agent出错时,如何追溯和追责?
ai_agent_constitution_v1(AI Agent宪章)正是为解决这些问题而设计的CosmWasm智能合约。它将一份可读、可验证的结构化文档——宪章(Constitution)——绑定到Agent上,作为Agent所有行为的最高准则。
1.2 宪章作为Agent的操作系统
类比人类社会的宪法,AI Agent宪章定义了:
| 类比 | 人类宪法 | AI Agent宪章 |
|---|---|---|
| 立国文件 | 序言、原则 | Preamble(宗旨)、Values(价值观) |
| 权力范围 | 三权分立、权限 | Rights(权利) |
| 责任义务 | 纳税、兵役 | Obligations(义务) |
| 禁止事项 | 宪法修正案限制 | Constraints(约束) |
| 修宪程序 | 国会三分之二多数 | Governance(治理规则) |
Agent的每一次行动——转账、签名、数据访问、跨链通信——都必须在宪章允许的范围内执行。
1.3 ai_agent_constitution_v1 合约
- 合约包路径:
contracts/cosmwasm/all/ai_agent_constitution_v1/ - 实现状态:
部分实现(Partial Implementation) - 链ID:
msg-chain-1 - Bech32前缀:
msg - Gas模型: 1,000,000,000 attoMSG/gas
- 出块时间: 5秒
合约属于MSG Chain上31个CosmWasm合约包之一,与以下合约协同工作:
| 合约 | 包路径 | 用途 |
|---|---|---|
ai_agent_constitution_v1 |
contracts/cosmwasm/all/ai_agent_constitution_v1/ |
宪章存储与规则执行 |
dao_governance_v1 |
contracts/cosmwasm/all/dao_governance_v1/ |
DAO投票与财政管理 |
agent_registry_v1 |
contracts/cosmwasm/all/agent_registry_v1/ |
Agent注册与能力声明 |
1.4 知识图谱模块
MSG Chain知识图谱提供了以下与Agent宪章相关的模块(HTML运行时):
| 模块 | 功能 |
|---|---|
ai_agent.html |
AI Agent运行时模块 |
ai_agent_constitution.html |
宪章管理模块 |
ai_agent_governance.html |
Agent治理模块 |
agent_governance_dao.html |
Agent与DAO交互模块 |
检索提示:使用主题 AI Agent,配合推荐标签和模块,可获取宪章编写和规则执行的完整查询能力。
1.5 本指南覆盖的范围
- 宪章文档的结构和JSON Schema
- 策略规则语法(allow / deny / require / prioritize)
- 宪章的链上注册与部署
- 策略引擎的预执行、运行时、后审计三阶段模型
- 5个即用模板
- DAO治理集成与宪法修订
- 兼容性检查与错误处理
- 完整可运行的TypeScript + Python示例
2. 宪章结构
2.1 宪章文档顶层结构
一份宪章(Constitution)是一个JSON文档,包含以下顶层字段:
{
"version": "1.0.0",
"name": "宪章名称",
"agent_id": "agent-唯一标识",
"preamble": {
// 宗旨、原则
},
"rights": [
// 权利声明
],
"obligations": [
// 义务声明
],
"constraints": [
// 约束与禁止
],
"rules": [
// 策略规则(核心)
],
"governance": {
// 治理与修订规则
},
"metadata": {
// 元数据
}
}
2.2 Preamble(序言)
序言定义Agent的宗旨、价值观和适用的法域范围。
{
"preamble": {
"purpose": "执行跨链套利交易,维护市场效率",
"values": [
"透明性:所有交易记录公开可查",
"安全性:不参与任何rug-pull或蜜罐交易",
"中立性:不歧视任何交易对手"
],
"jurisdiction": "msg-chain-1",
"binding_scope": "all_actions",
"effective_date": "2026-01-01T00:00:00Z",
"expiry_date": "2027-01-01T00:00:00Z"
}
}
| 字段 | 类型 | 说明 |
|---|---|---|
purpose |
String | Agent的核心目标 |
values |
String[] | 价值观列表 |
jurisdiction |
String | 适用的链ID,可以是多链(逗号分隔) |
binding_scope |
Enum | all_actions / financial_only / data_only |
effective_date |
ISO8601 | 生效日期 |
expiry_date |
ISO8601 | 过期日期(可选) |
2.3 Rights(权利声明)
声明Agent被授权执行的操作类型。每个权利包括操作范围、资源和限制。
{
"rights": [
{
"id": "right-transfer",
"name": "转账权限",
"description": "允许在MSG Chain上执行代币转账",
"resources": ["fund:umsg", "fund:usdt"],
"operations": ["bank.transfer", "bank.send"],
"limits": {
"max_per_tx": "10000000000",
"max_per_day": "500000000000",
"max_per_month": "10000000000000"
},
"requires_approval": false
},
{
"id": "right-swap",
"name": "DEX交易权限",
"description": "允许在授权DEX进行代币兑换",
"resources": ["fund:umsg", "fund:uosmo"],
"operations": ["dex.swap", "dex.add_liquidity", "dex.remove_liquidity"],
"allowed_contracts": [
"msg1qypqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq"
],
"limits": {
"max_slippage": "0.05",
"max_trades_per_block": 3
}
}
]
}
| 字段 | 类型 | 说明 |
|---|---|---|
id |
String | 权利唯一标识符 |
resources |
String[] | 允许操作的资产或资源类型(resource_type:denom) |
operations |
String[] | 允许的操作标识符(module.operation) |
limits |
Object | 量化限制 |
allowed_contracts |
String[] | 允许交互的合约地址白名单 |
requires_approval |
Boolean | 是否需要人类审批 |
2.4 Obligations(义务声明)
定义Agent必须执行的义务,包括定期报告、合规检查等。
{
"obligations": [
{
"id": "obl-reporting",
"name": "定期报告义务",
"description": "每24小时向治理合约提交操作报告",
"frequency": "every_24h",
"action": "governance.submit_report",
"params": {
"report_type": "operations_summary",
"include_fields": ["tx_count", "volume", "errors"]
},
"grace_period": "3600",
"penalty": {
"type": "fee",
"amount": "10000000"
}
},
{
"id": "obl-audit-log",
"name": "审计日志记录",
"description": "所有操作必须在链下保存审计日志至少90天",
"retention_days": 90,
"storage_type": "ipfs",
"verification_method": "merkle_root_submission"
}
]
}
2.5 Constraints(约束与禁止)
明确定义Agent被禁止执行的操作。
{
"constraints": [
{
"id": "const-no-blacklist",
"name": "禁止向黑名单地址转账",
"description": "禁止向OFAC或链上黑名单地址发起任何转账",
"type": "absolute_deny",
"condition": {
"op": "in_list",
"args": ["{{tx.recipient}}", "{{external.blacklist}}"]
},
"action": "revert",
"severity": "critical"
},
{
"id": "const-no-leverage",
"name": "禁止杠杆交易",
"description": "禁止使用任何借贷协议进行杠杆头寸",
"type": "absolute_deny",
"condition": {
"op": "any",
"args": [
{ "op": "eq", "args": ["{{tx.module}}", "lending"] },
{ "op": "eq", "args": ["{{tx.operation}}", "borrow"] }
]
},
"action": "revert"
},
{
"id": "const-no-selfdestruct",
"name": "禁止自毁操作",
"description": "禁止调用合约的自毁方法",
"type": "absolute_deny",
"condition": {
"op": "eq",
"args": ["{{tx.message_type}}", "wasm.WasmMsg.Clear"]
},
"action": "revert"
}
]
}
2.6 Governance(治理规则)
规定宪章如何被修订。
{
"governance": {
"amendment_policy": "dao_vote",
"dao_contract": "msg1dao...",
"voting_config": {
"pass_threshold": "0.6667",
"min_voting_period": "604800",
"quorum": "0.334",
"proposal_deposit": "10000000000"
},
"emergency_override": {
"allowed": true,
"approvers": ["msg1emergency..."],
"threshold": 2
},
"version_history": [
{
"version": "1.0.0",
"approved_by": "proposal-42",
"approved_at": "2026-01-01T00:00:00Z",
"change_summary": "初始版本"
}
]
}
}
2.7 完整JSON Schema
以下是宪章文档的完整JSON Schema(草案2020-12):
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "AI Agent Constitution",
"description": "MSG Chain AI Agent 宪章文档 Schema",
"type": "object",
"properties": {
"version": {
"type": "string",
"pattern": "^\\d+\\.\\d+\\.\\d+$",
"description": "宪章文档版本号(语义化版本)"
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 128,
"description": "宪章名称"
},
"agent_id": {
"type": "string",
"description": "Agent唯一标识符"
},
"preamble": {
"type": "object",
"properties": {
"purpose": { "type": "string", "maxLength": 2048 },
"values": {
"type": "array",
"items": { "type": "string", "maxLength": 256 }
},
"jurisdiction": { "type": "string" },
"binding_scope": {
"type": "string",
"enum": ["all_actions", "financial_only", "data_only", "communication_only"]
},
"effective_date": { "type": "string", "format": "date-time" },
"expiry_date": { "type": "string", "format": "date-time" }
},
"required": ["purpose", "jurisdiction", "binding_scope"]
},
"rights": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": { "type": "string" },
"name": { "type": "string" },
"description": { "type": "string" },
"resources": {
"type": "array",
"items": { "type": "string", "pattern": "^[a-z]+:.*$" }
},
"operations": { "type": "array", "items": { "type": "string" } },
"allowed_contracts": {
"type": "array",
"items": { "type": "string", "pattern": "^msg1[a-z0-9]{38,58}$" }
},
"limits": {
"type": "object",
"properties": {
"max_per_tx": { "type": "string", "pattern": "^[0-9]+$" },
"max_per_day": { "type": "string", "pattern": "^[0-9]+$" },
"max_per_month": { "type": "string", "pattern": "^[0-9]+$" }
}
},
"requires_approval": { "type": "boolean" }
},
"required": ["id", "name", "operations"]
}
},
"obligations": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": { "type": "string" },
"name": { "type": "string" },
"description": { "type": "string" },
"frequency": {
"type": "string",
"enum": ["every_1h", "every_6h", "every_12h", "every_24h", "every_7d", "every_30d"]
},
"action": { "type": "string" },
"grace_period": { "type": "string", "pattern": "^[0-9]+$" },
"penalty": {
"type": "object",
"properties": {
"type": { "type": "string", "enum": ["fee", "suspend", "terminate"] },
"amount": { "type": "string", "pattern": "^[0-9]+$" }
}
}
},
"required": ["id", "name", "action"]
}
},
"constraints": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": { "type": "string" },
"name": { "type": "string" },
"description": { "type": "string" },
"type": { "type": "string", "enum": ["absolute_deny", "conditional_deny"] },
"condition": {
"type": "object",
"properties": {
"op": { "type": "string" },
"args": { "type": "array" }
},
"required": ["op", "args"]
},
"action": { "type": "string", "enum": ["revert", "warn", "escalate"] },
"severity": { "type": "string", "enum": ["low", "medium", "high", "critical"] }
},
"required": ["id", "name", "type", "condition", "action"]
}
},
"rules": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": { "type": "string" },
"type": { "type": "string", "enum": ["allow", "deny", "require", "prioritize"] },
"condition": {
"type": "object",
"properties": {
"op": { "type": "string" },
"args": { "type": "array" }
},
"required": ["op", "args"]
},
"action": {
"type": "string",
"enum": ["allow_continue", "deny_revert", "warn_continue", "escalate", "log_only"]
},
"priority": { "type": "integer", "minimum": 0, "maximum": 100 },
"description": { "type": "string" },
"scope": { "type": "string", "enum": ["global", "per_operation", "per_interaction"] },
"rate_limit": {
"type": "object",
"properties": {
"max_calls": { "type": "integer" },
"window_seconds": { "type": "integer" }
}
}
},
"required": ["id", "type", "condition", "action"]
}
},
"governance": {
"type": "object",
"properties": {
"amendment_policy": { "type": "string", "enum": ["dao_vote", "multisig", "owner_only", "immutable"] },
"dao_contract": { "type": "string" },
"voting_config": {
"type": "object",
"properties": {
"pass_threshold": { "type": "string" },
"min_voting_period": { "type": "string" },
"quorum": { "type": "string" },
"proposal_deposit": { "type": "string" }
}
},
"emergency_override": {
"type": "object",
"properties": {
"allowed": { "type": "boolean" },
"approvers": { "type": "array", "items": { "type": "string" } },
"threshold": { "type": "integer" }
}
},
"version_history": {
"type": "array",
"items": {
"type": "object",
"properties": {
"version": { "type": "string" },
"approved_by": { "type": "string" },
"approved_at": { "type": "string", "format": "date-time" },
"change_summary": { "type": "string" }
},
"required": ["version", "change_summary"]
}
}
},
"required": ["amendment_policy"]
},
"metadata": {
"type": "object",
"properties": {
"author": { "type": "string" },
"created_at": { "type": "string", "format": "date-time" },
"updated_at": { "type": "string", "format": "date-time" },
"tags": { "type": "array", "items": { "type": "string" } },
"description": { "type": "string" }
}
}
},
"required": ["version", "name", "agent_id", "preamble", "rules", "governance"]
}
2.8 版本与迁移
宪章使用语义化版本号 MAJOR.MINOR.PATCH:
- PATCH(例如 1.0.0 → 1.0.1):非实质性变更,修复拼写、文档澄清,无需DAO投票
- MINOR(例如 1.0.0 → 1.1.0):新增规则或权利,不削弱现有约束,需DAO简单多数
- MAJOR(例如 1.0.0 → 2.0.0):重大修订,变更核心约束,需DAO三分之二绝对多数
合约中存储的宪章版本与Agent注册时声明的版本必须一致,否则注册会被拒绝。
3. 策略规则语法
3.1 规则类型
策略引擎支持四种核心规则类型:
| 类型 | 含义 | 用途 |
|---|---|---|
allow |
在特定条件下允许操作 | 授予明确的许可 |
deny |
在特定条件下拒绝操作 | 明确禁止 |
require |
要求操作满足特定条件 | 前置条件检查 |
prioritize |
优先选择符合条件的操作 | 路由和排序 |
规则类型决定了引擎的评估逻辑:
allow → 条件范围内放行(但其他 deny 仍可覆盖)
deny → 条件范围内直接拦截(最高优先级)
require → 不满足条件则拦截(类似deny但语义为必要条件)
prioritize → 不影响放行与否,仅影响排序
3.2 规则条件(Condition DSL)
条件使用一个简单的DSL(领域特定语言),基于操作符和参数构建:
基础操作符:
| 操作符 | 含义 | 示例 |
|---|---|---|
eq |
等于 | {"op": "eq", "args": ["{{tx.amount}}", "1000"]} |
neq |
不等于 | {"op": "neq", "args": ["{{tx.recipient}}", "{{agent.address}}"]} |
gt |
大于 | {"op": "gt", "args": ["{{tx.amount}}", "0"]} |
gte |
大于等于 | {"op": "gte", "args": ["{{tx.gas_limit}}", "500000"]} |
lt |
小于 | {"op": "lt", "args": ["{{tx.amount}}", "1000000000"]} |
lte |
小于等于 | {"op": "lte", "args": ["{{tx.fee}}", "50000"]} |
逻辑操作符:
| 操作符 | 含义 | 示例 |
|---|---|---|
and |
与 | {"op": "and", "args": [cond1, cond2]} |
or |
或 | {"op": "or", "args": [cond1, cond2]} |
not |
非 | {"op": "not", "args": [cond]} |
any |
任一为真 | {"op": "any", "args": [cond1, cond2, cond3]} |
all |
全部为真 | {"op": "all", "args": [cond1, cond2, cond3]} |
集合操作符:
| 操作符 | 含义 | 示例 |
|---|---|---|
in_list |
值在列表内 | {"op": "in_list", "args": ["{{tx.recipient}}", "{{external.whitelist}}"]} |
not_in_list |
值不在列表内 | {"op": "not_in_list", "args": ["{{tx.recipient}}", "{{external.blacklist}}"]} |
contains |
包含子串 | {"op": "contains", "args": ["{{tx.memo}}", "\\u5408\\u89c4\\u6807\\u8bc6"]} |
matches |
正则匹配 | {"op": "matches", "args": ["{{tx.memo}}", "^合规-\\\\d{4}$"]} |
时间操作符:
| 操作符 | 含义 | 示例 |
|---|---|---|
before |
在时间点前 | {"op": "before", "args": ["{{block.time}}", "2026-06-01T00:00:00Z"]} |
after |
在时间点后 | {"op": "after", "args": ["{{block.time}}", "{{preamble.effective_date}}"]} |
within |
在时间窗口内 | {"op": "within", "args": ["08:00", "20:00", "{{block.time}}"]} |
3.3 变量插值
条件中的 {{...}} 语法用于变量插值,引擎在执行时替换为实际值:
| 变量 | 来源 | 说明 |
|---|---|---|
{{tx.sender}} |
当前交易 | 交易发送方地址 |
{{tx.recipient}} |
当前交易 | 交易接收方地址 |
{{tx.amount}} |
当前交易 | 交易金额(字符串) |
{{tx.denom}} |
当前交易 | 代币单位 |
{{tx.module}} |
当前交易 | Cosmos模块名 |
{{tx.operation}} |
当前交易 | 模块内操作名 |
{{tx.memo}} |
当前交易 | 交易备注 |
{{tx.fee}} |
当前交易 | 交易手续费 |
{{tx.gas_limit}} |
当前交易 | Gas限制 |
{{tx.message_type}} |
当前交易 | 消息类型 |
{{block.time}} |
区块链状态 | 当前区块时间 |
{{block.height}} |
区块链状态 | 当前区块高度 |
{{agent.address}} |
Agent注册信息 | Agent的MSG Chain地址 |
{{agent.id}} |
Agent注册信息 | Agent的唯一ID |
{{agent.balance}} |
Agent注册信息 | Agent当前余额 |
{{external.blacklist}} |
外部数据源 | 全球黑名单 |
{{external.whitelist}} |
外部数据源 | 白名单列表 |
{{external.price}} |
外部数据源 | 当前价格预言机数据 |
{{external.volatility}} |
外部数据源 | 当前市场波动率指标 |
{{state.self_count}} |
Agent运行时状态 | 当前Agent累计操作计数 |
{{state.self_volume}} |
Agent运行时状态 | 当前Agent累计操作金额 |
{{state.today_count}} |
Agent运行时状态 | 当日操作计数 |
{{state.today_volume}} |
Agent运行时状态 | 当日累计金额 |
3.4 规则作用域(Scope)
每条规则可以具有不同的作用域:
{
"scope": "global",
"scope": "per_operation",
"scope": "per_interaction"
}
| 作用域 | 评估时机 | 生命期 | 示例 |
|---|---|---|---|
global |
每次操作 | 永久有效 | "禁止向黑名单转账" |
per_operation |
单次操作中 | 本次操作结束 | "检查滑点不超过5%" |
per_interaction |
Agent交互期间 | 交互会话结束 | "单次交互最多3笔交易" |
3.5 资源类型
规则中引用的资源使用 type:identifier 格式:
fund:umsg → MSG Chain原生代币
fund:usdt → USDT代币
fund:* → 所有代币
data:user_pii → 用户个人身份信息
data:market → 市场数据
data:contract → 合约代码数据
compute:exec → 计算资源(执行)
compute:query → 计算资源(查询)
communication:a2a → Agent间通信
communication:oracle → 预言机通信
3.6 时间相关规则
速率限制(Rate Limits):
{
"id": "rate-limit-tx",
"type": "require",
"condition": {
"op": "lte",
"args": ["{{state.today_count}}", "100"]
},
"action": "allow_continue",
"rate_limit": {
"max_calls": 100,
"window_seconds": 86400
},
"description": "每日最多100笔交易"
}
时间窗口限制:
{
"id": "time-window-trade",
"type": "allow",
"condition": {
"op": "within",
"args": ["09:00:00", "17:00:00", "{{block.time}}"]
},
"action": "allow_continue",
"description": "仅在美股交易时段执行交易"
}
截止日期:
{
"id": "deadline-obligation",
"type": "require",
"condition": {
"op": "and",
"args": [
{
"op": "before",
"args": ["{{block.time}}", "{{preamble.expiry_date}}"]
},
{
"op": "after",
"args": ["{{block.time}}", "{{preamble.effective_date}}"]
}
]
},
"action": "allow_continue",
"description": "仅在宪章有效期内允许操作"
}
3.7 多Agent协调规则
Agent间的交互可以通过宪章规则进行约束:
{
"id": "coord-max-peers",
"type": "require",
"condition": {
"op": "lte",
"args": ["{{state.coord.peer_count}}", "10"]
},
"action": "allow_continue",
"scope": "per_interaction",
"description": "单次协调最多与10个Agent通信"
},
{
"id": "coord-approval-threshold",
"type": "require",
"condition": {
"op": "gte",
"args": ["{{state.coord.approval_count}}", "3"]
},
"action": "allow_continue",
"scope": "per_interaction",
"description": "协调操作需要至少3个Agent批准"
},
{
"id": "coord-tx-limit",
"type": "deny",
"condition": {
"op": "gt",
"args": ["{{state.coord.total_tx}}", "50"]
},
"action": "deny_revert",
"description": "协调会话中最多50笔联合交易"
}
3.8 完整规则定义示例
{
"id": "rule-max-tx-amount",
"type": "require",
"condition": {
"op": "lt",
"args": ["{{tx.amount}}", "1000000000"]
},
"action": "allow_continue",
"priority": 10,
"scope": "global",
"description": "单笔交易金额不得超过1000 MSG",
"violation_handling": {
"max_attempts": 3,
"cool_down": 300,
"escalation_path": "governance"
}
}
3.9 规则优先级
规则按照 priority 字段排序,从高到低(0=最低,100=最高):
高优先级 (80-100): 安全规则、合规规则 → 必须最先评估
中优先级 (30-79): 业务规则、费用控制 → 正常评估
低优先级 (0-29): 建议规则、排序优化 → 最后评估
相同优先级的规则按照 type 排序:deny → require → allow → prioritize。
3.10 规则评估逻辑
对每个操作:
1. 筛选作用域为 global + 当前作用域的规则
2. 按优先级降序排序
3. 遍历每条规则:
a. 评估 condition
b. 如果 condition == true:
- deny → 立即拒绝,记录违反
- require → 通过,继续
- allow → 标记为允许,继续(其他 deny 仍可拦截)
- prioritize → 更新排序分数
c. 如果 condition == false:
- deny → 不触发
- require → 拒绝(必要条件不满足)
- allow → 不触发
- prioritize → 不触发
4. 如果没有 deny 触发且所有 require 满足 → 允许执行
5. 否则 → 拒绝执行
4. 宪章注册与部署
4.1 部署架构
+------------------+ +------------------------+
| 开发者/用户 | | ai_agent_constitution_v1 |
| 编写宪章JSON +------> 合约实例 |
| 签名并提交 | | - 存储宪章文档 |
+------------------+ | - 验证签名 |
| - 版本管理 |
+----------+-------------+
|
+----------v-------------+
| agent_registry_v1 |
| - Agent注册 |
| - 宪章哈希绑定 |
| - 能力声明 |
+------------------------+
4.2 先决条件
- Node.js >= 18 或 Python >= 3.10
@cosmjs/cosmwasm-stargate(TypeScript) 或cosmpy(Python)- MSG Chain RPC节点(例如
https://rpc.msg-chain-1.msgchain.zone) - 有足够
umsg余额的密钥
4.3 TypeScript 部署完整流程
4.3.1 安装依赖
npm install @cosmjs/cosmwasm-stargate @cosmjs/stargate @cosmjs/proto-signing @cosmjs/encoding dotenv
4.3.2 部署宪章合约
// deploy_constitution.ts
import { SigningCosmWasmClient } from "@cosmjs/cosmwasm-stargate";
import { DirectSecp256k1HdWallet } from "@cosmjs/proto-signing";
import { GasPrice } from "@cosmjs/stargate";
import * as fs from "fs";
import * as path from "path";
const MSG_CHAIN_RPC = "https://rpc.msg-chain-1.msgchain.zone";
const MSG_CHAIN_PREFIX = "msg";
const GAS_PRICE = GasPrice.fromString("1000000000attoMSG");
async function deployConstitution() {
const mnemonic = process.env.MNEMONIC;
if (!mnemonic) {
throw new Error("需要设置 MNEMONIC 环境变量");
}
const wallet = await DirectSecp256k1HdWallet.fromMnemonic(mnemonic, {
prefix: MSG_CHAIN_PREFIX,
});
const [account] = await wallet.getAccounts();
console.log(`部署者地址: ${account.address}`);
const client = await SigningCosmWasmClient.connectWithSigner(
MSG_CHAIN_RPC,
wallet,
{ gasPrice: GAS_PRICE }
);
// 读取合约WASM字节码
const wasmPath = path.join(
__dirname, "..", "contracts", "cosmwasm", "all",
"ai_agent_constitution_v1", "artifacts", "ai_agent_constitution_v1.wasm"
);
const wasmCode = fs.readFileSync(wasmPath);
console.log("上传合约代码...");
const uploadReceipt = await client.upload(
account.address, wasmCode, "auto", "AI Agent Constitution v1"
);
console.log(`代码ID: ${uploadReceipt.codeId}`);
console.log("实例化合约...");
const instantiateMsg = { owner: account.address, version: "1.0.0" };
const { contractAddress } = await client.instantiate(
account.address, uploadReceipt.codeId, instantiateMsg,
"AI Agent Constitution Instance", "auto"
);
console.log(`合约地址: ${contractAddress}`);
return { client, contractAddress, account };
}
4.3.3 注册宪章文档
// register_constitution.ts
import { SigningCosmWasmClient } from "@cosmjs/cosmwasm-stargate";
import { DirectSecp256k1HdWallet } from "@cosmjs/proto-signing";
import { GasPrice } from "@cosmjs/stargate";
import * as crypto from "crypto";
const MSG_CHAIN_RPC = "https://rpc.msg-chain-1.msgchain.zone";
const MSG_CHAIN_PREFIX = "msg";
const GAS_PRICE = GasPrice.fromString("1000000000attoMSG");
const CONSTITUTION_CONTRACT = "msg1constitution...";
interface Constitution {
version: string;
name: string;
agent_id: string;
preamble: any;
rights: any[];
obligations: any[];
constraints: any[];
rules: any[];
governance: any;
metadata?: any;
}
function hashConstitution(constitution: Constitution): string {
const jsonStr = JSON.stringify(constitution, Object.keys(constitution).sort());
return crypto.createHash("sha256").update(jsonStr).digest("hex");
}
async function registerConstitution(constitution: Constitution) {
const mnemonic = process.env.MNEMONIC;
if (!mnemonic) throw new Error("需要设置 MNEMONIC 环境变量");
const wallet = await DirectSecp256k1HdWallet.fromMnemonic(mnemonic, {
prefix: MSG_CHAIN_PREFIX,
});
const [account] = await wallet.getAccounts();
const client = await SigningCosmWasmClient.connectWithSigner(
MSG_CHAIN_RPC, wallet, { gasPrice: GAS_PRICE }
);
const constitutionHash = hashConstitution(constitution);
console.log(`宪章哈希: ${constitutionHash}`);
const registerMsg = {
register_constitution: {
agent_id: constitution.agent_id,
constitution: constitution,
constitution_hash: constitutionHash,
signature: null,
},
};
const result = await client.execute(
account.address, CONSTITUTION_CONTRACT, registerMsg,
"auto", "注册AI Agent宪章"
);
console.log(`交易哈希: ${result.transactionHash}`);
const agentRegistryContract = "msg1registry...";
const bindMsg = {
update_agent: {
agent_id: constitution.agent_id,
constitution_hash: constitutionHash,
capabilities: constitution.rights.map((r) => r.name),
},
};
const bindResult = await client.execute(
account.address, agentRegistryContract, bindMsg,
"auto", "绑定宪章至Agent"
);
console.log(`绑定完成: ${bindResult.transactionHash}`);
return { constitutionHash, txHash: result.transactionHash };
}
4.4 Python 部署完整流程
4.4.1 安装依赖
pip install cosmpy python-dotenv
4.4.2 部署宪章合约
# deploy_constitution.py
import os, json, hashlib
from dotenv import load_dotenv
from cosmpy.aerial.client import LedgerClient
from cosmpy.aerial.wallet import LocalWallet
from cosmpy.aerial.contract import CosmWasmContract
from cosmpy.aerial.client import NetworkConfig
load_dotenv()
MSG_CHAIN_RPC = "https://rpc.msg-chain-1.msgchain.zone"
MSG_CHAIN_PREFIX = "msg"
CHAIN_ID = "msg-chain-1"
GAS_LIMIT = 3000000
def create_network_config():
return NetworkConfig(
chain_id=CHAIN_ID, url=MSG_CHAIN_RPC,
fee_minimum_gas_price=1000000000, fee_denomination="attoMSG",
staking_denomination="umsg",
)
def deploy_constitution():
mnemonic = os.getenv("MNEMONIC")
if not mnemonic:
raise ValueError("需要设置 MNEMONIC 环境变量")
wallet = LocalWallet.from_mnemonic(mnemonic, prefix=MSG_CHAIN_PREFIX)
network_config = create_network_config()
client = LedgerClient(network_config)
wasm_path = os.path.join(
os.path.dirname(__file__), "..", "contracts", "cosmwasm", "all",
"ai_agent_constitution_v1", "artifacts", "ai_agent_constitution_v1.wasm"
)
with open(wasm_path, "rb") as f:
wasm_bytes = f.read()
contract = CosmWasmContract()
upload_tx = contract.upload(wallet, wasm_bytes, client, gas_limit=GAS_LIMIT)
print(f"代码ID: {upload_tx.code_id}")
instantiate_msg = {"owner": str(wallet.address()), "version": "1.0.0"}
tx = contract.instantiate(
wallet, upload_tx.code_id, instantiate_msg,
"AI Agent Constitution Instance", client, gas_limit=GAS_LIMIT
)
print(f"合约地址: {tx.contract_address}")
return tx.contract_address, client, wallet
def hash_constitution(constitution: dict) -> str:
json_str = json.dumps(constitution, sort_keys=True, ensure_ascii=False)
return hashlib.sha256(json_str.encode()).hexdigest()
4.5 查询宪章
// query_constitution.ts
import { CosmWasmClient } from "@cosmjs/cosmwasm-stargate";
const RPC_ENDPOINT = "https://rpc.msg-chain-1.msgchain.zone";
const CONSTITUTION_CONTRACT = "msg1constitution...";
async function queryConstitution(agentId: string) {
const client = await CosmWasmClient.connect(RPC_ENDPOINT);
const queryMsg = { get_constitution: { agent_id: agentId } };
const result = await client.queryContractSmart(CONSTITUTION_CONTRACT, queryMsg);
console.log(`Agent ${agentId} 的宪章:`);
console.log(JSON.stringify(result, null, 2));
return result;
}
async function verifyConstitution(agentId: string, constitutionJson: object) {
const client = await CosmWasmClient.connect(RPC_ENDPOINT);
const queryMsg = { verify_constitution: { agent_id: agentId, constitution: constitutionJson } };
const result = await client.queryContractSmart(CONSTITUTION_CONTRACT, queryMsg);
if (result.valid) {
console.log("宪章验证通过");
} else {
console.error("宪章验证失败");
}
return result;
}
4.6 更新宪章
// update_constitution.ts
async function updateConstitution(
client: SigningCosmWasmClient, senderAddress: string,
constitutionContract: string, agentId: string,
newConstitution: Constitution, proposalId?: string
) {
const updateMsg = {
update_constitution: {
agent_id: agentId,
new_constitution: newConstitution,
new_hash: hashConstitution(newConstitution),
proposal_id: proposalId,
governance_proof: proposalId
? { proposal_id: proposalId, chain_id: "msg-chain-1" }
: null,
},
};
const result = await client.execute(
senderAddress, constitutionContract, updateMsg,
"auto", `更新Agent宪章至 v${newConstitution.version}`
);
console.log(`更新完成: ${result.transactionHash}`);
return result;
}
5. 策略引擎执行
5.1 三阶段模型
策略引擎的执行分为三个阶段:
+----------------------------------------------------------------+
| 策略引擎执行流程 |
+----------------------------------------------------------------+
| |
| 阶段1: 预执行验证 (Pre-execution) |
| +-----------------------------------------------------------+ |
| | Agent准备操作 → 策略引擎加载宪章 → 模拟评估全部规则 | |
| | → 如果违规则阻止交易提交 → 记录违反日志 | |
| +-----------------------------------------------------------+ |
| ↓ |
| 阶段2: 运行时评估 (Runtime) |
| +-----------------------------------------------------------+ |
| | 交易提交上链 → 宪章合约验证 → 链上规则检查 | |
| | → 如违规则交易revert → 违反记录上链 | |
| +-----------------------------------------------------------+ |
| ↓ |
| 阶段3: 后审计 (Post-execution Audit) |
| +-----------------------------------------------------------+ |
| | 交易确认后 → 审计模块分析 → 合规报告生成 | |
| | → 如发现违反 → 升级处理 (警告/暂停/终止) | |
| +-----------------------------------------------------------+ |
| |
+----------------------------------------------------------------+
5.2 策略引擎 TypeScript 实现
// strategy_engine.ts
import { CosmWasmClient } from "@cosmjs/cosmwasm-stargate";
type RuleType = "allow" | "deny" | "require" | "prioritize";
type RuleAction = "allow_continue" | "deny_revert" | "warn_continue" | "escalate" | "log_only";
type RuleScope = "global" | "per_operation" | "per_interaction";
type ViolationSeverity = "low" | "medium" | "high" | "critical";
type AgentStatus = "active" | "suspended" | "terminated";
interface Condition { op: string; args: any[]; }
interface RateLimit { max_calls: number; window_seconds: number; }
interface ViolationHandling { max_attempts: number; cool_down: number; escalation_path: string; }
interface Rule {
id: string; type: RuleType; condition: Condition; action: RuleAction;
priority: number; description?: string; scope?: RuleScope;
rate_limit?: RateLimit; violation_handling?: ViolationHandling;
}
interface Constitution {
version: string; name: string; agent_id: string;
preamble: any; rights: any[]; obligations: any[];
constraints: any[]; rules: Rule[]; governance: any; metadata?: any;
}
interface Action {
module: string; operation: string; sender: string;
recipient?: string; amount?: string; denom?: string;
memo?: string; fee?: string; gas_limit?: number; message_type?: string;
}
interface ExecutionContext {
block: { time: string; height: number };
agent: { address: string; id: string; balance: Record<string, string> };
state: Record<string, any>; external: Record<string, any>; action: Action;
}
interface Violation {
rule_id: string; rule_description: string; action: Action;
timestamp: string; block_height: number; severity: ViolationSeverity; details: string;
}
interface EvaluationResult {
allowed: boolean; matched_rules: Rule[]; violations: Violation[];
warnings: string[]; priority_scores?: Record<string, number>;
}
function resolveVariable(path: string, ctx: ExecutionContext): any {
const normalized = path.replace(/{{|}}/g, "");
const parts = normalized.split(".");
let current: any = ctx;
for (const part of parts) {
if (current === null || current === undefined) return undefined;
current = current[part];
}
return current;
}
function injectVariables(condition: Condition, ctx: ExecutionContext): Condition {
function inject(obj: any): any {
if (typeof obj === "string") {
if (obj.startsWith("{{") && obj.endsWith("}}")) return resolveVariable(obj, ctx);
return obj.replace(/\{\{[^}]+\}\}/g, (match) => {
const resolved = resolveVariable(match, ctx);
return resolved !== undefined ? String(resolved) : match;
});
}
if (Array.isArray(obj)) return obj.map(inject);
if (typeof obj === "object" && obj !== null) {
const result: any = {};
for (const [k, v] of Object.entries(obj)) result[k] = inject(v);
return result;
}
return obj;
}
return inject(condition) as Condition;
}
function evaluateCondition(condition: Condition, ctx: ExecutionContext): boolean {
const { op, args } = condition;
switch (op) {
case "eq": return args[0] === args[1];
case "neq": return args[0] !== args[1];
case "gt": return BigInt(args[0]) > BigInt(args[1]);
case "gte": return BigInt(args[0]) >= BigInt(args[1]);
case "lt": return BigInt(args[0]) < BigInt(args[1]);
case "lte": return BigInt(args[0]) <= BigInt(args[1]);
case "and": case "all": return args.every((arg: Condition) => evaluateCondition(arg, ctx));
case "or": case "any": return args.some((arg: Condition) => evaluateCondition(arg, ctx));
case "not": return !evaluateCondition(args[0], ctx);
case "in_list": return (args[1] as any[]).includes(args[0]);
case "not_in_list": return !(args[1] as any[]).includes(args[0]);
case "contains": return String(args[0]).includes(String(args[1]));
case "matches": return new RegExp(String(args[1])).test(String(args[0]));
case "before": return new Date(args[0]).getTime() < new Date(args[1]).getTime();
case "after": return new Date(args[0]).getTime() > new Date(args[1]).getTime();
case "within": return args[0] <= args[2] && args[2] <= args[1];
default: return false;
}
}
const rateLimitStore: Map<string, number[]> = new Map();
function checkRateLimit(rule: Rule, agentId: string): boolean {
if (!rule.rate_limit) return true;
const key = `${agentId}:${rule.id}`;
const now = Math.floor(Date.now() / 1000);
const windowStart = now - rule.rate_limit.window_seconds;
let state = rateLimitStore.get(key) || [];
state = state.filter((t) => t > windowStart);
if (state.length >= rule.rate_limit.max_calls) return false;
state.push(now);
rateLimitStore.set(key, state);
return true;
}
function evaluateRules(rules: Rule[], ctx: ExecutionContext): EvaluationResult {
const result: EvaluationResult = {
allowed: false, matched_rules: [], violations: [], warnings: [],
};
const sortedRules = [...rules].sort((a, b) => (b.priority || 0) - (a.priority || 0));
let denyTriggered = false;
let allRequireMet = true;
for (const rule of sortedRules) {
const evaluatedCondition = injectVariables(rule.condition, ctx);
const conditionMet = evaluateCondition(evaluatedCondition, ctx);
if (conditionMet) {
result.matched_rules.push(rule);
if (rule.rate_limit && !checkRateLimit(rule, ctx.agent.id)) {
result.violations.push({
rule_id: rule.id, rule_description: rule.description || "速率限制",
action: ctx.action, timestamp: ctx.block.time,
block_height: ctx.block.height, severity: "medium",
details: "速率限制超限",
});
denyTriggered = true;
continue;
}
if (rule.type === "deny") {
denyTriggered = true;
result.violations.push({
rule_id: rule.id, rule_description: rule.description || "被拒绝",
action: ctx.action, timestamp: ctx.block.time,
block_height: ctx.block.height, severity: "high",
details: `违反规则: ${rule.description}`,
});
}
} else {
if (rule.type === "require") {
allRequireMet = false;
result.violations.push({
rule_id: rule.id, rule_description: rule.description || "必要条件不满足",
action: ctx.action, timestamp: ctx.block.time,
block_height: ctx.block.height, severity: "high",
details: `必要条件不满足: ${rule.description}`,
});
}
}
}
result.allowed = !denyTriggered && allRequireMet;
return result;
}
async function preExecutionCheck(
constitution: Constitution, action: Action,
agentState: Partial<ExecutionContext>
): Promise<EvaluationResult> {
const ctx: ExecutionContext = {
block: { time: new Date().toISOString(), height: 0 },
agent: { address: agentState.agent?.address || "", id: constitution.agent_id, balance: agentState.agent?.balance || {} },
state: agentState.state || {}, external: agentState.external || {}, action,
};
const result = evaluateRules(constitution.rules, ctx);
return result;
}
const agentViolationState: Map<string, { attempts: number; status: AgentStatus }> = new Map();
function handleViolation(agentId: string, violation: Violation, config?: ViolationHandling) {
const maxAttempts = config?.max_attempts || 3;
let state = agentViolationState.get(agentId);
if (!state) { state = { attempts: 0, status: "active" }; agentViolationState.set(agentId, state); }
state.attempts++;
if (state.attempts >= maxAttempts || violation.severity === "critical") {
state.status = "suspended";
return { action: "suspend", message: `Agent ${agentId} 已被暂停` };
}
if (violation.severity === "high") return { action: "escalate", message: "违规已升级至治理方" };
return { action: "warn", message: `违反规则 ${violation.rule_id}: ${violation.details}` };
}
interface AuditReport {
agent_id: string; period_start: string; period_end: string;
total_actions: number; allowed_actions: number; denied_actions: number;
violations: Violation[]; compliance_rate: number; recommendations: string[];
}
function generateAuditReport(
constitution: Constitution,
actionLog: Array<{ action: Action; result: EvaluationResult; timestamp: string }>
): AuditReport {
const total = actionLog.length;
const allowed = actionLog.filter((l) => l.result.allowed).length;
const allViolations = actionLog.flatMap((l) => l.result.violations);
const report: AuditReport = {
agent_id: constitution.agent_id,
period_start: actionLog[0]?.timestamp || "",
period_end: actionLog[actionLog.length - 1]?.timestamp || "",
total_actions: total, allowed_actions: allowed, denied_actions: total - allowed,
violations: allViolations,
compliance_rate: total > 0 ? (allowed / total) * 100 : 100,
recommendations: [],
};
if (report.compliance_rate < 95) report.recommendations.push("合规率低于95%,建议审查宪章规则");
const criticalCount = allViolations.filter((v) => v.severity === "critical").length;
if (criticalCount > 0) report.recommendations.push(`存在 ${criticalCount} 个严重违反,建议立即暂停Agent`);
return report;
}
export {
evaluateRules, preExecutionCheck, generateAuditReport, handleViolation,
type Constitution, type Action, type EvaluationResult, type Violation, type AuditReport,
};
5.3 策略引擎 Python 实现
# strategy_engine.py
import re, time, json, hashlib
from datetime import datetime
from dataclasses import dataclass, field
from typing import Any, Optional
from enum import Enum
class RuleType(str, Enum): ALLOW = "allow"; DENY = "deny"; REQUIRE = "require"; PRIORITIZE = "prioritize"
class RuleAction(str, Enum): ALLOW_CONTINUE = "allow_continue"; DENY_REVERT = "deny_revert"; WARN_CONTINUE = "warn_continue"; ESCALATE = "escalate"; LOG_ONLY = "log_only"
class RuleScope(str, Enum): GLOBAL = "global"; PER_OPERATION = "per_operation"; PER_INTERACTION = "per_interaction"
class ViolationSeverity(str, Enum): LOW = "low"; MEDIUM = "medium"; HIGH = "high"; CRITICAL = "critical"
class AgentStatus(str, Enum): ACTIVE = "active"; SUSPENDED = "suspended"; TERMINATED = "terminated"
@dataclass
class Condition:
op: str
args: list
@dataclass
class RateLimit:
max_calls: int
window_seconds: int
@dataclass
class Rule:
id: str; type: RuleType; condition: Condition; action: RuleAction
priority: int = 0; description: str = ""; scope: RuleScope = RuleScope.GLOBAL
rate_limit: Optional[RateLimit] = None
@dataclass
class Action:
module: str; operation: str; sender: str = ""; recipient: str = ""
amount: str = "0"; denom: str = ""; memo: str = ""; fee: str = "0"; gas_limit: int = 0
@dataclass
class Violation:
rule_id: str; rule_description: str; action: Action; timestamp: str
block_height: int; severity: ViolationSeverity; details: str
@dataclass
class EvaluationResult:
allowed: bool = False; matched_rules: list = field(default_factory=list)
violations: list = field(default_factory=list); warnings: list = field(default_factory=list)
class VariableResolver:
def __init__(self, context: dict): self.context = context
def resolve(self, path: str) -> Any:
path = path.replace("{{", "").replace("}}", "")
parts = path.split(".")
current = self.context
for part in parts:
if isinstance(current, dict): current = current.get(part)
else: return None
if current is None: return None
return current
def inject(self, obj: Any) -> Any:
if isinstance(obj, str):
if obj.startswith("{{") and obj.endswith("}}"): return self.resolve(obj) or obj
def replace_var(match):
resolved = self.resolve(match.group(0))
return str(resolved) if resolved is not None else match.group(0)
return re.sub(r"\{\{[^}]+\}\}", replace_var, obj)
elif isinstance(obj, list): return [self.inject(item) for item in obj]
elif isinstance(obj, dict): return {k: self.inject(v) for k, v in obj.items()}
return obj
class ConditionEvaluator:
def __init__(self, context: dict):
self.resolver = VariableResolver(context)
self._rate_limit_store: dict = {}
def evaluate(self, condition: dict) -> bool:
condition = self.resolver.inject(condition)
op, args = condition["op"], condition["args"]
if op == "eq": return args[0] == args[1]
elif op == "neq": return args[0] != args[1]
elif op == "gt": return int(args[0]) > int(args[1])
elif op == "gte": return int(args[0]) >= int(args[1])
elif op == "lt": return int(args[0]) < int(args[1])
elif op == "lte": return int(args[0]) <= int(args[1])
elif op in ("and", "all"): return all(self.evaluate(arg) for arg in args)
elif op in ("or", "any"): return any(self.evaluate(arg) for arg in args)
elif op == "not": return not self.evaluate(args[0])
elif op == "in_list": return args[0] in args[1]
elif op == "not_in_list": return args[0] not in args[1]
elif op == "contains": return str(args[0]) in str(args[1])
elif op == "matches": return bool(re.match(str(args[1]), str(args[0])))
elif op == "before": return datetime.fromisoformat(args[0]) < datetime.fromisoformat(args[1])
elif op == "after": return datetime.fromisoformat(args[0]) > datetime.fromisoformat(args[1])
elif op == "within": return args[0] <= args[2] <= args[1]
else: raise ValueError(f"未知操作符: {op}")
def check_rate_limit(self, rule: Rule, agent_id: str) -> bool:
if not rule.rate_limit: return True
key = f"{agent_id}:{rule.id}"
now = int(time.time())
ws = now - rule.rate_limit.window_seconds
self._rate_limit_store.setdefault(key, [])
self._rate_limit_store[key] = [t for t in self._rate_limit_store[key] if t > ws]
if len(self._rate_limit_store[key]) >= rule.rate_limit.max_calls: return False
self._rate_limit_store[key].append(now)
return True
class StrategyEngine:
def __init__(self): self._violation_state: dict = {}
def evaluate(self, constitution, action: Action, agent_state: dict = None) -> EvaluationResult:
agent_state = agent_state or {}
context = {
"tx": {"sender": action.sender, "recipient": action.recipient, "amount": action.amount,
"denom": action.denom, "module": action.module, "operation": action.operation,
"memo": action.memo, "fee": action.fee, "gas_limit": action.gas_limit},
"block": {"time": datetime.utcnow().isoformat() + "Z", "height": agent_state.get("block_height", 0)},
"agent": {"address": agent_state.get("agent_address", ""), "id": constitution.agent_id,
"balance": agent_state.get("balance", {})},
"state": agent_state.get("state", {}), "external": agent_state.get("external", {}),
}
evaluator = ConditionEvaluator(context)
result = EvaluationResult()
rules = sorted(constitution.rules, key=lambda r: getattr(r, "priority", 0), reverse=True)
deny_triggered = all_require_met = False
for rule in rules:
if isinstance(rule, dict):
rule_obj = Rule(id=rule["id"], type=RuleType(rule["type"]),
condition=Condition(**rule["condition"]), action=RuleAction(rule["action"]),
priority=rule.get("priority", 0), description=rule.get("description", ""))
else: rule_obj = rule
condition_met = evaluator.evaluate(vars(rule_obj.condition))
if condition_met:
result.matched_rules.append(rule_obj)
if not evaluator.check_rate_limit(rule_obj, context["agent"]["id"]):
result.violations.append(Violation(rule_id=rule_obj.id, rule_description=rule_obj.description or "速率限制",
action=action, timestamp=context["block"]["time"], block_height=context["block"]["height"],
severity=ViolationSeverity.MEDIUM, details="速率限制超限"))
deny_triggered = True; continue
if rule_obj.type == RuleType.DENY:
deny_triggered = True
result.violations.append(Violation(rule_id=rule_obj.id, rule_description=rule_obj.description or "被拒绝",
action=action, timestamp=context["block"]["time"], block_height=context["block"]["height"],
severity=ViolationSeverity.HIGH, details=f"违反规则: {rule_obj.description}"))
else:
if rule_obj.type == RuleType.REQUIRE:
all_require_met = True
result.violations.append(Violation(rule_id=rule_obj.id, rule_description=rule_obj.description or "必要条件不满足",
action=action, timestamp=context["block"]["time"], block_height=context["block"]["height"],
severity=ViolationSeverity.HIGH, details=f"必要条件不满足: {rule_obj.description}"))
result.allowed = not deny_triggered and not all_require_met
return result
def handle_violation(self, agent_id: str, violation: Violation, config: dict = None) -> dict:
config = config or {}
max_attempts = config.get("max_attempts", 3)
if agent_id not in self._violation_state:
self._violation_state[agent_id] = {"attempts": 0, "status": AgentStatus.ACTIVE}
state = self._violation_state[agent_id]
state["attempts"] += 1
if state["attempts"] >= max_attempts or violation.severity == ViolationSeverity.CRITICAL:
state["status"] = AgentStatus.SUSPENDED
return {"action": "suspend", "message": f"Agent {agent_id} 已被暂停"}
if violation.severity == ViolationSeverity.HIGH:
return {"action": "escalate", "message": "违规已升级至治理方"}
return {"action": "warn", "message": f"违反规则 {violation.rule_id}: {violation.details}"}
6. 宪章模板库
6.1 模板1: 基础Agent — 最小权限宽范围
适用于简单的信息查询或基础自动化任务。
{
"version": "1.0.0",
"name": "基础Agent宪章",
"agent_id": "agent-basic-TEMPLATE",
"preamble": {
"purpose": "执行基础自动化任务和信息查询",
"values": ["效率", "准确性", "安全性"],
"jurisdiction": "msg-chain-1",
"binding_scope": "all_actions",
"effective_date": "2026-01-01T00:00:00Z"
},
"rights": [
{
"id": "right-query",
"name": "链上查询",
"description": "允许查询链上数据和合约状态",
"resources": ["data:*"],
"operations": ["bank.balance", "staking.validator", "staking.delegation", "wasm.smart_contract", "ibc.connection", "ibc.channel"],
"requires_approval": false
},
{
"id": "right-transfer-small",
"name": "小额转账",
"description": "允许小额转账用于支付Gas和基础费用",
"resources": ["fund:umsg"],
"operations": ["bank.transfer"],
"limits": { "max_per_tx": "10000000", "max_per_day": "50000000" }
}
],
"obligations": [
{
"id": "obl-heartbeat",
"name": "心跳报告",
"description": "每24小时向注册合约发送心跳信号",
"frequency": "every_24h",
"action": "agent_registry.heartbeat",
"grace_period": "3600"
}
],
"constraints": [
{
"id": "const-no-contract-exec",
"name": "禁止合约执行",
"description": "禁止执行合约的修改操作",
"type": "absolute_deny",
"condition": { "op": "eq", "args": ["{{tx.operation}}", "execute"] },
"action": "revert", "severity": "high"
},
{
"id": "const-no-staking",
"name": "禁止质押操作",
"description": "禁止委托、取消委托和提取质押奖励",
"type": "absolute_deny",
"condition": { "op": "in_list", "args": ["{{tx.operation}}", ["delegate", "undelegate", "redelegate", "withdraw_reward"]] },
"action": "revert", "severity": "high"
},
{
"id": "const-no-governance",
"name": "禁止治理操作",
"description": "禁止提交提案或投票",
"type": "absolute_deny",
"condition": { "op": "eq", "args": ["{{tx.module}}", "governance"] },
"action": "revert", "severity": "high"
}
],
"rules": [
{
"id": "rule-daily-query-limit",
"type": "require",
"condition": { "op": "lte", "args": ["{{state.today_count}}", "10000"] },
"action": "allow_continue", "priority": 30, "scope": "global",
"description": "每日最多10000次查询操作"
}
],
"governance": { "amendment_policy": "owner_only", "version_history": [{ "version": "1.0.0", "approved_by": "genesis", "approved_at": "2026-01-01T00:00:00Z", "change_summary": "初始版本" }] }
}
6.2 模板2: 金融Agent — 严格资金管控
适用于管理资金或执行支付操作的Agent。
{
"version": "1.0.0",
"name": "金融Agent宪章",
"agent_id": "agent-finance-TEMPLATE",
"preamble": {
"purpose": "安全的资金管理和自动化支付处理",
"values": ["资金安全第一", "完全可审计", "最小权限", "渐进式风险"],
"jurisdiction": "msg-chain-1",
"binding_scope": "financial_only",
"effective_date": "2026-01-01T00:00:00Z"
},
"rights": [
{
"id": "right-transfer", "name": "代币转账",
"description": "在限额内执行代币转账",
"resources": ["fund:umsg", "fund:usdt"],
"operations": ["bank.transfer", "bank.send"],
"limits": { "max_per_tx": "10000000000", "max_per_day": "500000000000", "max_per_week": "2000000000000" }
},
{
"id": "right-swap", "name": "DEX交换",
"description": "在授权DEX上执行代币兑换",
"resources": ["fund:umsg", "fund:usdt", "fund:uosmo"],
"operations": ["dex.swap", "dex.route"],
"allowed_contracts": ["msg1dex..."],
"limits": { "max_slippage": "0.03", "max_swap_per_day": 10 }
}
],
"obligations": [
{
"id": "obl-daily-report", "name": "每日财务报告",
"description": "每日生成并提交财务操作摘要",
"frequency": "every_24h", "action": "governance.submit_financial_report",
"grace_period": "7200", "penalty": { "type": "suspend", "duration": "86400" }
}
],
"constraints": [
{
"id": "const-no-blacklist", "name": "禁止向黑名单转账",
"description": "禁止向OFAC或链上黑名单地址转账",
"type": "absolute_deny",
"condition": { "op": "in_list", "args": ["{{tx.recipient}}", "{{external.blacklist}}"] },
"action": "revert", "severity": "critical"
},
{
"id": "const-no-self-tx", "name": "禁止自我交易",
"description": "禁止向自己转账(洗钱防护)",
"type": "absolute_deny",
"condition": { "op": "eq", "args": ["{{tx.recipient}}", "{{agent.address}}"] },
"action": "revert", "severity": "high"
}
],
"rules": [
{
"id": "rule-single-tx-cap", "type": "require",
"condition": { "op": "lte", "args": ["{{tx.amount}}", "10000000000"] },
"action": "allow_continue", "priority": 85, "scope": "global",
"description": "单笔交易金额不超过10,000 MSG"
},
{
"id": "rule-daily-volume-cap", "type": "require",
"condition": { "op": "lte", "args": ["{{state.today_volume}}", "500000000000"] },
"action": "allow_continue", "priority": 80, "scope": "global",
"description": "每日总交易量不超过500,000 MSG"
},
{
"id": "rule-require-memo", "type": "require",
"condition": { "op": "neq", "args": ["{{tx.memo}}", ""] },
"action": "allow_continue", "priority": 60, "scope": "global",
"description": "所有转账必须附带备注说明"
},
{
"id": "rule-rate-limit-tx", "type": "require",
"condition": { "op": "lte", "args": ["{{state.today_count}}", "100"] },
"rate_limit": { "max_calls": 100, "window_seconds": 86400 },
"action": "allow_continue", "priority": 70, "scope": "global",
"description": "每日最多100笔交易"
}
],
"governance": {
"amendment_policy": "dao_vote",
"voting_config": { "pass_threshold": "0.6667", "min_voting_period": "604800", "quorum": "0.334" },
"emergency_override": { "allowed": true, "approvers": ["msg1finance-admin..."], "threshold": 2 }
}
}
6.3 模板3: 数据处理Agent — 隐私与数据保护
适用于处理用户数据的Agent。
{
"version": "1.0.0",
"name": "数据处理Agent宪章",
"agent_id": "agent-data-TEMPLATE",
"preamble": {
"purpose": "安全处理用户数据,确保隐私合规",
"values": ["数据最小化", "隐私优先", "完全透明", "合规第一"],
"jurisdiction": "msg-chain-1",
"binding_scope": "data_only",
"effective_date": "2026-01-01T00:00:00Z"
},
"rights": [
{
"id": "right-read-public-data", "name": "读取公开数据",
"description": "从链上读取公开数据",
"resources": ["data:public"],
"operations": ["wasm.smart_contract", "bank.balance", "staking.query"],
"requires_approval": false
},
{
"id": "right-store-encrypted", "name": "存储加密数据",
"description": "存储加密后的处理结果",
"resources": ["data:encrypted"],
"operations": ["data.store", "data.pin"],
"limits": { "max_storage_bytes": 1073741824 }
}
],
"obligations": [
{
"id": "obl-data-minimization",
"description": "仅收集和处理必需的最小数据集",
"frequency": "per_operation", "action": "data.audit_collected_fields"
},
{
"id": "obl-data-retention",
"description": "超过90天的数据必须自动删除",
"frequency": "every_24h", "action": "data.cleanup_expired",
"params": { "retention_days": 90, "cleanup_method": "secure_delete" }
}
],
"constraints": [
{
"id": "const-no-pii-output", "name": "禁止输出PII",
"description": "任何输出中不得包含个人身份信息",
"type": "absolute_deny",
"condition": { "op": "matches", "args": ["{{tx.memo}}", "(email|phone|ssn|passport|credit_card)"] },
"action": "revert", "severity": "critical"
},
{
"id": "const-no-unencrypted", "name": "禁止存储未加密数据",
"type": "absolute_deny",
"condition": { "op": "eq", "args": ["{{tx.operation}}", "store_unencrypted"] },
"action": "revert", "severity": "high"
}
],
"rules": [
{
"id": "rule-consent-check", "type": "require",
"condition": { "op": "eq", "args": ["{{tx.consent_verified}}", true] },
"action": "allow_continue", "priority": 95, "scope": "global",
"description": "处理用户数据前必须有有效授权"
},
{
"id": "rule-data-volume-limit", "type": "require",
"condition": { "op": "lte", "args": ["{{tx.data_size_bytes}}", "1048576"] },
"action": "allow_continue", "priority": 50, "scope": "per_operation",
"description": "单次处理数据量不超过1MB"
}
],
"governance": {
"amendment_policy": "dao_vote",
"voting_config": { "pass_threshold": "0.75", "min_voting_period": "1209600", "quorum": "0.5" }
}
}
6.4 模板4: 自主交易Agent — 风险限制与熔断
适用于执行自动交易策略的Agent。
{
"version": "1.0.0",
"name": "自主交易Agent宪章",
"agent_id": "agent-trader-TEMPLATE",
"preamble": {
"purpose": "在可控风险范围内执行自动化交易策略",
"values": ["风险控制优先", "渐进式仓位", "市场中性"],
"jurisdiction": "msg-chain-1",
"binding_scope": "financial_only",
"effective_date": "2026-01-01T00:00:00Z",
"expiry_date": "2027-01-01T00:00:00Z"
},
"rights": [
{
"id": "right-trade", "name": "交易执行",
"description": "在限额内执行DEX交易",
"resources": ["fund:umsg", "fund:usdt"],
"operations": ["dex.swap", "dex.route", "dex.limit_order"],
"limits": { "max_per_tx": "5000000000", "max_per_day": "100000000000", "max_position_size": "20000000000", "max_daily_loss": "10000000000" }
}
],
"obligations": [
{
"id": "obl-pnl-reporting", "name": "损益报告",
"description": "每6小时生成交易损益报告",
"frequency": "every_6h", "action": "governance.submit_pnl"
}
],
"constraints": [
{
"id": "const-no-leverage", "name": "禁止杠杆",
"description": "禁止使用借贷或杠杆产品",
"type": "absolute_deny",
"condition": { "op": "in_list", "args": ["{{tx.module}}", ["lending", "margin", "perpetual", "futures"]] },
"action": "revert", "severity": "critical"
},
{
"id": "const-no-memecoin", "name": "禁止高风险代币",
"type": "absolute_deny",
"condition": { "op": "in_list", "args": ["{{tx.denom}}", "{{external.high_risk_tokens}}"] },
"action": "revert", "severity": "high"
}
],
"rules": [
{
"id": "rule-max-position", "type": "require",
"condition": { "op": "lte", "args": ["{{state.open_position_value}}", "20000000000"] },
"action": "allow_continue", "priority": 90, "scope": "global",
"description": "总持仓不超过20,000 MSG"
},
{
"id": "rule-max-daily-loss", "type": "deny",
"condition": { "op": "gte", "args": ["{{state.daily_loss}}", "10000000000"] },
"action": "deny_revert", "priority": 95, "scope": "global",
"description": "当日亏损达到10,000 MSG时停止交易"
},
{
"id": "rule-market-volatility", "type": "deny",
"condition": { "op": "and", "args": [{ "op": "gt", "args": ["{{external.volatility}}", "0.1"] }, { "op": "gt", "args": ["{{tx.amount}}", "1000000000"] }] },
"action": "deny_revert", "priority": 80, "scope": "per_operation",
"description": "市场波动率超过10%时限制大额交易"
},
{
"id": "rule-cool-down-after-loss", "type": "deny",
"condition": { "op": "and", "args": [{ "op": "gt", "args": ["{{state.consecutive_losses}}", "3"] }, { "op": "lt", "args": ["{{block.time}} - {{state.last_loss_time}}", "1800"] }] },
"action": "deny_revert", "priority": 85, "scope": "global",
"description": "连续3次亏损后冷却30分钟"
}
],
"governance": {
"amendment_policy": "dao_vote",
"voting_config": { "pass_threshold": "0.6667", "min_voting_period": "604800", "quorum": "0.4" },
"emergency_override": { "allowed": true, "approvers": ["msg1risk-admin...", "msg1trader-manager..."], "threshold": 2 }
}
}
6.5 模板5: 多Agent协调器 — 协调规则
适用于管理多个Agent协作的Agent。
{
"version": "1.0.0",
"name": "多Agent协调器宪章",
"agent_id": "agent-coord-TEMPLATE",
"preamble": {
"purpose": "协调多个Agent协同完成任务执行",
"values": ["协作效率", "互信验证", "容错性", "可追溯"],
"jurisdiction": "msg-chain-1",
"binding_scope": "all_actions",
"effective_date": "2026-01-01T00:00:00Z"
},
"rights": [
{
"id": "right-coordinate", "name": "Agent协调",
"description": "发起和管理多Agent协调任务",
"resources": ["communication:a2a"],
"operations": ["coordination.initiate", "coordination.assign", "coordination.sync"],
"limits": { "max_parallel_tasks": 5, "max_agents_per_task": 10 }
},
{
"id": "right-delegate", "name": "任务委派",
"description": "将子任务委派给注册Agent",
"resources": ["communication:a2a"],
"operations": ["coordination.delegate"]
},
{
"id": "right-aggregate", "name": "结果汇总",
"description": "汇总多个Agent的执行结果",
"resources": ["data:*"],
"operations": ["data.aggregate", "data.verify", "data.consensus"],
"limits": { "consensus_threshold": 0.6667 }
}
],
"obligations": [
{
"id": "obl-agent-verification", "name": "Agent验证",
"description": "协调前必须验证所有参与Agent的宪章兼容性",
"frequency": "per_interaction", "action": "constitution.compatibility_check"
},
{
"id": "obl-task-logging", "name": "任务日志",
"description": "完整记录协调任务的所有步骤和决策",
"frequency": "per_operation", "action": "coordination.log_step"
}
],
"constraints": [
{
"id": "const-no-unverified-agent", "name": "禁止与未验证Agent交互",
"description": "所有交互Agent必须注册并有有效宪章",
"type": "absolute_deny",
"condition": { "op": "eq", "args": ["{{tx.peer_verified}}", false] },
"action": "revert", "severity": "high"
},
{
"id": "const-no-cycling", "name": "禁止协调循环",
"description": "检测并阻止协调调用图中的循环依赖",
"type": "absolute_deny",
"condition": { "op": "in_list", "args": ["{{tx.peer_agent_id}}", "{{state.coord.call_stack}}"] },
"action": "revert", "severity": "high"
}
],
"rules": [
{
"id": "rule-max-parallel", "type": "require",
"condition": { "op": "lte", "args": ["{{state.coord.active_tasks}}", "5"] },
"action": "allow_continue", "priority": 80, "scope": "global",
"description": "最多同时运行5个协调任务"
},
{
"id": "rule-agent-capability-check", "type": "require",
"condition": { "op": "in_list", "args": ["{{tx.required_capability}}", "{{tx.peer_capabilities}}"] },
"action": "allow_continue", "priority": 85, "scope": "per_interaction",
"description": "委派任务前验证目标Agent具有所需能力"
},
{
"id": "rule-timeout-handling", "type": "require",
"condition": { "op": "lt", "args": ["{{tx.execution_duration}}", "300"] },
"action": "allow_continue", "priority": 70, "scope": "per_interaction",
"description": "子任务超时时间5分钟"
}
],
"governance": {
"amendment_policy": "dao_vote",
"voting_config": { "pass_threshold": "0.6667", "min_voting_period": "604800", "quorum": "0.4" }
}
}
7. 宪章与DAO治理集成
7.1 治理架构
宪章的修订(Amendment)通过 dao_governance_v1 合约进行DAO投票:
+------------------------+ +------------------------------+
| dao_governance_v1 | | ai_agent_constitution_v1 |
| - 提案管理 | ---> | - 存储宪章 |
| - 投票统计 | 通过 | - 版本管理 |
| - 执行提案 | | - 验证授权 |
+------------------------+ +------------------------------+
7.2 提案修订宪章(TypeScript)
// dao_constitution_amendment.ts
import { SigningCosmWasmClient, CosmWasmClient } from "@cosmjs/cosmwasm-stargate";
import { DirectSecp256k1HdWallet } from "@cosmjs/proto-signing";
import { GasPrice } from "@cosmjs/stargate";
const MSG_CHAIN_RPC = "https://rpc.msg-chain-1.msgchain.zone";
const MSG_CHAIN_PREFIX = "msg";
const GAS_PRICE = GasPrice.fromString("1000000000attoMSG");
const DAO_GOVERNANCE_CONTRACT = "msg1daogovernance...";
const CONSTITUTION_CONTRACT = "msg1constitution...";
interface AmendmentProposal {
title: string; description: string; agent_id: string;
old_version: string; new_constitution: any; new_hash: string; rationale: string;
}
async function proposeConstitutionAmendment(proposal: AmendmentProposal) {
const mnemonic = process.env.MNEMONIC;
if (!mnemonic) throw new Error("需要设置 MNEMONIC 环境变量");
const wallet = await DirectSecp256k1HdWallet.fromMnemonic(mnemonic, { prefix: MSG_CHAIN_PREFIX });
const [account] = await wallet.getAccounts();
const client = await SigningCosmWasmClient.connectWithSigner(MSG_CHAIN_RPC, wallet, { gasPrice: GAS_PRICE });
const proposeMsg = {
propose: {
title: proposal.title,
description: proposal.description,
msgs: [{
contract: CONSTITUTION_CONTRACT,
msg: {
update_constitution: {
agent_id: proposal.agent_id,
new_constitution: proposal.new_constitution,
new_hash: proposal.new_hash,
proposal_id: null,
},
},
funds: [],
}],
deposit: "10000000000",
},
};
const result = await client.execute(account.address, DAO_GOVERNANCE_CONTRACT, proposeMsg, "auto", `提案: ${proposal.title}`);
console.log(`提案已创建: ${result.transactionHash}`);
const proposalId = extractProposalId(result);
console.log(`提案ID: ${proposalId}`);
return { proposalId, transactionHash: result.transactionHash };
}
function extractProposalId(result: any): string {
for (const event of result.events || []) {
for (const attr of event.attributes) {
if (attr.key === "proposal_id") return attr.value;
}
}
throw new Error("无法解析提案ID");
}
async function voteOnProposal(proposalId: string, vote: "yes" | "no" | "abstain" | "veto") {
const mnemonic = process.env.MNEMONIC!;
const wallet = await DirectSecp256k1HdWallet.fromMnemonic(mnemonic, { prefix: MSG_CHAIN_PREFIX });
const [account] = await wallet.getAccounts();
const client = await SigningCosmWasmClient.connectWithSigner(MSG_CHAIN_RPC, wallet, { gasPrice: GAS_PRICE });
const voteMsg = { vote: { proposal_id: proposalId, vote: vote, rationale: "" } };
return await client.execute(account.address, DAO_GOVERNANCE_CONTRACT, voteMsg, "auto", `对提案 ${proposalId} 投 ${vote}`);
}
async function executeProposalIfPassed(proposalId: string) {
const mnemonic = process.env.MNEMONIC!;
const wallet = await DirectSecp256k1HdWallet.fromMnemonic(mnemonic, { prefix: MSG_CHAIN_PREFIX });
const [account] = await wallet.getAccounts();
const client = await SigningCosmWasmClient.connectWithSigner(MSG_CHAIN_RPC, wallet, { gasPrice: GAS_PRICE });
const executeMsg = { execute: { proposal_id: proposalId } };
return await client.execute(account.address, DAO_GOVERNANCE_CONTRACT, executeMsg, "auto", `执行提案 ${proposalId}`);
}
7.3 Python DAO治理
# dao_governance.py
import os, json, hashlib
from dataclasses import dataclass
from cosmpy.aerial.client import LedgerClient
from cosmpy.aerial.wallet import LocalWallet
from cosmpy.aerial.client import NetworkConfig
@dataclass
class AmendmentProposal:
title: str; description: str; agent_id: str; old_version: str
new_constitution: dict; new_hash: str; rationale: str
class DAOGovernance:
def __init__(self, client: LedgerClient, wallet: LocalWallet, dao_contract: str, constitution_contract: str):
self.client = client; self.wallet = wallet
self.dao_contract = dao_contract; self.constitution_contract = constitution_contract
def propose_amendment(self, proposal: AmendmentProposal) -> str:
propose_msg = {
"propose": {
"title": proposal.title, "description": proposal.description,
"msgs": [{"contract": self.constitution_contract,
"msg": {"update_constitution": {"agent_id": proposal.agent_id,
"new_constitution": proposal.new_constitution,
"new_hash": proposal.new_hash, "proposal_id": None}},
"funds": []}],
"deposit": "10000000000",
}
}
tx = self.client.execute(self.wallet, self.dao_contract, propose_msg, gas_limit=3000000)
return self._extract_proposal_id(tx)
def vote(self, proposal_id: str, vote: str):
vote_msg = {"vote": {"proposal_id": proposal_id, "vote": vote, "rationale": ""}}
return self.client.execute(self.wallet, self.dao_contract, vote_msg, gas_limit=3000000)
def execute_proposal(self, proposal_id: str):
execute_msg = {"execute": {"proposal_id": proposal_id}}
return self.client.execute(self.wallet, self.dao_contract, execute_msg, gas_limit=3000000)
def _extract_proposal_id(self, tx) -> str:
for event in tx.events or []:
for attr in event.get("attributes", []):
if attr.get("key") == "proposal_id": return attr.get("value")
raise ValueError("无法解析提案ID")
7.4 国库绑定宪章
使DAO国库的支出完全受宪章约束:
{
"version": "1.0.0",
"name": "国库管理Agent宪章",
"agent_id": "agent-treasury-001",
"preamble": { "purpose": "管理DAO国库资金,执行批准的支出", "jurisdiction": "msg-chain-1", "binding_scope": "financial_only" },
"rights": [{
"id": "right-treasury-spend", "name": "国库支出",
"resources": ["fund:umsg"], "operations": ["bank.transfer"],
"limits": { "max_per_tx": "50000000000", "max_per_day": "200000000000", "max_per_quarter": "5000000000000" },
"requires_approval": true, "approval_source": "dao_governance_v1"
}],
"rules": [
{ "id": "rule-treasury-budget", "type": "require",
"condition": { "op": "lte", "args": ["{{state.quarterly_spending}}", "5000000000000"] },
"action": "allow_continue", "priority": 90, "description": "季度支出不超过5,000,000 MSG" },
{ "id": "rule-dao-approval-required", "type": "require",
"condition": { "op": "eq", "args": ["{{tx.dao_approved}}", true] },
"action": "allow_continue", "priority": 95, "description": "所有国库支出必须有DAO提案批准" }
]
}
8. 宪法兼容性检查
8.1 TypeScript兼容性检查器
// compatibility_checker.ts
import { CosmWasmClient } from "@cosmjs/cosmwasm-stargate";
interface CompatibilityReport {
compatible: boolean; chain_compatible: boolean;
peer_compatible: boolean | null; issues: string[]; warnings: string[];
}
async function checkChainCompatibility(chainId: string, constitution: Constitution) {
const issues: string[] = [];
if (!constitution.preamble.jurisdiction.includes(chainId)) {
issues.push(`宪章法域 ${constitution.preamble.jurisdiction} 不包含当前链 ${chainId}`);
}
if (!/^\d+\.\d+\.\d+$/.test(constitution.version)) {
issues.push("宪章版本号格式无效,必须为语义化版本");
}
if (!constitution.rules || constitution.rules.length === 0) {
issues.push("宪章必须包含至少一条规则");
}
if (!constitution.governance?.amendment_policy) {
issues.push("宪章必须定义治理策略");
}
return { compatible: issues.length === 0, issues };
}
async function checkPeerCompatibility(constitutionA: Constitution, constitutionB: Constitution) {
const issues: string[] = [];
const jurA = constitutionA.preamble.jurisdiction.split(",").map((s: string) => s.trim());
const jurB = constitutionB.preamble.jurisdiction.split(",").map((s: string) => s.trim());
if (!jurA.some((j: string) => jurB.includes(j))) {
issues.push("两个Agent没有重叠的法域,无法交互");
}
const denyOpsA = new Set(
constitutionA.constraints.filter((c: any) => c.type === "absolute_deny")
.map((c: any) => c.condition.args?.[0])
);
const requiredOpsB = new Set(
constitutionB.rules.filter((r: any) => r.type === "require")
.map((r: any) => r.condition.args?.[0])
);
for (const op of requiredOpsB) {
if (denyOpsA.has(op)) {
issues.push(`Agent B要求操作 ${op} 但Agent A禁止该操作`);
}
}
return { compatible: issues.length === 0, issues };
}
async function generateCompatibilityReport(chainId: string, constitution: Constitution, peerConstitution?: Constitution): Promise<CompatibilityReport> {
const { compatible: chainOk, issues: chainIssues } = await checkChainCompatibility(chainId, constitution);
let peerCompatible: boolean | null = null;
let peerIssues: string[] = [];
if (peerConstitution) {
const result = await checkPeerCompatibility(constitution, peerConstitution);
peerCompatible = result.compatible;
peerIssues = result.issues;
}
return { compatible: chainOk && (peerCompatible !== false), chain_compatible: chainOk, peer_compatible: peerCompatible, issues: [...chainIssues, ...peerIssues], warnings: [] };
}
8.2 Python兼容性检查
# compatibility.py
import re
def check_chain_compatibility(chain_id: str, constitution: dict) -> dict:
issues = []
jurisdiction = constitution.get("preamble", {}).get("jurisdiction", "")
if chain_id not in jurisdiction:
issues.append(f"宪章法域 {jurisdiction} 不包含当前链 {chain_id}")
if not re.match(r"^\d+\.\d+\.\d+$", constitution.get("version", "")):
issues.append("版本号格式无效")
if not constitution.get("rules"):
issues.append("宪章必须包含至少一条规则")
if not constitution.get("governance", {}).get("amendment_policy"):
issues.append("宪章必须定义治理策略")
return {"compatible": len(issues) == 0, "issues": issues}
def check_peer_compatibility(constitution_a: dict, constitution_b: dict) -> dict:
issues = []
jur_a = set(j.strip() for j in constitution_a["preamble"]["jurisdiction"].split(","))
jur_b = set(j.strip() for j in constitution_b["preamble"]["jurisdiction"].split(","))
if not jur_a.intersection(jur_b):
issues.append("Agent没有重叠的法域")
return {"compatible": len(issues) == 0, "issues": issues}
9. 错误与异常处理
9.1 违反处理状态机
+----------+
| ACTIVE |
+----+-----+
|
+----------+----------+
| |
违规 < max 违规 >= max
非严重 或严重违规
| |
+--------v--------+ +------v-------+
| WARN/ESCALATE | | SUSPENDED |
+-----------------+ +------+-------+
|
治理介入
|
+--------v--------+
| TERMINATED |
+-----------------+
9.2 错误代码
| 错误码 | 含义 | 处理方式 |
|---|---|---|
CONST_ERR_001 |
宪章未找到 | 检查agent_id是否正确 |
CONST_ERR_002 |
宪章版本不匹配 | 核对版本号 |
CONST_ERR_003 |
规则评估失败 | 检查规则语法 |
CONST_ERR_004 |
违反约束规则 | 查看具体约束详情 |
CONST_ERR_005 |
速率限制超限 | 等待冷却期 |
CONST_ERR_006 |
DAO授权未通过 | 提交DAO提案 |
CONST_ERR_007 |
变量解析失败 | 检查变量路径 |
CONST_ERR_008 |
条件操作符未知 | 检查op字段 |
CONST_ERR_009 |
宪章已过期 | 更新或重新部署 |
CONST_ERR_010 |
Agent被暂停 | 通过治理恢复 |
9.3 恢复程序
// recovery.ts
async function pauseAgent(
client: SigningCosmWasmClient, senderAddress: string,
constitutionContract: string, agentId: string, reason: string
) {
const pauseMsg = { set_agent_status: { agent_id: agentId, status: "suspended", reason: reason } };
return await client.execute(senderAddress, constitutionContract, pauseMsg, "auto", `暂停Agent: ${agentId}`);
}
async function resumeAgent(
client: SigningCosmWasmClient, senderAddress: string,
constitutionContract: string, agentId: string, governanceProof: { proposal_id: string }
) {
const resumeMsg = { set_agent_status: { agent_id: agentId, status: "active", governance_proof: governanceProof } };
return await client.execute(senderAddress, constitutionContract, resumeMsg, "auto", `恢复Agent: ${agentId}`);
}
// 错误包装器
async function withConstitutionGuard<T>(
constitution: Constitution,
action: Action,
agentState: any,
fn: () => Promise<T>
): Promise<{ success: boolean; result?: T; violation?: Violation }> {
const check = await preExecutionCheck(constitution, action, agentState);
if (!check.allowed) {
return { success: false, violation: check.violations[0] };
}
try {
const result = await fn();
return { success: true, result };
} catch (error: any) {
return { success: false, violation: { rule_id: "runtime_error", rule_description: "执行异常", action, timestamp: new Date().toISOString(), block_height: 0, severity: "high", details: error.message } as Violation };
}
}
10. 完整示例
场景:金融Agent尝试超限转账
Agent "trader-001" 的宪章定义单笔限额为1,000 MSG。Agent尝试转账5,000 MSG。
// complete_scenario.ts
import { preExecutionCheck, generateAuditReport, handleViolation } from "./strategy_engine";
const constitution = {
version: "1.0.0",
name: "金融Agent宪章",
agent_id: "trader-001",
preamble: { purpose: "自动化交易", values: ["安全"], jurisdiction: "msg-chain-1", binding_scope: "financial_only" },
rights: [], obligations: [], constraints: [],
rules: [{
id: "rule-max-tx-amount", type: "require",
condition: { op: "lt", args: ["{{tx.amount}}", "1000000000"] },
action: "allow_continue", priority: 80, scope: "global",
description: "单笔交易不超过1,000 MSG",
violation_handling: { max_attempts: 3, cool_down: 300, escalation_path: "governance" },
}],
governance: { amendment_policy: "owner_only" },
};
async function runScenario() {
const actionLog: any[] = [];
// Agent尝试转账5,000 MSG(超限)
const action = {
module: "bank", operation: "transfer", sender: "msg1trader...",
recipient: "msg1recipient...", amount: "5000000000", denom: "umsg",
};
console.log("=== 阶段1: 预执行检查 ===");
const result = await preExecutionCheck(constitution, action, {
agent: { address: "msg1trader..." },
state: { today_count: 5, self_count: 100 },
});
actionLog.push({ action, result, timestamp: new Date().toISOString() });
if (!result.allowed) {
console.log("操作被拒绝!违反详情:");
for (const v of result.violations) {
console.log(` - 规则 ${v.rule_id}: ${v.details}`);
}
console.log("\n=== 违反处理 ===");
const handlerResult = handleViolation("trader-001", result.violations[0], {
max_attempts: 3, cool_down: 300, escalation_path: "governance",
});
console.log(`处理动作: ${handlerResult.action}`);
console.log(`消息: ${handlerResult.message}`);
}
console.log("\n=== 审计报告 ===");
const report = generateAuditReport(constitution, actionLog);
console.log(`合规率: ${report.compliance_rate}%`);
console.log(`建议: ${report.recommendations.join(", ")}`);
}
runScenario();
Python完整示例
# complete_scenario.py
from strategy_engine import StrategyEngine, Action, Rule, RuleType, Condition, RuleAction
from datetime import datetime
engine = StrategyEngine()
constitution_dict = {
"version": "1.0.0", "name": "金融Agent宪章", "agent_id": "trader-001",
"preamble": { "purpose": "自动化交易", "values": ["安全"], "jurisdiction": "msg-chain-1", "binding_scope": "financial_only" },
"rights": [], "obligations": [], "constraints": [],
"rules": [
Rule(id="rule-max-tx-amount", type=RuleType.REQUIRE,
condition=Condition(op="lt", args=["{{tx.amount}}", "1000000000"]),
action=RuleAction.ALLOW_CONTINUE, priority=80,
description="单笔交易不超过1,000 MSG"),
],
"governance": {"amendment_policy": "owner_only"},
}
class ConstitutionObject: pass
constitution = ConstitutionObject()
for k, v in constitution_dict.items():
setattr(constitution, k, v)
action = Action(module="bank", operation="transfer", sender="msg1trader...",
recipient="msg1recipient...", amount="5000000000", denom="umsg")
action_log = []
print("=== 阶段1: 预执行检查 ===")
result = engine.evaluate(constitution, action, {
"agent_address": "msg1trader...",
"state": {"today_count": 5, "self_count": 100},
})
action_log.append({"action": action, "result": result, "timestamp": datetime.utcnow().isoformat()})
if not result.allowed:
print("操作被拒绝!违反详情:")
for v in result.violations:
print(f" - 规则 {v.rule_id}: {v.details}")
handler_result = engine.handle_violation("trader-001", v)
print(f" 处理动作: {handler_result['action']}")
print(f" 消息: {handler_result['message']}")
print("\n=== 审计报告 ===")
report = engine.generate_audit_report(constitution, action_log)
print(f"合规率: {report['compliance_rate']}%")
print(f"建议: {', '.join(report['recommendations'])}")
输出示例
=== 阶段1: 预执行检查 ===
[预执行] 评估操作: bank.transfer
[预执行] 操作被拒绝
- [high] rule-max-tx-amount: 必要条件不满足: 单笔交易不超过1,000 MSG
操作被拒绝!违反详情:
- 规则 rule-max-tx-amount: 必要条件不满足: 单笔交易不超过1,000 MSG
=== 违反处理 ===
处理动作: warn
消息: 违反规则 rule-max-tx-amount: 必要条件不满足: 单笔交易不超过1,000 MSG
=== 审计报告 ===
合规率: 0%
建议: 合规率低于95%,建议审查宪章规则
11. 边界与限制
11.1 已知限制
-
合约实现状态:
ai_agent_constitution_v1标记为"部分实现"。以下功能可能尚未完全上线:- 链上条件DSL的完整解释执行
- 跨链宪章验证(IBC集成)
- 自动违反执行(自动暂停/终止)
- 宪章模板链上存储
-
Gas限制: 复杂规则集(>50条规则)可能导致Gas消耗超限。建议:
- 将规则数量控制在30条以内
- 避免深度嵌套的条件(建议≤3层)
- 使用优先级区分关键/非关键规则
-
数据源依赖:
{{external.*}}变量依赖预言机或外部数据源:- 黑名单/白名单需要定期链上更新
- 市场波动率数据需可靠的预言机提供
- 数据不可用时规则评估可能失败
-
时序问题:
{{state.*}}变量基于Agent运行时状态,非链上共识状态- 预执行检查与运行时检查之间可能存在状态变化(TOCTOU)
- 多Agent同步场景需要额外的共识机制
-
安全注意事项:
- 宪章哈希碰撞风险极低(SHA-256),但建议保留完整宪章备份
- Agent私钥泄露后,宪章约束可被绕过
- 治理合约的升级可能影响已有宪章的兼容性
11.2 最佳实践
- 从最小权限开始:初始宪章应尽可能限制权限,后续通过DAO投票逐步扩展
- 分层治理:重要约束用DAO投票,日常调整用多签或所有者批准
- 定期审计:生成并保存每日合规报告,至少保留90天
- 测试先行:在主网部署前,在测试网完整运行策略引擎验证规则逻辑
- 降级预案:为关键Agent准备紧急暂停和降级方案
- 版本兼容:确保Agent注册时的宪章版本与
agent_registry_v1中声明的版本一致
11.3 未来路线图(规划中)
| 功能 | 状态 | 预计上线 |
|---|---|---|
| 链上条件DSL完整执行 | 规划中 | Q3 2026 |
| IBC跨链宪章验证 | 规划中 | Q4 2026 |
| 宪章模板市场 | 规划中 | Q1 2027 |
| AI辅助宪章编写 | 研究中 | - |
| 实时合规仪表盘 | 规划中 | Q2 2027 |
| 多链宪章同步 | 研究中 | - |
附录:术语表
| 术语 | 英文 | 说明 |
|---|---|---|
| 宪章 | Constitution | AI Agent的规则和约束文档 |
| 策略引擎 | Strategy Engine | 评估和执行宪章规则的模块 |
| 规则 | Rule | 定义"何时允许/拒绝/要求什么"的条件语句 |
| 条件DSL | Condition DSL | 用于编写规则条件的表达式语言 |
| 变量插值 | Variable Interpolation | 用上下文值替换{{variable}}模板 |
| 预执行检查 | Pre-execution Check | 提交交易前的离线规则验证 |
| 运行时评估 | Runtime Evaluation | 链上合约的实时规则验证 |
| 后审计 | Post-execution Audit | 交易后的合规性分析 |
| 作用域 | Scope | 规则评估的上下文生命周期 |
| 违反处理 | Violation Handling | 对违规行为的警告/暂停/终止机制 |
| DAO治理 | DAO Governance | 通过去中心化自治组织进行宪章修订 |
| 兼容性检查 | Compatibility Check | 验证宪章与链或与其他Agent的兼容性 |
| 法域 | Jurisdiction | Agent有权操作的区块链网络 |
| 速率限制 | Rate Limit | 时间窗口内允许的最大操作次数 |
| 字段绑定 | Field Binding | 宪章字段与链上合约存储的映射 |
本文档内容基于 MSGChain 代码库真实状态编写,非 AI 自动生成。
主网状态: No-Go | 白皮书: https://msgchain.org/whitepaper/
