返回結構契約 · 由發佈門禁強制執行
我們不會改這些字段。
而且這句話有一把鎖。
做 Agent 集成的人最怕的從來不是功能少,是某天我們改了返回結構,害他半夜起來修 bug。「我們不會亂改」這句話誰都會說 —— 所以我們把它變成一道發佈門禁:已發佈的標識符只要有一個消失或改名,我們自己的構建就過不去。
31
22
90 天
同一個問題,問兩次答案一樣
同一時刻、同一份名單下,同一個地址查兩次,判決、原因碼和證據鏈接完全一致。判決來自名單和確定性規則,不來自模型打分,所以不會因為「再問一次」而改變。
答案只會因為三件事而變化:名單本身更新了、鏈上情況變了(交易數、地址年齡、關聯的風險地址),或者判定規則調整了。每條返回都帶 evaluated_at(這次判定算出來的時刻)和 evidence_as_of(各份名單覆蓋到哪天)—— 事後復盤時,憑這兩個字段就能說清「當時為什麼這麼判」。
可以放心寫進代碼的
這四個是語言無關、結構穩定的。新值可能隨時增加 —— 遇到沒見過的值請當作「沒處理」,不要當作錯誤。
signal_keysverdictreason_coderetry千萬不要寫進代碼的
signals · note · advice
這些是給人讀的散文。會翻譯、會改措辭、會因為一次文案返修就全變。按它做邏輯,下一次改文案你就崩。
risk 分數的具體數值
0–100 這個刻度不變,但同一個地址得幾分會隨數據變好而變。用它排序可以,用它做閾值判決要自己承擔漂移。
數組裡的順序
signals、evidence 的順序不作承諾。
要改的話,我們必須怎麼做
- 新標識符先與舊的並存,兩個一起返回。
- 舊的在 /api/contract 裡標 deprecated,並寫明移除日期,至少 90 天之後。
- 到期才移除。
在第 2 步走完之前,門禁不會放行刪除 —— 這不是流程規定,是構建腳本里的一行判斷。
當前已登記的 signal_keys
按前綴分組。前綴本身也是穩定的:list.* 是名單命中,taint.* 是資金沾染,age.* 是地址年齡/活躍度,src.* 是數據源降級,scope.* 是覆蓋邊界,endpoint.* 是端點層。
age.activeage.active.tronage.brandnewage.brandnew.tronage.new7dage.new7d.tronage.receiveonlyendpoint.deep_subdomainendpoint.delistedendpoint.free_hostingendpoint.ip_literalendpoint.non_publicendpoint.parent_listedendpoint.phishing_listedendpoint.punycodefreeze.unknownfrozen.issuerfrozen.usdtintel.profilelabel.tronscanlist.delistedlist.oceanaltrelated.onehop.outscope.btcscope.solsrc.degradedsrc.onchainsrc.tron.degradedsrc.tronscantaint.onehoptaint.usdt當前已登記的 reason_codes
behavioral_anomalyclearelevated_risk_payeeidempotency_key_invalididempotency_key_reusedidempotency_request_in_progressintent_information_requiredintent_injection_markerinvalid_inputkey_ip_deniedkey_scope_deniedkya_proof_missingkya_unattributedkyc_requiredmandate_intent_mismatchmandate_revokedover_daily_limitover_per_tx_limitpayee_not_allowlistedreplay_detectedsanctioned_or_high_risk_payeescreening_unavailable機讀版本
GET https://oceanalt.com/api/contract
同一份內容,含語義說明與棄用清單。你的 CI 可以直接拉它做迴歸比對。

