एजेंटिक वेब प्रोटोकॉल (AWP)
ADK-Rust Agentic Web Protocol (AWP) प्रकार और वेबसाइटों तथा सेवाओं को AI एजेंटों के लिए सुलभ बनाने हेतु Axum एकीकरण प्रदान करता है। कार्यान्वयन दो crates में फैला है: awp-types (शुद्ध प्रोटोकॉल प्रकार) और adk-awp (रूट्स, मिडलवेयर, और सेवा इंटरफेस)। अनुप्रयोग एजेंट डिस्पैच, प्रमाणीकरण, प्राधिकरण, और स्थायी वेबहुक डिलीवरी प्रदान करते हैं।
अवलोकन
AWP किसी भी वेबसाइट को अपनी क्षमताओं, नीतियों, और व्यावसायिक संदर्भ को मशीन-पठनीय प्रारूप में घोषित करने में सक्षम बनाता है। AI एजेंट इन क्षमताओं की खोज कर सकते हैं, प्रोटोकॉल संस्करणों पर बातचीत कर सकते हैं, घटनाओं की सदस्यता ले सकते हैं, और टाइप किए गए A2A संदेशों के माध्यम से इंटरैक्ट कर सकते हैं। adk-awp अपने HTTP सीमा पर body और rate limits लागू करता है; application handlers पहचान और capability authorization लागू करते हैं।
AWP का उपयोग तब करें जब:
- आप चाहते हैं कि AI एजेंट आपके सेवा को प्रोग्रामेटिक रूप से खोजें और उससे इंटरैक्ट करें
- आपको trust-level मेटाडेटा और application-enforced access control के लिए एक hook चाहिए
- आप मानव आगंतुकों और AI एजेंटों दोनों को एक ही endpoints से सेवा देना चाहते हैं
- आपको event subscriptions और HMAC-SHA256 signing primitives की आवश्यकता है
- आप service monitoring के लिए एक health state machine चाहते हैं
आर्किटेक्चर
AWP अनुरोध प्रवाह
एप्लिकेशन लेआउट
┌─────────────────────────────────────────────────┐
│ Your Application │
│ │
│ ┌──────────────┐ ┌──────────────────────────┐ │
│ │ LLM Agent │ │ awp_routes(state) │ │
│ │ (adk-agent) │ │ ├ /.well-known/awp.json │ │
│ │ │ │ ├ /awp/manifest │ │
│ │ Instructions│ │ ├ /awp/health │ │
│ │ derived from│ │ └ /awp/a2a │ │
│ │ business. │ │ auth + management routes│ │
│ │ toml │ │ │ │
│ └──────────────┘ └──────────────────────────┘ │
│ ▲ ▲ │
│ │ │ │
│ ┌────┴──────────────────────┴────┐ │
│ │ BusinessContextLoader │ │
│ │ (business.toml + ArcSwap) │ │
│ └────────────────────────────────┘ │
└─────────────────────────────────────────────────┘
Crates
| क्रेट | उद्देश्य | निर्भरताएँ |
|---|---|---|
awp-types | प्रोटोकॉल प्रकार (एनम, स्ट्रक्ट, त्रुटियाँ) | शून्य adk-* निर्भरताएँ — serde, uuid, chrono, thiserror केवल |
adk-awp | रूट्स, मिडलवेयर, सेवा इंटरफेस, और इन-मेमोरी कार्यान्वयन | awp-types, adk-core, axum 0.8, tokio, dashmap |
विभाजन का मतलब है कि कोई भी Rust प्रोजेक्ट awp-types पर निर्भर हो सकता है, बिना ADK ट्री को शामिल किए।
त्वरित शुरुआत
1. एक business.toml बनाएं
site_name = "My Shop"
site_description = "An online store powered by AWP"
domain = "myshop.example.com"
contact = "hello@myshop.example.com"
[business]
country = "US"
currency = "USD"
languages = ["en"]
[brand_voice]
tone = "friendly and helpful"
greeting = "Welcome! How can I help?"
[[capabilities]]
name = "browse_products"
description = "Browse the product catalog"
endpoint = "/api/products"
method = "GET"
access_level = "anonymous"
[[capabilities]]
name = "place_order"
description = "Place an order"
endpoint = "/api/orders"
method = "POST"
access_level = "known"
[[products]]
sku = "WIDGET-001"
name = "Standard Widget"
price = 1999
inventory = 500
tags = ["widget"]
[[policies]]
name = "privacy"
description = "Minimal data collection, no tracking."
policy_type = "privacy"
[payments]
providers = ["stripe"]
auto_approve_threshold = 5000
[support]
escalation_contacts = ["support@myshop.example.com"]
hours = "Mon-Fri 9-5 EST"
2. AWP रूट्स लोड करें और सर्व करें
use std::sync::Arc;
use adk_awp::{AwpA2aHandler, AwpState, BusinessContextLoader, awp_routes};
use async_trait::async_trait;
use awp_types::AwpError;
use axum::http::{HeaderMap, header};
use serde_json::{Value, json};
struct ApplicationA2a {
bearer_token: Arc<str>,
}
#[async_trait]
impl AwpA2aHandler for ApplicationA2a {
async fn handle(&self, headers: HeaderMap, message: Value) -> Result<Value, AwpError> {
let expected = format!("Bearer {}", self.bearer_token);
let authorized = headers
.get(header::AUTHORIZATION)
.and_then(|value| value.to_str().ok())
.is_some_and(|value| value == expected);
if !authorized {
return Err(AwpError::Unauthorized("invalid A2A credential".to_string()));
}
// Authorize the requested capability and dispatch to the application agent.
Ok(json!({ "status": "processed", "messageId": message["id"] }))
}
}
let loader = BusinessContextLoader::from_file("business.toml".as_ref())?;
let a2a_token: Arc<str> = std::env::var("AWP_A2A_TOKEN")?.into();
let state = AwpState::builder(loader.context_ref())
.a2a_handler(Arc::new(ApplicationA2a { bearer_token: a2a_token }))
.build();
let app = axum::Router::new()
.merge(awp_routes(state))
.merge(your_custom_routes);
let listener = tokio::net::TcpListener::bind("127.0.0.1:3456").await?;
axum::serve(
listener,
app.into_make_service_with_connect_info::<std::net::SocketAddr>(),
)
.await?;
यह संस्करण-वार्ता, दर-सीमांकन, और 64 KiB A2A बॉडी सीमा के साथ चार सार्वजनिक AWP एंडपॉइंट्स पंजीकृत करता है। बिना एक AwpA2aHandler के, POST /awp/a2a 503 लौटाता है और उस कार्य को कभी स्वीकार नहीं करता जो डिस्पैच नहीं किया गया था। ConnectInfo सहकर्मी पता प्रदान करता है, जिसका उपयोग गुमनाम दर-सीमा बकेट्स को अलग करने के लिए किया जाता है; इसके बिना, अज्ञात कॉलर जानबूझकर एक ही बकेट साझा करते हैं।
सार्वजनिक AWP एंडपॉइंट्स
| विधि | पथ | विवरण |
|---|---|---|
| GET | /.well-known/awp.json | डिस्कवरी दस्तावेज़ — एजेंटों के लिए प्रवेश बिंदु |
| GET | /awp/manifest | JSON-LD क्षमता मैनिफेस्ट |
| GET | /awp/health | स्वास्थ्य स्थिति (Healthy/Degrading/Degraded) |
| POST | /awp/a2a | एप्लिकेशन-प्रदानित A2A dispatch |
प्रमाणित प्रबंधन एंडपॉइंट्स
awp_management_routes() सदस्यता प्रबंधन को अलग से और
बिना किसी प्रमाणीकरण परत के लौटाता है। इसे मर्ज करने से पहले
एप्लिकेशन के auth middleware लागू करें:
| विधि | पथ | विवरण |
|---|---|---|
| POST | /awp/events/subscribe | एक webhook subscription बनाएँ |
| GET | /awp/events/subscriptions | सभी subscriptions की सूची बनाएँ |
| DELETE | /awp/events/subscriptions/{id} | एक सदस्यता हटाएँ |
डिस्कवरी दस्तावेज़
/.well-known/awp.json पर स्थित डिस्कवरी दस्तावेज़ आपके business.toml से स्वचालित रूप से जनरेट होता है:
{
"version": { "major": 1, "minor": 0 },
"siteName": "My Shop",
"siteDescription": "An online store powered by AWP",
"capabilityManifestUrl": "https://myshop.example.com/awp/manifest",
"a2aEndpointUrl": "https://myshop.example.com/awp/a2a",
"eventsEndpointUrl": "https://myshop.example.com/awp/events/subscribe",
"healthEndpointUrl": "https://myshop.example.com/awp/health",
"supportedTrustLevels": ["anonymous"]
}
क्षमता मैनिफेस्ट
/awp/manifest पर स्थित मैनिफेस्ट JSON-LD फ़ॉर्मेट का उपयोग करता है:
{
"@context": "https://schema.org",
"@type": "WebAPI",
"name": "My Shop",
"description": "An online store powered by AWP",
"capabilities": [
{
"name": "browse_products",
"description": "Browse the product catalog",
"endpoint": "/api/products",
"method": "GET"
}
]
}
विश्वास स्तर
AWP बढ़ती पहुँच के साथ चार विश्वास स्तरों का उपयोग करता है:
| स्तर | विभेदक | कैसे असाइन किया गया |
|---|---|---|
Anonymous | 0 | कोई क्रेडेंशियल नहीं |
Known | 1 | मान्य API कुंजी या JWT |
Partner | 2 | JWT के साथ partner स्कोप |
Internal | 3 | JWT के साथ internal स्कोप |
विश्वास स्तर क्रमबद्ध हैं: Anonymous < Known < Partner < Internal. business.toml में प्रत्येक capability अपना न्यूनतम access_level घोषित करती है।
DefaultTrustAssigner हर अनुरोध को Anonymous के रूप में वर्गीकृत करता है। एक bearer या API key header तब तक विश्वसनीय नहीं माना जाता जब तक कोई application verifier उसे मान्य न कर दे। इसलिए उच्च trust levels के लिए एक custom assigner आवश्यक होता है।
उस assigner के साथ .supported_trust_levels(...) को भी configure करें ताकि discovery केवल वही levels advertise करे जिन्हें deployment सत्यापित कर सकता है।
Custom Trust Assignment
कस्टम logic के लिए TrustLevelAssigner trait को implement करें:
use std::sync::Arc;
use adk_awp::TrustLevelAssigner;
use async_trait::async_trait;
use awp_types::TrustLevel;
use axum::http::{HeaderMap, header};
struct MyTrustAssigner {
bearer_token: Arc<str>,
}
#[async_trait]
impl TrustLevelAssigner for MyTrustAssigner {
async fn assign(&self, headers: &HeaderMap) -> TrustLevel {
let expected = format!("Bearer {}", self.bearer_token);
if headers
.get(header::AUTHORIZATION)
.and_then(|value| value.to_str().ok())
.is_some_and(|value| value == expected)
{
TrustLevel::Known
} else {
TrustLevel::Anonymous
}
}
}
Partner या Internal assign करते समय, application के बाकी हिस्से के समान ही verified identity और scope source का उपयोग करें।
Rate Limiting
Built-in InMemoryRateLimiter per-trust-level limits के साथ sliding window algorithm का उपयोग करता है:
| विश्वसनीयता स्तर | डिफ़ॉल्ट सीमा |
|---|---|
| अनाम | 30 अनुरोध/मिनट |
| ज्ञात | 120 अनुरोध/मिनट |
| भागीदार | 600 अनुरोध/मिनट |
| आंतरिक | असीमित |
Rejected requests receive HTTP 429 with a Retry-After header.
कस्टम सीमाएँ
use std::collections::HashMap;
use awp_types::TrustLevel;
use adk_awp::{InMemoryRateLimiter, RateLimitConfig};
let mut limits = HashMap::new();
limits.insert(TrustLevel::Anonymous, RateLimitConfig {
max_requests: 10,
window_secs: 60,
});
limits.insert(TrustLevel::Known, RateLimitConfig {
max_requests: 100,
window_secs: 60,
});
let limiter = InMemoryRateLimiter::with_config(limits);
संस्करण नेगोशिएशन
सभी AWP routes में version negotiation middleware शामिल है:
- Clients
AWP-Version: 1.1header भेजते हैं (optional — defaults to current version) - Server major version compatibility की जाँच करता है
- Compatible requests आगे बढ़ते हैं; incompatible requests को HTTP 406 मिलता है
- Malformed version values को HTTP 400 मिलता है
- Response में
AWP-Version: 1.0header शामिल होता है
इवेंट सब्सक्रिप्शन
Subscription management एक privileged surface है. Accept करने से पहले
authentication के पीछे awp_management_routes() को mount करें। Callback URLs absolute HTTPS URLs होना चाहिए और signing secrets में
कम से कम 32 bytes होने चाहिए:
# Subscribe
curl -X POST http://localhost:3456/awp/events/subscribe \
-H "Authorization: Bearer $AWP_ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"subscriber": "my-agent",
"callbackUrl": "https://my-agent.example/webhook",
"eventTypes": ["health.changed"],
"secret": "replace-with-at-least-32-random-bytes"
}'
# List subscriptions
curl -H "Authorization: Bearer $AWP_ADMIN_TOKEN" \
http://localhost:3456/awp/events/subscriptions
InMemoryEventSubscriptionService matching deliveries पर sign और log करता है लेकिन
कोई network I/O नहीं करता। Production applications destination validation, एक durable queue,
bounded retries, और अपना HTTP client के साथ
EventSubscriptionService implement करती हैं।
एक HTTP delivery implementation HMAC-SHA256 signature के साथ एक X-AWP-Signature header carry कर सकती है:
X-AWP-Signature: sha256=<hex_digest>
Signatures को adk_awp::verify_signature(payload, secret, signature) के साथ verify करें।
Health State Machine
Health endpoint service state को strictly validated transitions के साथ track करता है:
Healthy → Degrading → Degraded
↑ │ │
└─────────┘ │
└─────────────────────┘
State changes सभी matching subscribers को health.changed events emit करती हैं।
use adk_awp::HealthStateMachine;
// Transition to degrading
health.report_degrading("database latency high").await?;
// Transition to degraded
health.report_degraded("database unreachable").await?;
// Recover
health.report_healthy().await?;
Invalid transitions (e.g., Healthy → Degraded) error return करते हैं।
Consent Storage
AWP में एक consent storage interface शामिल है। Regulatory compliance के लिए application-specific notice, lawful basis, retention, access controls, और deletion policy भी आवश्यक हैं; किसी storage implementation को चुनना compliance स्थापित नहीं करता:
use adk_awp::InMemoryConsentService;
let consent = InMemoryConsentService::new();
// Capture consent
consent.capture_consent("visitor-123", "analytics").await?;
// Check consent
let has_consent = consent.check_consent("visitor-123", "analytics").await?;
// Revoke consent
consent.revoke_consent("visitor-123", "analytics").await?;
Requester Type Detection
AWP यह detect करता है कि request किसी human से आई है या किसी AI agent से:
X-AWP-Channel: agentheader → Agent (explicit override)Accept: application/json+ agent User-Agent pattern → Agent- Otherwise → Human
Agent User-Agent patterns: bot, crawler, spider, agent, gpt, claude, gemini, perplexity, anthropic, openai.
use adk_awp::detect_requester_type;
use axum::http::HeaderMap;
let mut headers = HeaderMap::new();
headers.insert("X-AWP-Channel", "agent".parse().unwrap());
let requester = detect_requester_type(&headers);
// RequesterType::Agent
AWP संदेश प्रकार
Generic A2A messages से आगे, AWP agent routing के लिए typed message categories परिभाषित करता है:
| प्रकार | विवरण |
|---|---|
VisitorIntentSignal | खरीद या सेवा का इरादा |
ContentGapSignal | गायब या पुरानी सामग्री का पता चला |
PaymentIntent | भुगतान जीवनचक्र संदेश |
SupportEscalation | मानव सहायता को एस्केलेशन |
ReviewSignal | किसी प्लेटफ़ॉर्म से समीक्षा या प्रतिक्रिया |
OperationsProposal | इन्वेंटरी, शेड्यूलिंग प्रस्ताव |
InvokeCapability | घोषित क्षमता को कॉल करें |
RenderUi | UI रेंडरिंग का अनुरोध करें |
OutboundTrigger | सक्रिय आउटबाउंड संदेश |
use awp_types::{AwpMessageType, AwpTypedMessage};
let msg = AwpTypedMessage {
id: uuid::Uuid::now_v7(),
sender: "visitor-agent".to_string(),
recipient: "payment-agent".to_string(),
awp_type: AwpMessageType::PaymentIntent,
timestamp: chrono::Utc::now(),
payload: serde_json::json!({"sku": "WIDGET-001", "amount": 2500}),
};
भुगतान इरादे
AWP स्वामी-नीति-संचालित भुगतानों के लिए एक सरलीकृत भुगतान जीवनचक्र परिभाषित करता है:
Draft → PendingApproval → Approved → Executing → Settled
→ Rejected
→ Cancelled
PaymentPolicy यह मूल्यांकन करता है कि स्वतः अनुमोदन करना है या स्वामी अनुमोदन आवश्यक है:
use awp_types::{PaymentPolicy, TrustLevel};
let policy = PaymentPolicy::default(); // $50 auto-approve, $500 require approval
let decision = policy.evaluate(2500, TrustLevel::Known);
// PaymentPolicyDecision::AutoApprove (amount $25 <= $50 threshold)
let decision = policy.evaluate(60_000, TrustLevel::Partner);
// PaymentPolicyDecision::RequireApproval (amount $600 > $500 threshold)
business.toml स्कीमा
पूर्ण स्कीमा समृद्ध व्यावसायिक कॉन्फ़िगरेशन का समर्थन करता है:
| अनुभाग | फ़ील्ड | आवश्यक |
|---|---|---|
| (मूल) | site_name, site_description, domain, contact | हाँ (संपर्क को छोड़कर) |
[business] | name, country, languages, currency, timezone | नहीं |
[brand_voice] | tone, greeting, escalation_message | नहीं |
[[products]] | sku, name, price, inventory, tags, description | नहीं |
[[capabilities]] | name, description, endpoint, method, access_level | हाँ |
[[policies]] | name, description, policy_type | हाँ |
[channels] | whatsapp, email, website, sms | नहीं |
[payments] | providers, auto_approve_threshold, require_approval_threshold | नहीं |
[support] | escalation_contacts, hours, sla | नहीं |
[content] | topics, auto_draft, publish_delay | नहीं |
[reviews] | platforms, auto_respond_threshold | नहीं |
[outreach] | follow_up_delay, require_consent | नहीं |
सभी विस्तारित अनुभाग वैकल्पिक हैं — मौजूदा न्यूनतम business.toml फ़ाइलें काम करती रहती हैं।
हॉट रीलोड
BusinessContextLoader, ArcSwap के माध्यम से हॉट-रीलोड का समर्थन करता है:
let loader = BusinessContextLoader::from_file("business.toml".as_ref())?;
loader.watch("business.toml".into()).await?;
// Changes to business.toml are picked up automatically every 5 seconds
उदाहरण चलाना
एक पूर्ण AWP एजेंट उदाहरण शामिल है:
cd examples/awp_agent
cp .env.example .env # add your GOOGLE_API_KEY
cargo run
उदाहरण:
- उत्पादों, नीतियों, और ब्रांड वॉइस के साथ
business.tomlलोड करता है - व्यावसायिक संदर्भ से निकाले गए निर्देशों के साथ एक LLM एजेंट बनाता है
- उस एजेंट के लिए प्रमाणित A2A डिस्पैच स्थापित करता है
- एक अलग डेमो क्रेडेंशियल के पीछे प्रबंधन रूट्स माउंट करता है
- हर एंडपॉइंट का परीक्षण करता है और प्रोटोकॉल सत्यापन प्रिंट करता है
सर्वोत्तम प्रथाएँ
- न्यूनतम
business.tomlसे शुरू करें — केवलsite_name,site_description,domain, क्षमताएँ, और नीतियाँ आवश्यक हैं - क्षमता प्राधिकरण लागू करें —
access_levelमैनिफ़ेस्ट मेटाडेटा है; एप्लिकेशन हैंडलर को इसे लागू करना होगा - उत्पादन में हॉट-रीलोड सक्षम करें — बिना डाउनटाइम कॉन्फ़िग अपडेट के लिए
loader.watch()कॉल करें - कस्टम
TrustLevelAssignerलागू करें — डिफ़ॉल्ट जानबूझकर केवलAnonymousअसाइन करता है - प्रबंधन रूट्स को प्रमाणित करें — असुरक्षित राउटर से कभी भी सब्सक्रिप्शन CRUD उजागर न करें
- वास्तविक A2A डिस्पैच स्थापित करें — फ़ेल-क्लोज़्ड डिफ़ॉल्ट
503लौटाता है - स्थायी इवेंट डिलीवरी का उपयोग करें — डेस्टिनेशन नीति, क्यूइंग, और सीमित पुनःप्रयास लागू करें
- वेबहुक हस्ताक्षरों की पुष्टि करें — आने वाले वेबहुक पर
X-AWP-Signatureसत्यापित करें
संबंधित
- A2A प्रोटोकॉल — एजेंट-से-एजेंट संचार (AWP के पूरक)
- सर्वर परिनियोजन — एजेंटों को HTTP सर्वरों के रूप में चलाना
- पहुंच नियंत्रण — भूमिका-आधारित अनुमतियाँ
पिछला: ← A2A प्रोटोकॉल | अगला: मूल्यांकन →